Non-SDK Storage

Last Updated on : 2025-10-22 01:53:12download

Get audio and video data

  1. Create a ring buffer read object.

    You need to create separate objects for video and audio.

    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. Locate the I-frame to be read. If a pre-record is required, it is recommended to call this interface after creating the read object, in order to lock the starting position of the pre-record frame.

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

    If this interface returns a failure, it indicates that a frame matching the request parameters could not be found. The operation can be retried until it is successful.

  3. Synchronize the audio frame position after locating the video key frame.

    OPERATE_RET tuya_ipc_ring_buffer_sync_stream(RING_BUFFER_USER_HANDLE_T handle_video, RING_BUFFER_USER_HANDLE_T handle_audio);
    
  4. Get frames. Get frames sequentially using the created audio and video ring buffer objects.

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

    The retry parameter indicates whether to retry fetching a frame in case of an exception.

Data encryption and decryption

If you want to develop a video file encryption feature, refer to this section. If not, you can ignore it.

Various encryption methods are available. You can dive into the details and design your own implementation.

Obtain keys

Obtain keys from the cloud

You can generate and manage encryption keys yourself, or obtain them from the cloud.

It is recommended to minimize the frequency of calls to this API, as excessive use will increase network I/O load.

OPERATE_RET httpc_iot_cloud_storage_encrypt_key_get(OUT ty_cJSON **result);

Encryption

You can generate and manage encryption vectors yourself, or use the following APIs to encrypt data.

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

When designing an encryption scheme, you should fully consider and make sure that all data is correctly decrypted during playback.

Decryption

For encrypted frames, use the following interfaces to decrypt the data:

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 must be identical to the key used for encryption.
  • pdata_in and pdata_out can share the same memory block.

The interfaces above are provided for reference only. You can implement your own decryption logic or utilize other open-source tools.

Data storage

After obtaining frame data, you need to design the data storage path and other details to facilitate fast retrieval and reading during playback.

Playback

If you have implemented features such as storage stream and need a playback feature, you can refer to the signaling processing flow in the demo.

The following signaling is available for playback interaction:

  • Search by month: MEDIA_STREAM_PLAYBACK_QUERY_MONTH_SIMPLIFY. Refer to the demo for return values.
  • Search for a specific day: MEDIA_STREAM_PLAYBACK_QUERY_DAY_TS or MEDIA_STREAM_PLAYBACK_QUERY_DAY_TS_WITH_ENCRYPT. Refer to the demo for the types of return values.
  • Start playback: MEDIA_STREAM_PLAYBACK_START_TS. After receiving this signal, the device returns immediately and needs to locate the new playback time point and send audio and video files.
    • The sending operation needs to be executed in another thread. You need to implement thread creation, destruction, and resource management by yourself.
    • Send audio and video files frame by frame. For the playback sending interface, refer to the context of invoking tuya_ipc_media_playback_send_video_frame_with_encrypt and tuya_ipc_media_playback_send_audio_frame_with_encrypt in the demo.
    • You need to implement the playback time point feature and use it with the sending thread.
  • Pause the playback: MEDIA_STREAM_PLAYBACK_PAUSE.
  • Resume the playback: MEDIA_STREAM_PLAYBACK_RESUME.
  • Mute the playback: MEDIA_STREAM_PLAYBACK_MUTE.
  • Unmute the playback: MEDIA_STREAM_PLAYBACK_UNMUTE.
  • Set the playback speed: MEDIA_STREAM_PLAYBACK_SET_SPEED, used together with the sending thread. For playback speeds greater than 4 times, it is recommended to only send I-frames.
  • Stop the playback: MEDIA_STREAM_PLAYBACK_STOP.
  • Start download: MEDIA_STREAM_DOWNLOAD_START.
    • Refer to the signaling processing for starting playback and change the sending interface to tuya_imm_p2p_app_download_data.
      • When the type parameter is TUYA_DOWNLOAD_VIDEO, the pHead parameter should be of type STORAGE_FRAME_HEAD_T, and the pData parameter is the frame data.
      • When the type parameter is TUYA_DOWNLOAD_VIDEO_ALLOW_ENCRYPT, the pHead parameter is of type TUYA_DOWNLOAD_FRAME_HEAD_ENCRYPT_T, and the pData parameter is the frame data.
    • After the download is sent, you need to call tuya_imm_p2p_app_download_status to set the sending completion flag.
    • Pay attention to download thread creation, destruction, and resource management.
  • Stop download: MEDIA_STREAM_DOWNLOAD_STOP.
  • Pause download: MEDIA_STREAM_DOWNLOAD_PAUSE.
  • Resume download: MEDIA_STREAM_DOWNLOAD_RESUME.
  • Cancel download: MEDIA_STREAM_DOWNLOAD_CANCLE.
  • Delete playback: MEDIA_STREAM_PLAYBACK_DELETE. After the file is deleted, use tuya_imm_p2p_delete_video_finish to report the status.

FAQs

Do I need to disable the APIs provided by the SDK?

Just do not call tuya_ipc_ss_init. If you want to enable features such as downloading and deleting playback, you need to upload the specified capability flags. Call tuya_ipc_skill_enable to set the capability flags individually, as shown below:

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