pymisb 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. pymisb-1.0.0/LICENSE +26 -0
  2. pymisb-1.0.0/MANIFEST.in +18 -0
  3. pymisb-1.0.0/PKG-INFO +384 -0
  4. pymisb-1.0.0/README.md +333 -0
  5. pymisb-1.0.0/pymisb/__init__.py +13 -0
  6. pymisb-1.0.0/pymisb/common/__init__.py +15 -0
  7. pymisb-1.0.0/pymisb/common/dji.py +432 -0
  8. pymisb-1.0.0/pymisb/common/encoder.py +158 -0
  9. pymisb-1.0.0/pymisb/common/ts.py +39 -0
  10. pymisb-1.0.0/pymisb/constants.py +40 -0
  11. pymisb-1.0.0/pymisb/demux/__init__.py +7 -0
  12. pymisb-1.0.0/pymisb/demux/__main__.py +3 -0
  13. pymisb-1.0.0/pymisb/demux/engine.py +206 -0
  14. pymisb-1.0.0/pymisb/klvdata/__init__.py +13 -0
  15. pymisb-1.0.0/pymisb/klvdata/common.py +137 -0
  16. pymisb-1.0.0/pymisb/klvdata/element.py +53 -0
  17. pymisb-1.0.0/pymisb/klvdata/elementparser.py +146 -0
  18. pymisb-1.0.0/pymisb/klvdata/klvparser.py +64 -0
  19. pymisb-1.0.0/pymisb/klvdata/misb0102.py +36 -0
  20. pymisb-1.0.0/pymisb/klvdata/misb0601.py +674 -0
  21. pymisb-1.0.0/pymisb/klvdata/misb0903.py +182 -0
  22. pymisb-1.0.0/pymisb/klvdata/misbEG0104.py +23 -0
  23. pymisb-1.0.0/pymisb/klvdata/setparser.py +128 -0
  24. pymisb-1.0.0/pymisb/klvdata/streamparser.py +53 -0
  25. pymisb-1.0.0/pymisb/mux/__init__.py +7 -0
  26. pymisb-1.0.0/pymisb/mux/__main__.py +3 -0
  27. pymisb-1.0.0/pymisb/mux/engine.py +425 -0
  28. pymisb-1.0.0/pymisb/stream/__init__.py +7 -0
  29. pymisb-1.0.0/pymisb/stream/__main__.py +3 -0
  30. pymisb-1.0.0/pymisb/stream/engine.py +264 -0
  31. pymisb-1.0.0/pymisb/vmti/__init__.py +7 -0
  32. pymisb-1.0.0/pymisb/vmti/__main__.py +3 -0
  33. pymisb-1.0.0/pymisb/vmti/engine.py +173 -0
  34. pymisb-1.0.0/pymisb.egg-info/SOURCES.txt +33 -0
  35. pymisb-1.0.0/pyproject.toml +45 -0
  36. pymisb-1.0.0/setup.cfg +4 -0
