实时交互
使用 MOSS-Live 通过一条 WebSocket 进行实时语音对话,并结合摄像头或屏幕共享进行画面理解。
/v1/realtimemoss-live-1.0创建 API Key
进入 API Key 管理平台 创建密钥,并仅在服务端环境变量中使用。
环境变量 MOSS_API_KEY=<your_api_key_here>连接与鉴权
使用服务端 WebSocket 客户端连接接口;在查询参数中指定模型,通过握手请求头传入 API Key。
字段类型要求说明模型 ID,固定为 moss-live-1.0,放在 WebSocket 连接地址的查询参数中。
Bearer
<API Key>;只能放在 WebSocket 握手请求头中。连接地址 wss://api.mosi.cn/v1/realtime?model=moss-live-1.0 Authorization: Bearer $MOSS_API_KEY配置会话
连接成功后发送
attach_session,收到session_attached并保存session_id后,再用session.update配置人设与业务规则。等待session.updated并检查data.error;为空字符串表示配置成功,之后再启用媒体。字段类型要求说明替换默认人设,最多 8000 字符。
助手名称与别名,用于称呼识别和转写纠正。
业务规则,不改变人设;只传该字段时保留原人设。
配置人设与业务指令 { "action": "session.update", "session": { "persona": { "name": "小安", "aliases": [ "安安" ], "prompt": "你是友好的助手小安,语气温和、简洁。" }, "instructions": "请用一句简短的中文回答。" } }发送实时语音和视频
音频与画面共用一条 WebSocket。会话配置成功后,先启用所需输入。
启用输入 · 控制事件 // 开启麦克风 {"action":"mic_state","enabled":true} // 需要画面时,先启用 tagged-v1 {"action":"media.mode","binary_protocol":"tagged-v1"} // 开启摄像头;屏幕共享将 source 改为 screen {"action":"video.state","source":"camera","enabled":true}音频按实时速度持续发送,16 kHz、单声道 PCM S16LE;说话结束后继续发送静音帧。启用 tagged-v1 后,每条音频前加 0x00。
画面按每帧 JPEG 单独发送。启用 tagged-v1 后,摄像头帧前加 0x01,屏幕帧前加 0x02。
Node.js ws · 发送媒体 // ws 为已有连接,pcmBytes / jpegBytes 为采集后的 Buffer。 ws.send(Buffer.concat([Buffer.from([0x00]), pcmBytes])); // 音频 ws.send(Buffer.concat([Buffer.from([0x01]), jpegBytes])); // 摄像头 ws.send(Buffer.concat([Buffer.from([0x02]), jpegBytes])); // 屏幕选择关注来源:camera、screen 或 auto;auto 在两路画面都有输入时优先摄像头。
选择关注画面 { "action": "video.stream_focus", "source": "screen" }接收与展示回答
展示
input.transcript.done用户转写和output.transcript.done回答文本,按顺序播放 48 kHz、单声道 PCM S16LE,保留与response.audio.context的对应关系。每个音频块实际播放完后发送playback.chunk.completed;收到response.audio.done且本轮全部播放完成后,再发送playback.completed。不要等待回答文本结束才确认播放。收到response.audio.stop后停止对应播放,并发送playback.stopped,回传当前未确认音频块实际播放的时长。回答被打断时会收到response.interrupted;response.ended的data.status为completed、aborted或failed时,本轮都已结束。音频块播放完成 { "action": "playback.chunk.completed", "chunk_id": "<chunk_id>", "run_id": "<run_id>", "turn_id": "<turn_id>" }本轮播放完成 { "action": "playback.completed", "run_id": "<run_id>", "turn_id": "<turn_id>" }停止播放 { "action": "playback.stopped", "run_id": "<run_id>", "turn_id": "<turn_id>", "played_audio_ms": 1200 }结束对话
停止屏幕将 source 改为 screen,同时停止该来源的 JPEG。仅停止画面不会结束会话或停止计费,音频仍使用 0x00 前缀。计费从
session_attached到连接关闭,结束后异步结算。通话中不实时扣费,不因余额变化主动中断。停止摄像头 { "action": "video.state", "source": "camera", "enabled": false }结束会话 ws.close(); stream?.getTracks().forEach(track => track.stop()); // 清空音频队列,释放采集与播放资源。验证成功
收到
input.transcript.done、output.transcript.done和音频,完成实际播放确认,最终收到response.ended且data.status=completed,全程没有error。