使用 DevTools CLI
DevTools CLI 是 TiRTC 的开发联调工具,完整源代码可以在 tirtc-developer-tools 获取。
没有真实设备端时,你可以用它在电脑上启动一个模拟设备端;需要复现连接、音视频、命令、流消息或语音对讲链路时,也可以用它快速搭建一套可控环境。
常用能力包括:
- 提供两种开发期 token 获取方式:生成一次性 token 和二维码,或启动 token HTTP 服务。
- 在 macOS 或 Linux 上启动模拟设备端,向客户端发送设备端音视频。
- 收到客户端发来的命令消息后,用相同的
cmdw(命令字)和 payload 回发一条命令,便于检查命令收发链路。 - 按固定周期发送流消息,便于检查客户端是否能持续接收。
- 在 macOS arm64 或 x64 上使用系统摄像头 / 麦克风作为模拟设备端的音视频源,并播放客户端发送过来的麦克风音频,用于验证语音对讲。
使用前准备
开始前准备以下内容:
| 准备项 | 用在哪里 |
|---|---|
| Node.js / npm | 安装和运行 CLI |
AccessKeyId、SecretKeyId、AppId | 生成客户端连接 token |
device_id、device_secret_key | 启动模拟设备端、生成客户端连接 token |
运行环境
CLI 当前支持:
| 平台 | 支持能力 |
|---|---|
| macOS arm64 | 一次性 token 与二维码、token HTTP 服务、文件输入、系统摄像头 / 麦克风输入、系统音视频输出、本地预览 |
| macOS x64 | 一次性 token 与二维码、token HTTP 服务、文件输入、系统摄像头 / 麦克风输入、系统音视频输出、本地预览 |
| Linux x86_64 | 一次性 token 与二维码、token HTTP 服务、文件输入、文件输出 |
如果要测试语音对讲,请使用 macOS arm64 或 x64。--input system 会使用 Mac 摄像头 / 麦克风作为模拟设备端的音视频源;--output both 会在 Mac 上播放客户端发送过来的麦克风音频,并保留文件输出,方便排查。
安装并确认版本
使用 npm 官方源安装或更新 CLI,避免本地配置的第三方镜像返回旧版本:
npm install -g tirtc-devtools-cli@latest --registry=https://registry.npmjs.org安装后检查版本:
tirtc-devtools-cli --version请确认版本不低于 0.6.9,再继续使用下面的命令。
配置联调凭证
在运行 CLI 的机器上设置这些环境变量:
export TIRTC_ACCESS_KEY_ID="your_access_key_id"
export TIRTC_SECRET_KEY_ID="your_secret_key_id"
export TIRTC_APP_ID="your_app_id"
export TIRTC_DEVICE_ID="your_device_id"
export TIRTC_DEVICE_SECRET_KEY="your_device_secret_key"客户端连接目标设备时,remote_id 传上述 TIRTC_DEVICE_ID。如果后面使用 CLI 启动模拟设备端,这个值也会作为模拟设备端的 device_id。
这些凭证只应放在受控开发环境中,不要写进客户端代码、日志、截图或工单。
如果你要同时调试多台设备,可以用 JSON 文件按 device_id 映射 device_secret_key,并设置:
export TIRTC_DEVICE_SECRET_MAP="./device-secrets.json"device-secrets.json 示例:
{
"device-001": "device_001_secret_key",
"device-002": "device_002_secret_key"
}选择要完成的联调任务
根据你的联调目标选择对应内容,不需要从上到下全部执行:
| 你的目标 | 阅读位置 |
|---|---|
| 为客户端获取连接 token | 为客户端准备连接 token |
| 没有真实设备端,需要启动一个可连接的设备端 | 启动模拟设备端 |
| 验证客户端与模拟设备端的完整链路 | 分别准备 token、启动模拟设备端,再进入联调客户端与模拟设备端 |
为客户端准备连接 token
DevTools CLI 提供两种方式准备客户端连接 token。token issue 会直接生成一次性 token 和二维码;token serve 会启动一个 HTTP 服务,供客户端在连接前请求 token。
使用 token issue 或 token serve 准备连接 token 时,目标设备不需要在线,也不需要先启动真实设备或 CLI 模拟设备端。客户端实际发起连接时,目标设备才需要已经启动并在线。
方式一:生成一次性 token 和二维码
token issue 的参数是客户端要连接的目标设备 remote_id。连接真实设备时,传入真实设备的 device_id;连接 CLI 模拟设备端时,传入 TIRTC_DEVICE_ID:
tirtc-devtools-cli token issue "$TIRTC_DEVICE_ID"执行时,CLI 会读取准备好的环境变量,用它们生成客户端连接 token:
TIRTC_ACCESS_KEY_IDTIRTC_SECRET_KEY_IDTIRTC_APP_IDTIRTC_DEVICE_SECRET_KEY,或TIRTC_DEVICE_SECRET_MAP
通常不需要配置 endpoint。需要指定接入地址时,可以追加:
tirtc-devtools-cli token issue "$TIRTC_DEVICE_ID" \
--endpoint "<SERVICE_ENTRY>"成功后,CLI 会输出:
AppIdremote_id- 连接
token - Payload JSON,包含
AppId、remote_id、token和可选 endpoint - 终端二维码
- 本地二维码 PNG 文件路径
二维码里包含客户端连接所需的 AppId、remote_id 和 token。Flutter Android 客户端可以直接扫码导入这些字段;也可以打开 CLI 输出的 PNG 文件扫码。
一次性 token 有防重放语义。每次重新连接或连接失败后重试,都重新运行一次 token issue,使用新生成的二维码或 token。
方式二:启动 token 签发 HTTP 服务
token serve 会启动开发用 HTTP 服务。客户端在进入播放页前向这个服务请求 token,用来连接客户端指定的目标设备。
tirtc-devtools-cli token serve \
--port 8966token serve 默认监听 8966 端口。如果这个端口已经被占用,可以换成其他端口,后面客户端填写的服务地址也要使用同一个端口。
启动成功后,CLI 会输出:
- 开发用 token 服务监听地址
- 客户端应填写的 Token 签发服务地址
- HTTP 请求 body 和 cURL 示例
保持这个终端打开。手机和电脑在同一 Wi-Fi / 局域网下时,客户端填写的 Token 签发服务地址通常是:
http://your_computer_lan_ip:8966不要把 127.0.0.1 填到手机上的客户端里;它指向的是手机自己,不是运行 CLI 的电脑。
这个服务只适合开发和受控联调。它不负责识别请求 token 的用户,也不判断该用户是否有权限访问目标设备。生产环境应由你的业务服务端完成登录鉴权、设备权限判断和 token 签发。
启动模拟设备端
模拟设备端有两种获取音视频数据方式:
| 方式 | 支持平台 | 适合验证 |
|---|---|---|
| 本地文件输入 | macOS arm64 / x64、Linux x86_64 | 连接、设备端发送音视频、命令交互、流消息 |
| 系统摄像头 / 麦克风输入 | macOS arm64 / x64 | 连接、设备端发送音视频、命令交互、流消息、语音对讲 |
方式一:本地文件输入
本地文件输入适合验证连接、设备端发送音视频、命令交互和流消息。
模拟设备端会循环发送你准备好的 MP4。启动前,先用 input prepare 把 MP4 写入 --cache-dir,供后续 device start --input file 读取。
如果你还没有自己的 MP4,可以先下载下面的建议资源:
mkdir -p .build/tirtc-source
curl -L "https://download.tangeopen.com/TIRTC_OPEN_DOC/assets/sea.mp4" \
-o .build/tirtc-source/sea.mp4准备文件输入缓存:
tirtc-devtools-cli --json input prepare \
--file .build/tirtc-source/sea.mp4 \
--cache-dir cache/tirtc-file-device再启动模拟设备端:
tirtc-devtools-cli --json device start \
--input file \
--output file \
--video-codec h264 \
--audio-codec g711a \
--audio-sample-rate 16000 \
--audio-channels 1 \
--cache-dir cache/tirtc-file-device这个命令会读取文件输入缓存,把音视频发送给已连接的客户端。收到客户端发来的命令消息后,CLI 会用相同的 cmdw 和 payload 回发一条命令,并每 10 秒在视频流 stream_id = 11 上发送一条流消息。
方式二:系统摄像头 / 麦克风输入
tirtc-devtools-cli --json device start \
--input system \
--preview \
--output both \
--video-codec h264 \
--audio-codec g711a \
--audio-sample-rate 16000 \
--audio-channels 1 \
--cache-dir cache/tirtc-flutter-client-test命令启动时,系统可能会弹出摄像头、麦克风等权限提示;在这些提示里点击“允许”。如果终端提示需要授权,也按提示完成授权后重新运行命令。
这个命令会做几件事:
- 开始采集电脑摄像头 / 麦克风的音视频。
- 在电脑上打开本地预览窗口。
- 等待客户端连接。
- 收到客户端发来的命令消息后,用相同的
cmdw和 payload 回发一条命令。 - 每 10 秒在视频流
stream_id = 11上发送一条流消息,payload 是当前 epoch 秒字符串。 - 接收客户端发送的本地音频,默认接收
stream_id = 14。 - 用 Mac 系统输出播放收到的客户端音频。
如果客户端还没有打开麦克风或还没有发送本地音频,CLI 会继续等待;这不表示设备端启动失败。
音视频格式参数
上面两种启动方式都可以通过参数调整模拟设备端发送给客户端的音视频格式。常规联调保持示例命令里的 h264、g711a、16000、1 即可。
--video-codec 支持:
| 值 | 说明 |
|---|---|
h264 | 默认值,适合常规客户端联调 |
h265 | 用于验证客户端 H.265 解码 |
mjpeg | 用于验证客户端 MJPEG 解码 |
音频相关参数:
| 参数 | 可选值 | 默认值 | 说明 |
|---|---|---|---|
--audio-codec | g711a / aac / pcm / opus / amr | g711a | 选择模拟设备端发送的音频编码。amr 按 AMR-NB 处理,只支持 8000 Hz、单声道 |
--audio-sample-rate | 8000 / 16000 | 16000 | 选择音频采样率 |
--audio-channels | 1 / 2 | 1 | 选择单声道或双声道 |
文件输入方式下,input prepare 会把上表支持的格式写入同一个 --cache-dir。后续启动 device start --input file 时,继续使用这个 --cache-dir,再按需调整音视频格式参数即可。
模拟设备端发送给客户端的音视频使用固定 stream_id:
| 媒体 | stream_id |
|---|---|
| 音频 | 10 |
| 视频 | 11 |
使用系统摄像头 / 麦克风输入做语音对讲时,CLI 默认接收客户端本地音频 stream_id = 14。
启动成功后,先看这条日志:
[device] listener ready; waiting for client connections没有客户端连接不算启动失败。默认情况下,device start 会持续运行,直到你结束进程。
联调客户端与模拟设备端
要验证客户端与模拟设备端的完整链路,先选择一种方式准备 token,并启动模拟设备端。
连接客户端
客户端连接这个模拟设备端时,remote_id 填 TIRTC_DEVICE_ID;音频 stream_id 使用 10,视频 stream_id 使用 11。
如果使用 Flutter Android Example 作为参考客户端,在 Android 手机上安装并打开:
使用一次性 token 和二维码连接
- 点击右上角扫码按钮,允许相机权限。
- 扫描
token issue输出的终端二维码,或打开本地二维码 PNG 文件扫码。 - 回到配置页后,确认
AppId、remote_id、token已填入。 - 音频
stream_id使用10,视频stream_id使用11。如果输入框为空,Example 会使用默认值10/11。 - 点击「进入播放页」。
使用 token HTTP 服务连接
使用 token serve 时,在配置页填写:
AppId填配置联调凭证时设置的TIRTC_APP_ID。remote_id填模拟设备端使用的TIRTC_DEVICE_ID。- “Token 签发服务地址”填
token serve输出的服务地址,例如http://your_computer_lan_ip:8966。 - 音频
stream_id使用10,视频stream_id使用11。如果输入框为空,Example 会使用默认值10/11。 - 点击「进入播放页」。
看到画面后,说明连接和视频接收已经跑通。CLI 终端通常会出现类似日志:
[device] client connected session=1
[device] first audio packet sent session=1
[device] first video packet sent session=1 codec=h264验证命令交互
在客户端向设备端发送一条命令消息。CLI 模拟设备端收到后,会把这条命令的 cmdw 和 payload 原样回发给客户端。这里的 cmdw 和 payload 按命令消息传输的口径理解:cmdw 是双方约定的命令字,payload 是命令携带的数据。
这只是联调用来验证链路的默认行为,不代表你的业务必须回显命令。客户端能收到这条回发消息,就说明命令收发链路可用。
如果使用 Flutter Android Example,播放页右上角有「发送命令」入口。
验证步骤:
- 点击「发送命令」。
- 选择
Echo预设。 - 点击「发送」。
- 在命令面板里确认能看到发送记录和接收记录。
验证流消息
CLI 模拟设备端会持续发送流消息:
stream_id:11- 发送周期:约 10 秒
- payload:当前 epoch 秒字符串
客户端需要能持续收到这些流消息。如果使用 Flutter Android Example,收到后会在播放页画面上显示类似:
流消息:1760000000验证语音对讲
语音对讲需要使用系统摄像头 / 麦克风输入方式启动模拟设备端。
如果使用的是本地文件输入,则跳过这一项;文件输入路径不打开 Mac 麦克风,也不播放客户端麦克风音频。
客户端 API 级接入方式见语音对讲。
对讲前,先确认设备端和客户端的本地音频设置。
设备端是否打开 AEC 由模拟设备端的启动命令决定。CLI 的采集侧 AEC 只支持单声道系统输入,示例命令已经是 --audio-channels 1,不要改成 --audio-channels 2。需要处理 Mac 麦克风采集时,在系统输入启动命令里加入:
--audio-input-aec enabled这个参数处理 Mac 麦克风采集,主要影响客户端听到的声音;不需要时不加这个参数。
客户端本地音频需要使用 stream_id = 14。以 Flutter Android Example 为例,进入播放页前,在配置页点击「偏好设置」,进入「本地音频采集与传输」:
- 「传输 Stream ID」设为
14。 - 如果要处理 Android 手机麦克风采集产生的回声,把「AEC」开关打开。这主要影响 Mac 上听到的客户端声音。
设置完成后回到配置页,点击「进入播放页」。
进入播放页后:
- 在 Flutter Android Example 点击「启动麦克风」;其他客户端则打开本地麦克风发送。
- 对客户端设备说话。
- 在运行 CLI 的 Mac 上确认能听到客户端麦克风声音。
- 对 Mac 麦克风说话,确认客户端仍能听到设备端发送的声音。
- 测试结束后点击「停止麦克风」,或在其他客户端关闭本地麦克风发送。
CLI 可以帮助确认音频链路在收发,但不能替代人工判断回声消除效果和通话听感。
常见问题
安装后 CLI 版本仍低于 0.6.9
重新使用 npm 官方源安装最新版本:
npm install -g tirtc-devtools-cli@latest --registry=https://registry.npmjs.org如果 tirtc-devtools-cli --version 仍显示旧版本,检查当前命令是否指向另一份历史安装:
type -a tirtc-devtools-cli确认终端优先使用本次 npm 全局安装生成的可执行文件,再重新检查版本。
连接失败
优先检查:
device start终端是否仍在运行。remote_id是否等于TIRTC_DEVICE_ID。- 使用
token issue时,扫码后配置页里的AppId、remote_id、token是否已经填入;连接失败后是否重新生成并扫描新的二维码。 - 使用
token serve时,token serve终端是否仍在运行,手机能否访问 Token 签发服务地址。手机真机不要填写127.0.0.1。 - 是否改动过 endpoint 相关高级参数。常规联调不需要配置 endpoint,保持 CLI 默认值即可。
客户端连接后没有声音或画面
优先检查:
- 客户端音频是否使用
stream_id = 10,视频是否使用stream_id = 11。 - 如果使用系统摄像头 / 麦克风输入,macOS 是否允许 CLI 使用摄像头和麦克风。
- 客户端是否已经进入播放页,并且视频视图没有被遮挡。
- 当前客户端版本是否支持所选视频编码;常规联调用
h264。
系统输入启动时报 asset_missing
优先检查:
- CLI 版本是否不低于
0.6.9。系统摄像头 / 麦克风输入不需要 MP4 文件输入缓存;旧版本可能仍按文件输入路径做检查,导致误报asset_missing。 - 命令是否明确传了
--input system,并且没有混用旧的--source参数。 - 如果你实际想走本地文件输入,先下载建议的 MP4,然后执行
input prepare --file .build/tirtc-source/sea.mp4,再用同一个--cache-dir启动device start --input file。
Mac 听不到客户端麦克风声音
优先检查:
- CLI 设备端是否使用
--input system --output both启动。 - 客户端发送本地音频的
stream_id是否为14。 - 客户端是否已经打开麦克风或本地音频发送。
- 客户端系统是否已授予应用麦克风权限。
- Mac 系统输出设备是否正确,音量是否可听。
如果 device/summary.json 里的 media_receive.reason_code 是 audio_receive_pending,表示 CLI 还没有收到客户端麦克风音频。先检查客户端麦克风、本地音频发送开关和 stream_id。
仍然失败时,保留 CLI 终端输出、当前 --cache-dir 下的 device/summary.json 和客户端日志。对外发送前,先删除或打码连接 token、SecretKeyId、device_secret_key 等敏感信息。