子设备录像本地存储

更新时间:2026-05-12 08:48:55LLM 副本以 Markdown 格式查看下载 PDF

功能描述

本地存储提供将子设备的实时流视频存储到视频网关存储卡的能力,并且可设置录像模式,在全局生效。同时,提供基本的存储卡状态管理策略,保证码流写入流程的正常运行。

基本功能说明

头文件

tuya_ipc_stream_storage.h

录像目录结构

本地存储使用通用文件系统(FAT32 等),以 MP4 格式存储音视频,按多级目录、特定文件名组织文件以加速检索。

DCIM   // 存储目录,位于存储卡的文件系统的顶层目录
├── uuid0  // 第一个设备的持续录像存储目录,每个设备只存一种码流
│   └── 20250314
│       ├── 20250314_1741881600_xxx.mp4 // 录像片段,记录 UTC 时间为 1741881600 开始的录像
│       └── .					      
│       └── . 
│       └── .   
│       └── 
│  
├── uuid1  //第二个设备的持续录像存储目录,内部结构同上
│   		...... 	 
│    

存储空间管理

初始化成功后,自动启动存储空间管理策略,包括存储卡热插拔监测等。

在存储卡异常后,自动触发自动停止录像等功能;在存储卡可用空间达到下限后,自动进入循环覆盖的写入模式。

为保证足够的读写性能,需要根据写入码流的参数来选择对应级别的存储卡。

录像 & 回放

录像数据源

  • 当前每个子设备只支持写入一路音频和视频码流,不支持单子设备多通道写入。
  • 存储模块开始写入存储卡时,自动从每个子设备的主码流的环形缓冲区(Ring buffer,ringbuf)中获取数据。
  • 录像所用的音视频数据,来自于对应子设备的 ringbuf。开发者在上层需要管理子设备与 ringbuf 的对应关系,否则录像时子设备数据会出现先后不一致的问题。

录像模式

共有 3 种录像模式:

  • 不录像
  • 连续录像(7 * 24 小时持续录像)
  • 事件录像

目前仅支持全局设置。

录像格式

目前仅支持 MP4 格式存储音视频数据。支持的 MP4 视频编码包括 H.264 和 H.265,音频支持 PCM 和 G711 两种。

循环覆盖

存储空间不足 512 MB 时,程序会自动删除最旧的录像文件,为新录像预留存储空间。每次仅删除一个录像文件。

录像检索

  • 按月历检索:检索该月有录像的日期。
  • 进度条检索:检索存储卡中某天的录像时间的分布。

录像回放

读取存储卡中的音视频数据,按照一定速率、有选择地传输给客户端并显示。

  • 录像回放:支持回放状态控制、进度条跳转、倍速等特性。
  • 回放状态控制:包含开始、暂停、恢复、和结束。
  • 倍速回放:加快或减慢数据读取和显示的速度,支持的倍速有 0.5 倍和 2 倍。

录像下载

读取存储卡中的音视频数据,通过发送接口传递给 App 等客户端。

录像删除

按天删除,由用户在 App 上触发,进而删除某一天的录像。

数据结构和接口说明

下文将列举主要的数据结构和接口。

由开发者实现的接口

因运行的平台可能不同,以下接口必须由开发者自行实现,否则程序编译链接时会提示出错。函数实现可参考 Demo。

SD_STATUS_E tuya_ipc_sd_get_status(VOID);
STREAM_STORAGE_WRITE_MODE_E tuya_ipc_sd_get_mode_config();
VOID tuya_ipc_sd_get_capacity(UINT_T* p_total, UINT_T* p_used, UINT_T* p_free);
VOID tuya_ipc_sd_remount(VOID);

存储模块初始化

初始化存储模块,该操作会开启存储卡管理、写入缓存空间的创建等步骤。

OPERATE_RET tuya_ipc_ss_init(IN TUYA_IPC_STORAGE_VAR_T* p_storage_var);

typedef struct {
    UINT_T camera_device_max_count;                     // 摄像头子设备最大数量
    CHAR_T continue_mount_path[SS_BASE_PATH_LEN];        // 连续存储的基础路径
    CHAR_T event_mount_path[SS_BASE_PATH_LEN];           // 事件存储的基础路径

    STREAM_STORAGE_PATH_MAP_T channel_name_map;         // 通道名称映射(/DCIM/xxx/)
    STREAM_STORAGE_EVENT_TYPE_NAME_T event_type_map;
    UINT_T max_event_per_day;                           // 已废弃
    
    STREAM_STORAGE_WRITE_MODE_E storage_mode;           // 全局存储模式
    SS_SD_STATUS_CHANGED_CB sd_status_changed_cb;   
    INT_T stor_format;                                  // 存储格式,0 表示 MP4 格式
    UINT_T skills;                                      // 存储能力,0 表示默认(TUYA_IPC_SKILL_BASIC | TUYA_IPC_SKILL_DOWNLOAD)

    INT_T max_event_duration;                           // 事件文件最大时长,0 表示默认(300 秒)
    INT_T max_continue_duration;                        // 连续录像文件最大时长,0 表示默认(120 秒)
    UINT_T write_card_period_s;                         // 视频写卡周期,0 表示默认(6 秒)

    CHAR_T event_album_query_name[SS_BASE_FILE_NAME_LEN]; // App 下发的事件相册查询名称

    STREAM_STORAGE_MEDIA_INFO_T* device_media_info_arr; // 各设备的媒体信息数组

    BOOL_T encrypt_enable;                            // 是否启用加密,TRUE:启用,FALSE:关闭
} TUYA_IPC_STORAGE_VAR_T;

存储模块反初始化

执行反初始化,释放缓存资源。

