Skip to content

事件协议

TiRTC AI 对讲在命令通道上传输控制事件。所有事件均使用 JSON-RPC 2.0,payload 为 UTF-8 JSON,TiRTC 命令字为:

c
#define TIRTC_AI_SIGNALING 0x2100

提示

此命令字 0x2100 属于 TiRTC 开发者应用层保留范围(0x2000 ~ 0xffff),并非 SDK 内部预留。你可以根据自己项目的实际情况更改该值,只需确保设备端和业务服务端协商一致,且不与 TiRTC 内部保留命令(小于 0x2000)冲突即可。

协议基础

JSON-RPC 消息分为两类:

类型特征说明
Requestid 字段发送方需要接收方返回成功或失败响应,例如 start_session
Notification不带 id 字段单向通知,不要求响应,例如 captioninterrupt

id 使用字符串。平台返回的 JSON-RPC 响应不带 method,设备端应使用响应中的 id 匹配原始请求。

通用 Request 结构:

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "method": "start_session",
  "params": {}
}

通用成功响应:

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "result": {}
}

通用失败响应:

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "error": {
    "code": -32602,
    "message": "Invalid params"
  }
}

事件总览

method方向类型说明
start_session设备 -> 平台Request建连后启动 AI 对讲会话。
caption平台 -> 设备Notification下发 ASR / TTS 字幕。
round_start平台 -> 设备Notification一轮回复音频开始。
round_end平台 -> 设备Notification一轮回复音频结束。
interrupt设备 -> 平台Notification主动打断当前回复。
submit_speech设备 -> 平台Notification手动提交当前上行语音。
update_config设备 -> 平台Request运行时更新会话配置,目前仅支持 extra_params
device_action平台 -> 设备Request平台请求设备执行声明过的设备能力。
end_session双向Notification结束当前会话。

start_session

方向:设备 -> 探鸽平台

TiRTC 连接建立后,设备端必须先发送 start_session,用于创建本次 AI 对讲会话。探鸽平台收到后会加载设备和角色配置,并返回会话 ID 与实际使用的音频格式。

请求示例:

json
{
  "jsonrpc": "2.0",
  "id": "start-session-001",
  "method": "start_session",
  "params": {
    "device_id": "DEMO_DEVICE_01",
    "role_id": "role_xxx",
    "input_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    },
    "output_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    }
  }
}

params 字段:

字段必填说明
device_id设备 ID。
role_id角色 ID,来自探鸽平台角色配置或设备角色绑定查询。
input_audio设备上行音频格式;不传时使用平台默认值(通常为 pcm)。推荐显式传入,以确保两端理解一致,避免兼容性风险。
output_audio平台下行音频格式;不传时使用平台默认值(通常为 pcm)。推荐显式传入,以确保两端理解一致,避免兼容性风险。

input_audiooutput_audio 均包含以下字段:

字段类型说明
codecstring音频编码格式。
sample_rateint采样率(Hz)。
channelsint声道数。

支持的音频格式

codec支持的采样率(Hz)支持的声道
opus160001
pcm1600080001
g711a1600080001
amr8000(NB)、16000(WB)1

说明:

  • 平台内部 ASR / LLM / TTS Pipeline 固定为 16 kHz 单声道;与内部格式不一致的上行音频会在平台侧重采样。
  • 会话实际使用的格式以 start_session 成功响应中的 input_audiooutput_audio 为准;设备端发送音频与解码下行音频时必须与响应一致。
  • 传入不支持的 codec、采样率或声道组合时,平台返回 JSON-RPC error,messageInvalid audio format

成功响应:

json
{
  "jsonrpc": "2.0",
  "id": "start-session-001",
  "result": {
    "session_id": "aivoice-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "input_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    },
    "output_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    }
  }
}

失败响应示例:

json
{
  "jsonrpc": "2.0",
  "id": "start-session-001",
  "error": {
    "code": -32602,
    "message": "Invalid audio format"
  }
}

设备收到失败响应后,应停止本次会话启动流程,并释放采集、播放等本地资源。

caption

