Read and Parse KLV Metadata from MPEG-TS with FFmpeg
This article provides a practical guide on how to extract, read, and parse Key-Length-Value (KLV) metadata embedded within MPEG-TS (MPEG Transport Stream) files using FFmpeg and FFprobe. You will learn how to identify KLV telemetry streams, extract the raw binary metadata payload, and inspect the packet data directly from the command line.
Step 1: Identify the KLV Metadata Stream
Before extracting KLV data (often used for MISB drone telemetry in military and civilian aerospace applications), you must identify which stream inside the MPEG-TS file contains the metadata.
Run the following ffprobe command to inspect the
streams:
ffprobe -i input.tsIn the output, look for a stream labeled with Data or
klva (KLV Asynchronous) or klvs (KLV
Synchronous). It will look similar to this:
Stream #0:2[0x1f1]: Data: bin_data (klva / 0x61766c6b)
In this example, the metadata is on stream index 0:2
(data stream).
Step 2: Extract Raw KLV Metadata to a File
Once you know the stream index, you can use ffmpeg to
extract the raw KLV binary payload without re-encoding the video or
audio.
Use the following command to map the data stream and output it as a raw binary file:
ffmpeg -i input.ts -map 0:d -c copy -f data output.klv-map 0:d: Selects all data streams from the input file. If you have multiple data streams and want a specific one (e.g., stream 2), use-map 0:2.-c copy: Copies the data bitstream directly without modification.-f data: Forces the output format to raw data.
Step 3: Inspect KLV Packets Using FFprobe
If you want to view the raw hex representation of the KLV packets
directly in the terminal without exporting a file, you can use
ffprobe to dump the packet payloads.
Run this command:
ffprobe -v error -select_streams d -show_packets -show_data input.ts-select_streams d: Selects only the data streams.-show_packets: Displays packet-level information.-show_data: Prints the payload of the packets in hexadecimal and ASCII formats.
The output will display packets containing the 16-byte Universal Label (Key), the length field, and the value payload:
[PACKET]
codec_type=data
stream_index=2
pts=85700
dts=85700
duration=3600
size=127
data=
00000000 06 0e 2b 34 02 0b 01 01 0e 01 03 01 01 00 00 00 ..+4............
00000010 51 81 80 02 01 01 02 08 00 04 60 50 58 74 e7 c0 Q.........`PXt..
...
[/PACKET]
Step 4: Understanding and Parsing the KLV Structure
The extracted .klv file or hex payload follows the SMPTE
ST 336 standard. To parse this binary data into human-readable metrics
(such as latitude, longitude, and altitude), you must decode the three
elements of the KLV structure:
- Key (Universal Label): A 16-byte unique identifier
that defines what the data is (e.g., the MISB ST 0601 UAS Local Metadata
Set key:
06 0E 2B 34 02 0B 01 01 0E 01 03 01 01 00 00 00). - Length: A variable-length field (often BER-encoded) indicating the size of the value payload in bytes.
- Value: The actual telemetry data payload, which is parsed based on the specific standard identified by the Key.
Because FFmpeg does not natively decode the internal telemetry fields
of MISB/KLV standards into text, you must pass the extracted raw
output.klv file to a dedicated KLV parser library (such as
Python’s klvdata package or custom C/C++ parsers) to map
the binary values to real-world coordinates and sensor headings.