C API 说明
C SDK 用于设备录像上传,公共头文件为 include/tirtc/ticloudstorage.h。所有时间戳使用 UTC Unix 毫秒。
返回 ID 的函数成功时返回正数,失败时返回负数错误码;其他函数成功返回 TICLOUDSTORAGE_OK。
接入头文件、二进制库和设备身份见 C SDK 接入。
调用顺序
结构体字段、返回值处理和线程同步见上传录像。
// 每个进程按一次 TiCloudStorage 生命周期初始化。
struct TiCloudStorageOptions options = TICLOUDSTORAGE_OPTIONS_INITIALIZER;
TiCloudStorageInit(&options);
// 一条 Service 对应一条独立媒体时间线。
struct TiCloudStorageServiceOptions service_options =
TICLOUDSTORAGE_SERVICE_OPTIONS_INITIALIZER;
service_options.device_secret_key = device_secret_key;
service_options.on_token_will_expire = on_token_will_expire;
service_options.on_token_expired = on_token_expired;
int service_id = TiCloudStorageServiceCreate(device_id, &service_options);
TiCloudStorageServiceUpdateToken(service_id, device_access_token);
TiCloudStorageServiceStart(service_id);
// 提交逻辑上传请求。正数 upload_id 只表示请求已经受理。
struct TiCloudStorageUploadRequestOptions request =
TICLOUDSTORAGE_UPLOAD_REQUEST_OPTIONS_INITIALIZER;
request.start_time_ms = TICLOUDSTORAGE_TIME_EARLIEST;
request.duration_ms = 0;
request.on_progress = on_upload_progress;
request.on_result = on_upload_result;
int upload_id = TiCloudStorageUploadRequest(service_id, &request);
// 采集线程持续写入完整编码帧;成功只表示帧进入本地队列。
TiCloudStorageQueueWriteFrame(service_id, &frame_info, frame_data);
// duration_ms 为 0 时,设置右开的结束时间,再等待唯一的 on_result。
TiCloudStorageUploadSetEnd(service_id, upload_id, end_time_ms);
// 确认所需结果和录像查询状态、停止送帧线程后,再释放资源。
// 请求 user_data 保持有效到 ServiceStop 成功返回。
TiCloudStorageServiceStop(service_id);
TiCloudStorageServiceDestroy(service_id);
TiCloudStorageUninit();需要保留录像时,等待上传结果,并按上传录像确认录像查询状态,再停止送帧线程和 Service。TiCloudStorageServiceStop() 不会代替应用排空上传或等待索引上报完成。
错误码
C SDK 失败时返回负数。当前取值从 -50000 起,按类别分段。业务判断比较这些常量,不要解析 TiCloudStorageGetErrorString() 的文本。
| 值 | 常量 | 含义 |
|---|---|---|
| 0 | TICLOUDSTORAGE_OK | 成功 |
| -50001 | TICLOUDSTORAGE_E_INVALID_ARGUMENT | 参数不合法 |
| -50002 | TICLOUDSTORAGE_E_NOT_INITIALIZED | 尚未初始化,或已经反初始化 |
| -50003 | TICLOUDSTORAGE_E_ALREADY_INITIALIZED | 已经初始化,不能重复初始化 |
| -50004 | TICLOUDSTORAGE_E_NO_MEMORY | 内存不足 |
| -50005 | TICLOUDSTORAGE_E_INTERNAL | SDK 内部错误 |
| -50099 | TICLOUDSTORAGE_E_NOT_IMPLEMENTED | 该能力未实现 |
| -50100 | TICLOUDSTORAGE_E_SERVICE_NOT_FOUND | Service 不存在 |
| -50101 | TICLOUDSTORAGE_E_SERVICE_INVALID_STATE | Service 当前状态不允许该操作 |
| -50102 | TICLOUDSTORAGE_E_SERVICE_ID_EXHAUSTED | 无法再分配 Service ID |
| -50103 | TICLOUDSTORAGE_E_SERVICES_ACTIVE | 仍有 Service,不能反初始化 |
| -50200 | TICLOUDSTORAGE_E_UNSUPPORTED_MEDIA | 媒体编号不在音频或视频预留范围 |
| -50201 | TICLOUDSTORAGE_E_TIMESTAMP_OUT_OF_ORDER | 同一通道、同一媒体类型时间戳倒退 |
| -50202 | TICLOUDSTORAGE_E_QUEUE_FULL | 本地环形队列没有可用空间 |
| -50300 | TICLOUDSTORAGE_E_UPLOAD_NOT_FOUND | 上传请求不存在 |
| -50301 | TICLOUDSTORAGE_E_UPLOAD_FINISHED | 上传请求已经结束 |
| -50302 | TICLOUDSTORAGE_E_UPLOAD_RANGE_INVALID | 上传时间范围无效 |
| -50303 | TICLOUDSTORAGE_E_TOO_MANY_UPLOADS | 同一 Service 的活动上传请求达到上限 |
| -50304 | TICLOUDSTORAGE_E_UPLOAD_START_TIMEOUT | 等待视频关键帧超时 |
| -50400 | TICLOUDSTORAGE_E_AUTH_FAILED | 鉴权失败或 Token 无效 |
| -50401 | TICLOUDSTORAGE_E_NETWORK_UNAVAILABLE | 网络不可用 |
| -50402 | TICLOUDSTORAGE_E_NETWORK_TIMEOUT | 请求超时 |
| -50403 | TICLOUDSTORAGE_E_RATE_LIMITED | 被限流 |
| -50404 | TICLOUDSTORAGE_E_SERVER_UNAVAILABLE | 服务暂不可用 |
| -50405 | TICLOUDSTORAGE_E_PROTOCOL_ERROR | 与云端的协议交互失败 |
TiCloudStorageGetErrorString
const char *TiCloudStorageGetErrorString(int error);返回只读诊断文本。业务分支应比较错误码,不要解析字符串。
版本与构建信息
TiCloudStorageGetVersion
const char *TiCloudStorageGetVersion(void);返回只读的 SDK 版本字符串,可用于记录诊断日志。调用方不得修改或释放返回值。
TiCloudStorageGetBuildInfo
const char *TiCloudStorageGetBuildInfo(void);返回只读的构建信息字符串,可用于排查运行问题。字段和格式可能随版本变化,不应作为业务判断依据。
基础类型与配置
TiCloudStorageOptions
| 字段 | 说明 |
|---|---|
struct_size | 必须设置为结构体大小,推荐使用 TICLOUDSTORAGE_OPTIONS_INITIALIZER |
endpoint | 服务地址;NULL 使用内置公有云地址 |
log_level | 最低日志级别 |
on_log | 日志回调;消息只在回调期间有效,回调不能阻塞 |
TiCloudStorageLogLevel
| 常量 | 值 | 说明 |
|---|---|---|
TICLOUDSTORAGE_LOG_DEFAULT | 0 | 使用 SDK 默认级别,当前为 TICLOUDSTORAGE_LOG_INFO |
TICLOUDSTORAGE_LOG_TRACE | 1 | 输出 Trace 及以上级别日志 |
TICLOUDSTORAGE_LOG_DEBUG | 2 | 输出 Debug 及以上级别日志 |
TICLOUDSTORAGE_LOG_INFO | 3 | 输出 Info 及以上级别日志 |
TICLOUDSTORAGE_LOG_WARN | 4 | 输出 Warn 及以上级别日志 |
TICLOUDSTORAGE_LOG_ERROR | 5 | 只输出 Error 级别日志 |
TICLOUDSTORAGE_LOG_NONE | 6 | 关闭 SDK 日志输出 |
TiCloudStorageMedia
音频编号包括 PCM、A-law、AAC、Opus、μ-law 和 G.726;视频编号包括 JPEG、H.264 和 H.265。
| 常量 | 值 | 媒体格式 |
|---|---|---|
TICLOUDSTORAGE_AUDIO_PCM | 1 | PCM 音频 |
TICLOUDSTORAGE_AUDIO_ALAW | 2 | G.711 A-law 音频 |
TICLOUDSTORAGE_AUDIO_AAC | 3 | AAC-LC 音频;每次写入一个完整 ADTS 帧 |
TICLOUDSTORAGE_AUDIO_OPUS | 4 | Opus 音频 |
TICLOUDSTORAGE_AUDIO_ULAW | 5 | G.711 μ-law 音频 |
TICLOUDSTORAGE_AUDIO_G726 | 6 | G.726 音频 |
TICLOUDSTORAGE_VIDEO_JPEG | 65 | JPEG 视频帧 |
TICLOUDSTORAGE_VIDEO_H264 | 66 | H.264 视频 |
TICLOUDSTORAGE_VIDEO_H265 | 67 | H.265 视频 |
媒体编号范围由下列常量界定:
| 常量 | 值 | 说明 |
|---|---|---|
TICLOUDSTORAGE_AUDIO_MIN | 1 | 音频编号下界,与 TICLOUDSTORAGE_AUDIO_PCM 相同 |
TICLOUDSTORAGE_AUDIO_MAX | 64 | 音频编号上界 |
TICLOUDSTORAGE_VIDEO_MIN | 65 | 视频编号下界,与 TICLOUDSTORAGE_VIDEO_JPEG 相同 |
TICLOUDSTORAGE_VIDEO_MAX | 127 | 视频编号上界 |
TICLOUDSTORAGE_IS_AUDIO(media) 和 TICLOUDSTORAGE_IS_VIDEO(media) 只判断编号是否位于上述范围。音频编号 7~64 和视频编号 68~127 是预留值,被宏判为对应类别不表示 SDK 支持该格式。宏会多次求值参数,不要传入自增、函数调用等有副作用的表达式。
TiCloudStorageFrameInfo
| 字段 | 说明 |
|---|---|
channel_id | 0~255;同一采集通道的音视频使用相同 ID |
media | 一个 TICLOUDSTORAGE_AUDIO_* 或 TICLOUDSTORAGE_VIDEO_* 值 |
flags | 视频关键帧标志或音频采样类型 |
reserved | 必须为 0 |
timestamp_ms | 大于 0 的 UTC Unix 毫秒 |
length | 完整编码帧字节数 |
上传任务覆盖当前 Service 的全部媒体通道,不通过 channel_id 选择部分通道。
视频帧的 flags 取值如下:
| 常量 | 值 | 说明 |
|---|---|---|
0 | 0 | 非关键帧 |
TICLOUDSTORAGE_FRAME_FLAG_KEY_FRAME | 0x01 | 关键帧;JPEG 在上传队列中始终按关键帧处理,供客户端播放时仍应设置该标志 |
H.264 和 H.265 关键帧必须携带完整参数集,并设置 TICLOUDSTORAGE_FRAME_FLAG_KEY_FRAME。C SDK 从关键帧开始上传并自动完成后续分片,应用不需要管理分片边界。完整要求见上传录像。
音频帧的 flags 必须使用下列采样格式之一:
| 常量 | 值 | 采样格式 |
|---|---|---|
TICLOUDSTORAGE_AUDIO_SAMPLE_8K16B1C | 0 | 8 kHz、16 位、单声道 |
TICLOUDSTORAGE_AUDIO_SAMPLE_16K16B1C | 1 | 16 kHz、16 位、单声道 |
TICLOUDSTORAGE_AUDIO_SAMPLE_8K16B2C | 2 | 8 kHz、16 位、双声道 |
TICLOUDSTORAGE_AUDIO_SAMPLE_16K16B2C | 3 | 16 kHz、16 位、双声道 |
生命周期
TiCloudStorageInit
int TiCloudStorageInit(const struct TiCloudStorageOptions *options);初始化进程级资源。同一时刻只能成功初始化一次;options 可以为 NULL。
TiCloudStorageUninit
int TiCloudStorageUninit(void);调用前必须销毁全部 Service。成功返回后不再触发任何回调。
Service
TiCloudStorageServiceOptions
| 字段 | 说明 |
|---|---|
struct_size | 必须设置,推荐使用 TICLOUDSTORAGE_SERVICE_OPTIONS_INITIALIZER |
on_token_will_expire / on_token_expired | Token 即将到期、到期或被平台拒绝时的通知,具体触发方式见下方 TiCloudStorageServiceUpdateToken |
user_data | Service 级业务上下文,销毁返回前保持有效 |
device_secret_key | 必填,SDK 会复制且不得写入日志 |
buffer_size_bytes | 当前 Service 的内存帧队列容量,单位为字节;0 使用默认值,配置方法见上传录像 |
upload_queue_max_slices | 待上传切片数上限;0 使用默认值 2,允许值为 1~6,超出时创建 Service 返回 TICLOUDSTORAGE_E_INVALID_ARGUMENT。队列满时丢弃最旧的待上传切片,并计入相应请求的缺口 |
upload_force_http | 非零时仅将当前 Service 的媒体上传强制为明文 HTTP,包括将上传地址中的 HTTPS 改为 HTTP。0 使用交付包默认行为:支持 TLS 的包使用 HTTPS,不支持 TLS 的包使用 HTTP |
token_expire_warning_sec | 到期前预警秒数,0 关闭预警 |
max_key_frame_interval_ms | 当前 Service 各视频通道允许的最大关键帧间隔,单位为毫秒。0 使用默认值 5000;其他取值为 1~20000。起始关键帧等待时间为 max(3 × max_key_frame_interval_ms, 10000),因此默认等待 15 秒,最长等待 60 秒 |
关键帧间隔和等待时间对应以下公开常量:
| 常量 | 值 | 说明 |
|---|---|---|
TICLOUDSTORAGE_DEFAULT_MAX_KEY_FRAME_INTERVAL_MS | 5000 | max_key_frame_interval_ms 为 0 时采用的默认值 |
TICLOUDSTORAGE_MAX_KEY_FRAME_INTERVAL_MS | 20000 | max_key_frame_interval_ms 的配置上限 |
TICLOUDSTORAGE_MIN_KEY_FRAME_WAIT_MS | 10000 | 起始关键帧等待时间下限 |
所有 Service 回调由回调分发线程执行,不能阻塞,也不能在回调内调用 Stop、Destroy 或 Uninit。Token 回调可以调用 TiCloudStorageServiceUpdateToken()。
TiCloudStorageServiceCreate
int TiCloudStorageServiceCreate(
const char *device_id,
const struct TiCloudStorageServiceOptions *options);一个 Service 是一条独立媒体时间线,也是队列和上传任务的资源隔离边界。成功返回进程内唯一的正数 service_id。
TiCloudStorageServiceUpdateToken
int TiCloudStorageServiceUpdateToken(int service_id, const char *access_token);可以在启动前或运行期间设置 device_access_token。Token 过期会暂停云端传输,但不停止写队列或主动清空任务;更新有效 Token 后继续传输仍保留的待上传数据,队列容量和请求结束条件仍然有效。
本地时钟判断 Token 到期时触发 on_token_expired;平台每次因 Token 无效或过期而拒绝请求时,也会触发该回调。回调可能重复发生,应用应把续签交给业务线程并避免并发重复续签。
换入新 Token 后重新启用到期通知。重复设置尚未过期的同一个 Token 不会重新触发通知;重复设置已经过期的同一个 Token 后,可以再次收到到期通知。
TiCloudStorageServiceStart
int TiCloudStorageServiceStart(int service_id);启动后才接受写帧和上传请求。没有有效 Token 不影响本地启动,但云端传输会等待 Token。一个 Service 只能成功启动一次;已经启动或停止后再次调用,返回 TICLOUDSTORAGE_E_SERVICE_INVALID_STATE。
TiCloudStorageServiceStop
int TiCloudStorageServiceStop(int service_id);调用前先停止送帧线程。本接口停止上传处理,不排空帧队列,也不保证待上传数据或索引已经交付。被中止请求不补发 on_result。
本接口会阻塞,等待已发出的网络请求以及正在执行的回调结束,不能用于立即打断网络 I/O。回调中的阻塞操作也会延长停止时间。成功返回后不再触发该 Service 的回调,此时才可释放请求上下文;Service 级上下文保留到销毁成功。
TiCloudStorageServiceDestroy
int TiCloudStorageServiceDestroy(int service_id);只能销毁尚未启动或已经停止的 Service。成功后 service_id 失效。
上传任务
TiCloudStorageUploadRequestOptions
| 字段 | 说明 |
|---|---|
struct_size | 必须设置,推荐使用 TICLOUDSTORAGE_UPLOAD_REQUEST_OPTIONS_INITIALIZER |
start_time_ms | 搜索起始视频关键帧的时间下界;可用 TICLOUDSTORAGE_TIME_EARLIEST |
duration_ms | 0 表示持续到显式 SetEnd;正数从实际起始关键帧计算结束边界 |
on_progress | 一段媒体上传成功或确认失败时返回该段结果;一个请求可以触发多次 |
on_result | 请求关闭后触发一次;正常完成时返回唯一的最终结果 |
user_data | 请求级业务上下文,保持有效至所属 Service 的 TiCloudStorageServiceStop() 成功返回 |
回调中的结构体和字符串只在回调期间有效,需要异步处理时先复制。on_progress 的范围属于融合录像文件,不区分 channel_id。
on_result 返回请求的最终结果,后续进度通知不再改变该结果。请求上下文在 Service 停止成功前保持有效,期间不要释放或用于其他请求。
TiCloudStorageUploadRequest
int TiCloudStorageUploadRequest(
int service_id,
const struct TiCloudStorageUploadRequestOptions *options);成功返回正数 upload_id,只表示请求已受理。任意视频通道的第一个合法关键帧都可以启动请求;音频不能单独启动请求。等待关键帧超时后,通过 on_result 返回 TICLOUDSTORAGE_E_UPLOAD_START_TIMEOUT。
每个分片必须从视频帧开始,首视频帧之前的音频会被丢弃;分片内的音视频按时间顺序写入。
start_time_ms 最多晚于当前 UTC 时间 TICLOUDSTORAGE_MAX_FUTURE_START_MS(10 秒)。更早的时间能否命中,取决于环形队列是否仍保留对应关键帧。
每个 Service 同时最多存在 TICLOUDSTORAGE_MAX_UPLOADS_PER_SERVICE(64)个未结束的上传请求,等待起始关键帧的请求也计入该上限。没有可用请求名额时,接口返回 TICLOUDSTORAGE_E_TOO_MANY_UPLOADS。
TiCloudStorageUploadSetEnd
int TiCloudStorageUploadSetEnd(
int service_id,
int upload_id,
uint64_t end_time_ms);end_time_ms 是右开边界。重复设置相同值幂等成功,可以向前收缩但不能向后扩大。返回成功只表示新边界已接受,最终结果以 on_result 为准。
TiCloudStorageUploadResult
| 常量 | 值 | 说明 |
|---|---|---|
TICLOUDSTORAGE_UPLOAD_COMPLETE | 0 | 所选范围的媒体数据已按逻辑时间槽完成上传,未记录缺口 |
TICLOUDSTORAGE_UPLOAD_PARTIAL | 1 | 部分媒体数据上传成功,但请求范围内记录了缺口,包括开头或结尾缺失 |
TICLOUDSTORAGE_UPLOAD_FAILED | 2 | 没有成功上传的媒体区间 |
结果按整个 Service 的融合录像统计,各通道的媒体覆盖范围可能不同。成功区间以 5 秒逻辑时间槽为基础,裁剪到请求实际起点和结束边界。TiCloudStorageUploadResult 的字段如下:
| 字段 | 说明 |
|---|---|
upload_id | SDK 为本次逻辑上传请求生成的 ID |
requested_start_time_ms | 提交请求时的 start_time_ms |
requested_end_time_ms | 最终采用的请求结束边界。设置了 duration_ms 和 TiCloudStorageUploadSetEnd() 时,取两者确定的较早边界 |
start_time_ms | 最早上传成功区间的开始时间;没有成功区间时为 0 |
end_time_ms | 最晚上传成功区间的右开结束时间;没有成功区间时为 0 |
net_duration_ms | 所有上传成功区间的累计时长,不包含中间缺口;没有成功区间时为 0 |
result | 一个 TiCloudStorageUploadResultCode 值 |
error | TICLOUDSTORAGE_OK 或说明失败原因的负数错误码 |
message | 可选诊断信息,可能为 NULL;字符串只在回调期间有效 |
size_bytes | 云端确认成功的全部融合媒体数据量,不包含重试产生的重复流量 |
通过 result 判断完整、部分成功或失败,再结合 error、请求范围、成功范围、累计时长和 size_bytes 处理结果。PARTIAL 的缺口也可能位于请求开头或结尾。
媒体上传结果和录像查询状态分别确认。收到结果后,按上传录像从客户端验证查询和播放。
TiCloudStorageUploadRange
| 字段 | 说明 |
|---|---|
start_time_ms | 该分片逻辑时间槽的开始时间,包含该时间点 |
end_time_ms | 逻辑时间槽的右开结束时间,等于 start_time_ms + 5000 |
size_bytes | 云端确认成功的实际上传字节数;失败回调中为 0,不包含重试产生的重复流量 |
on_progress 使用这个结构返回一个固定 5 秒逻辑时间槽的处理结果,不表示分片内实际首末帧的时间戳。范围不对应单独的 channel_id,回调返回后结构体失效。
媒体帧队列
TiCloudStorageQueueGetInfo
int TiCloudStorageQueueGetInfo(
int service_id,
struct TiCloudStorageQueueInfo *info);返回容量、已用空间、已进入上传处理但尚未释放的数据量、帧数、最早/最新帧和最早/最新关键帧时间。inflight_bytes 包含等待上传、正在传输和等待重试的数据;持续升高表示上传处理落后于写入速度。
| 字段 | 说明 |
|---|---|
capacity_bytes | 队列总容量,包括帧数据和 SDK 内部帧头 |
used_bytes | 当前已经使用的队列空间,包括帧数据和 SDK 内部帧头 |
inflight_bytes | used_bytes 中已进入上传处理、尚未释放且暂时不能覆盖的空间 |
frame_count | 队列当前保存的音视频帧总数 |
oldest_time_ms | 按写入顺序,队列当前保留的第一帧时间戳 |
latest_time_ms | 按写入顺序,队列当前保留的最后一帧时间戳 |
oldest_key_frame_time_ms | 当前全局关键帧索引中最早保留的关键帧时间戳;JPEG 每帧均计入 |
latest_key_frame_time_ms | 当前全局关键帧索引中最新保留的关键帧时间戳;JPEG 每帧均计入 |
队列为空时,帧数量和所有时间戳字段均为 0。队列不为空但没有视频关键帧时,两个关键帧时间字段为 0。
TiCloudStorageQueueWriteFrame
int TiCloudStorageQueueWriteFrame(
int service_id,
const struct TiCloudStorageFrameInfo *frame_info,
const void *frame);SDK 在函数返回前复制结构体和完整帧。本接口线程安全,但应用必须保证同一 channel_id、同一媒体类型的时间戳单调不减;不同通道之间不要求全局重排。
返回成功只表示环形队列已接收当前帧,不表示已经上传,也不表示编码数据能够被客户端播放。使用 AAC 时,每次传入一个包含 ADTS 头的完整 AAC-LC 帧。其他编码格式、关键帧和音频数据的要求见上传录像。