VOID tuya_ipc_ss_uninit(VOID);

设置本地存储模式

设置全局存储模式。

OPERATE_RET tuya_ipc_ss_set_write_mode(IN CONST STREAM_STORAGE_WRITE_MODE_E write_mode);

在初始化阶段,SDK 内部会调用 tuya_ipc_sd_get_mode_config 获取由上层保存的配置,并进行设置。

获取本地存储模式

获取当前的存储模式。

STREAM_STORAGE_WRITE_MODE_E tuya_ipc_ss_get_write_mode();

添加子设备并开启存储

程序运行过程中,可以使用此接口动态添加开启子设备存储,存储模式遵循全局的设置。

OPERATE_RET tuya_ipc_ss_add_new_node_storage_by_sub_node_id(IN CONST CHAR_T* sub_node_id, IN STREAM_STORAGE_MEDIA_INFO_T* media_info);

移除子设备存储

程序运行过程中,调用以下接口,移除已添加设备的存储功能。

OPERATE_RET tuya_ipc_ss_remove_sub_node_storage_by_sub_node_id(IN CONST CHAR_T* sub_node_id);

启动事件录像

启动子设备事件录像。

TUYA_IPC_SS_EVENT_HANDLE_T tuya_ipc_ss_start_event_by_handle(IN CONST CHAR_T* sub_node_id, IN STREAM_STORAGE_START_EVENT_INFO_T* p_event_info);

事件录像时长达到设置的最大值时,自动停止此次事件录像。

停止事件录像

停止子设备事件录像。

OPERATE_RET tuya_ipc_ss_stop_event_by_handle(TUYA_IPC_SS_EVENT_HANDLE_T event_handle);

获取子设备事件录像状态

获取当前子设备事件录像的状态。

STORAGE_STATUS_E tuya_ipc_ss_get_event_record_status_by_sub_node_id(IN CONST CHAR_T* sub_node_id);

删除录像

删除指定子设备的录像,仅限于某天的全部录像。

OPERATE_RET tuya_ipc_ss_delete_video(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN UINT_T year, IN UINT_T month, IN UINT_T day);

回放 & 下载控制

按月查询

获取指定子设备有录像的月份。

OPERATE_RET tuya_ipc_ss_pb_query_by_month(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN USHORT_T year, IN USHORT_T month, OUT UINT_T *p_return_days);

按天查询

获取指定子设备在某天所有的录像片段的起止时间。

OPERATE_RET tuya_ipc_ss_pb_query_by_day(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN USHORT_T year, IN USHORT_T month, IN UCHAR_T day, OUT SS_QUERY_DAY_TS_ARR_T** p_ts_arr);

调用后,使用 tuya_ipc_ss_pb_query_free_ts_arr(p_day_ts) 并根据需要合理地释放传出参数的空间。

开始回放

开始指定子设备的回放。此函数只是传入发送回调,内部找到读取对应的帧后,会执行回调,然后在回调中使用专用接口发送帧数据。

OPERATE_RET tuya_ipc_ss_pb_start(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, 
                                    IN INT_T req_id,
                                    IN SS_PB_EVENT_CB event_cb,
                                    IN SS_PB_GET_MEDIA_CB video_cb, 
                                    IN SS_PB_GET_MEDIA_CB audio_cb);

回放查找

查找指定子设备和时间的帧数据,此函数需要与回放开始接口配合使用,调用顺序参照 Demo。

OPERATE_RET tuya_ipc_ss_pb_seek(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN INT_T req_id, IN SS_FILE_TIME_TS_T* pb_file_info, IN UINT_T play_timestamp);

设置播放速度

OPERATE_RET tuya_ipc_ss_pb_set_speed(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN INT_T req_id, IN UINT_T pb_speed);

回放暂停、静音等

OPERATE_RET tuya_ipc_ss_pb_set_status(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN INT_T req_id, IN SS_PB_STATUS_E new_status);

回放停止退出

OPERATE_RET tuya_ipc_ss_pb_stop(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx);

下载预设

接收到信令后,调此接口,设置需要下载的片段起止时间。

OPERATE_RET tuya_ipc_ss_donwload_pre(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN SS_DOWNLOAD_FILES_TS_T* pb_files_info);

单独调用此接口并不会开启发送,需要配合以下接口才能开始发送数据。

设置下载状态

OPERATE_RET tuya_ipc_ss_download_set_status(IN CHAR_T* sub_node_id, IN UINT_T p2p_pb_idx, IN SS_DOWNLOAD_STATUS_E new_status);

设置下载状态为 SS_DL_START 后会开始发送帧数据。调用顺序参考 Demo。

使用说明

关于录像本地存储的更多使用说明,请参考 IPC 录像本地存储 文档。

非 SDK 存储方案适配

如不使用 SDK 提供的存储方案,可以自行设计、实现存储和回放方案,回放相关功能只需适配相关信令处理即可。在 Demo 的 ty_sdk_media_callback.c 中有执行 App 端回放控制信令的处理逻辑,可以按需修改使用。具体步骤仍可参考上述 IPC 相关文档。

与 IPC 差异:

  • 回放信令命名差异。如在 IPC 中,回放查询月份的信令为 MEDIA_STREAM_PLAYBACK_QUERY_MONTH_SIMPLIFY;而在视频网关中,则为 MEDIA_STREAM_PLAYBACK_QUERY_MONTH_SIMPLIFY_GW
  • 下载开始信令处理不同。视频网关接收到 MEDIA_STREAM_DOWNLOAD_START_GW 时,开发者可在 C2C_TRANS_CTRL_GW_DL_START 结构化信息中,自定义需要下载录像的编码信息。