控制台

实时交互

使用 MOSS-Live 通过一条 WebSocket 进行实时语音对话,并结合摄像头或屏幕共享进行画面理解。

Endpoint
WSS/v1/realtime
模型名称
moss-live-1.0
  1. 创建 API Key

    进入 API Key 管理平台 创建密钥,并仅在服务端环境变量中使用。

    环境变量
    MOSS_API_KEY=<your_api_key_here>
  2. 连接与鉴权

    使用服务端 WebSocket 客户端连接接口;在查询参数中指定模型,通过握手请求头传入 API Key。

    字段类型要求说明
    model: query string必填

    模型 ID,固定为 moss-live-1.0,放在 WebSocket 连接地址的查询参数中。

    Authorization: HTTP header必填

    Bearer <API Key>;只能放在 WebSocket 握手请求头中。

    连接地址
    wss://api.mosi.cn/v1/realtime?model=moss-live-1.0
    Authorization: Bearer $MOSS_API_KEY
  3. 配置会话

    连接成功后发送 attach_session,收到 session_attached 并保存 session_id 后,再用 session.update 配置人设与业务规则。等待 session.updated 并检查 data.error;为空字符串表示配置成功,之后再启用媒体。

    字段类型要求说明
    persona.prompt: string可选

    替换默认人设,最多 8000 字符。

    persona.name / aliases: string / array可选

    助手名称与别名,用于称呼识别和转写纠正。

    instructions: string可选

    业务规则,不改变人设;只传该字段时保留原人设。

    配置人设与业务指令
    {
      "action": "session.update",
      "session": {
        "persona": {
          "name": "小安",
          "aliases": [
            "安安"
          ],
          "prompt": "你是友好的助手小安,语气温和、简洁。"
        },
        "instructions": "请用一句简短的中文回答。"
      }
    }
  4. 发送实时语音和视频

    音频与画面共用一条 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"
    }
  5. 接收与展示回答

    展示 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
    }
  6. 结束对话

    停止屏幕将 source 改为 screen,同时停止该来源的 JPEG。仅停止画面不会结束会话或停止计费,音频仍使用 0x00 前缀。计费从 session_attached 到连接关闭,结束后异步结算。通话中不实时扣费,不因余额变化主动中断。

    停止摄像头
    {
      "action": "video.state",
      "source": "camera",
      "enabled": false
    }
    结束会话
    ws.close();
    stream?.getTracks().forEach(track => track.stop());
    // 清空音频队列,释放采集与播放资源。
  7. 验证成功

    收到 input.transcript.done、output.transcript.done 和音频,完成实际播放确认,最终收到 response.ended 且 data.status=completed,全程没有 error。

下一步