User Metadata mission¶
The User Metadata mission demonstrates how to:
Create a service that publishes custom user metadata
Attach metadata both to live streams and to recorded tracks
Push metadata periodically (e.g., 30 FPS)
Handle metadata updates through listener callbacks
Implement the same logic in C, C++, and Python
This mission shows how to extend video streams and recordings with custom metadata. It can be used to embed application-specific information (sensor values, AI inference results, annotations, etc.) into the video pipeline of the drone.
The source code is available in C, C++ and Python:
Getting started¶
Build, install and run the User Metadata sample mission¶
Please follow the instructions of the README file.
Mission overview¶
The User Metadata sample mission demonstrates how to interact with the Metadata Publisher API.
The mission works as follows:
At startup, the service initializes a MetadataPublisher with a listener.
The listener receives callbacks when the list of metadata entries for a stream or a record is updated.
The service first adds one stream metadata (for a resource like the front camera), and one record metadata (for a video track).
Once registered, the mission enters a loop where it pushes random values into both the stream metadata and the record metadata.
The metadata is pushed at ~30 FPS, simulating real-time data injection per frame.
How does it work¶
The listener handles two types of updates:
onStreamUserMetadataList: triggered when stream metadata list is updated for a resource path.onRecordUserMetadataList: triggered when record metadata list is updated for a specific camera and track.
Add metadata keys:
Stream metadata is created with
addStreamUserMetadata(uid, size, resource_id)Record metadata is created with
addRecordUserMetadata(uid, size, camera_id, track_name)
Push values:
The publisher regularly pushes new values (e.g., random integers) into both stream and record metadata.
This data is automatically injected into the live video stream or recording.
Stop publisher:
On termination, the publisher is stopped and destroyed gracefully.
C++ Example:
mp.addStreamUserMetadata("dynamic_stream_value", 1, "front");
mp.addRecordUserMetadata("dynamic_record_value", 1, 1, "DefaultVideo");
uint8_t random_value = static_cast<uint8_t>(std::rand() % 101);
mp.push("dynamic_stream_value", &random_value, 1);
mp.push("dynamic_record_value", &random_value, 1);
C Example:
metadata_publisher_add_stream_user_metadata(mp, "dynamic_stream_value",
1, "front");
metadata_publisher_add_record_user_metadata(mp,"dynamic_record_value", 1,
1, "DefaultVideo");
uint8_t random_value = (uint8_t)(rand() % 101);
metadata_publisher_push(mp, "dynamic_stream_value", &random_value, 1);
metadata_publisher_push(mp, "dynamic_record_value", &random_value, 1);
Python Example:
mp.add_stream_user_metadata(STREAM_UID, 1, RESOURCE_ID)
mp.add_record_user_metadata(RECORD_UID, 1, CAMERA_ID, TRACK_NAME)
random_value = random.randint(0, 100)
mp.push(STREAM_UID, bytes([random_value]))
mp.push(RECORD_UID, bytes([random_value]))
Note
This mission illustrates how to publish custom metadata alongside live and recorded video. This metadata can later be retrieved or processed for advanced applications such as telemetry embedding, AI inference overlays, or post-flight analysis.