Use DevTools CLI
DevTools CLI is the TiRTC development and integration tool. Use it to issue client connection tokens, or start a local simulated device on macOS or Linux so a client can connect, render audio/video, exchange commands, and receive stream messages.
This page focuses on one common test path: start a simulated device with the CLI, then connect it from a client. The client can be your own app, or a public example such as the Flutter Android Example. Connection, rendering, command echo, and stream messages can be verified on macOS or Linux; talkback requires macOS arm64.
You will verify:
- the client connects to the device and renders video;
- the client sends a command and receives the echoed response;
- the client keeps receiving stream messages from the device;
- when using macOS arm64 system input/output, the client enables its microphone and sends audio to the Mac, while the CLI plays the received remote audio.
Runtime
CLI support:
| Platform | Supported capabilities |
|---|---|
| macOS arm64 | token, fixed file input, system camera / microphone input, system audio/video output, local preview |
| Linux x86_64 | token, fixed file input, file output |
Use macOS arm64 for talkback testing. --input system uses the Mac camera and microphone, and --output both plays the client's uplink audio on the Mac while keeping file evidence.
Prerequisites
| Item | Used for |
|---|---|
| Node.js / npm | Install and run the CLI |
AccessKeyId, SecretKeyId, AppId | Issue client connection tokens |
device_id, device_secret_key | Start the simulated device |
| Client app | Your TiRTC client; if you do not have one ready, use the Flutter Android Example as a reference |
Install or update the CLI:
npm install -g tirtc-devtools-cli@latestMake sure the CLI version is 0.6.5 or later:
tirtc-devtools-cli --versionCheck the installation:
tirtc-devtools-cli --help1. Configure Credentials
Set these environment variables on the machine that runs the 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"When the client connects to this simulated device, its remote_id must be the same TIRTC_DEVICE_ID.
For multiple devices, use a JSON file that maps device_id to device_secret_key:
export TIRTC_DEVICE_SECRET_MAP="./device-secrets.json"Example:
{
"device-001": "device_001_secret_key",
"device-002": "device_002_secret_key"
}2. Start the Simulated Device
The simulated device has two input modes. Linux supports local file input only. For talkback testing, use system camera / microphone input on macOS arm64.
| Mode | Supported platforms | Best for |
|---|---|---|
| Local file input | macOS arm64 / Linux x86_64 | connection, rendering, command echo, stream messages |
| System camera / microphone input | macOS arm64 | connection, rendering, command echo, stream messages, talkback |
Option 1: Local File Input
Local file input is the cross-platform path for connection, rendering, command echo, and stream message tests. It does not use the camera or microphone, and it is not the talkback path.
Use this option when you want a no-camera device downlink test. For talkback, switch to Option 2: System Camera / Microphone Input.
The simulated device loops the MP4 you prepare. Before starting it, run input prepare to convert the MP4 into the fixed input used by device start --input file.
If you do not have your own MP4 yet, download this suggested file first:
mkdir -p .build/tirtc-source
curl -L "https://download.tangeopen.com/TIRTC_OPEN_DOC/assets/sea.mp4" \
-o .build/tirtc-source/sea.mp4Prepare the fixed file input:
tirtc-devtools-cli --json input prepare \
--file .build/tirtc-source/sea.mp4 \
--cache-dir cache/tirtc-file-deviceStart the simulated 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-deviceThis command sends downlink audio/video from the local file, waits for a client to connect, automatically echoes commands received from the client, and sends one stream message every 10 seconds on video stream_id = 11.
Option 2: System Camera / Microphone Input
System camera / microphone input is supported on macOS arm64 only. Use this mode for talkback testing:
This mode reads directly from the Mac system camera and microphone. You do not need to run input prepare first, and this mode does not depend on the fixed media assets generated for local file input.
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-testWhen the command starts, macOS may show camera, microphone, and local network permission prompts. Click Allow. If the terminal indicates that permission is required, grant it and rerun the command.
This command:
- uses the Mac camera and microphone as the device downlink audio/video source;
- opens a local preview window on the Mac;
- waits for a client to connect;
- automatically echoes commands received from the client;
- sends one stream message every 10 seconds on video
stream_id = 11; the payload is the current epoch seconds string; - receives the client's local audio uplink on
stream_id = 14by default; - plays the received client uplink audio on the Mac.
If the client has not enabled its microphone or local audio uplink yet, the CLI keeps waiting for that audio. This does not mean the simulated device failed to start.
Audio Processing Options
System input does not enable audio 3A processing by default. The default is equivalent to:
--audio-input-aec disabled \
--audio-input-agc disabled \
--audio-input-ans disabledTo enable AEC on the Mac microphone input side, append this option to the device start command above:
--audio-input-aec enabledTo also test automatic gain control or noise suppression, append these options as needed:
--audio-input-agc medium \
--audio-input-ans mediumThese input-side options apply only to --input system, and they require --audio-channels 1. The CLI has input-side AEC only. The output side supports --audio-output-agc and --audio-output-ans, and those options apply only with --output system or --output both.
To verify CLI-side AEC in this run, use this complete command:
tirtc-devtools-cli --json device start \
--input system \
--preview \
--output both \
--video-codec h264 \
--audio-codec g711a \
--audio-sample-rate 16000 \
--audio-channels 1 \
--audio-input-aec enabled \
--cache-dir cache/tirtc-flutter-client-testTo explicitly disable AEC, change that line to --audio-input-aec disabled, or remove the line. The default is disabled.
The simulated device uses fixed downlink stream IDs:
| Media | stream_id |
|---|---|
| Device audio downlink | 10 |
| Device video downlink | 11 |
When using system camera / microphone input for talkback, the CLI receives the client's local audio uplink on stream_id = 14 by default.
When startup succeeds, first check for this log:
[device] listener ready; waiting for client connectionsNo connected client is not a startup failure. By default, device start keeps running until you stop it.
3. Issue a One-Time Connection Token
Open another terminal and issue a one-time token for the client:
tirtc-devtools-cli token issue "$TIRTC_DEVICE_ID"You usually do not need to configure an endpoint. The CLI uses the default access endpoint and writes the connection information into the QR code.
On success, the CLI prints:
AppId;remote_id;- connection
token; - terminal QR code;
- local QR PNG path.
A client with QR scan support can scan this QR code to fill the connection information. Connection tokens have anti-replay semantics. Before every new scan, reconnect attempt, or retry after a failed connection, run token issue again and use the new QR code.
4. Connect a Client
The client must use the AppId, remote_id, and connection token printed by token issue to connect to this simulated device. Use audio stream_id = 10 and video stream_id = 11.
If you use the Flutter Android Example as a reference client, install and open it on an Android phone:
Connection steps:
- Tap the scan button in the upper-right corner and allow camera access.
- Scan the QR code printed by
token issue. - After returning to the configuration page, check that
AppId,remote_id, andtokenare filled. - Use audio
stream_id = 10and videostream_id = 11. If the stream ID fields are empty, the Example uses defaults10/11. - Enter the playback page.
When video appears, connection and video downlink are working. The CLI terminal usually prints logs similar to:
[device] client connected session=1
[device] first audio packet sent session=1
[device] first video packet sent session=1 codec=h2645. Verify Command Echo
Send one command from the client to the device. The CLI simulated device sends back the same command ID and payload for every command it receives. Receiving the response confirms that the command request/response path works.
If you use the Flutter Android Example, the playback page has a command button in the upper-right corner.
Steps:
- Tap the command button.
- Select the
Echopreset. - Tap send.
- In the command panel, confirm that both the sent record and the received record are shown.
6. Verify Stream Messages
The CLI device keeps sending stream messages:
- stream ID:
11; - period: about 10 seconds;
- payload: current epoch seconds string.
The client should keep receiving these stream messages. If you use the Flutter Android Example, it shows a bubble on the playback page after receiving one:
流消息:1760000000Keep the playback page open and confirm that the bubble keeps refreshing. Receiving only one message is not enough to prove continuous delivery.
7. Verify Talkback
Talkback requires the system camera / microphone input mode in Step 2.
If you selected local file input in Step 2, skip this step. The file input path does not open the Mac microphone and does not play the client uplink audio.
Before testing talkback, confirm that the client's local audio uplink uses stream_id = 14. If you use the Flutter Android Example, open preferences and confirm that the local audio uplink stream ID is 14.
Then return to the playback page:
- Enable the microphone or local audio uplink in the client.
- Speak into the client device.
- Confirm that the Mac running the CLI can play the client uplink audio.
- Speak into the Mac microphone and confirm that the client still plays the device downlink audio.
- Disable the client microphone or local audio uplink when the test is done.
If you hear obvious echo during the call, enable client-side AEC and repeat the test. Keep other audio processing options at their defaults for the common path; adjust them only when you need a focused listening comparison. Automation can prove that the link stays healthy, but it cannot replace manual evaluation of echo cancellation, gain, or noise suppression quality.
CLI-side AEC and client-side AEC work at different points. --audio-input-aec enabled processes the Mac microphone input and mainly affects the device downlink audio heard by the client. Client-side AEC processes the client microphone input and mainly affects the client uplink audio heard on the Mac.
Optional: Start a Token HTTP Service
token serve starts an HTTP service that simulates your backend's token issuing step. Use it when you want the client to request a short-lived token from a service before connecting.
tirtc-devtools-cli token serve \
--port 8966In the client configuration page, use an address that the client can access, for example:
http://your_computer_lan_ip:8966This service is only for development and controlled integration. It does not implement login, user identity checks, or device access authorization. Production tokens should be issued by your backend after those checks.
Common Failures
QR Scan Succeeds but Connection Fails
Check:
- whether the
device startterminal is still running; - whether
remote_idequalsTIRTC_DEVICE_ID; - whether
token issueused the current device'sTIRTC_DEVICE_ID; - whether you issued and scanned a fresh QR code after a failed connection;
- whether endpoint-related advanced options were changed. For the common integration path, do not configure an endpoint and keep the CLI defaults.
Client Connects but Has No Audio or Video
Check:
- whether the client uses audio
stream_id = 10and videostream_id = 11; - if you use system camera / microphone input, whether macOS allowed the CLI to use the camera and microphone;
- whether the client has entered the playback page and the video view is visible;
- whether the selected video codec is supported by the client. Use
h264for the common path.
System Input Reports asset_missing
Check:
- whether the CLI version is
0.6.5or later. System camera / microphone input does not need fixed media assets; older versions may still run the file-input asset check, miss the packaged scripts required by file input prepare, or treat missing client talkback audio as a device failure. - whether the command explicitly passes
--input systemand does not mix in the legacy--sourceoption. - if you actually want local file input, download the suggested MP4 first, then run
input prepare --file .build/tirtc-source/sea.mp4and startdevice start --input filewith the same--cache-dir.
The Mac Cannot Hear the Client Uplink Audio
Check:
- whether the CLI device was started with
--input system --output both; - whether the client local audio uplink stream ID is
14; - whether the client microphone or local audio uplink has been enabled;
- whether the client system has granted microphone permission to the app;
- whether the Mac output device and volume are correct.
If device/summary.json reports media_receive.reason_code as audio_receive_pending, the CLI has not received the client uplink audio yet. Check the client microphone, local audio uplink switch, and stream_id first.
If the issue remains, keep the CLI terminal output, cache/tirtc-flutter-client-test/device/summary.json, and client logs. Before sharing logs, remove or mask connection tokens, SecretKeyId, device_secret_key, and other secrets.