Device Integration
The goal of device integration is to establish a TiRTC connection with the peer_id and token delivered by your application server, then handle uplink and downlink audio, room events, and cleanup when leaving the room.
This page assumes that the device has completed TiRTC SDK integration. If not, complete the TiRTC device integration first.
Prerequisites
Before calling TiRtcWhipConnect, the device must complete the TiRTC device-side startup flow:
- Call
TiRtcInit()to initialize the SDK. - Set
device_secret_keyaccording to the TiRTC device integration requirements, then callTiRtcStart(device_id, &callbacks)to start the device side. - Wait for
TIRTC_EVENT_SYS_STARTED, then callTiRtcWhipConnect(peer_id, token, ...)to join Room.
Calling TiRtcWhipConnect immediately after TiRtcInit() is not the minimum Room device connection path and may leave the SDK without the required device identity or platform connection context. For the TiRTC startup flow, see Connect Devices.
Connection Steps
- Complete TiRTC initialization and device-side startup, then wait for
TIRTC_EVENT_SYS_STARTED. - Obtain
peer_idandtokenfrom your application server. - Call TiRTC
TiRtcWhipConnectwith thepeer_idandtokendelivered by your application server. - Wait for TiRTC to report the connection result.
- After the connection is ready, send
join_room, then start uplink audio only after validation succeeds. - Listen for downlink audio and decode it according to
output_audioin thejoin_roomresponse. - Listen on command channel
0x2200for room snapshots and participant events. - When actively leaving, send
leave_roomfirst. Enter resource cleanup after receiving a room close notification or after the signaling is sent.
Pass both peer_id and token to the TiRTC TiRtcWhipConnect API unchanged. Do not parse peer_id or rewrite it into another parameter set on the device side.
Connection Example
After receiving peer_id and token, call the TiRTC SDK directly to establish the connection. A 0 return value from TiRtcWhipConnect only means the connection request was submitted. Treat the callback with err == 0 as the success signal.
#include "tiRTC.h"
#include <stdbool.h>
#include <string.h>
static tirtc_conn_t g_room_conn = NULL;
static bool g_tirtc_ready = false;
static int room_tirtc_runtime_init(const char *device_id)
{
if (g_tirtc_ready) {
return 0;
}
int ret = TiRtcInit();
if (ret != 0) {
return ret;
}
TIRTCCALLBACKS cbs;
memset(&cbs, 0, sizeof(cbs));
ret = TiRtcStart(device_id, &cbs);
if (ret != 0) {
TiRtcUninit();
return ret;
}
g_tirtc_ready = true;
return 0;
}
static void on_room_whip(int err, tirtc_conn_t hconn, void *user_data)
{
(void)user_data;
if (err != 0) {
/* Connection failed: log the error and clear local room state */
return;
}
g_room_conn = hconn;
/* After connection succeeds, start uplink audio and listen on command 0x2200 */
}
int start_room_tirtc_connect(const char *device_id,
const char *peer_id,
const char *token)
{
int ret = 0;
if (device_id == NULL || device_id[0] == '\0' ||
peer_id == NULL || peer_id[0] == '\0' ||
token == NULL || token[0] == '\0') {
return -1;
}
ret = room_tirtc_runtime_init(device_id);
if (ret != 0) {
return ret;
}
return TiRtcWhipConnect(peer_id, token, on_room_whip, NULL);
}
void stop_room_tirtc_connect(void)
{
if (g_room_conn != NULL) {
TiRtcClose(g_room_conn);
g_room_conn = NULL;
}
if (g_tirtc_ready) {
TiRtcStop();
TiRtcUninit();
g_tirtc_ready = false;
}
}TiRtcWhipConnect returning 0 only means that the connection request was submitted. Treat the callback with err == 0 as the success signal. Start the connection only after receiving TIRTC_EVENT_SYS_STARTED.
Send join_room
After the TiRTC connection is established, the device must send a JSON-RPC Request on command channel 0x2200 within 10 seconds. room_id and device_id must match the values used to request the credentials.
{
"jsonrpc": "2.0",
"id": 1,
"method": "join_room",
"params": {
"room_id": "room-001",
"device_id": "device-001",
"input_audio": {"codec": "pcm", "sample_rate": 16000, "channels": 1},
"output_audio": {"codec": "g711a", "sample_rate": 16000, "channels": 1}
}
}The device joins the room only after a successful response. The response contains session_id and the normalized audio formats. Identity or format validation failures return a JSON-RPC error.
The legacy start_session method is no longer supported. The device must complete join_room immediately after TiRTC connects before sending audio or any other room signaling.
Supported Audio Format and Sample Rate
The current Room device path supports the following format in both directions:
| codec | Sample rate (Hz) | Channels |
|---|---|---|
opus | 8000, 16000 | 1 |
pcm | 8000, 16000 | 1 |
g711a | 8000, 16000 | 1 |
amr | 8000 (AMR-NB), 16000 (AMR-WB) | 1 |
The device can specify the codec and sample rate for input_audio and output_audio independently in join_room. It must use the formats echoed in the successful response, and its media and flags values must match input_audio.
Uplink Audio Example
Send audio frames from the capture thread at a fixed interval. A 20 ms frame is recommended.
#include <stdint.h>
#include <string.h>
#include "tiRTC.h"
static const uint8_t kRoomAudioStreamId = 1;
int room_send_audio_opus(tirtc_conn_t hconn,
const void *opus_data,
uint32_t len,
uint32_t ts_ms)
{
TIRTCFRAMEINFO fi;
memset(&fi, 0, sizeof(fi));
fi.stream_id = kRoomAudioStreamId;
fi.media = TIRTC_AUDIO_OPUS;
/* Must match the uplink audio format configured on the platform side */
fi.flags = TIRTC_AUDIOSAMPLE_16K16B1C;
fi.ts = ts_ms;
fi.length = len;
return TiRtcSendAudioStream(hconn, &fi, opus_data);
}Audio parameters must match across:
- The format actually captured and encoded by the device.
fi.mediaassigned in C code.- Audio sample specification
fi.flagsassigned in C code.
For example, opus/16000/mono corresponds to TIRTC_AUDIO_OPUS and TIRTC_AUDIOSAMPLE_16K16B1C.
Downlink Audio Handling
Room downlink audio is delivered through a TiRTC audio stream. Decode it according to output_audio in the join_room response and send it to the playback pipeline:
- Filter room downlink audio by
stream_id. - Decode according to the audio frame's
mediaandflags, and verify them againstoutput_audio. - Support continuous streaming playback instead of waiting for a whole audio segment.
- Stop playback and clear buffers after receiving
room_closedor leaving the room locally.
Command Channel
Room uses TiRTC command channel 0x2200 to carry JSON-RPC 2.0 messages:
- After the connection is ready, the device must send
join_room. Once the join succeeds, Room service sendsroom_snapshotto initialize the local participant list. - When actively leaving, the device must send a
leave_roomNotification withoutid. - The device can send
get_room_snapshotto actively request the participant list. - When the local microphone state changes, the device can send
set_mic_statewithon,speaking, oroff. - Update local participant state when receiving
participant_joined,participant_left, orparticipant_mic_state_changed. - Enter resource cleanup after receiving
room_closed.
For complete fields, see Room Signaling.
Command Receive Example
The following example shows command filtering and event dispatching. Implement jsonrpc_method, method_equals, and handle_* functions in your business code using a JSON library.
#include <stdint.h>
#include "tiRTC.h"
#define TIRTC_ROOM_SIGNALING 0x2200
static const char *jsonrpc_method(const void *data, uint32_t len);
static int method_equals(const char *method, const char *expected);
static void handle_room_snapshot(const void *data, uint32_t len);
static void handle_participant_joined(const void *data, uint32_t len);
static void handle_participant_left(const void *data, uint32_t len);
static void handle_participant_mic_state_changed(const void *data, uint32_t len);
static void handle_room_closed(const void *data, uint32_t len);
static void on_room_command(tirtc_conn_t hconn, uint32_t cmdw,
const void *data, uint32_t len)
{
const char *method;
(void)hconn;
if (cmdw != TIRTC_ROOM_SIGNALING || data == NULL || len == 0) {
return;
}
/* data is a UTF-8 JSON-RPC string. Use a JSON library in production. */
method = jsonrpc_method(data, len);
if (method_equals(method, "room_snapshot")) {
handle_room_snapshot(data, len);
return;
}
if (method_equals(method, "participant_joined")) {
handle_participant_joined(data, len);
return;
}
if (method_equals(method, "participant_left")) {
handle_participant_left(data, len);
return;
}
if (method_equals(method, "participant_mic_state_changed")) {
handle_participant_mic_state_changed(data, len);
return;
}
if (method_equals(method, "room_closed")) {
handle_room_closed(data, len);
return;
}
}Handling recommendations:
room_snapshot: initialize the local participant list from the snapshot.participant_joined: add the new participant to the local participant list.participant_left: remove the participant from the local participant list.participant_mic_state_changed: update the specified participant's microphone state.set_mic_state: send it when the local microphone switch or speaking state changes. It only synchronizes state and does not replace local capture or uplink control.room_closed: stop capture and playback, then enter resource cleanup.
Resource Cleanup
The device should route active leave, network disconnect, business timeout, and room close notifications to the same cleanup flow:
- For an active leave, first send a
leave_roomNotification withoutidon command channel0x2200. - Stop capture and playback.
- Close the TiRTC connection.
- Clear local room state and playback buffers.
- Discard expired
tokenvalues and request a new credential for the next join.
Minimal Run-Through Path
To quickly eliminate environment and configuration issues, run this end-to-end path first:
- Server Request Test: Use your application server to call
POST /v1/token/roomand ensure it returns validpeer_idandtoken. For complete fields, see Server API. - Device Startup Test: Confirm that the device has completed
TiRtcInit()andTiRtcStart(), and has receivedTIRTC_EVENT_SYS_STARTED. - Device Connection Test: Pass
device_id,peer_id, andtokentostart_room_tirtc_connect, then verify thaton_room_whipreturnserr == 0. - Join And Snapshot Verification: After the connection succeeds, send
join_room. After its success response, the device should receiveroom_snapshoton command channel0x2200. - Multi-Device Join Verification: Let two devices request credentials for the same business
room_idand join the room. The first device should receiveparticipant_joined. - Microphone State Verification: One device sends
set_mic_stateto switch amongon,speaking, andoff. Other online devices should receiveparticipant_mic_state_changed. - Audio And Leave Verification: One device sends test audio continuously, and another device should receive downlink audio. When either device sends
leave_room, the other online devices should receiveparticipant_left.