typed-ffmpeg-compatible 3.5.1__py3-none-any.whl → 3.6__py3-none-any.whl

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 (71) hide show
  1. typed_ffmpeg/__init__.py +4 -1
  2. typed_ffmpeg/_version.py +2 -2
  3. typed_ffmpeg/base.py +4 -1
  4. typed_ffmpeg/codecs/__init__.py +2 -0
  5. typed_ffmpeg/codecs/decoders.py +1852 -1853
  6. typed_ffmpeg/codecs/encoders.py +2001 -1782
  7. typed_ffmpeg/codecs/schema.py +6 -12
  8. typed_ffmpeg/common/__init__.py +1 -0
  9. typed_ffmpeg/common/cache.py +9 -6
  10. typed_ffmpeg/common/schema.py +11 -0
  11. typed_ffmpeg/common/serialize.py +13 -7
  12. typed_ffmpeg/compile/__init__.py +1 -0
  13. typed_ffmpeg/compile/compile_cli.py +55 -8
  14. typed_ffmpeg/compile/compile_json.py +4 -0
  15. typed_ffmpeg/compile/compile_python.py +15 -0
  16. typed_ffmpeg/compile/context.py +15 -4
  17. typed_ffmpeg/compile/validate.py +9 -8
  18. typed_ffmpeg/dag/factory.py +2 -0
  19. typed_ffmpeg/dag/global_runnable/__init__.py +1 -0
  20. typed_ffmpeg/dag/global_runnable/global_args.py +2 -2
  21. typed_ffmpeg/dag/global_runnable/runnable.py +51 -11
  22. typed_ffmpeg/dag/io/__init__.py +1 -0
  23. typed_ffmpeg/dag/io/_input.py +20 -5
  24. typed_ffmpeg/dag/io/_output.py +24 -9
  25. typed_ffmpeg/dag/io/output_args.py +21 -7
  26. typed_ffmpeg/dag/nodes.py +20 -0
  27. typed_ffmpeg/dag/schema.py +19 -6
  28. typed_ffmpeg/dag/utils.py +2 -2
  29. typed_ffmpeg/exceptions.py +2 -1
  30. typed_ffmpeg/expressions.py +884 -0
  31. typed_ffmpeg/ffprobe/__init__.py +1 -0
  32. typed_ffmpeg/ffprobe/parse.py +7 -1
  33. typed_ffmpeg/ffprobe/probe.py +3 -1
  34. typed_ffmpeg/ffprobe/schema.py +83 -1
  35. typed_ffmpeg/ffprobe/xml2json.py +8 -2
  36. typed_ffmpeg/filters.py +540 -631
  37. typed_ffmpeg/formats/__init__.py +2 -0
  38. typed_ffmpeg/formats/demuxers.py +1869 -1921
  39. typed_ffmpeg/formats/muxers.py +1382 -1107
  40. typed_ffmpeg/formats/schema.py +6 -12
  41. typed_ffmpeg/info.py +8 -0
  42. typed_ffmpeg/options/__init__.py +15 -0
  43. typed_ffmpeg/options/codec.py +711 -0
  44. typed_ffmpeg/options/format.py +196 -0
  45. typed_ffmpeg/options/framesync.py +43 -0
  46. typed_ffmpeg/options/timeline.py +22 -0
  47. typed_ffmpeg/schema.py +15 -0
  48. typed_ffmpeg/sources.py +392 -381
  49. typed_ffmpeg/streams/__init__.py +2 -0
  50. typed_ffmpeg/streams/audio.py +1071 -882
  51. typed_ffmpeg/streams/av.py +9 -3
  52. typed_ffmpeg/streams/subtitle.py +3 -3
  53. typed_ffmpeg/streams/video.py +1873 -1725
  54. typed_ffmpeg/types.py +3 -2
  55. typed_ffmpeg/utils/__init__.py +1 -0
  56. typed_ffmpeg/utils/escaping.py +8 -4
  57. typed_ffmpeg/utils/frozendict.py +31 -1
  58. typed_ffmpeg/utils/lazy_eval/__init__.py +1 -0
  59. typed_ffmpeg/utils/lazy_eval/operator.py +75 -27
  60. typed_ffmpeg/utils/lazy_eval/schema.py +176 -4
  61. typed_ffmpeg/utils/run.py +2 -0
  62. typed_ffmpeg/utils/snapshot.py +3 -2
  63. typed_ffmpeg/utils/typing.py +2 -1
  64. typed_ffmpeg/utils/view.py +2 -1
  65. {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/METADATA +1 -1
  66. typed_ffmpeg_compatible-3.6.dist-info/RECORD +73 -0
  67. typed_ffmpeg_compatible-3.5.1.dist-info/RECORD +0 -67
  68. {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/WHEEL +0 -0
  69. {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/entry_points.txt +0 -0
  70. {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/licenses/LICENSE +0 -0
  71. {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1 @@
1
+ """FFprobe utilities for media file analysis."""
@@ -1,4 +1,6 @@
1
- #!/usr/bin/env python3
1
+ """FFprobe XML parsing utilities."""
2
+
3
+ # !/usr/bin/env python3
2
4
 
3
5
  import json
4
6
  import types
@@ -29,6 +31,7 @@ def _get_actual_type(type_hint: Any) -> type[Any]:
29
31
 
30
32
  Returns:
31
33
  The actual type
34
+
32
35
  """
33
36
  # If type_hint is a string, evaluate it in the schema's module context
34
37
  if isinstance(type_hint, str):
@@ -57,6 +60,7 @@ def is_dataclass_type(obj: type[Any]) -> TypeGuard[type[T]]:
57
60
 
58
61
  Returns:
59
62
  True if the object is a dataclass type, False otherwise
63
+
60
64
  """
61
65
  return is_dataclass(obj)
62
66
 
@@ -71,6 +75,7 @@ def _parse_obj_from_dict(data: Any, cls: type[T]) -> T | None:
71
75
 
72
76
  Returns:
73
77
  The parsed dataclass instance
78
+
74
79
  """
75
80
  if data is None:
76
81
  return None
@@ -125,6 +130,7 @@ def parse_ffprobe(xml_string: str) -> ffprobeType:
125
130
 
126
131
  Returns:
127
132
  The parsed ffprobeType instance
133
+
128
134
  """
129
135
  json_str = xml_string_to_json(xml_string)
130
136
  json_dict = json.loads(json_str)
@@ -79,6 +79,7 @@ def _probe(
79
79
  print(f"Duration: {float(info['format']['duration']):.2f} seconds")
80
80
  print(f"Streams: {len(info['streams'])}")
81
81
  ```
82
+
82
83
  """
83
84
  args = [
84
85
  cmd,
@@ -172,6 +173,7 @@ def probe(
172
173
  print(f"Duration: {float(info['format']['duration']):.2f} seconds")
173
174
  print(f"Streams: {len(info['streams'])}")
174
175
  ```
176
+
175
177
  """
176
178
  return json.loads(
177
179
  _probe(
@@ -250,8 +252,8 @@ def probe_obj(
250
252
  print(f"Duration: {float(info.format.duration):.2f} seconds")
251
253
  print(f"Streams: {len(info.streams)}")
252
254
  ```
253
- """
254
255
 
256
+ """
255
257
  xml = _probe(
256
258
  filename,
257
259
  show_program_version=show_program_version,
@@ -1,4 +1,6 @@
1
- #!/usr/bin/env python3
1
+ """FFprobe XML schema definitions."""
2
+
3
+ # !/usr/bin/env python3
2
4
 
3
5
  from dataclasses import dataclass
4
6
  from typing import Optional
@@ -6,6 +8,8 @@ from typing import Optional
6
8
 
7
9
  @dataclass(kw_only=True, frozen=True)
8
10
  class ffprobeType:
11
+ """Root type for FFprobe XML output."""
12
+
9
13
  program_version: Optional["programVersionType"] = None
10
14
  library_versions: Optional["libraryVersionsType"] = None
11
15
  pixel_formats: Optional["pixelFormatsType"] = None
@@ -21,17 +25,23 @@ class ffprobeType:
21
25
 
22
26
  @dataclass(kw_only=True, frozen=True)
23
27
  class packetsType:
28
+ """Container for packet information."""
29
+
24
30
  packet: tuple["packetType", ...] | None = None
25
31
 
26
32
 
27
33
  @dataclass(kw_only=True, frozen=True)
28
34
  class framesType:
35
+ """Container for frame information."""
36
+
29
37
  frame: tuple["frameType", ...] | None = None
30
38
  subtitle: tuple["subtitleType", ...] | None = None
31
39
 
32
40
 
33
41
  @dataclass(kw_only=True, frozen=True)
34
42
  class packetsAndFramesType:
43
+ """Container for both packet and frame information."""
44
+
35
45
  packet: tuple["packetType", ...] | None = None
36
46
  frame: tuple["frameType", ...] | None = None
37
47
  subtitle: tuple["subtitleType", ...] | None = None
@@ -39,11 +49,15 @@ class packetsAndFramesType:
39
49
 
40
50
  @dataclass(kw_only=True, frozen=True)
41
51
  class tagsType:
52
+ """Container for tag information."""
53
+
42
54
  tag: tuple["tagType", ...] | None = None
43
55
 
44
56
 
45
57
  @dataclass(kw_only=True, frozen=True)
46
58
  class packetType:
59
+ """Information about a single packet."""
60
+
47
61
  tags: Optional["tagsType"] = None
48
62
  side_data_list: Optional["packetSideDataListType"] = None
49
63
  codec_type: str | None = None
@@ -63,23 +77,31 @@ class packetType:
63
77
 
64
78
  @dataclass(kw_only=True, frozen=True)
65
79
  class packetSideDataListType:
80
+ """Container for packet side data information."""
81
+
66
82
  side_data: tuple["packetSideDataType", ...] | None = None
67
83
 
68
84
 
69
85
  @dataclass(kw_only=True, frozen=True)
70
86
  class packetSideDataType:
87
+ """Information about packet side data."""
88
+
71
89
  side_datum: tuple["packetSideDatumType", ...] | None = None
72
90
  type: str | None = None
73
91
 
74
92
 
75
93
  @dataclass(kw_only=True, frozen=True)
76
94
  class packetSideDatumType:
95
+ """Individual packet side data item."""
96
+
77
97
  key: str | None = None
78
98
  value: str | None = None
79
99
 
80
100
 
81
101
  @dataclass(kw_only=True, frozen=True)
82
102
  class frameType:
103
+ """Information about a single frame."""
104
+
83
105
  tags: Optional["tagsType"] = None
84
106
  logs: Optional["logsType"] = None
85
107
  side_data_list: Optional["frameSideDataListType"] = None
@@ -125,11 +147,15 @@ class frameType:
125
147
 
126
148
  @dataclass(kw_only=True, frozen=True)
127
149
  class logsType:
150
+ """Container for log information."""
151
+
128
152
  log: tuple["logType", ...] | None = None
129
153
 
130
154
 
131
155
  @dataclass(kw_only=True, frozen=True)
132
156
  class logType:
157
+ """Information about a single log entry."""
158
+
133
159
  context: str | None = None
134
160
  level: int | None = None
135
161
  category: int | None = None
@@ -140,11 +166,15 @@ class logType:
140
166
 
141
167
  @dataclass(kw_only=True, frozen=True)
142
168
  class frameSideDataListType:
169
+ """Container for frame side data information."""
170
+
143
171
  side_data: tuple["frameSideDataType", ...] | None = None
144
172
 
145
173
 
146
174
  @dataclass(kw_only=True, frozen=True)
147
175
  class frameSideDataType:
176
+ """Information about frame side data."""
177
+
148
178
  timecodes: Optional["frameSideDataTimecodeList"] = None
149
179
  components: Optional["frameSideDataComponentList"] = None
150
180
  side_datum: tuple["frameSideDatumType", ...] | None = None
@@ -155,43 +185,59 @@ class frameSideDataType:
155
185
 
156
186
  @dataclass(kw_only=True, frozen=True)
157
187
  class frameSideDatumType:
188
+ """Individual frame side data item."""
189
+
158
190
  key: str | None = None
159
191
  value: str | None = None
160
192
 
161
193
 
162
194
  @dataclass(kw_only=True, frozen=True)
163
195
  class frameSideDataTimecodeList:
196
+ """Container for frame side data timecode information."""
197
+
164
198
  timecode: tuple["frameSideDataTimecodeType", ...] | None = None
165
199
 
166
200
 
167
201
  @dataclass(kw_only=True, frozen=True)
168
202
  class frameSideDataTimecodeType:
203
+ """Information about frame side data timecode."""
204
+
169
205
  value: str | None = None
170
206
 
171
207
 
172
208
  @dataclass(kw_only=True, frozen=True)
173
209
  class frameSideDataComponentList:
210
+ """Container for frame side data component information."""
211
+
174
212
  component: tuple["frameSideDataComponentType", ...] | None = None
175
213
 
176
214
 
177
215
  @dataclass(kw_only=True, frozen=True)
178
216
  class frameSideDataComponentType:
217
+ """Information about frame side data component."""
218
+
179
219
  pieces: Optional["frameSideDataPieceList"] = None
180
220
  side_datum: tuple["frameSideDatumType", ...] | None = None
181
221
 
182
222
 
183
223
  @dataclass(kw_only=True, frozen=True)
184
224
  class frameSideDataPieceList:
225
+ """Container for frame side data piece information."""
226
+
185
227
  piece: tuple["frameSideDataPieceType", ...] | None = None
186
228
 
187
229
 
188
230
  @dataclass(kw_only=True, frozen=True)
189
231
  class frameSideDataPieceType:
232
+ """Information about frame side data piece."""
233
+
190
234
  side_datum: tuple["frameSideDatumType", ...] | None = None
191
235
 
192
236
 
193
237
  @dataclass(kw_only=True, frozen=True)
194
238
  class subtitleType:
239
+ """Information about a subtitle frame."""
240
+
195
241
  media_type: str | None = None
196
242
  pts: int | None = None
197
243
  pts_time: float | None = None
@@ -203,16 +249,22 @@ class subtitleType:
203
249
 
204
250
  @dataclass(kw_only=True, frozen=True)
205
251
  class streamsType:
252
+ """Container for stream information."""
253
+
206
254
  stream: tuple["streamType", ...] | None = None
207
255
 
208
256
 
209
257
  @dataclass(kw_only=True, frozen=True)
210
258
  class programsType:
259
+ """Container for program information."""
260
+
211
261
  program: tuple["programType", ...] | None = None
212
262
 
213
263
 
214
264
  @dataclass(kw_only=True, frozen=True)
215
265
  class streamDispositionType:
266
+ """Information about stream disposition flags."""
267
+
216
268
  default: int | None = None
217
269
  dub: int | None = None
218
270
  original: int | None = None
@@ -235,6 +287,8 @@ class streamDispositionType:
235
287
 
236
288
  @dataclass(kw_only=True, frozen=True)
237
289
  class streamType:
290
+ """Information about a single stream."""
291
+
238
292
  disposition: Optional["streamDispositionType"] = None
239
293
  tags: Optional["tagsType"] = None
240
294
  side_data_list: Optional["packetSideDataListType"] = None
@@ -290,6 +344,8 @@ class streamType:
290
344
 
291
345
  @dataclass(kw_only=True, frozen=True)
292
346
  class programType:
347
+ """Information about a single program."""
348
+
293
349
  tags: Optional["tagsType"] = None
294
350
  streams: Optional["streamsType"] = None
295
351
  program_id: int | None = None
@@ -301,6 +357,8 @@ class programType:
301
357
 
302
358
  @dataclass(kw_only=True, frozen=True)
303
359
  class formatType:
360
+ """Information about the media format."""
361
+
304
362
  tags: Optional["tagsType"] = None
305
363
  filename: str | None = None
306
364
  nb_streams: int | None = None
@@ -317,18 +375,24 @@ class formatType:
317
375
 
318
376
  @dataclass(kw_only=True, frozen=True)
319
377
  class tagType:
378
+ """Information about a single tag."""
379
+
320
380
  key: str | None = None
321
381
  value: str | None = None
322
382
 
323
383
 
324
384
  @dataclass(kw_only=True, frozen=True)
325
385
  class errorType:
386
+ """Information about an error."""
387
+
326
388
  code: int | None = None
327
389
  string: str | None = None
328
390
 
329
391
 
330
392
  @dataclass(kw_only=True, frozen=True)
331
393
  class programVersionType:
394
+ """Information about the program version."""
395
+
332
396
  version: str | None = None
333
397
  copyright: str | None = None
334
398
  build_date: str | None = None
@@ -339,11 +403,15 @@ class programVersionType:
339
403
 
340
404
  @dataclass(kw_only=True, frozen=True)
341
405
  class chaptersType:
406
+ """Container for chapter information."""
407
+
342
408
  chapter: tuple["chapterType", ...] | None = None
343
409
 
344
410
 
345
411
  @dataclass(kw_only=True, frozen=True)
346
412
  class chapterType:
413
+ """Information about a single chapter."""
414
+
347
415
  tags: tuple["tagsType", ...] | None = None
348
416
  id: int | None = None
349
417
  time_base: str | None = None
@@ -355,6 +423,8 @@ class chapterType:
355
423
 
356
424
  @dataclass(kw_only=True, frozen=True)
357
425
  class libraryVersionType:
426
+ """Information about a library version."""
427
+
358
428
  name: str | None = None
359
429
  major: int | None = None
360
430
  minor: int | None = None
@@ -365,11 +435,15 @@ class libraryVersionType:
365
435
 
366
436
  @dataclass(kw_only=True, frozen=True)
367
437
  class libraryVersionsType:
438
+ """Container for library version information."""
439
+
368
440
  library_version: tuple["libraryVersionType", ...] | None = None
369
441
 
370
442
 
371
443
  @dataclass(kw_only=True, frozen=True)
372
444
  class pixelFormatFlagsType:
445
+ """Information about pixel format flags."""
446
+
373
447
  big_endian: int | None = None
374
448
  palette: int | None = None
375
449
  bitstream: int | None = None
@@ -381,17 +455,23 @@ class pixelFormatFlagsType:
381
455
 
382
456
  @dataclass(kw_only=True, frozen=True)
383
457
  class pixelFormatComponentType:
458
+ """Information about a pixel format component."""
459
+
384
460
  index: int | None = None
385
461
  bit_depth: int | None = None
386
462
 
387
463
 
388
464
  @dataclass(kw_only=True, frozen=True)
389
465
  class pixelFormatComponentsType:
466
+ """Container for pixel format component information."""
467
+
390
468
  component: tuple["pixelFormatComponentType", ...] | None = None
391
469
 
392
470
 
393
471
  @dataclass(kw_only=True, frozen=True)
394
472
  class pixelFormatType:
473
+ """Information about a pixel format."""
474
+
395
475
  flags: Optional["pixelFormatFlagsType"] = None
396
476
  components: Optional["pixelFormatComponentsType"] = None
397
477
  name: str | None = None
@@ -403,6 +483,8 @@ class pixelFormatType:
403
483
 
404
484
  @dataclass(kw_only=True, frozen=True)
405
485
  class pixelFormatsType:
486
+ """Container for pixel format information."""
487
+
406
488
  pixel_format: tuple["pixelFormatType", ...] | None = None
407
489
 
408
490
 
@@ -1,10 +1,13 @@
1
+ """XML to JSON conversion utilities for FFprobe output."""
2
+
1
3
  import json
2
4
  import xml.etree.ElementTree as ET
3
5
  from typing import Any, cast
4
6
 
5
7
 
6
8
  def xml_to_dict(element: ET.Element) -> dict[str, Any]:
7
- """Convert an XML Element to a dictionary representation.
9
+ """
10
+ Convert an XML Element to a dictionary representation.
8
11
 
9
12
  This function recursively converts an XML Element and its children into a nested
10
13
  dictionary structure. Attributes are preserved as dictionary keys, and text content
@@ -19,6 +22,7 @@ def xml_to_dict(element: ET.Element) -> dict[str, Any]:
19
22
  - Child elements are stored as nested dictionaries
20
23
  - Multiple elements with the same tag are stored as lists
21
24
  - Text content is stored under the 'text' key
25
+
22
26
  """
23
27
  node: dict[str, Any] = {}
24
28
  if element.attrib:
@@ -43,7 +47,8 @@ def xml_to_dict(element: ET.Element) -> dict[str, Any]:
43
47
 
44
48
 
45
49
  def xml_string_to_json(xml_string: str) -> str:
46
- """Convert an XML string to a JSON string.
50
+ """
51
+ Convert an XML string to a JSON string.
47
52
 
48
53
  This function takes an XML string, parses it into an ElementTree structure,
49
54
  converts it to a dictionary using xml_to_dict, and then serializes it to a JSON string.
@@ -65,6 +70,7 @@ def xml_string_to_json(xml_string: str) -> str:
65
70
  }
66
71
  }
67
72
  }'
73
+
68
74
  """
69
75
  root = ET.fromstring(xml_string)
70
76
  return json.dumps({root.tag: xml_to_dict(root)}, indent=2)