C API 说明
C SDK 提供 TiRTC 的 C API,用于启动 TiRTC、建立或接收连接,并收发音视频流、流消息和命令。 如果还没接入头文件和库,先看 C SDK 接入。
调用顺序
设备端的典型调用顺序如下。代码只展示先后关系,省略错误处理、回调结构体定义和音视频帧填充细节。
// 初始化 SDK 运行时。每个进程按一次 SDK 生命周期调用一次。
TiRtcInit();
// 配置设备身份,然后以 device_id 启动。
TiRtcSetOption(TIRTC_OPT_DEVICE_SECRET_KEY, device_secret_key, strlen(device_secret_key));
TiRtcSetOption(TIRTC_OPT_CLIENT_ID, client_id, strlen(client_id));
TiRtcStart(device_id, &callbacks);
// TiRtcStart() 返回 0 后,等待 TIRTC_EVENT_SYS_STARTED。
// SDK 启动完成后,设备端等待客户端连接。
// 客户端连入时,SDK 会调用 on_conn_accepted(hconn)。
// 保存这个 hconn;后续收发都围绕这条连接进行。
// 拿到 hconn 后,可以收发命令和流消息。
TiRtcSendCommand(hconn, cmdw, command_payload, command_length);
TiRtcSendMessageStream(hconn, &message_frame_info, message_payload);
// 按你的发送策略发送音视频流。
// 常见做法是在客户端订阅后开始发送;也可以在连接建立后直接发送。
// 需要 SDK 提供视频发送码率建议时,先为对应连接和视频流设置码率参数。
TiRtcConnSetVideoBitrateParams(hconn, video_stream_id,
min_bps, max_bps, start_bps);
TiRtcSendVideoStream(hconn, &video_frame_info, video_payload);
TiRtcSendAudioStream(hconn, &audio_frame_info, audio_payload);
// 当前连接使用 TGTRP 时,SDK 产生新的码率建议后会触发 on_update_bitrate。
// 把调整任务投递到编码线程,不要在 SDK 回调内直接重配编码器。
// 连接出现错误或业务结束后,由业务线程提交断开操作。
// 如果在 on_conn_error 中发现错误,先把 hconn 投递到业务线程,不要在回调内调用。
TiRtcDisconnect(hconn);
// TiRtcDisconnect() 返回后不要再使用 hconn。
// 需要确认 SDK 内部释放完成时,等待 on_disconnected(hconn)。
// 所有连接处理完毕后,再停止 SDK 并释放运行时资源。
TiRtcStop();
TiRtcUninit();TiRtcStart() 返回 0 只表示启动请求通过参数检查;设备端真正启动完成以 TIRTCCALLBACKS.on_event(TIRTC_EVENT_SYS_STARTED, ...) 为准。
错误码
#define TIRTC_E_NOT_INITIALIZED -40001 // 未初始化,需先调用 TiRtcInit()
#define TIRTC_E_INVALID_HANDLE -40002 // 无效连接句柄
#define TIRTC_E_INVALID_PARAMETER -40003 // 无效参数
#define TIRTC_E_INVALID_LICENSE -40004 // 无效设备 license
#define TIRTC_E_TIMEOUTED -40005 // 操作超时
#define TIRTC_E_BUSY -40006 // 网络忙,常见于发送缓冲区满
#define TIRTC_E_CONN_TIMEOUTCLOSE -40007 // 心跳超时关闭
#define TIRTC_E_CONN_REMOTECLOSE -40008 // 远端主动关闭
#define TIRTC_E_CONN_OTHER_ERROR -40009 // 其他连接错误
#define TIRTC_E_LACK_OF_RESOURCE -40010 // 资源不足,包含内存不足
#define TIRTC_E_CACHE_EXPIRED -40011 // 连接参数缓存未命中或已过期
#define TIRTC_E_SERVER_ERROR -40012 // 服务器端错误
#define TIRTC_E_INTERNAL_ERROR -40013 // SDK 内部错误
#define TIRTC_E_NO_SECRET_KEY -40014 // 未设置 secret key
#define TIRTC_E_UNEXPECTED_RESPONSE -40015 // 服务器响应格式非预期
// HTTP 传输层错误。
#define TIRTC_E_HTTP_TIMEOUT -2 // 请求超时
#define TIRTC_E_HTTP_RESET -3 // 连接被复位
#define TIRTC_E_HTTP_PEER_CLOSED -4 // 对端关闭连接
#define TIRTC_E_HTTP_RESOLVE -5 // 域名解析失败
#define TIRTC_E_HTTP_CONNECT -6 // 连接失败
#define TIRTC_E_HTTP_SSL -7 // SSL 握手失败
#define TIRTC_E_HTTP_GENERIC -8 // 通用连接错误
#define TIRTC_E_HTTP_WS_HANDSHAKE -9 // WebSocket 握手失败
#define TIRTC_E_HTTP_INVALID_HANDLE -10 // 无效 HTTP 句柄
#define TIRTC_E_HTTP_SERVER_DOWN -11 // 服务器不可用
#define TIRTC_E_HTTP_INVALID_PROTO -12 // 不支持的协议
#define TIRTC_E_HTTP_SOCKET -13 // Socket 错误
#define TIRTC_E_HTTP_NOMEM -14 // HTTP 层内存不足
// HTTP 协议解析错误。
#define TIRTC_E_HTTP_HEADER -101 // HTTP 响应头格式错误
#define TIRTC_E_HTTP_URL -102 // URL 格式错误0 表示成功。错误码也可用 TiRtcGetErrorStr(...) 转成可读文本。
HTTP 错误码可能由 TiRtcStart()、TiRtcServiceRequest() 等需要访问服务端的操作返回。收到这类错误时,可先根据错误码区分 DNS、连接、SSL 和 HTTP 响应格式问题,再结合 SDK 日志定位。
TiRtcGetErrorStr
// 把错误码转换成可读字符串;0 返回 "OK"。
// 未知错误码返回 "未知错误码"。
const char *TiRtcGetErrorStr(int error);版本与构建信息
TiRtcGetVersion
// 返回 SDK 版本字符串。返回值由 SDK 持有,无需释放。
const char *TiRtcGetVersion(void);TiRtcGetBuildInfo
// 返回 JSON 格式的构建信息字符串。返回值由 SDK 持有,无需释放。
const char *TiRtcGetBuildInfo(void);基础类型与配置
tirtc_conn_t
typedef struct _tirtc_conn *tirtc_conn_t;tirtc_conn_t 表示一条连接。
- 其他端连接到本端时,通过
TIRTCCALLBACKS.on_conn_accepted传出。 - 主动连接其他端时,通过
TIRTCCONNECTCALLBACK传出。 on_conn_error触发后,这个句柄不能再用于收发,但仍需在回调之外调用TiRtcDisconnect()释放连接。TiRtcDisconnect()返回后,就不要再对这个句柄执行发送、查询或再次断开。on_disconnected回调返回后,连接对象由 SDK 自动释放。
TIRTCOPTION
TIRTCOPTION 是 TiRtcSetOption(...) 的配置项。除特别说明外,都应在 TiRtcStart() 前设置。设备端启动相关配置会用到 device_id、device_secret_key 和 client_id。支持下列配置项:
// const char *。切换自部署云端实例或测试、联调环境时设置,例如 "https://ep-tirtc.my-domain.com";
// 其他情况不设置,使用默认入口。
// 部分裁剪包只接受 http:// 服务入口;传入 https:// 会返回 TIRTC_E_INVALID_PARAMETER。
TIRTC_OPT_SERVICE_ENDPOINT
// const char *。设备 secret key。
// 需要用 device_id 启动设备端时,先设置这个选项。
TIRTC_OPT_DEVICE_SECRET_KEY
// const char *。设备端启动必填的硬件或生产标识。
// 必须在 TiRtcStart(device_id, ...) 前设置;未设置会导致启动失败。
// 长度必须为 1 到 64 个可打印 ASCII 字符。
// 取值要稳定、可追溯,能在生产或售后系统里定位到一台实物设备。
// 同一个 device_id 首次启动后会绑定当次上报的 client_id;
// 后续启动同一个 device_id 时,必须继续使用同一个 client_id。
TIRTC_OPT_CLIENT_ID
// int *。最大连接数,默认 5;不设置时使用默认值。
// 传入值必须大于 0,主要用于资源受限设备上的资源规划。
TIRTC_OPT_MAX_CONNECTIONS
// int *。设备自身直接使用的联网方式,取值见 TIRTCNETCONN。
// 默认 TIRTC_NETCONN_WIFI;设备直接通过 4G 联网时必须显式设置。
TIRTC_OPT_NETWORK_TYPE
// const char *。设备直接通过 4G 联网时所用 SIM 卡的 ICCID。
// TIRTC_OPT_NETWORK_TYPE 为 TIRTC_NETCONN_4G 时必填。
// 设备通过 Wi-Fi 联网时,不用填写上游路由器内 SIM 卡的 ICCID。
TIRTC_OPT_ICCID
// int *。是否支持休眠唤醒,0 关闭,1 开启,默认 0。
TIRTC_OPT_WAKEUP
// int *。是否处于受限网络,0 表示否,1 表示是,默认 0。
//
// 受限网络是指设备当前出口只允许访问预先加入白名单的域名或 IP 地址,
// 无法访问其他互联网地址。它描述的是出口网络的访问限制,与设备自身
// 通过 4G 还是 Wi-Fi 联网无关。
//
// 设备直接使用受限的物联网卡,或者通过 Wi-Fi 接入使用此类物联网卡的
// 路由器,都应设置为 1;其他网络具有相同限制时,也应设置为 1。
//
// SDK 无法可靠判断这一属性。设备应用应根据 SIM 卡、运营商或上游路由器
// 的配置,在 TiRtcStart() 前传入准确值。设备直接通过 4G 联网时,必须
// 显式设置为 0 或 1,不应依赖默认值。SDK 将根据该值适配当前网络。
//
// 弱信号、网速慢、NAT 或没有公网 IP 不属于这里所说的受限网络。
TIRTC_OPT_RESTRICTED_NETWORK
// uint32_t *。发送缓冲区大小,单位字节。
// 必须在 TiRtcInit() 之前设置才生效。
// 普通包默认 512 KB;部分裁剪包默认 100 KB。
TIRTC_OPT_MAX_SEND_BUFFER
// int *。是否开启连接参数缓存,0 关闭,1 开启,默认 1。
// 开启后,SDK 会缓存成功连接时服务器返回的连接参数,用于后续连接同一 remote_id。
TIRTC_OPT_CONNECT_CACHE
// const char *。客户端模式必填的 App ID,设备端可选。
TIRTC_OPT_APP_ID
// int *。网络轮询超时时间,单位毫秒;输入值会限制到 1..50。
// 增大该值可降低系统负载,但会增加网络响应时间。
// 可在 SDK 运行期间调整;TiRtcSetOption() 返回实际生效的毫秒数。
TIRTC_OPT_TGTRP_POLL_TIMEOUTTIRTCNETCONN
typedef enum {
TIRTC_NETCONN_WIFI = 0, // 设备自身通过 Wi-Fi 联网,默认值
TIRTC_NETCONN_4G // 设备自身直接通过 4G 联网;需要设置 TIRTC_OPT_ICCID
} TIRTCNETCONN;音视频流与帧
TIRTCMEDIA
TIRTCMEDIA 填入 TIRTCFRAMEINFO.media,用于说明这一帧是音频、视频还是流消息。
typedef enum TIRTCMEDIA {
TIRTC_MEDIA_MESSAGE = 0, // 流消息
TIRTC_AUDIO_MIN = 1,
TIRTC_AUDIO_PCM = TIRTC_AUDIO_MIN, // PCM 原始音频
TIRTC_AUDIO_ALAW = 2, // G.711 A-law
TIRTC_AUDIO_AAC = 3, // AAC-LC 压缩音频;每次发送一个包含完整 ADTS 头的编码帧
TIRTC_AUDIO_OPUS = 4, // Opus 压缩音频
TIRTC_AUDIO_AMR = 5, // AMR,根据采样参数选择 NB / WB
TIRTC_AUDIO_MAX = 64,
TIRTC_VIDEO_MIN = 65,
TIRTC_VIDEO_JPEG = TIRTC_VIDEO_MIN, // JPEG 图像帧
TIRTC_VIDEO_H264 = 66, // H.264 视频帧
TIRTC_VIDEO_H265 = 67, // H.265 视频帧
TIRTC_VIDEO_MAX = 127
} TIRTCMEDIA;
// 辅助判断宏:判断 TIRTCMEDIA 取值是否属于音频或视频类型。
#define TIRTC_IS_AUDIO(mt) ((mt) >= TIRTC_AUDIO_MIN && (mt) <= TIRTC_AUDIO_MAX)
#define TIRTC_IS_VIDEO(mt) ((mt) >= TIRTC_VIDEO_MIN && (mt) <= TIRTC_VIDEO_MAX)media 只标记 payload 的媒体类型,C SDK 不检查实际编码内容。客户端能否播放还取决于平台支持范围和帧的组织方式,见音视频格式与帧要求。
TIRTCAUDIOSAMPLE
音频采样规格填入音频帧的 TIRTCFRAMEINFO.flags。
typedef enum {
TIRTC_AUDIOSAMPLE_8K16B1C = 0, // 8 kHz,16 bit,单声道
TIRTC_AUDIOSAMPLE_16K16B1C, // 16 kHz,16 bit,单声道
TIRTC_AUDIOSAMPLE_8K16B2C, // 8 kHz,16 bit,双声道
TIRTC_AUDIOSAMPLE_16K16B2C // 16 kHz,16 bit,双声道
} TIRTCAUDIOSAMPLE;TIRTCFRAMEINFO
typedef struct TIRTCFRAMEINFO {
uint8_t stream_id; // 流标识,取值 0..15
uint8_t media; // 帧类型,取值见 TIRTCMEDIA
uint8_t flags; // 视频:bit0 表示关键帧;音频:取值见 TIRTCAUDIOSAMPLE
uint8_t reserved; // 预留字段,当前填 0
uint32_t ts; // 主机序时间戳,单位 ms
uint32_t length; // payload 字节长度,不含帧头自身
} TIRTCFRAMEINFO;
// TIRTC_FRAME_FLAG_KEY_FRAME 用来标记视频关键帧。
// TIRTC_IS_KEY_FRAME(flags) 用来判断这一帧是不是关键帧。
#define TIRTC_FRAME_FLAG_KEY_FRAME 0x01
#define TIRTC_IS_KEY_FRAME(flags) ((flags) & TIRTC_FRAME_FLAG_KEY_FRAME)同一连接内,音频和视频不能共用同一个 stream_id。发送视频时,每路视频流的第一帧必须带 TIRTC_FRAME_FLAG_KEY_FRAME。
事件与回调
TIRTCSYSEVENT
typedef enum {
TIRTC_EVENT_SYS_STARTED, // SDK 成功启动
TIRTC_EVENT_SYS_STOPPED, // SDK 已停止
TIRTC_EVENT_ACCESS_HIJACKING, // HTTP 请求被重定向,可能遭受中间人攻击
} TIRTCSYSEVENT;系统事件通过 TIRTCCALLBACKS.on_event 通知。
TIRTCCALLBACKS
TIRTCCALLBACKS 传给 TiRtcStart(...)。创建结构体时应先整体清零,再设置需要的回调;未使用的回调必须为 NULL。这个结构体和其中的函数指针生命周期必须覆盖整个 SDK 运行期,不能指向临时栈变量。
typedef struct TIRTCCALLBACKS {
// SDK 内部事件。event 取值见 TIRTCSYSEVENT。
void (*on_event)(int event, const void *data, int len);
// 其他端连接到本端。hconn 可立即用于发送音视频流、流消息或命令。
void (*on_conn_accepted)(tirtc_conn_t hconn);
// 连接出现错误。无论 error 取值为何,这条连接上的收发操作都不再有效,
// 但连接不会自动释放,应把 hconn 投递到业务线程,并在回调外调用 TiRtcDisconnect() 释放资源。
// 远端主动关闭也会触发此回调,error 为 TIRTC_E_CONN_REMOTECLOSE。
void (*on_conn_error)(tirtc_conn_t hconn, int error);
// TiRtcDisconnect() 内部操作完成。
// 回调返回后连接对象由 SDK 自动释放。
void (*on_disconnected)(tirtc_conn_t hconn);
// 收到对端音频帧。data 只在当前回调内有效。
void (*on_audio)(tirtc_conn_t hconn, const TIRTCFRAMEINFO *pFi, void *data);
// 收到对端视频帧。data 只在当前回调内有效。
void (*on_video)(tirtc_conn_t hconn, const TIRTCFRAMEINFO *pFi, void *data);
// 收到对端流消息,pFi->media == TIRTC_MEDIA_MESSAGE。
void (*on_message)(tirtc_conn_t hconn, const TIRTCFRAMEINFO *pFi, void *data);
// 收到对端命令通道数据。cmdw 是收到的 32 位命令字。
void (*on_command)(tirtc_conn_t hconn, uint32_t cmdw,
const void *data, uint32_t len);
// 对端请求本端为指定视频流发送关键帧。
// 如果本端正在发送这路视频流,收到后应尽快发送一个关键帧。
void (*on_request_key_frame)(tirtc_conn_t hconn, uint8_t stream_id);
// 对端希望本端开始发送指定视频流;返回 0 表示接受,非 0 表示拒绝。
// 接受后,应用按自己的采集或文件输入策略调用 TiRtcSendVideoStream()。
int (*on_subscribe_video)(tirtc_conn_t hconn, uint8_t stream_id);
// 对端希望本端停止发送指定视频流。
// 应停止继续发送对应 stream_id 的视频帧。
void (*on_unsubscribe_video)(tirtc_conn_t hconn, uint8_t stream_id);
// 对端希望本端开始发送指定音频流;返回 0 表示接受,非 0 表示拒绝。
// 接受后,应用按自己的采集或文件输入策略调用 TiRtcSendAudioStream()。
int (*on_subscribe_audio)(tirtc_conn_t hconn, uint8_t stream_id);
// 对端希望本端停止发送指定音频流。
// 应停止继续发送对应 stream_id 的音频帧。
void (*on_unsubscribe_audio)(tirtc_conn_t hconn, uint8_t stream_id);
// SDK 结合实时传输状况,为指定的视频流提供建议发送码率。
// target_bitrate_bps 是绝对目标值,单位 bps,不是增量或比例。
// 当前连接使用 TGTRP,并且已经为这条连接和视频流成功调用
// TiRtcConnSetVideoBitrateParams() 时,SDK 才会触发此回调。
void (*on_update_bitrate)(tirtc_conn_t hconn,
uint8_t stream_id,
uint32_t target_bitrate_bps);
} TIRTCCALLBACKS;所有回调都在 SDK 内部线程中调用,不要在回调里执行阻塞或耗时操作。需要写文件、解码、编码、访问网络或等待锁时,先把必要数据复制到业务线程。
on_update_bitrate 只给出 SDK 建议的目标码率,不会直接修改设备的视频编码器。应用应把 hconn、stream_id 和 target_bitrate_bps 投递到编码线程,再更新对应编码器。此能力只对使用 TGTRP 实时音视频传输协议 的连接生效。完整用法见根据网络带宽调整视频发送码率。
其他回调类型
// TiRtcConnect() 和 WHIP 连接接口的异步结果回调。
// error 为 0 表示连接成功;失败时 hconn 为 NULL。
typedef void (*TIRTCCONNECTCALLBACK)(int error, tirtc_conn_t hconn, void *user_data);
// 日志输出回调。log 不是以 '\0' 结尾的字符串,读取时以 length 为准。
typedef void (*TIRTCLOGCALLBACK)(const char *log, uint32_t length);
// WHIP 服务端 answer SDP 就绪回调。禁止在此回调中阻塞。
typedef void (*TIRTCWHIPSERVERONSDPREADYCB)(const char *sdp, int len, void *user);
// TiRtcServiceRequest() 的结果回调。
// body 在回调返回后不再有效;请求失败时可能为 NULL。
typedef void (*TIRTCSERVICEREQUESTCALLBACK)(const char *body, void *user_data);生命周期
TiRtcInit
// 初始化 SDK 运行时。必须在 TiRtcStart() 前调用。
// 返回 0 表示成功,非 0 为错误码。
int TiRtcInit(void);TIRTC_OPT_MAX_SEND_BUFFER 必须在 TiRtcInit() 前设置才生效。
TiRtcUninit
// 释放 SDK 运行时资源。在 TiRtcStop() 完成后调用。
void TiRtcUninit(void);TiRtcSetOption
// 设置全局配置项。
// opt 取值见 TIRTCOPTION,data 类型由具体配置项决定,len 为 data 字节长度。
// 通常返回 0 表示成功;参数不合法时返回 TIRTC_E_INVALID_PARAMETER。
// TIRTC_OPT_TGTRP_POLL_TIMEOUT 返回实际生效的轮询间隔,详见该选项说明。
int TiRtcSetOption(TIRTCOPTION opt, const void *data, uint32_t len);TiRtcStart
// 启动 SDK。
// deviceId == NULL:只启动客户端功能,不支持接收连接。
// deviceId != NULL:以设备端身份启动;需提前设置 TIRTC_OPT_DEVICE_SECRET_KEY。
// 返回 0 只表示参数通过初步检查,启动完成看 on_event(TIRTC_EVENT_SYS_STARTED)。
int TiRtcStart(const char *deviceId, const TIRTCCALLBACKS *cbs);cbs 不能为 NULL,也不能指向临时变量。
设备直接通过 4G 联网时,应先将 TIRTC_OPT_NETWORK_TYPE 设为 TIRTC_NETCONN_4G,再通过 TIRTC_OPT_ICCID 提供 SIM 卡 ICCID。使用 4G 定向卡时,还需要将 TIRTC_OPT_RESTRICTED_NETWORK 设为 1。
TIRTC_OPT_NETWORK_TYPE 已设为 TIRTC_NETCONN_4G、但没有提供 ICCID 时,TiRtcStart() 返回 TIRTC_E_INVALID_PARAMETER。
TiRtcStop
// 停止 SDK。完成后通过 on_event(TIRTC_EVENT_SYS_STOPPED) 通知。
// 返回 0 或错误码。
int TiRtcStop(void);连接管理
TiRtcConnect
remote_id 是本次连接的目标标识;连接设备端时传目标设备的 device_id,例如 PRODFENGXXXX。token 传业务服务端签发的 token。
// 主动发起连接。应在 TiRtcInit()、TiRtcStart() 成功后调用。
// remote_id 是目标设备标识;连接设备端时传目标设备的 device_id,例如 "PRODFENGXXXX"。
// token 是业务服务端签发的一次性连接授权凭证,不要重复使用。
// 开启 TIRTC_OPT_CONNECT_CACHE 后,连接成功会按 remote_id 缓存连接参数。
// 缓存有效期由服务器返回;有效期内再次连接同一 remote_id 时,token 可传 NULL。
// 缓存未命中或过期时,返回 TIRTC_E_CACHE_EXPIRED。
// 返回 0 只表示连接请求已提交。
// 连接成功或 SDK 检测到失败时,通过 cb 通知结果。
int TiRtcConnect(const char *remote_id,
const char *token,
TIRTCCONNECTCALLBACK cb,
void *user_data);TiRtcConnect() 返回 0 不表示连接已经建立。C SDK 客户端还应在应用层为每次连接设置超时,避免底层没有返回失败回调时一直等待。
目标设备的连接数达到上限时,当前没有专用错误码。cb 可能收到 TIRTC_E_TIMEOUTED,也可能在应用设定的超时时间内没有返回失败结果。设备离线或网络异常也可能表现为超时,不能据此判断目标设备是否达到连接数上限。
TiRtcDisconnect
// 主动断开连接。业务结束、切换目标设备或需要重连时调用。
// 返回 0 表示成功提交断开操作;hconn 无效时返回 TIRTC_E_INVALID_HANDLE。
int TiRtcDisconnect(tirtc_conn_t hconn);这是异步操作,不会阻塞到 SDK 内部彻底释放完成。调用返回后即认为 hconn 不再有效,不应再对它执行任何操作。若需等待 SDK 内部释放完成,可在 on_disconnected() 回调中处理。
on_conn_error() 发生后也必须执行此操作。由于回调运行在 SDK 内部线程中,应先把 hconn 投递到应用自己的业务线程,再调用 TiRtcDisconnect()。在 on_disconnected() 到达前,这条连接仍可能计入当前连接数。
TiRtcGetSendBufferUsed
// 返回连接当前发送缓冲区已使用字节数;hconn 无效时返回 0。
size_t TiRtcGetSendBufferUsed(tirtc_conn_t hconn);可与 TIRTC_OPT_MAX_SEND_BUFFER 设置的上限对比,用于判断是否需要丢帧或限流。
TiRtcConnSetUserData
// 把用户数据指针关联到连接。成功返回 0,hconn 无效时返回 TIRTC_E_INVALID_HANDLE。
int TiRtcConnSetUserData(tirtc_conn_t hconn, void *user_data);TiRtcConnGetUserData
// 取回由 TiRtcConnSetUserData() 关联的用户数据指针;hconn 无效时返回 NULL。
void *TiRtcConnGetUserData(tirtc_conn_t hconn);TiRtcConnSetVideoBitrateParams
为一条已经建立的连接设置指定视频流的码率参数。当前连接使用 TGTRP 时,SDK 根据这些参数和网络可用带宽计算建议码率,并通过 TIRTCCALLBACKS.on_update_bitrate 通知设备应用。应用仍需自行更新视频编码器。
int TiRtcConnSetVideoBitrateParams(tirtc_conn_t hconn,
uint8_t stream_id,
uint32_t min_bps,
uint32_t max_bps,
uint32_t start_bps);参数要求:
hconn:已经建立的连接句柄。stream_id:要调整的视频流 ID,取值范围为0..15。min_bps、max_bps:允许 SDK 建议的最小和最大目标码率,单位 bps。start_bps:当前或初始目标码率,单位 bps。应填写设备编码器当前使用的目标码率。- 三个码率参数必须满足
0 < min_bps <= start_bps <= max_bps。
返回值:
0:设置请求已提交。SDK 产生新的码率建议时,通过on_update_bitrate通知应用。TIRTC_E_INVALID_HANDLE:hconn无效。TIRTC_E_INVALID_PARAMETER:stream_id或码率范围不合法,或者当前连接未使用 TGTRP,无法提供码率建议。
应在连接成功后、开始发送对应视频流前调用。每条连接、每路视频流分别设置。实现步骤和示例见根据网络带宽调整视频发送码率。
音视频流和流消息发送
TiRtcSendMessageStream
// 通用的音频、视频和流消息发送接口。连接建立后调用,线程安全,支持多线程并发调用。
// pFi 不能为 NULL,frame 指向 payload 数据。
// 返回 >0 表示发送字节数;返回 <0 表示错误码。
int TiRtcSendMessageStream(tirtc_conn_t hconn,
const TIRTCFRAMEINFO *pFi,
const void *frame);发送策略:
pFi->media == TIRTC_MEDIA_MESSAGE时发送流消息。pFi->media为音频或视频类型时,按TIRTCFRAMEINFO描述发送音视频帧。- 发送操作只根据
pFi->media选择传输策略,不检查 payload 内容。 - 每路视频流第一帧必须是关键帧。发送缓冲区满时,SDK 会丢弃后续非关键视频帧,直到下一个关键帧到来。
- 音频帧直接入队,不使用视频关键帧跳帧逻辑。
- 流消息可以放在任意
stream_id上,帧头其余成员由你的业务协议自行解释。
音视频 payload 的完整帧、关键帧参数集、音频包长和时间戳要求见音视频格式与帧要求。
TiRtcSendVideoStream
// 视频发送封装。连接建立并准备发送视频帧时调用,pFi->media 必须是视频类型。
// 返回值同 TiRtcSendMessageStream();media 不是视频类型时返回 TIRTC_E_INVALID_PARAMETER。
int TiRtcSendVideoStream(tirtc_conn_t hconn,
const TIRTCFRAMEINFO *pFi,
const void *frame);TiRtcSendAudioStream
// 音频发送封装。连接建立并准备发送音频帧时调用,pFi->media 必须是音频类型,pFi->flags 填 TIRTCAUDIOSAMPLE。
// 返回值同 TiRtcSendMessageStream();media 不是音频类型时返回 TIRTC_E_INVALID_PARAMETER。
int TiRtcSendAudioStream(tirtc_conn_t hconn,
const TIRTCFRAMEINFO *pFi,
const void *frame);当 pFi->media 为 TIRTC_AUDIO_AAC 时,frame 必须包含一个完整的 AAC-LC ADTS 帧。保留 ADTS 头,不要拆分一帧或拼接多帧;ADTS 头声明的采样率和声道数必须与实际音频及 pFi->flags 一致,ADTS 声明的帧长度必须与 pFi->length 一致。
命令收发
命令数据可以双向收发:发送使用 TiRtcSendCommand() 或辅助宏,接收通过 TIRTCCALLBACKS.on_command 回调完成。
TiRtcSendCommand
// 在命令通道上发送自定义数据。连接建立后调用。
// cmdw 是 32 位命令字;开发者应用应使用 >= 0x10000 的值。
// data 可为 NULL,length 为参数字节数。
// 返回 >0 表示发送字节数,<0 表示错误码。
int TiRtcSendCommand(tirtc_conn_t hconn,
uint32_t cmdw,
const void *data,
uint32_t length);cmdw 是发送和接收时使用的完整 32 位命令字。需要解析命令标识、序号或应答标志时,使用命令字格式和辅助宏。
简单单向命令可以直接约定 cmdw >= 0x10000。需要请求、响应、重复请求或乱序应答时,使用 SDK 提供的命令字格式:
- bit 0:
RESPONSE_BIT,为1表示这是对己方先前请求的应答。 - bit 1..15:
cmd,命令标识;开发者应用使用0x4000..0x7fff。 - bit 16..31:
sn,命令序号,用于匹配请求和应答。
命令字范围:
0..0x1fff:SDK 内部使用。0x2000..0xffff:预留范围,不用于开发者应用。>= 0x10000:开发者应用使用。
atomic_get_cmd_sn
// 原子地返回下一个命令序号并自增。返回值低 16 位为有效序号。
uint32_t atomic_get_cmd_sn(void);需要乱序应答时,先调用 atomic_get_cmd_sn() 获取序号,再把对应的应答处理器挂入等待队列,最后发送命令。必须先挂等待队列再发送,否则应答可能在处理器挂入前就已到达。
命令字辅助宏
// 命令字辅助宏:用于从 cmdw 取命令标识、取序号、组装命令字,以及判断是否为 SDK 保留命令。
#define GET_CMD(cmdw) (((cmdw) >> 1) & 0x7fff)
#define GET_SN(cmdw) ((cmdw) >> 16)
#define MAKE_CMDW(cmd, sn) (((uint32_t)(sn)) << 16 | (((cmd) << 1) & 0xffff))
#define IS_RESERVED_CMDW(cmdw) (cmdw < 0x2000)
#define RESPONSE_BIT 0x0001
// 发送请求,清除应答位。需要自行在 cmdw 中组装序号。
#define TiRtcSendReq(hconn, cmd, data, length) \
TiRtcSendCommand(hconn, (cmd)&~RESPONSE_BIT, data, length)
// 发送请求,自动将 sn 填入高 16 位。
#define TiRtcSendReqWithSn(hconn, sn, cmd, data, length) \
TiRtcSendCommand(hconn, MAKE_CMDW(cmd, sn), data, length)
// 发送应答,置位应答位。cmdw 直接来自收到的请求命令字。
#define TiRtcSendResp(hconn, cmdw, data, length) \
TiRtcSendCommand(hconn, (cmdw)|RESPONSE_BIT, data, length)控制远端媒体发送
本节接口的 stream_id 取值范围均为 0..15;超出范围时返回 TIRTC_E_INVALID_PARAMETER。
TiRtcRequestKeyFrame
// 连接建立且远端正在发送这路视频流时调用。
// 通知远端为 stream_id 对应的视频流发送关键帧。
// 远端收到后触发 on_request_key_frame 回调;返回 0 表示成功,否则为错误码。
int TiRtcRequestKeyFrame(tirtc_conn_t hconn, uint8_t stream_id);TiRtcSubscribeVideo
// 连接建立后调用,通知远端开始发送 stream_id 对应的视频流。
// 这个方法只控制远端发送;收到的视频帧通过 on_video 回调交给应用。
// 远端收到后触发 on_subscribe_video 回调;返回 0 表示成功,否则为错误码。
int TiRtcSubscribeVideo(tirtc_conn_t hconn, uint8_t stream_id);TiRtcUnsubscribeVideo
// 不再需要远端发送这路视频流时调用。
// 这个方法只控制远端停止发送;本地已收到的视频帧仍由应用自行处理。
// 远端收到后触发 on_unsubscribe_video 回调;返回 0 表示成功,否则为错误码。
int TiRtcUnsubscribeVideo(tirtc_conn_t hconn, uint8_t stream_id);TiRtcSubscribeAudio
// 连接建立后调用,通知远端开始发送 stream_id 对应的音频流。
// 这个方法只控制远端发送;收到的音频帧通过 on_audio 回调交给应用。
// 远端收到后触发 on_subscribe_audio 回调;返回 >= 0 表示成功,< 0 表示错误码。
int TiRtcSubscribeAudio(tirtc_conn_t hconn, uint8_t stream_id);TiRtcUnsubscribeAudio
// 不再需要远端发送这路音频流时调用。
// 这个方法只控制远端停止发送;本地已收到的音频帧仍由应用自行处理。
// 远端收到后触发 on_unsubscribe_audio 回调;返回 >= 0 表示成功,< 0 表示错误码。
int TiRtcUnsubscribeAudio(tirtc_conn_t hconn, uint8_t stream_id);日志
TiRtcLogSetLevel
// 设置日志详细程度。1..5 对应 error / warn / ok / info / verbose。
// level > 10 时会打开 WebRTC 底层日志,输出量很大,可能影响性能。
void TiRtcLogSetLevel(int level);TiRtcLogSetCallback
// 设置日志输出回调。
// 设置后,SDK 额外通过回调传递日志,不关闭默认控制台输出。
// cb 传 NULL 可停止回调。
void TiRtcLogSetCallback(TIRTCLOGCALLBACK cb);TiRtcLogSetCallback(...) 可用于把日志接入应用自己的日志链路。log 指向的内容只在本次回调期间有效,也不保证以 NUL 结尾;需要保留时,应在回调返回前按 length 复制。回调在产生日志的线程中同步执行,并可能来自不同线程,处理函数需要保证线程安全并避免阻塞。
应用可以把日志输出到平台日志系统,写入文件或存储卡,或者按需上传。耗时的存储和上传操作应通过应用自己的容量受控队列交给其他任务处理;自行保存时还需要负责文件大小限制和滚动策略。不同平台的选择和完整示例参考配置 SDK 日志输出。
WHIP
TiRtcWhipAccept
// WHIP 服务端接口:接收 offer SDP,异步生成 answer SDP。
// candidate 在服务器不能直接连到公网时传外网地址;否则传 NULL。
// 返回 0 表示请求已提交,非 0 为错误码。
int TiRtcWhipAccept(const char *offer,
int offer_len,
const char *candidate,
TIRTCWHIPSERVERONSDPREADYCB whip_sdp_cb,
TIRTCCONNECTCALLBACK cb,
void *user);典型流程是:HTTP POST /whip 收到 offer SDP 后调用 TiRtcWhipAccept(...),在 whip_sdp_cb 中返回 HTTP 201,body 为 answer SDP。DataChannel 全部就绪或出错时,通过 cb 通知。
TiRtcWhipConnect
// WHIP 客户端接口:通过平台信令向目标服务发起连接。
// service_desc 是服务描述符,不是 device_id 或 remote_id。
// 返回 0 只表示连接请求已提交,最终结果通过 cb 通知。
int TiRtcWhipConnect(const char *service_desc,
const char *token,
TIRTCCONNECTCALLBACK cb,
void *user_data);服务请求
TiRtcServiceRequest
// 请求 TiRTC 云平台的 HTTP API。
// json_body 为 NULL 时使用 GET,否则使用 POST。
// token 作为客户端访问时传授权 token,作为设备端访问时传 NULL。
int TiRtcServiceRequest(const char *path,
const char *json_body,
const char *token,
TIRTCSERVICEREQUESTCALLBACK cb,
void *user_data);返回值含义:
0:请求已提交;响应 body 通过cb返回。< 0:TiRTC 错误码。30X..50X:服务端返回的 HTTP 状态码。> 599:服务端返回的业务错误码,按对应平台接口文档解释。