dji-telemetry 1.0.0__tar.gz → 1.0.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dji-telemetry
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Parse DJI drone SRT telemetry files and overlay flight data onto video footage
5
5
  Author: jetervaz
6
6
  License: MIT
@@ -22,7 +22,7 @@ Export telemetry data:
22
22
  export(telemetry, 'telemetry.gpx')
23
23
  """
24
24
 
25
- __version__ = '1.0.0'
25
+ __version__ = '1.0.1'
26
26
 
27
27
  # Core parser
28
28
  from .parser import (
@@ -0,0 +1,329 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ DJI Telemetry Overlay - Command Line Interface
4
+ """
5
+
6
+ import argparse
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from dji_telemetry import (
11
+ __version__,
12
+ parse_srt,
13
+ export,
14
+ process_video,
15
+ generate_overlay_video,
16
+ generate_overlay_frames,
17
+ add_audio,
18
+ get_video_info,
19
+ OverlayConfig,
20
+ )
21
+
22
+
23
+ def progress_bar(current: int, total: int, width: int = 50):
24
+ """Display a progress bar."""
25
+ percent = current / total
26
+ filled = int(width * percent)
27
+ bar = '=' * filled + '-' * (width - filled)
28
+ sys.stdout.write(f'\r[{bar}] {percent*100:.1f}% ({current}/{total})')
29
+ sys.stdout.flush()
30
+ if current == total:
31
+ print()
32
+
33
+
34
+ def cmd_overlay(args):
35
+ """Process video with telemetry overlay."""
36
+ video_path = Path(args.video)
37
+ srt_path = Path(args.srt) if args.srt else video_path.with_suffix('.SRT')
38
+
39
+ if not video_path.exists():
40
+ print(f"Error: Video file not found: {video_path}")
41
+ return 1
42
+
43
+ if not srt_path.exists():
44
+ print(f"Error: SRT file not found: {srt_path}")
45
+ return 1
46
+
47
+ output_path = Path(args.output) if args.output else video_path.with_name(
48
+ video_path.stem + '_telemetry.mp4'
49
+ )
50
+
51
+ print(f"Parsing telemetry: {srt_path}")
52
+ telemetry = parse_srt(srt_path)
53
+ print(f" Loaded {len(telemetry.frames)} frames")
54
+ print(f" Duration: {telemetry.duration_seconds:.1f}s")
55
+ print(f" Max altitude: {telemetry.max_altitude:.1f}m")
56
+ print(f" Max speed: {telemetry.max_speed * 3.6:.1f} km/h")
57
+
58
+ # Build overlay config
59
+ config = OverlayConfig(
60
+ show_altitude=not args.no_altitude,
61
+ show_speed=not args.no_speed,
62
+ show_vertical_speed=not args.no_vspeed,
63
+ show_coordinates=not args.no_coords,
64
+ show_camera_settings=not args.no_camera,
65
+ show_timestamp=not args.no_timestamp,
66
+ show_speed_gauge=not args.no_gauge,
67
+ gauge_max_speed_kmh=args.gauge_max,
68
+ )
69
+
70
+ print(f"\nProcessing video: {video_path}")
71
+ temp_output = output_path.with_name(output_path.stem + '_temp.mp4')
72
+
73
+ process_video(
74
+ video_path, telemetry, temp_output, config,
75
+ progress_callback=progress_bar if not args.quiet else None
76
+ )
77
+
78
+ # Add audio if requested
79
+ if args.audio:
80
+ print(f"Adding audio from: {video_path}")
81
+ add_audio(temp_output, video_path, output_path)
82
+ temp_output.unlink()
83
+ else:
84
+ temp_output.rename(output_path)
85
+
86
+ print(f"\nOutput saved to: {output_path}")
87
+ return 0
88
+
89
+
90
+ def cmd_overlay_only(args):
91
+ """Generate transparent overlay video."""
92
+ srt_path = Path(args.srt)
93
+
94
+ if not srt_path.exists():
95
+ print(f"Error: SRT file not found: {srt_path}")
96
+ return 1
97
+
98
+ output_path = Path(args.output) if args.output else srt_path.with_name(
99
+ srt_path.stem + '_overlay.mp4'
100
+ )
101
+
102
+ print(f"Parsing telemetry: {srt_path}")
103
+ telemetry = parse_srt(srt_path)
104
+ print(f" Loaded {len(telemetry.frames)} frames")
105
+
106
+ config = OverlayConfig(
107
+ show_altitude=not args.no_altitude,
108
+ show_speed=not args.no_speed,
109
+ show_vertical_speed=not args.no_vspeed,
110
+ show_coordinates=not args.no_coords,
111
+ show_camera_settings=not args.no_camera,
112
+ show_timestamp=not args.no_timestamp,
113
+ show_speed_gauge=not args.no_gauge,
114
+ gauge_max_speed_kmh=args.gauge_max,
115
+ )
116
+
117
+ print(f"\nGenerating overlay video: {args.width}x{args.height} @ {args.fps}fps")
118
+ generate_overlay_video(
119
+ telemetry, output_path,
120
+ width=args.width, height=args.height, fps=args.fps,
121
+ config=config,
122
+ progress_callback=progress_bar if not args.quiet else None
123
+ )
124
+
125
+ print(f"\nOutput saved to: {output_path}")
126
+ return 0
127
+
128
+
129
+ def cmd_frames(args):
130
+ """Generate transparent overlay frames."""
131
+ srt_path = Path(args.srt)
132
+
133
+ if not srt_path.exists():
134
+ print(f"Error: SRT file not found: {srt_path}")
135
+ return 1
136
+
137
+ output_dir = Path(args.output) if args.output else srt_path.with_name(
138
+ srt_path.stem + '_frames'
139
+ )
140
+
141
+ print(f"Parsing telemetry: {srt_path}")
142
+ telemetry = parse_srt(srt_path)
143
+ print(f" Loaded {len(telemetry.frames)} frames")
144
+
145
+ config = OverlayConfig(
146
+ show_altitude=not args.no_altitude,
147
+ show_speed=not args.no_speed,
148
+ show_vertical_speed=not args.no_vspeed,
149
+ show_coordinates=not args.no_coords,
150
+ show_camera_settings=not args.no_camera,
151
+ show_timestamp=not args.no_timestamp,
152
+ show_speed_gauge=not args.no_gauge,
153
+ )
154
+
155
+ print(f"\nGenerating frames: {args.width}x{args.height} @ {args.fps}fps")
156
+ generate_overlay_frames(
157
+ telemetry, output_dir,
158
+ width=args.width, height=args.height, fps=args.fps,
159
+ config=config, format=args.format,
160
+ progress_callback=progress_bar if not args.quiet else None
161
+ )
162
+
163
+ print(f"\nFrames saved to: {output_dir}")
164
+ return 0
165
+
166
+
167
+ def cmd_export(args):
168
+ """Export telemetry data to CSV, JSON, or GPX."""
169
+ srt_path = Path(args.srt)
170
+
171
+ if not srt_path.exists():
172
+ print(f"Error: SRT file not found: {srt_path}")
173
+ return 1
174
+
175
+ output_path = Path(args.output)
176
+
177
+ print(f"Parsing telemetry: {srt_path}")
178
+ telemetry = parse_srt(srt_path)
179
+ print(f" Loaded {len(telemetry.frames)} frames")
180
+ print(f" Duration: {telemetry.duration_seconds:.1f}s")
181
+ print(f" Distance: {telemetry.total_distance:.1f}m")
182
+
183
+ print(f"\nExporting to: {output_path}")
184
+ export(telemetry, output_path, format=args.format)
185
+
186
+ print("Done!")
187
+ return 0
188
+
189
+
190
+ def cmd_info(args):
191
+ """Show information about video and SRT files."""
192
+ path = Path(args.path)
193
+
194
+ if not path.exists():
195
+ print(f"Error: File not found: {path}")
196
+ return 1
197
+
198
+ if path.suffix.upper() == '.SRT':
199
+ print(f"SRT File: {path}")
200
+ print("-" * 50)
201
+ telemetry = parse_srt(path)
202
+ print(f"Frames: {len(telemetry.frames)}")
203
+ print(f"Duration: {telemetry.duration_seconds:.1f}s")
204
+ print(f"Distance: {telemetry.total_distance:.1f}m")
205
+ print(f"Max altitude: {telemetry.max_altitude:.1f}m")
206
+ print(f"Max speed: {telemetry.max_speed * 3.6:.1f} km/h")
207
+ print(f"Start coords: {telemetry.start_coordinates[0]:.6f}, {telemetry.start_coordinates[1]:.6f}")
208
+ print(f"End coords: {telemetry.end_coordinates[0]:.6f}, {telemetry.end_coordinates[1]:.6f}")
209
+
210
+ elif path.suffix.upper() in ['.MP4', '.MOV', '.AVI', '.MKV']:
211
+ print(f"Video File: {path}")
212
+ print("-" * 50)
213
+ info = get_video_info(path)
214
+ print(f"Resolution: {info['width']}x{info['height']}")
215
+ print(f"FPS: {info['fps']:.2f}")
216
+ print(f"Frames: {info['frame_count']}")
217
+ print(f"Duration: {info['duration_seconds']:.1f}s")
218
+
219
+ else:
220
+ print(f"Unknown file type: {path.suffix}")
221
+ return 1
222
+
223
+ return 0
224
+
225
+
226
+ def main():
227
+ parser = argparse.ArgumentParser(
228
+ description='DJI Telemetry Overlay - Overlay telemetry data on drone footage',
229
+ formatter_class=argparse.RawDescriptionHelpFormatter,
230
+ epilog='''
231
+ Examples:
232
+ # Process video with telemetry overlay (auto-detect SRT)
233
+ %(prog)s overlay video.MP4 --audio
234
+
235
+ # Generate transparent overlay video
236
+ %(prog)s overlay-only telemetry.SRT -o overlay.mp4 --width 3840 --height 2160
237
+
238
+ # Export telemetry to different formats
239
+ %(prog)s export telemetry.SRT -o data.csv
240
+ %(prog)s export telemetry.SRT -o data.json
241
+ %(prog)s export telemetry.SRT -o flight.gpx
242
+
243
+ # Show file information
244
+ %(prog)s info video.SRT
245
+ '''
246
+ )
247
+ parser.add_argument('--version', action='version', version=f'%(prog)s {__version__}')
248
+
249
+ subparsers = parser.add_subparsers(dest='command', help='Commands')
250
+
251
+ # === overlay command ===
252
+ p_overlay = subparsers.add_parser('overlay', help='Process video with telemetry overlay')
253
+ p_overlay.add_argument('video', help='Input video file (MP4)')
254
+ p_overlay.add_argument('--srt', '-s', help='SRT telemetry file (default: same name as video)')
255
+ p_overlay.add_argument('--output', '-o', help='Output video file')
256
+ p_overlay.add_argument('--audio', '-a', action='store_true', help='Copy audio from original video')
257
+ p_overlay.add_argument('--quiet', '-q', action='store_true', help='Suppress progress output')
258
+ # Overlay options
259
+ p_overlay.add_argument('--no-altitude', action='store_true', help='Hide altitude')
260
+ p_overlay.add_argument('--no-speed', action='store_true', help='Hide horizontal speed')
261
+ p_overlay.add_argument('--no-vspeed', action='store_true', help='Hide vertical speed')
262
+ p_overlay.add_argument('--no-coords', action='store_true', help='Hide GPS coordinates')
263
+ p_overlay.add_argument('--no-camera', action='store_true', help='Hide camera settings')
264
+ p_overlay.add_argument('--no-timestamp', action='store_true', help='Hide timestamp')
265
+ p_overlay.add_argument('--no-gauge', action='store_true', help='Hide speed gauge')
266
+ p_overlay.add_argument('--gauge-max', type=float, default=50.0, help='Speed gauge max (km/h, default: 50)')
267
+ p_overlay.set_defaults(func=cmd_overlay)
268
+
269
+ # === overlay-only command ===
270
+ p_overlay_only = subparsers.add_parser('overlay-only', help='Generate transparent overlay video')
271
+ p_overlay_only.add_argument('srt', help='SRT telemetry file')
272
+ p_overlay_only.add_argument('--output', '-o', help='Output video file')
273
+ p_overlay_only.add_argument('--width', '-W', type=int, default=1920, help='Video width (default: 1920)')
274
+ p_overlay_only.add_argument('--height', '-H', type=int, default=1080, help='Video height (default: 1080)')
275
+ p_overlay_only.add_argument('--fps', type=float, default=30.0, help='Frames per second (default: 30)')
276
+ p_overlay_only.add_argument('--quiet', '-q', action='store_true', help='Suppress progress output')
277
+ # Overlay options
278
+ p_overlay_only.add_argument('--no-altitude', action='store_true', help='Hide altitude')
279
+ p_overlay_only.add_argument('--no-speed', action='store_true', help='Hide horizontal speed')
280
+ p_overlay_only.add_argument('--no-vspeed', action='store_true', help='Hide vertical speed')
281
+ p_overlay_only.add_argument('--no-coords', action='store_true', help='Hide GPS coordinates')
282
+ p_overlay_only.add_argument('--no-camera', action='store_true', help='Hide camera settings')
283
+ p_overlay_only.add_argument('--no-timestamp', action='store_true', help='Hide timestamp')
284
+ p_overlay_only.add_argument('--no-gauge', action='store_true', help='Hide speed gauge')
285
+ p_overlay_only.add_argument('--gauge-max', type=float, default=50.0, help='Speed gauge max (km/h)')
286
+ p_overlay_only.set_defaults(func=cmd_overlay_only)
287
+
288
+ # === frames command ===
289
+ p_frames = subparsers.add_parser('frames', help='Generate transparent overlay frames (PNG sequence)')
290
+ p_frames.add_argument('srt', help='SRT telemetry file')
291
+ p_frames.add_argument('--output', '-o', help='Output directory')
292
+ p_frames.add_argument('--width', '-W', type=int, default=1920, help='Frame width (default: 1920)')
293
+ p_frames.add_argument('--height', '-H', type=int, default=1080, help='Frame height (default: 1080)')
294
+ p_frames.add_argument('--fps', type=float, default=30.0, help='Frames per second (default: 30)')
295
+ p_frames.add_argument('--format', '-f', default='png', choices=['png', 'jpg'], help='Image format')
296
+ p_frames.add_argument('--quiet', '-q', action='store_true', help='Suppress progress output')
297
+ # Overlay options
298
+ p_frames.add_argument('--no-altitude', action='store_true', help='Hide altitude')
299
+ p_frames.add_argument('--no-speed', action='store_true', help='Hide horizontal speed')
300
+ p_frames.add_argument('--no-vspeed', action='store_true', help='Hide vertical speed')
301
+ p_frames.add_argument('--no-coords', action='store_true', help='Hide GPS coordinates')
302
+ p_frames.add_argument('--no-camera', action='store_true', help='Hide camera settings')
303
+ p_frames.add_argument('--no-timestamp', action='store_true', help='Hide timestamp')
304
+ p_frames.add_argument('--no-gauge', action='store_true', help='Hide speed gauge')
305
+ p_frames.set_defaults(func=cmd_frames)
306
+
307
+ # === export command ===
308
+ p_export = subparsers.add_parser('export', help='Export telemetry to CSV, JSON, or GPX')
309
+ p_export.add_argument('srt', help='SRT telemetry file')
310
+ p_export.add_argument('--output', '-o', required=True, help='Output file (extension determines format)')
311
+ p_export.add_argument('--format', '-f', choices=['csv', 'json', 'gpx'], help='Output format (auto-detected from extension)')
312
+ p_export.set_defaults(func=cmd_export)
313
+
314
+ # === info command ===
315
+ p_info = subparsers.add_parser('info', help='Show information about video or SRT file')
316
+ p_info.add_argument('path', help='Video or SRT file')
317
+ p_info.set_defaults(func=cmd_info)
318
+
319
+ args = parser.parse_args()
320
+
321
+ if not args.command:
322
+ parser.print_help()
323
+ return 1
324
+
325
+ return args.func(args)
326
+
327
+
328
+ if __name__ == '__main__':
329
+ sys.exit(main())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dji-telemetry
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Parse DJI drone SRT telemetry files and overlay flight data onto video footage
5
5
  Author: jetervaz
6
6
  License: MIT
@@ -2,6 +2,7 @@ LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
4
  dji_telemetry/__init__.py
5
+ dji_telemetry/cli.py
5
6
  dji_telemetry/exporter.py
6
7
  dji_telemetry/overlay.py
7
8
  dji_telemetry/parser.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dji-telemetry = dji_telemetry.cli:main
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dji-telemetry"
7
- version = "1.0.0"
7
+ version = "1.0.1"
8
8
  description = "Parse DJI drone SRT telemetry files and overlay flight data onto video footage"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -40,7 +40,7 @@ dev = [
40
40
  ]
41
41
 
42
42
  [project.scripts]
43
- dji-telemetry = "cli:main"
43
+ dji-telemetry = "dji_telemetry.cli:main"
44
44
 
45
45
  [project.urls]
46
46
  Homepage = "https://github.com/jetervaz/dji-telemetry"
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- dji-telemetry = cli:main
File without changes
File without changes
File without changes