方向:探鸽平台 -> 设备

caption 用于下发字幕。字幕可能来自用户语音识别,也可能来自平台回复内容。

示例:

json
{
  "jsonrpc": "2.0",
  "method": "caption",
  "params": {
    "text": "你好,有什么可以帮您?",
    "caption_type": 1,
    "is_final": true,
    "mode": 0,
    "utterance_id": 1001,
    "seq_num": 3,
    "begin_time_ms": 120,
    "end_time_ms": 1680
  }
}

params 字段:

字段必有说明
text字幕文本。
caption_type字幕来源:0 表示 ASR 用户字幕,1 表示 TTS 回复字幕。
is_final是否为该段话的最终字幕。
mode传输模式:0 表示全量文本,1 表示增量文本。
utterance_id话语 ID,同一段话的字幕共享同一个 ID。
seq_num序列号,用于同一段话内排序。
begin_time_ms字幕片段开始时间,单位毫秒;可能为空或为 0
end_time_ms字幕片段结束时间,单位毫秒;可能为空或为 0

合并建议:

  • 使用 caption_type + utterance_id 作为字幕分组键。
  • mode=1 时,将 text 追加到当前分组。
  • mode=0 时,用 text 替换当前分组内容。
  • is_final=true 时,将当前分组标记为最终文本。

ASR 增量示例:

json
{
  "jsonrpc": "2.0",
  "method": "caption",
  "params": {
    "text": "帮我",
    "caption_type": 0,
    "is_final": false,
    "mode": 1,
    "utterance_id": 2001,
    "seq_num": 1
  }
}
json
{
  "jsonrpc": "2.0",
  "method": "caption",
  "params": {
    "text": "帮我打开灯。",
    "caption_type": 0,
    "is_final": true,
    "mode": 0,
    "utterance_id": 2001,
    "seq_num": 3
  }
}

round_start

方向:探鸽平台 -> 设备

round_start 表示一轮平台回复音频开始。设备端可用它切换 UI 状态,例如点亮“正在说话”灯效、打开播放状态、启用回声抑制策略等。

示例:

json
{
  "jsonrpc": "2.0",
  "method": "round_start"
}

处理建议:

  • round_startround_end 通常成对出现。
  • 设备端不要仅依赖该事件决定是否播放音频,实际播放仍以音频流为准。
  • 收到 round_start 后,如果用户再次说话或按键打断,可发送 interrupt

round_end

方向:探鸽平台 -> 设备

round_end 表示一轮平台回复音频结束。设备端可用它恢复到等待用户输入状态,或清理本轮播放状态。

示例:

json
{
  "jsonrpc": "2.0",
  "method": "round_end"
}

处理建议:

  • 收到 round_end 后,设备端可以恢复拾音提示、关闭“正在说话”灯效。
  • 打断场景下,平台也会尽快下发 round_end,设备端应停止播放旧轮次缓冲。

interrupt

方向:设备 -> 探鸽平台

interrupt 用于主动打断当前回复。典型场景包括用户按键打断、唤醒词打断、业务逻辑要求立即停止当前播报等。

示例:

json
{
  "jsonrpc": "2.0",
  "method": "interrupt"
}

处理建议:

  • 发送后设备端应立即停止播放本地缓存中的旧回复音频。
  • 平台收到后会停止当前输出,并通过后续事件和音频流进入新状态。
  • 如果打断由用户语音触发,设备端也可以继续上行用户新一轮语音。

submit_speech

方向:设备 -> 探鸽平台

submit_speech 用于手动提交当前上行语音。典型场景包括按键松开发送、半双工对讲、UI 控件确认发送,或设备端本地 VAD 已判断用户说完一句话。

示例:

json
{
  "jsonrpc": "2.0",
  "method": "submit_speech"
}

处理建议:

  • 发送 submit_speech 后,平台会把当前已收到的上行语音视为已提交,并推动后续 ASR / LLM / TTS 流程。
  • submit_speech 不用于打断平台当前回复;如需停止正在播放或生成的回复,应发送 interrupt
  • 如果设备端只依赖平台云端 VAD 自动判断语音结束,通常不需要发送该事件。

