子设备录像本地存储

更新时间:2025-05-08 06:43:12下载pdf

功能描述

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

基本功能说明

头文件

tuya_ipc_stream_storage.h

录像目录结构

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

DCIM   // 存储目录,位于存储卡的文件系统的顶层目录
├── uuid0  // 第一个设备的持续录像存储目录,每个设备只存一种码流
│   └── 2025
│       └── 03
│           └── 14
│               ├── 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 base_path[SS_BASE_PATH_LEN];                 // 存储路径
    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;                                   // 视频文件格式 默认 MP4:0
    UINT_T skills;     // 存储能力,默认 0 代表: TUYA_IPC_SKILL_BASIC | TUYA_IPC_SKILL_DELETE_BY_DAY | TUYA_IPC_SKILL_SPEED_PLAY_0Point5 | TUYA_IPC_SKILL_SPEED_PLAY_2
 
    INT_T max_event_duration;                           // 事件录像片段最大时长,默认 0:(300s)
    INT_T max_continue_duration;                        // 持续录像片段最大时长,默认 0:(120s)
    UINT_T write_card_period_s;                         //  暂不启用
    TUYA_IPC_STORAGE_WORKING_PATH_NAME_T path_name;     // 存储路径自定义命名,默认关闭
    CHAR_T event_album_query_name[SS_BASE_FILE_NAME_LEN];  // 暂不启用
    STREAM_STORAGE_MEDIA_INFO_T* device_media_info_arr;     // 每个子设备的媒体信息配置数组,数组大小为 camera_device_max_count
} 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);

启动事件录像

启动子设备事件录像。

OPERATE_RET tuya_ipc_ss_start_event_by_type(IN CONST CHAR_T* sub_node_id, IN TUYA_ALARM_TYPE_E type);

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

停止事件录像

停止子设备事件录像。

OPERATE_RET tuya_ipc_ss_stop_event_by_type(IN CONST CHAR_T* sub_node_id, IN TUYA_ALARM_TYPE_E type);

获取子设备事件录像状态

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

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 录像本地存储 文档。

在 Demo 的 ty_sdk_media_callback.c 中有执行 App 端回放控制信令的处理逻辑,然后按需修改使用。