非 SDK 存储开发指导

更新时间:2025-09-30 06:45:17下载pdf

获取音视频数据

  1. 创建读取 ringbuf 对象。

    视频和音频需要分开创建。

    RING_BUFFER_USER_HANDLE_T tuya_ipc_ring_buffer_open(INT_T device, INT_T channel, IPC_STREAM_E stream, RBUF_OPEN_TYPE_E open_type);
    
  2. 定位要读取的 I 帧位置。如需要预录功能,建议在创建读取对象后,调用此接口,锁定预录帧的起始位置。

    OPERATE_RET tuya_ipc_ring_buffer_anchor_user(RING_BUFFER_USER_HANDLE_T handle, UINT_T frame_num, BOOL_T check_overlap);
    

    如返回失败,则表示找不到入参条件下的帧,可继续等待至找到为止。

  3. 在定位到视频关键帧的位置后,需要同步音频帧位置。

    OPERATE_RET tuya_ipc_ring_buffer_sync_stream(RING_BUFFER_USER_HANDLE_T handle_video, RING_BUFFER_USER_HANDLE_T handle_audio);
    
  4. 取帧。通过创建的音视频 ringbuf 对象,依次取帧。

    RING_BUFFER_NODE_T* tuya_ipc_ring_buffer_get_av_frame(RING_BUFFER_USER_HANDLE_T v_handle, RING_BUFFER_USER_HANDLE_T a_handle, BOOL_T is_retry);
    

    retry 表示是否重复取帧,异常情况下可使用此参数。

数据加密与解密

如果您需要开发视频文件加密功能,请参考本章节的介绍,如不需要可忽略。

加密方法有多种,您可自行了解相关细节并设计实现。

密钥获取

云端获取接口

加密密钥可以自行生成管理,也可以从云端获取。

建议尽量减少调用此接口的频次,否则会加重网络 I/O 负载。

OPERATE_RET httpc_iot_cloud_storage_encrypt_key_get(OUT ty_cJSON **result);

加密

加密向量可自行生成、管理。可使用以下接口进行数据加密。

OPERATE_RET openssl_aes_cbc128_encrypt(IN CONST BYTE_T *pdata_in, IN CONST UINT_T data_len,
                                      OUT BYTE_T *pdata_out, OUT UINT_T *pdata_out_len,
                                      IN CONST BYTE_T *pkey, IN BYTE_T *piv);

设计加密方案时,应进行充分的考虑,必须确保所有数据在回放环节能够被正确解密。

解密

对于加密的帧,使用以下接口解密数据:

OPERATE_RET openssl_aes_cbc128_decrypt(IN CONST BYTE_T *pdata_in, IN CONST UINT_T data_len,
                                      OUT BYTE_T *pdata_out, OUT UINT_T *pdata_out_len,
                                      IN CONST BYTE_T *pkey, IN BYTE_T *piv);
  • pkey 密钥需要和加密时的密钥相同。
  • pdata_inpdata_out 可以共用同一块内存。

上述接口仅作为参考,您可以自行实现解密逻辑的代码,也可以使用其他开源工具。

数据存储

获取帧数据以后,需要自行设计数据存储路径等细节,以便在回放时快速检索读取数据。

回放

如自行实现了存储码流等功能,同时需要回放功能,可参考 Demo 中对应的信令处理流程。

回放交互有以下信令:

  • 月份检索:MEDIA_STREAM_PLAYBACK_QUERY_MONTH_SIMPLIFY,返回值参考 Demo 的实现。
  • 具体某一天检索:MEDIA_STREAM_PLAYBACK_QUERY_DAY_TSMEDIA_STREAM_PLAYBACK_QUERY_DAY_TS_WITH_ENCRYPT,返回值类型参考 Demo 的实现。
  • 开始回放:MEDIA_STREAM_PLAYBACK_START_TS,该信令接收后,需要立即返回,需要实现定位新的播放位置和发送音视频的操作。
    • 其中发送操作需要单独在另外的线程中执行,线程创建、销毁和资源管理需要自行实现。
    • 逐帧发送,回放发送音视频帧接口可参考 Demo 中调用 tuya_ipc_media_playback_send_video_frame_with_encrypttuya_ipc_media_playback_send_audio_frame_with_encrypt 的上下文。
    • 定位播放位置功能需要自行实现,并配合发送线程。
  • 回放暂停:MEDIA_STREAM_PLAYBACK_PAUSE
  • 回放再开始:MEDIA_STREAM_PLAYBACK_RESUME
  • 回放静音:MEDIA_STREAM_PLAYBACK_MUTE
  • 回放非静音:MEDIA_STREAM_PLAYBACK_UNMUTE
  • 回放倍速设置:MEDIA_STREAM_PLAYBACK_SET_SPEED,需要配合发送线程,且大于 4 倍速的回放建议只发送 I 帧。
  • 回放结束:MEDIA_STREAM_PLAYBACK_STOP
  • 下载开始:MEDIA_STREAM_DOWNLOAD_START
    • 参考开始回放信令处理,发送接口需要改为 tuya_imm_p2p_app_download_data
      • type 参数为 TUYA_DOWNLOAD_VIDEO 时,pHead 参数类型为 STORAGE_FRAME_HEAD_T,pData 参数为帧数据。
      • type 参数为 TUYA_DOWNLOAD_VIDEO_ALLOW_ENCRYPT 时,pHead 参数类型为 TUYA_DOWNLOAD_FRAME_HEAD_ENCRYPT_T,pData 参数为帧数据。
    • 下载发送结束后,需要调用 tuya_imm_p2p_app_download_status 设置发送完成标记。
    • 注意下载线程创建、销毁和资源管理。
  • 下载结束:MEDIA_STREAM_DOWNLOAD_STOP
  • 下载暂停:MEDIA_STREAM_DOWNLOAD_PAUSE
  • 下载再开始:MEDIA_STREAM_DOWNLOAD_RESUME
  • 下载取消:MEDIA_STREAM_DOWNLOAD_CANCLE
  • 回放删除:MEDIA_STREAM_PLAYBACK_DELETE,文件删除后,使用 tuya_imm_p2p_delete_video_finish 上报状态。

常见问题

是否需要禁用 SDK 提供的接口?

不调用 tuya_ipc_ss_init 即可。如果需要开启回放的下载、删除等功能,需要单独上传对应的能力标记位。可调用 tuya_ipc_skill_enable 单独设置能力标记,如下所示:

TUYA_IPC_SKILL_PARAM_U skill_param = { .value = TUYA_IPC_SKILL_BASIC | TUYA_IPC_SKILL_DOWNLOAD | TUYA_IPC_SKILL_DELETE_BY_DAY};
tuya_ipc_skill_enable(TUYA_IPC_SKILL_LOCALSTG, &skill_param);