update_config

方向:设备 -> 探鸽平台

update_config 用于在会话运行中更新少量动态上下文。当前仅支持 extra_params,常用于位置、业务状态等会随会话变化的信息。平台会把新的 extra_params 合并到当前会话,不会改写欢迎语、音色、系统提示词等静态配置。

请求示例:

json
{
  "jsonrpc": "2.0",
  "id": "update-config-001",
  "method": "update_config",
  "params": {
    "extra_params": {
      "latitude": 39.9800718,
      "longitude": 116.309314
    }
  }
}

成功响应:

json
{
  "jsonrpc": "2.0",
  "id": "update-config-001",
  "result": {
    "success": true,
    "message": "更新配置成功"
  }
}

失败响应示例:

json
{
  "jsonrpc": "2.0",
  "id": "update-config-001",
  "error": {
    "code": -32602,
    "message": "update_config only supports extra_params, got \"voice\""
  }
}

注意事项:

  • 响应是 JSON-RPC response,不会返回 method: "config_updated"
  • 设备端应通过响应里的 id 匹配 update_config 请求。
  • extra_params 外的字段会被拒绝。

device_action

方向:探鸽平台 -> 设备

当角色配置中声明了设备能力,平台可能通过 device_action 请求设备执行动作。该消息是 JSON-RPC Request,设备必须保留 id 并在执行完成后返回同一个 id 的 response。

平台下发示例:

json
{
  "jsonrpc": "2.0",
  "id": "device-action-001",
  "method": "device_action",
  "params": {
    "action": "set_light",
    "data": {
      "power": "on"
    }
  }
}

设备执行成功响应:

json
{
  "jsonrpc": "2.0",
  "id": "device-action-001",
  "result": {
    "ok": true,
    "data": {
      "power": "on"
    }
  }
}

设备执行失败响应:

json
{
  "jsonrpc": "2.0",
  "id": "device-action-001",
  "error": {
    "code": -32000,
    "message": "device is busy"
  }
}

end_session

方向:双向

end_session 用于结束当前 AI 对讲会话。设备端主动结束、平台策略结束、用户语义触发结束时都可以使用该事件。

设备到平台示例:

json
{
  "jsonrpc": "2.0",
  "method": "end_session"
}

平台到设备示例:

json
{
  "jsonrpc": "2.0",
  "method": "end_session"
}

处理建议:

  • 设备端收到或发送 end_session 后,应停止采集、停止播放,并释放本地会话状态。
  • 结束流程需要可幂等执行,避免重复事件导致崩溃或资源泄漏。
  • 如果需要关闭 TiRTC 连接,可在本地资源释放后断开连接。

设备端接收示例

c
#include <stdint.h>
#include <string.h>
#include "tiRTC.h"

#define TIRTC_AI_SIGNALING 0x2100

static void on_command(tirtc_conn_t hconn, uint32_t cmdw,
                       const void *data, uint32_t len)
{
    (void)hconn;
    if (cmdw != TIRTC_AI_SIGNALING || data == NULL || len == 0) {
        return;
    }

    /* data 是 UTF-8 JSON-RPC 字符串。
     * 生产代码中请使用 JSON 库解析 method / params,
     * 然后分发到 caption、round_start、round_end、interrupt、submit_speech、device_action、end_session 等处理函数。 */
}

自检清单

  • 命令字使用 0x2100
  • 所有 payload 均为合法 UTF-8 JSON。
  • start_sessionid,并处理成功/失败响应。
  • role_id 必传且有效。
  • 已处理 caption 的增量和全量模式。
  • 已处理 round_start / round_end 状态切换。
  • 已实现 interrupt 的本地立即停止播放逻辑。
  • 如需手动提交语音,已实现 submit_speech 的发送逻辑。
  • 如需运行时更新配置,已按 id 处理 update_config 的 JSON-RPC response。
  • 如需设备能力调用,已按 id 处理 device_action 请求和响应。
  • 已实现 end_session 的幂等清理逻辑。

AI Chat 文档