MISB ST0601 / STANAG 4609 mux, demux & live streaming library for Python
Project description
pymisb
MISB ST0601 / STANAG 4609 mux, demux & live streaming library for Python.
| Module | What it does |
|---|---|
| mux | Turn DJI drone footage + telemetry into STANAG 4609 videos with embedded KLV |
| demux | Extract and decode KLV telemetry from any STANAG-compliant video file |
| stream | Read KLV in real-time from live UDP/RTP/RTSP streams |
| vmti | Parse MISB ST 0903 VMTI target tracking metadata |
pip install pymisb
Donations — If this project is useful for you, consider buying me a beer!
Quick start
Mux — create a MISB video
from pymisb.common import build_klv_packets
from pymisb.mux import mux_with_ffmpeg
packets = build_klv_packets("telemetry.csv")
mux_with_ffmpeg("drone.mp4", packets, "output.ts")
Demux — read KLV from a video
from pymisb.demux import extract_klv, decode_packets
klv_data = extract_klv("output.ts")
packets = decode_packets(klv_data)
for pkt in packets:
meta = pkt.MetadataList()
print(meta[13]) # Sensor Latitude
Stream — real-time KLV from live feeds
from pymisb.stream import open_stream
with open_stream("udp://@:5000") as reader:
for pkt in reader:
meta = pkt.MetadataList()
print(meta[13]) # Sensor Latitude in real-time
VMTI — target tracking metadata
from pymisb.vmti import parse_vmti, extract_vmti
targets = parse_vmti(extract_vmti("video.ts"))
for t in targets:
print(t["target_centroid_lat"], t["target_classification"])
Package structure
pymisb/
├── constants.py Shared constants (keys, versions, FOV, etc.)
├── common/
│ ├── encoder.py MISB ST0601 KLV packet builder
│ ├── dji.py DJI CSV + binary .txt flight record parsers
│ └── ts.py Path defaults and KLV stream writer
├── mux/
│ └── engine.py MPEG-TS muxing (PES/PCR/KLV injection + FFmpeg)
├── demux/
│ └── engine.py KLV extraction and decoding from files
├── stream/
│ └── engine.py Real-time KLV from UDP/RTP/RTSP streams
├── vmti/
│ └── engine.py MISB ST 0903 VMTI target metadata
└── klvdata/ Vendored MISB ST0601/0903 KLV decoder
Requirements
- Python 3.12+ (3.12, 3.13)
- FFmpeg on the PATH (for muxing, demuxing, and streaming)
Installation
From PyPI
pip install pymisb
From source
git clone https://github.com/All4Gis/pymisb.git
cd pymisb
pip install .
Development (editable)
git clone https://github.com/All4Gis/pymisb.git
cd pymisb
pip install -e ".[test]"
Verify
python -c "from pymisb.constants import UAS_LS_KEY; print('OK')"
pymisb-mux --help
pymisb-demux --help
CLI usage
Muxing
# From DJI CSV telemetry
pymisb-mux --video drone.mp4 --csv telemetry.csv
pymisb-mux --video drone.mp4 --csv telemetry.csv --out output.ts
# From DJI binary .txt flight record
pymisb-mux --video drone.mp4 --dji-txt DJIFlightRecord.txt
# KLV only (no video muxing)
pymisb-mux --csv telemetry.csv --out output.ts --klv-only
# Or via module
python -m pymisb.mux --video drone.mp4 --csv telemetry.csv
Demuxing
# Dump all KLV packets
pymisb-demux output.ts
# Playback at the video's real rate
pymisb-demux output.ts --play
# Accelerated playback x4
pymisb-demux output.ts --play --speed 4
# Show every ST0601 tag
pymisb-demux output.ts --all
# Tag tree of the first packet
pymisb-demux output.ts --structure
Streaming (live)
# Read KLV from a live UDP stream
pymisb-stream udp://@:5000
# RTSP camera
pymisb-stream rtsp://camera.local/stream --all
# Or via module
python -m pymisb.stream udp://@:5000
VMTI (target tracking)
# Decode VMTI targets from a video
pymisb-vmti video.ts
# Show all target fields
pymisb-vmti video.ts --all
Library API
pymisb.common — encoder and parsers
from pymisb.common import (
build_st0601_packet, # Build a single ST0601 KLV packet
build_klv_packets, # Parse DJI CSV -> list of KLV packets
build_klv_packets_from_txt, # Parse DJI .txt -> list of KLV packets
default_output, # Generate default output path
write_klv_stream, # Write packets as raw KLV file
)
pymisb.mux — MPEG-TS muxing
from pymisb.mux import (
mux_with_ffmpeg, # Full mux pipeline (FFmpeg + KLV injection)
inject_klv_into_ts, # Low-level: inject KLV into existing TS
)
pymisb.demux — KLV extraction and decoding from files
from pymisb.demux import (
extract_klv, # Extract raw KLV bytes from TS via FFmpeg
decode_packets, # Decode raw KLV into parsed ST0601 packets
)
pymisb.stream — real-time KLV from live streams
from pymisb.stream import open_stream
# Iterator mode — yields packets as they arrive
with open_stream("udp://@:5000") as reader:
for pkt in reader:
meta = pkt.MetadataList()
print(meta[13])
# Callback mode
def on_packet(pkt):
print(pkt.MetadataList()[13])
reader = open_stream("rtsp://camera.local/stream")
reader.start(callback=on_packet)
reader.stop()
pymisb.vmti — MISB ST 0903 VMTI target tracking
from pymisb.vmti import parse_vmti, extract_vmti, decode_vmti_stream
# From a TS file
targets = parse_vmti(extract_vmti("video.ts"))
for t in targets:
print(t["target_centroid_lat"], t["target_classification"])
# From raw bytes
targets = decode_vmti_stream(vmti_bytes)
pymisb.constants — shared configuration
from pymisb.constants import (
UAS_LS_KEY, # 16-byte UAS Datalink Local Set universal key
KLV_HEADER_KEY, # Shifted key for DJI non-standard headers
ST0601_VERSION, # MISB ST0601 version (Tag 65)
HFOV_DEG, VFOV_DEG, # Camera field of view (degrees)
EARTH_MEAN_RADIUS, # WGS-84 radius in meters
)
Configuration
Edit pymisb/constants.py to adjust:
HFOV_DEG/VFOV_DEG— camera field of view (affects sensor footprint)ST0601_VERSION— advertised Local Set version (Tag 65)
Supported standards
| Standard | Name | Status |
|---|---|---|
| MISB ST 0601 | UAS Datalink Local Set | Full (encode + decode) |
| MISB ST 0903 | VMTI (Video Moving Target Indicator) | Decode |
| MISB ST 0102 | Security Metadata | Decode (via klvdata) |
| MISB EG 0104 | UAV Basic Universal Metadata | Decode (via klvdata) |
| STANAG 4609 | NATO video standard | Full (mux + demux) |
Testing
# Install with test dependencies
pip install -e ".[test]"
# Run all tests
pytest tests/ -v
# Run specific test file
pytest tests/test_misb_common.py -v
# Run specific test
pytest tests/test_misb_common.py::TestBuildSt0601Packet -v
# With coverage
pip install pytest-cov
pytest tests/ --cov=pymisb --cov-report=term-missing
| Test file | Coverage |
|---|---|
tests/test_misb_common.py |
ST0601 encoder, DJI parsers, BER/BCC, geometry |
tests/test_misb_mux.py |
MPEG-TS primitives (PES, PTS, PCR, packetization) |
tests/test_klvdata.py |
Vendored klvdata decoder (ST0601 tags, BER-TLV, integration) |
CI runs on every push across Python 3.12-3.13 on Linux, macOS, and Windows.
Publishing
# Build
pip install build
python -m build
# Publish to PyPI
pip install twine
twine upload dist/*
# Or TestPyPI first
twine upload --repository testpypi dist/*
pip install --index-url https://test.pypi.org/simple/ pymisb
License
This project is licensed under the MIT License.
The vendored klvdata decoder in pymisb/klvdata/ is derived from
paretech/klvdata (MIT). See
THIRD_PARTY_LICENSES.md for full attribution.
"From raw drone footage to geospatial intelligence — one KLV packet at a time."
Made with passion by Fran Raga franka1986@gmail.com - June 2026.
If this saved you a few hours, give the repo a star and fly safe. Happy coding!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pymisb-2.0.1.tar.gz.
File metadata
- Download URL: pymisb-2.0.1.tar.gz
- Upload date:
- Size: 37.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d828f4401bc4c88906aba663f42e353ee1304cb24376271b657f87f0ef62707f
|
|
| MD5 |
a8c28a123810ea3392b3037586687b24
|
|
| BLAKE2b-256 |
52512f48ac9be818c4b6aef94a3eb89c9ec42964ff6d5825d7f8a6c1d353ed76
|
File details
Details for the file pymisb-2.0.1-py3-none-any.whl.
File metadata
- Download URL: pymisb-2.0.1-py3-none-any.whl
- Upload date:
- Size: 46.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afb2893020108d2962b7811fc57a9055e66233fde5302bd18a863d8a68d1eedf
|
|
| MD5 |
e51e46fabb872decce7faa2b3c595bc2
|
|
| BLAKE2b-256 |
aca53b4bd69446a011c5e1c25baeec15db445125daec63dae72b58bc7d6488ed
|