pymisb-1.0.0/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ License Agreement (pymisb)
2
+ ================================
3
+
4
+ Copyright (c) 2026 Fran Raga. All rights reserved.
5
+
6
+ This software is free and may be used, copied, modified, and distributed
7
+ for any purpose, commercial or non-commercial, without restriction,
8
+ provided that the following conditions are met:
9
+
10
+ 1. ATTRIBUTION: Any project, product, publication, or derivative work that
11
+ uses this software (in whole or in part) must include a clear credit to
12
+ the original author:
13
+
14
+ Fran Raga - pymisb
15
+ https://github.com/All4Gis/pymisb
16
+
17
+ This credit must appear in the source code, documentation, README,
18
+ About page, or any other reasonable location visible to end users.
19
+
20
+ 2. NO WARRANTY: This software is provided "as is", without warranty of any
21
+ kind, express or implied, including but not limited to the warranties of
22
+ merchantability, fitness for a particular purpose, and noninfringement.
23
+ In no event shall the author be liable for any claim, damages, or other
24
+ liability arising from the use of this software.
25
+
26
+ By using this software you agree to these terms.
@@ -0,0 +1,18 @@
1
+ include LICENSE
2
+ include README.md
3
+
4
+ recursive-include pymisb *.py
5
+
6
+ prune tests
7
+ prune pymisb.egg-info
8
+ prune dist
9
+ prune build
10
+ prune output
11
+ prune sample
12
+ prune assets
13
+
14
+ global-exclude __pycache__
15
+ global-exclude *.pyc
16
+ global-exclude .DS_Store
17
+ global-exclude setup.cfg
18
+ global-exclude *.egg-info
pymisb-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,384 @@
1
+ Metadata-Version: 2.4
2
+ Name: pymisb
3
+ Version: 1.0.0
4
+ Summary: MISB ST0601 / STANAG 4609 mux, demux & live streaming library for Python
5
+ Author-email: Fran Raga <franka1986@gmail.com>
6
+ License: License Agreement (pymisb)
7
+ ================================
8
+
9
+ Copyright (c) 2026 Fran Raga. All rights reserved.
10
+
11
+ This software is free and may be used, copied, modified, and distributed
12
+ for any purpose, commercial or non-commercial, without restriction,
13
+ provided that the following conditions are met:
14
+
15
+ 1. ATTRIBUTION: Any project, product, publication, or derivative work that
16
+ uses this software (in whole or in part) must include a clear credit to
17
+ the original author:
18
+
19
+ Fran Raga - pymisb
20
+ https://github.com/All4Gis/pymisb
21
+
22
+ This credit must appear in the source code, documentation, README,
23
+ About page, or any other reasonable location visible to end users.
24
+
25
+ 2. NO WARRANTY: This software is provided "as is", without warranty of any
26
+ kind, express or implied, including but not limited to the warranties of
27
+ merchantability, fitness for a particular purpose, and noninfringement.
28
+ In no event shall the author be liable for any claim, damages, or other
29
+ liability arising from the use of this software.
30
+
31
+ By using this software you agree to these terms.
32
+
33
+ Project-URL: Homepage, https://github.com/All4Gis/pymisb
34
+ Project-URL: Repository, https://github.com/All4Gis/pymisb
35
+ Project-URL: Issues, https://github.com/All4Gis/pymisb/issues
36
+ Keywords: dji,misb,stanag,klv,st0601,st0903,vmti,drone,telemetry,gis,streaming
37
+ Classifier: Development Status :: 4 - Beta
38
+ Classifier: Intended Audience :: Developers
39
+ Classifier: Intended Audience :: Science/Research
40
+ Classifier: Topic :: Multimedia :: Video
41
+ Classifier: Topic :: Scientific/Engineering :: GIS
42
+ Classifier: Programming Language :: Python :: 3
43
+ Classifier: Programming Language :: Python :: 3.12
44
+ Classifier: Programming Language :: Python :: 3.13
45
+ Requires-Python: >=3.12
46
+ Description-Content-Type: text/markdown
47
+ License-File: LICENSE
48
+ Provides-Extra: test
49
+ Requires-Dist: pytest>=7.0; extra == "test"
50
+ Dynamic: license-file
51
+
52
+ <p align="center">
53
+ <img src="assets/banner.png" alt="pymisb — MISB ST0601 / STANAG 4609 mux, demux &amp; streaming" style="width: 100%; height: auto; max-height: 300px; object-fit: contain;">
54
+ </p>
55
+
56
+ # pymisb
57
+
58
+ [![CI](https://github.com/All4Gis/pymisb/actions/workflows/ci.yml/badge.svg)](https://github.com/All4Gis/pymisb/actions/workflows/ci.yml)
59
+ [![PyPI version](https://badge.fury.io/py/pymisb.svg)](https://pypi.org/project/pymisb/)
60
+
61
+ **MISB ST0601 / STANAG 4609** mux, demux & live streaming library for Python.
62
+
63
+ | Module | What it does |
64
+ |--------|-------------|
65
+ | **mux** | Turn DJI drone footage + telemetry into STANAG 4609 videos with embedded KLV |
66
+ | **demux** | Extract and decode KLV telemetry from any STANAG-compliant video file |
67
+ | **stream** | Read KLV in real-time from live UDP/RTP/RTSP streams |
68
+ | **vmti** | Parse MISB ST 0903 VMTI target tracking metadata |
69
+
70
+ ```bash
71
+ pip install pymisb
72
+ ```
73
+
74
+ > **Donations** — If this project is useful for you, consider buying me a beer! [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate/?hosted_button_id=YMHU4Z52S2G8N)
75
+
76
+ ## Quick start
77
+
78
+ ### Mux — create a MISB video
79
+
80
+ ```python
81
+ from pymisb.common import build_klv_packets
82
+ from pymisb.mux import mux_with_ffmpeg
83
+
84
+ packets = build_klv_packets("telemetry.csv")
85
+ mux_with_ffmpeg("drone.mp4", packets, "output.ts")
86
+ ```
87
+
88
+ ### Demux — read KLV from a video
89
+
90
+ ```python
91
+ from pymisb.demux import extract_klv, decode_packets
92
+
93
+ klv_data = extract_klv("output.ts")
94
+ packets = decode_packets(klv_data)
95
+ for pkt in packets:
96
+ meta = pkt.MetadataList()
97
+ print(meta[13]) # Sensor Latitude
98
+ ```
99
+
100
+ ### Stream — real-time KLV from live feeds
101
+
102
+ ```python
103
+ from pymisb.stream import open_stream
104
+
105
+ with open_stream("udp://@:5000") as reader:
106
+ for pkt in reader:
107
+ meta = pkt.MetadataList()
108
+ print(meta[13]) # Sensor Latitude in real-time
109
+ ```
110
+
111
+ ### VMTI — target tracking metadata
112
+
113
+ ```python
114
+ from pymisb.vmti import parse_vmti, extract_vmti
115
+
116
+ targets = parse_vmti(extract_vmti("video.ts"))
117
+ for t in targets:
118
+ print(t["target_centroid_lat"], t["target_classification"])
119
+ ```
120
+
121
+ ## Package structure
122
+
123
+ ```
124
+ pymisb/
125
+ ├── constants.py Shared constants (keys, versions, FOV, etc.)
126
+ ├── common/
127
+ │ ├── encoder.py MISB ST0601 KLV packet builder
128
+ │ ├── dji.py DJI CSV + binary .txt flight record parsers
129
+ │ └── ts.py Path defaults and KLV stream writer
130
+ ├── mux/
131
+ │ └── engine.py MPEG-TS muxing (PES/PCR/KLV injection + FFmpeg)
132
+ ├── demux/
133
+ │ └── engine.py KLV extraction and decoding from files
134
+ ├── stream/
135
+ │ └── engine.py Real-time KLV from UDP/RTP/RTSP streams
136
+ ├── vmti/
137
+ │ └── engine.py MISB ST 0903 VMTI target metadata
138
+ └── klvdata/ Vendored MISB ST0601/0903 KLV decoder
139
+ ```
140
+
141
+ ## Requirements
142
+
143
+ - **Python 3.12+** (3.12, 3.13)
144
+ - **FFmpeg** on the PATH (for muxing, demuxing, and streaming)
145
+
146
+ ## Installation
147
+
148
+ ### From PyPI
149
+
150
+ ```bash
151
+ pip install pymisb
152
+ ```
153
+
154
+ ### From source
155
+
156
+ ```bash
157
+ git clone https://github.com/All4Gis/pymisb.git
158
+ cd pymisb
159
+ pip install .
160
+ ```
161
+
162
+ ### Development (editable)
163
+
164
+ ```bash
165
+ git clone https://github.com/All4Gis/pymisb.git
166
+ cd pymisb
167
+ pip install -e ".[test]"
168
+ ```
169
+
170
+ ### Verify
171
+
172
+ ```bash
173
+ python -c "from pymisb.constants import UAS_LS_KEY; print('OK')"
174
+ pymisb-mux --help
175
+ pymisb-demux --help
176
+ ```
177
+
178
+ ## CLI usage
179
+
180
+ ### Muxing
181
+
182
+ ```bash
183
+ # From DJI CSV telemetry
184
+ pymisb-mux --video drone.mp4 --csv telemetry.csv
185
+ pymisb-mux --video drone.mp4 --csv telemetry.csv --out output.ts
186
+
187
+ # From DJI binary .txt flight record
188
+ pymisb-mux --video drone.mp4 --dji-txt DJIFlightRecord.txt
189
+
190
+ # KLV only (no video muxing)
191
+ pymisb-mux --csv telemetry.csv --out output.ts --klv-only
192
+
193
+ # Or via module
194
+ python -m pymisb.mux --video drone.mp4 --csv telemetry.csv
195
+ ```
196
+
197
+ ### Demuxing
198
+
199
+ ```bash
200
+ # Dump all KLV packets
201
+ pymisb-demux output.ts
202
+
203
+ # Playback at the video's real rate
204
+ pymisb-demux output.ts --play
205
+
206
+ # Accelerated playback x4
207
+ pymisb-demux output.ts --play --speed 4
208
+
209
+ # Show every ST0601 tag
210
+ pymisb-demux output.ts --all
211
+
212
+ # Tag tree of the first packet
213
+ pymisb-demux output.ts --structure
214
+ ```
215
+
216
+ ### Streaming (live)
217
+
218
+ ```bash
219
+ # Read KLV from a live UDP stream
220
+ pymisb-stream udp://@:5000
221
+
222
+ # RTSP camera
223
+ pymisb-stream rtsp://camera.local/stream --all
224
+
225
+ # Or via module
226
+ python -m pymisb.stream udp://@:5000
227
+ ```
228
+
229
+ ### VMTI (target tracking)
230
+
231
+ ```bash
232
+ # Decode VMTI targets from a video
233
+ pymisb-vmti video.ts
234
+
235
+ # Show all target fields
236
+ pymisb-vmti video.ts --all
237
+ ```
238
+
239
+ ## Library API
240
+
241
+ ### `pymisb.common` — encoder and parsers
242
+
243
+ ```python
244
+ from pymisb.common import (
245
+ build_st0601_packet, # Build a single ST0601 KLV packet
246
+ build_klv_packets, # Parse DJI CSV -> list of KLV packets
247
+ build_klv_packets_from_txt, # Parse DJI .txt -> list of KLV packets
248
+ default_output, # Generate default output path
249
+ write_klv_stream, # Write packets as raw KLV file
250
+ )
251
+ ```
252
+
253
+ ### `pymisb.mux` — MPEG-TS muxing
254
+
255
+ ```python
256
+ from pymisb.mux import (
257
+ mux_with_ffmpeg, # Full mux pipeline (FFmpeg + KLV injection)
258
+ inject_klv_into_ts, # Low-level: inject KLV into existing TS
259
+ )
260
+ ```
261
+
262
+ ### `pymisb.demux` — KLV extraction and decoding from files
263
+
264
+ ```python
265
+ from pymisb.demux import (
266
+ extract_klv, # Extract raw KLV bytes from TS via FFmpeg
267
+ decode_packets, # Decode raw KLV into parsed ST0601 packets
268
+ )
269
+ ```
270
+
271
+ ### `pymisb.stream` — real-time KLV from live streams
272
+
273
+ ```python
274
+ from pymisb.stream import open_stream
275
+
276
+ # Iterator mode — yields packets as they arrive
277
+ with open_stream("udp://@:5000") as reader:
278
+ for pkt in reader:
279
+ meta = pkt.MetadataList()
280
+ print(meta[13])
281
+
282
+ # Callback mode
283
+ def on_packet(pkt):
284
+ print(pkt.MetadataList()[13])
285
+
286
+ reader = open_stream("rtsp://camera.local/stream")
287
+ reader.start(callback=on_packet)
288
+ reader.stop()
289
+ ```
290
+
291
+ ### `pymisb.vmti` — MISB ST 0903 VMTI target tracking
292
+
293
+ ```python
294
+ from pymisb.vmti import parse_vmti, extract_vmti, decode_vmti_stream
295
+
296
+ # From a TS file
297
+ targets = parse_vmti(extract_vmti("video.ts"))
298
+ for t in targets:
299
+ print(t["target_centroid_lat"], t["target_classification"])
300
+
301
+ # From raw bytes
302
+ targets = decode_vmti_stream(vmti_bytes)
303
+ ```
304
+
305
+ ### `pymisb.constants` — shared configuration
306
+
307
+ ```python
308
+ from pymisb.constants import (
309
+ UAS_LS_KEY, # 16-byte UAS Datalink Local Set universal key
310
+ KLV_HEADER_KEY, # Shifted key for DJI non-standard headers
311
+ ST0601_VERSION, # MISB ST0601 version (Tag 65)
312
+ HFOV_DEG, VFOV_DEG, # Camera field of view (degrees)
313
+ EARTH_MEAN_RADIUS, # WGS-84 radius in meters
314
+ )
315
+ ```
316
+
317
+ ## Configuration
318
+
319
+ Edit `pymisb/constants.py` to adjust:
320
+
321
+ - `HFOV_DEG` / `VFOV_DEG` — camera field of view (affects sensor footprint)
322
+ - `ST0601_VERSION` — advertised Local Set version (Tag 65)
323
+
324
+ ## Supported standards
325
+
326
+ | Standard | Name | Status |
327
+ |----------|------|--------|
328
+ | MISB ST 0601 | UAS Datalink Local Set | Full (encode + decode) |
329
+ | MISB ST 0903 | VMTI (Video Moving Target Indicator) | Decode |
330
+ | MISB ST 0102 | Security Metadata | Decode (via klvdata) |
331
+ | MISB EG 0104 | UAV Basic Universal Metadata | Decode (via klvdata) |
332
+ | STANAG 4609 | NATO video standard | Full (mux + demux) |
333
+
334
+ ## Testing
335
+
336
+ ```bash
337
+ # Install with test dependencies
338
+ pip install -e ".[test]"
339
+
340
+ # Run all tests
341
+ pytest tests/ -v
342
+
343
+ # Run specific test file
344
+ pytest tests/test_misb_common.py -v
345
+
346
+ # Run specific test
347
+ pytest tests/test_misb_common.py::TestBuildSt0601Packet -v
348
+
349
+ # With coverage
350
+ pip install pytest-cov
351
+ pytest tests/ --cov=pymisb --cov-report=term-missing
352
+ ```
353
+
354
+ | Test file | Coverage |
355
+ |-----------|----------|
356
+ | `tests/test_misb_common.py` | ST0601 encoder, DJI parsers, BER/BCC, geometry |
357
+ | `tests/test_misb_mux.py` | MPEG-TS primitives (PES, PTS, PCR, packetization) |
358
+ | `tests/test_klvdata.py` | Vendored klvdata decoder (ST0601 tags, BER-TLV, integration) |
359
+
360
+ CI runs on every push across Python 3.12-3.13 on Linux, macOS, and Windows.
361
+
362
+ ## Publishing
363
+
364
+ ```bash
365
+ # Build
366
+ pip install build
367
+ python -m build
368
+
369
+ # Publish to PyPI
370
+ pip install twine
371
+ twine upload dist/*
372
+
373
+ # Or TestPyPI first
374
+ twine upload --repository testpypi dist/*
375
+ pip install --index-url https://test.pypi.org/simple/ pymisb
376
+ ```
377
+
378
+ ---
379
+
380
+ > _"From raw drone footage to geospatial intelligence — one KLV packet at a time."_
381
+
382
+ Made with passion by **Fran Raga** <franka1986@gmail.com> - June 2026.
383
+
384
+ If this saved you a few hours, give the repo a star and fly safe. Happy coding!