Local Storage of Sub-device Video

Last Updated on : 2025-05-19 06:45:54download

Functional description

Local storage allows the sub-device to store its real-time streaming video on base station storage cards. The recording mode can be set to take effect globally. Also, it provides basic storage card status management policies to ensure the normal stream writing operation.

Basic features

Header file

tuya_ipc_stream_storage.h

Recording directory structure

Local storage uses universal file systems (such as FAT32) to store audio and video in MP4 format, and organizes files in multi-level directories with specific filenames to accelerate retrieval.

DCIM   // The storage directory, located in the top-level directory in the storage card file system.
├── uuid0 // The continuous video storage directory of the first device. Each device only stores one stream.
│   └── 2025
│       └── 03
│           └── 14
│               ├── 1741881600_xxx.mp4 // The video clip, recording the video starting at UTC 1741881600
│               └── .					      
│               └── .
│               └── .   
│               └──
│  
├── uuid1  // The continuous video storage directory of the second device, and its internal structure is the same as above.
│   		… 	
│    

Storage space management

After successful initialization, the storage space management policy is automatically started, including hot-swap monitoring of storage cards.

If an exception occurs in the storage card, it automatically stops the recording. When the available storage space reaches the lower limit, it automatically enters circular overwrite mode.

To ensure sufficient read and write performance, select a storage card of the corresponding class based on the stream write parameters.

Recording and playback

Video data source

  • Currently, each sub-device only supports writing one audio and video stream. Multi-channel writing is not allowed for a single sub-device.
  • When the storage module starts writing to the storage card, it automatically retrieves data from the ring buffer (ringbuf) of each sub-device’s main stream.
  • The recorded audio and video data comes from the corresponding sub-device’s ringbuf. You must manage the mapping between sub-devices and ring buffer at the application layer. Otherwise, timestamp inconsistencies may occur in the recorded sub-device data.

Recording mode

Three recording modes are supported:

  • No recording
  • Continuous recording (24/7)
  • Event-based recording

Currently, only global configuration is supported.

Video format

Only the MP4 format is supported for audio and video storage. Available MP4 video encodings include H.264 and H.265, and audio encodings include PCM and G711.

Circular overwrite

When storage space falls below 512 MB, the system automatically deletes the earliest recording files to reserve space for new recordings. Only one video file is deleted at a time.

Video search

  • Search by calendar: Search for dates with recorded footage within the specified month.
  • Search by progress bar: Search for the distribution of recording time segments for a certain day on the storage card.

Video playback

Read audio and video from the storage card and selectively send the data to the client at a specific rate.

  • The user can control playback, adjust the speed, and jump to a specified position on the timeline.
  • Playback control supports start, pause, resume, and end.
  • Speed up or slow down the playback by 0.5x or 2x.

Video download

Read audio and video data from the storage card and transmit it to the client applications (such as mobile apps) via the specified interface.

Video deletion

Delete the recording on a specific day after the user initiates the deletion on the mobile app.

Data structure and API description

The main data structures and APIs are listed below.

Interfaces implemented by you

The following interfaces must be implemented by you as they are platform-dependent. Failure to do so will result in compilation or linking errors. Refer to the demo for implementation examples.

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);

Initialize storage module

Initialize the storage module. This operation activates storage card management and creates write cache space.

OPERATE_RET tuya_ipc_ss_init(IN TUYA_IPC_STORAGE_VAR_T* p_storage_var);

typedef struct {
    UINT_T camera_device_max_count;                     // The maximum number of audio and video sub-devices.
    CHAR_T base_path[SS_BASE_PATH_LEN];                 // The storage base path.
    UINT_T max_event_per_day;                           // The maximum daily event recordings.

    STREAM_STORAGE_WRITE_MODE_E storage_mode;        // The global storage mode.
    SS_SD_STATUS_CHANGED_CB sd_status_changed_cb;       // The callback invoked when the storage card status changes.
    INT_T stor_format;                                   // The video file format. The default value of 0 indicates MP4.
    UINT_T skills;     // The storage capabilities. The default value is 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;                           // The maximum duration of an event recording clip (in seconds). The default value: 0, and the maximum value: 300s.
    INT_T max_continue_duration;                        // The maximum duration of a continuous recording clip (in seconds). The default value: 0, and the maximum value: 120s.
    UINT_T write_card_period_s;                         //  Reserved (unused).
    TUYA_IPC_STORAGE_WORKING_PATH_NAME_T path_name;     // Custom path naming (disabled by default).
    CHAR_T event_album_query_name[SS_BASE_FILE_NAME_LEN];  // Reserved (unused).
    STREAM_STORAGE_MEDIA_INFO_T* device_media_info_arr;     // The media config array of each sub-device (size=camera_device_max_count).
} TUYA_IPC_STORAGE_VAR_T;

Deinitialize storage module

Perform deinitialization to free the buffer memory.

VOID tuya_ipc_ss_uninit(VOID);

Set local storage mode

Set the global storage mode.

OPERATE_RET tuya_ipc_ss_set_write_mode(IN CONST STREAM_STORAGE_WRITE_MODE_E write_mode);

During initialization, the SDK internally calls tuya_ipc_sd_get_mode_config to retrieve and apply configurations saved by the upper-layer application.

Get local storage mode

Get the current storage mode.

STREAM_STORAGE_WRITE_MODE_E tuya_ipc_ss_get_write_mode();

Add a sub-device and enable storage

During runtime, call this API to dynamically enable storage for sub-devices, with storage modes adhering to global configurations.

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);

Remove sub-device storage

During runtime, call this API to remove storage functionality from an added sub-device.

OPERATE_RET tuya_ipc_ss_remove_sub_node_storage_by_sub_node_id(IN CONST CHAR_T* sub_node_id);

Start event recording

Start event recording for the specified sub-device.

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

The event recording automatically stops when reaching the configured maximum duration.

Stop event recording

Stop event recording for the specified sub-device.

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

Get event recording status

Get the status of event recording of the specified sub-device.

STORAGE_STATUS_E tuya_ipc_ss_get_event_record_status_by_sub_node_id(IN CONST CHAR_T* sub_node_id);

Delete recordings

Delete all recordings of the specified sub-device on a certain day.

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);

Playback & download

Search by month

Get the month in which the specified sub-device has recorded video.

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);

Search by day

Get the start and end times of all video clips of the specified sub-device on a certain day.

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);

After calling this API, use tuya_ipc_ss_pb_query_free_ts_arr(p_day_ts) and properly free the output parameter memory as needed.

Start playback

Start video playback of the specified sub-device. This function only registers the transmission callback. Internally, after locating and reading the corresponding frame, it executes the callback where dedicated APIs are used to send frame data.

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);

Search for playback

Search for the frame data of the specified sub-device and time. This function needs to be used in conjunction with the playback start API. The calling sequence is explained in the 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);

Set the playback speed

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);

Pause and mute the playback

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);

Stop and exit the playback

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

Preset the download

After receiving the command signaling, call this API to set the start and end times for the download segment.

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);

Calling this interface alone does not initiate data transmission. It must be used in combination with the following APIs to begin sending data.

Set the download status

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);

Setting the download status to SS_DL_START initiates frame data transmission. The calling sequence is explained in the demo.

Explore more

For more information on local video storage, refer to the IPC Local Storage.

The app’s playback control signaling processing logic is implemented in ty_sdk_media_callback.c within the demo. Modify as needed for your use case.