The Sensor SDK provides API interfaces to record device data into Matroska (.mkv) files. The Matroska container format can store video data, IMU data, and device calibration information. You can use the k4arecorder command-line tool for recording or directly use the recording API to capture content.
For detailed information about the recording API, refer to k4a_record_create().
For detailed information about the Matroska file format specification, refer to《 K4A Wrapper Recording File Format》
Using the Playback API
Recorded files can be played back using the Playback API, which allows accessing sensor data in the same format as the SDK.
Opening a recording file
In the following example, we open a recording file using k4a_playback_open() output its length, and then close it using k4a_playback_close() .
k4a_playback_t playback_handle = NULL; if (k4a_playback_open("recording.mkv", &playback_handle) != K4A_RESULT_SUCCEEDED) { printf("Failed to open recording\n"); return 1; } uint64_t recording_length = k4a_playback_get_last_timestamp_usec(playback_handle); printf("Recording is %lld seconds long\n", recording_length / 1000000); k4a_playback_close(playback_handle);
Reading Captures
After opening the file, captures within the recording can be read. The following example demonstrates reading each capture from the file.
k4a_capture_t capture = NULL; k4a_stream_result_t result = K4A_STREAM_RESULT_SUCCEEDED; while (result == K4A_STREAM_RESULT_SUCCEEDED) { result = k4a_playback_get_next_capture(playback_handle, &capture); if (result == K4A_STREAM_RESULT_SUCCEEDED) { // Process capture here k4a_capture_release(capture); } else if (result == K4A_STREAM_RESULT_EOF) { // End of file reached break; } } if (result == K4A_STREAM_RESULT_FAILED) { printf("Failed to read entire recording\n"); return 1; }
Searching within the Recording
After reaching the end of the file, it may be necessary to go back and read again. To accomplish this, k4a_playback_get_previous_capture() can be used for seeking back, but depending on the length of the recording, this approach may be very slow. Alternatively,k4a_playback_seek_timestamp()function can be used to jump to a specific timestamp in the file.
In this example, we specify timestamps in microseconds to locate various points in the file.
// Seek to the beginning of the file if (k4a_playback_seek_timestamp(playback_handle, 0, K4A_PLAYBACK_SEEK_BEGIN) != K4A_RESULT_SUCCEEDED) { return 1; } // Seek to the end of the file if (k4a_playback_seek_timestamp(playback_handle, 0, K4A_PLAYBACK_SEEK_END) != K4A_RESULT_SUCCEEDED) { return 1; } // Seek to 10 seconds from the start if (k4a_playback_seek_timestamp(playback_handle, 10 * 1000000, K4A_PLAYBACK_SEEK_BEGIN) != K4A_RESULT_SUCCEEDED) { return 1; } // Seek to 10 seconds from the end if (k4a_playback_seek_timestamp(playback_handle, -10 * 1000000, K4A_PLAYBACK_SEEK_END) != K4A_RESULT_SUCCEEDED) { return 1; }
Reading Tag Information
Recorded content may also include various metadata such as device serial number and firmware version. This metadata is stored in recording tags and can be accessed using the k4a_playback_get_tag() function.
// Print the serial number of the device used to record char serial_number[256]; size_t serial_number_size = 256; k4a_buffer_result_t buffer_result = k4a_playback_get_tag(playback_handle, "K4A_DEVICE_SERIAL_NUMBER", &serial_number, &serial_number_size); if (buffer_result == K4A_BUFFER_RESULT_SUCCEEDED) { printf("Device serial number: %s\n", serial_number); } else if (buffer_result == K4A_BUFFER_RESULT_TOO_SMALL) { printf("Device serial number too long.\n"); } else { printf("Tag does not exist. Device serial number was not recorded.\n"); }
Recording Tag List
Below is a list of all default tags that can be included in a recording file. Many of these values can be used as part of the k4a_record_configurationt structure and can be read using the k4a_playback_get_record_configuration() function.
If a tag does not exist, assume the default value.
Tag Name | Default Value | k4a_record_configuration_t Field Note |
Note |
K4A_COLOR_MODE | “OFF” | color_format / color_resolution | Possible values: “OFF”, “MJPG_1080P”, “NV12_720P”, “YUY2_720P”, etc. |
K4A_DEPTH_MODE | “OFF” | depth_mode / depth_track_enabled | Possible values: “OFF”, “NFOV_UNBINNED”, “PASSIVE_IR”, etc. |
K4A_IR_MODE | “OFF” | depth_mode / ir_track_enabled | Possible values: “OFF”, “ACTIVE”, “PASSIVE” |
K4A_IMU_MODE | “OFF” | imu_track_enabled | Possible values: “ON”, “OFF” |
K4A_CALIBRATION_FILE | “calibration.json” | N/A | Refer to k4a_device_get_raw_calibration() |
K4A_DEPTH_DELAY_NS | “0” | depth_delay_off_color_usec | Value is stored in nanoseconds, API uses microseconds. |
K4A_WIRED_SYNC_MODE | “STANDALONE” | wired_sync_mode | Possible values: “STANDALONE”, “MASTER”, “SUBORDINATE” |
K4A_SUBORDINATE_DELAY_NS | “0” | subordinate_delay_off_master_usec | Value is stored in nanoseconds, API uses microseconds. |
K4A_COLOR_FIRMWARE_VERSION | “” | N/A | Device color firmware version, e.g., “1.x.xx” |
K4A_DEPTH_FIRMWARE_VERSION | “” | N/A | Device depth firmware version, e.g., “1.x.xx” |
K4A_DEVICE_SERIAL_NUMBER | “” | N/A | Serial number of the recording device |
K4A_START_OFFSET_NS | “0” | start_timestamp_offset_usec | See Timestamp Synchronization below. |
K4A_COLOR_TRACK | None | N/A | Refer to 《 K4A Wrapper Recording File Format》 |
K4A_DEPTH_TRACK | None | N/A | Refer to 《 K4A Wrapper Recording File Format》 |
K4A_IR_TRACK | None | N/A | Refer to 《 K4A Wrapper Recording File Format》 |
K4A_IMU_TRACK | None | N/A | Refer to 《 K4A Wrapper Recording File Format》 |
Timestamp Synchronization
The Matroska format requires that the recorded content starts with a timestamp of 0. When using multi-device synchronization, the first timestamp in each device can be non-zero.
To retain the original timestamps of the devices when switching between recording and playback, the file stores an offset to be applied to the timestamps. The K4A_START_OFFSET_NS tag is used to specify the timestamp offset so that the file can be resynchronized after recording. This timestamp offset can be added to each timestamp in the file to reconstruct the original device timestamps.
The start offset is also provided in the k4a_record_configuration_t structure.