typed-ffmpeg-compatible 3.3__py3-none-any.whl → 3.4__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 (30) hide show
  1. typed_ffmpeg/__init__.py +4 -2
  2. typed_ffmpeg/_version.py +2 -2
  3. typed_ffmpeg/base.py +6 -5
  4. typed_ffmpeg/codecs/__init__.py +3 -0
  5. typed_ffmpeg/codecs/decoders.py +6644 -0
  6. typed_ffmpeg/codecs/encoders.py +6435 -0
  7. typed_ffmpeg/codecs/schema.py +17 -0
  8. typed_ffmpeg/common/serialize.py +1 -1
  9. typed_ffmpeg/compile/compile_cli.py +2 -0
  10. typed_ffmpeg/dag/global_runnable/global_args.py +59 -55
  11. typed_ffmpeg/dag/io/_input.py +72 -64
  12. typed_ffmpeg/dag/io/_output.py +114 -105
  13. typed_ffmpeg/dag/io/output_args.py +118 -104
  14. typed_ffmpeg/dag/nodes.py +1 -1
  15. typed_ffmpeg/dag/schema.py +1 -1
  16. typed_ffmpeg/filters.py +1717 -675
  17. typed_ffmpeg/sources.py +1641 -571
  18. typed_ffmpeg/streams/__init__.py +2 -1
  19. typed_ffmpeg/streams/audio.py +1994 -1554
  20. typed_ffmpeg/streams/video.py +4540 -2843
  21. typed_ffmpeg/utils/{forzendict.py → frozendict.py} +56 -1
  22. typed_ffmpeg/utils/run.py +1 -1
  23. typed_ffmpeg/utils/snapshot.py +1 -1
  24. typed_ffmpeg/utils/view.py +3 -2
  25. {typed_ffmpeg_compatible-3.3.dist-info → typed_ffmpeg_compatible-3.4.dist-info}/METADATA +1 -1
  26. {typed_ffmpeg_compatible-3.3.dist-info → typed_ffmpeg_compatible-3.4.dist-info}/RECORD +30 -26
  27. {typed_ffmpeg_compatible-3.3.dist-info → typed_ffmpeg_compatible-3.4.dist-info}/WHEEL +0 -0
  28. {typed_ffmpeg_compatible-3.3.dist-info → typed_ffmpeg_compatible-3.4.dist-info}/entry_points.txt +0 -0
  29. {typed_ffmpeg_compatible-3.3.dist-info → typed_ffmpeg_compatible-3.4.dist-info}/licenses/LICENSE +0 -0
  30. {typed_ffmpeg_compatible-3.3.dist-info → typed_ffmpeg_compatible-3.4.dist-info}/top_level.txt +0 -0
typed_ffmpeg/sources.py CHANGED
@@ -1,4 +1,5 @@
1
1
  # NOTE: this file is auto-generated, do not modify
2
+
2
3
  from typing import Any, Literal
3
4
 
4
5
  from .common.schema import FFMpegFilterDef
@@ -8,6 +9,7 @@ from .schema import Auto, Default
8
9
  from .streams.audio import AudioStream
9
10
  from .streams.video import VideoStream
10
11
  from .types import (
12
+ Binary,
11
13
  Boolean,
12
14
  Color,
13
15
  Dictionary,
@@ -24,6 +26,7 @@ from .types import (
24
26
  String,
25
27
  Video_rate,
26
28
  )
29
+ from .utils.frozendict import merge
27
30
 
28
31
 
29
32
  def abuffer(
@@ -33,7 +36,7 @@ def abuffer(
33
36
  sample_fmt: Sample_fmt = Default("none"),
34
37
  channel_layout: String = Default(None),
35
38
  channels: Int = Default(0),
36
- extra_options: dict[str, Any] = None,
39
+ extra_options: dict[str, Any] | None = None,
37
40
  ) -> AudioStream:
38
41
  """
39
42
 
@@ -55,14 +58,16 @@ def abuffer(
55
58
  """
56
59
  filter_node = filter_node_factory(
57
60
  FFMpegFilterDef(name="abuffer", typings_input=(), typings_output=("audio",)),
58
- **{
59
- "time_base": time_base,
60
- "sample_rate": sample_rate,
61
- "sample_fmt": sample_fmt,
62
- "channel_layout": channel_layout,
63
- "channels": channels,
64
- }
65
- | (extra_options or {}),
61
+ **merge(
62
+ {
63
+ "time_base": time_base,
64
+ "sample_rate": sample_rate,
65
+ "sample_fmt": sample_fmt,
66
+ "channel_layout": channel_layout,
67
+ "channels": channels,
68
+ },
69
+ extra_options,
70
+ ),
66
71
  )
67
72
  return filter_node.audio(0)
68
73
 
@@ -74,7 +79,7 @@ def aevalsrc(
74
79
  sample_rate: String = Default("44100"),
75
80
  duration: Duration = Default(-1e-06),
76
81
  channel_layout: String = Default(None),
77
- extra_options: dict[str, Any] = None,
82
+ extra_options: dict[str, Any] | None = None,
78
83
  ) -> AudioStream:
79
84
  """
80
85
 
@@ -96,14 +101,16 @@ def aevalsrc(
96
101
  """
97
102
  filter_node = filter_node_factory(
98
103
  FFMpegFilterDef(name="aevalsrc", typings_input=(), typings_output=("audio",)),
99
- **{
100
- "exprs": exprs,
101
- "nb_samples": nb_samples,
102
- "sample_rate": sample_rate,
103
- "duration": duration,
104
- "channel_layout": channel_layout,
105
- }
106
- | (extra_options or {}),
104
+ **merge(
105
+ {
106
+ "exprs": exprs,
107
+ "nb_samples": nb_samples,
108
+ "sample_rate": sample_rate,
109
+ "duration": duration,
110
+ "channel_layout": channel_layout,
111
+ },
112
+ extra_options,
113
+ ),
107
114
  )
108
115
  return filter_node.audio(0)
109
116
 
@@ -115,7 +122,7 @@ def afdelaysrc(
115
122
  nb_samples: Int = Default(1024),
116
123
  taps: Int = Default(0),
117
124
  channel_layout: String = Default("stereo"),
118
- extra_options: dict[str, Any] = None,
125
+ extra_options: dict[str, Any] | None = None,
119
126
  ) -> AudioStream:
120
127
  """
121
128
 
@@ -137,14 +144,92 @@ def afdelaysrc(
137
144
  """
138
145
  filter_node = filter_node_factory(
139
146
  FFMpegFilterDef(name="afdelaysrc", typings_input=(), typings_output=("audio",)),
140
- **{
141
- "delay": delay,
142
- "sample_rate": sample_rate,
143
- "nb_samples": nb_samples,
144
- "taps": taps,
145
- "channel_layout": channel_layout,
146
- }
147
- | (extra_options or {}),
147
+ **merge(
148
+ {
149
+ "delay": delay,
150
+ "sample_rate": sample_rate,
151
+ "nb_samples": nb_samples,
152
+ "taps": taps,
153
+ "channel_layout": channel_layout,
154
+ },
155
+ extra_options,
156
+ ),
157
+ )
158
+ return filter_node.audio(0)
159
+
160
+
161
+ def afireqsrc(
162
+ *,
163
+ preset: Int
164
+ | Literal[
165
+ "custom",
166
+ "flat",
167
+ "acoustic",
168
+ "bass",
169
+ "beats",
170
+ "classic",
171
+ "clear",
172
+ "deep",
173
+ "dubstep",
174
+ "electronic",
175
+ "hardstyle",
176
+ "hop",
177
+ "jazz",
178
+ "metal",
179
+ "movie",
180
+ "pop",
181
+ "b",
182
+ "rock",
183
+ "vocal",
184
+ ]
185
+ | Default = Default("flat"),
186
+ gains: String = Default("0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"),
187
+ bands: String = Default(
188
+ "25 40 63 100 160 250 400 630 1000 1600 2500 4000 6300 10000 16000 24000"
189
+ ),
190
+ taps: Int = Default(4096),
191
+ sample_rate: Int = Default(44100),
192
+ nb_samples: Int = Default(1024),
193
+ interp: Int | Literal["linear", "cubic"] | Default = Default("linear"),
194
+ phase: Int | Literal["linear", "min"] | Default = Default("min"),
195
+ extra_options: dict[str, Any] | None = None,
196
+ ) -> AudioStream:
197
+ """
198
+
199
+ Generate a FIR equalizer coefficients audio stream.
200
+
201
+ Args:
202
+ preset: set equalizer preset (from -1 to 17) (default flat)
203
+ gains: set gain values per band (default "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0")
204
+ bands: set central frequency values per band (default "25 40 63 100 160 250 400 630 1000 1600 2500 4000 6300 10000 16000 24000")
205
+ taps: set number of taps (from 16 to 65535) (default 4096)
206
+ sample_rate: set sample rate (from 1 to INT_MAX) (default 44100)
207
+ nb_samples: set the number of samples per requested frame (from 1 to INT_MAX) (default 1024)
208
+ interp: set the interpolation (from 0 to 1) (default linear)
209
+ phase: set the phase (from 0 to 1) (default min)
210
+
211
+ Returns:
212
+ default: the audio stream
213
+
214
+ References:
215
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#afireqsrc)
216
+
217
+ """
218
+ filter_node = filter_node_factory(
219
+ FFMpegFilterDef(name="afireqsrc", typings_input=(), typings_output=("audio",)),
220
+ **merge(
221
+ {
222
+ "preset": preset,
223
+ "gains": gains,
224
+ "bands": bands,
225
+ "taps": taps,
226
+ "sample_rate": sample_rate,
227
+ "nb_samples": nb_samples,
228
+ "interp": interp,
229
+ "phase": phase,
230
+ },
231
+ extra_options,
232
+ ),
148
233
  )
149
234
  return filter_node.audio(0)
150
235
 
@@ -205,7 +290,7 @@ def afirsrc(
205
290
  "kaiser",
206
291
  ]
207
292
  | Default = Default("blackman"),
208
- extra_options: dict[str, Any] = None,
293
+ extra_options: dict[str, Any] | None = None,
209
294
  ) -> AudioStream:
210
295
  """
211
296
 
@@ -229,16 +314,18 @@ def afirsrc(
229
314
  """
230
315
  filter_node = filter_node_factory(
231
316
  FFMpegFilterDef(name="afirsrc", typings_input=(), typings_output=("audio",)),
232
- **{
233
- "taps": taps,
234
- "frequency": frequency,
235
- "magnitude": magnitude,
236
- "phase": phase,
237
- "sample_rate": sample_rate,
238
- "nb_samples": nb_samples,
239
- "win_func": win_func,
240
- }
241
- | (extra_options or {}),
317
+ **merge(
318
+ {
319
+ "taps": taps,
320
+ "frequency": frequency,
321
+ "magnitude": magnitude,
322
+ "phase": phase,
323
+ "sample_rate": sample_rate,
324
+ "nb_samples": nb_samples,
325
+ "win_func": win_func,
326
+ },
327
+ extra_options,
328
+ ),
242
329
  )
243
330
  return filter_node.audio(0)
244
331
 
@@ -249,7 +336,7 @@ def ainterleave(
249
336
  duration: Int | Literal["longest", "shortest", "first"] | Default = Default(
250
337
  "longest"
251
338
  ),
252
- extra_options: dict[str, Any] = None,
339
+ extra_options: dict[str, Any] | None = None,
253
340
  ) -> AudioStream:
254
341
  """
255
342
 
@@ -273,11 +360,13 @@ def ainterleave(
273
360
  typings_output=("audio",),
274
361
  ),
275
362
  *streams,
276
- **{
277
- "nb_inputs": nb_inputs,
278
- "duration": duration,
279
- }
280
- | (extra_options or {}),
363
+ **merge(
364
+ {
365
+ "nb_inputs": nb_inputs,
366
+ "duration": duration,
367
+ },
368
+ extra_options,
369
+ ),
281
370
  )
282
371
  return filter_node.audio(0)
283
372
 
@@ -287,7 +376,7 @@ def allrgb(
287
376
  rate: Video_rate = Default("25"),
288
377
  duration: Duration = Default(-1e-06),
289
378
  sar: Rational = Default("1/1"),
290
- extra_options: dict[str, Any] = None,
379
+ extra_options: dict[str, Any] | None = None,
291
380
  ) -> VideoStream:
292
381
  """
293
382
 
@@ -307,12 +396,14 @@ def allrgb(
307
396
  """
308
397
  filter_node = filter_node_factory(
309
398
  FFMpegFilterDef(name="allrgb", typings_input=(), typings_output=("video",)),
310
- **{
311
- "rate": rate,
312
- "duration": duration,
313
- "sar": sar,
314
- }
315
- | (extra_options or {}),
399
+ **merge(
400
+ {
401
+ "rate": rate,
402
+ "duration": duration,
403
+ "sar": sar,
404
+ },
405
+ extra_options,
406
+ ),
316
407
  )
317
408
  return filter_node.video(0)
318
409
 
@@ -322,7 +413,7 @@ def allyuv(
322
413
  rate: Video_rate = Default("25"),
323
414
  duration: Duration = Default(-1e-06),
324
415
  sar: Rational = Default("1/1"),
325
- extra_options: dict[str, Any] = None,
416
+ extra_options: dict[str, Any] | None = None,
326
417
  ) -> VideoStream:
327
418
  """
328
419
 
@@ -342,12 +433,14 @@ def allyuv(
342
433
  """
343
434
  filter_node = filter_node_factory(
344
435
  FFMpegFilterDef(name="allyuv", typings_input=(), typings_output=("video",)),
345
- **{
346
- "rate": rate,
347
- "duration": duration,
348
- "sar": sar,
349
- }
350
- | (extra_options or {}),
436
+ **merge(
437
+ {
438
+ "rate": rate,
439
+ "duration": duration,
440
+ "sar": sar,
441
+ },
442
+ extra_options,
443
+ ),
351
444
  )
352
445
  return filter_node.video(0)
353
446
 
@@ -355,7 +448,7 @@ def allyuv(
355
448
  def amerge(
356
449
  *streams: AudioStream,
357
450
  inputs: Int = Auto("len(streams)"),
358
- extra_options: dict[str, Any] = None,
451
+ extra_options: dict[str, Any] | None = None,
359
452
  ) -> AudioStream:
360
453
  """
361
454
 
@@ -378,10 +471,12 @@ def amerge(
378
471
  typings_output=("audio",),
379
472
  ),
380
473
  *streams,
381
- **{
382
- "inputs": inputs,
383
- }
384
- | (extra_options or {}),
474
+ **merge(
475
+ {
476
+ "inputs": inputs,
477
+ },
478
+ extra_options,
479
+ ),
385
480
  )
386
481
  return filter_node.audio(0)
387
482
 
@@ -395,7 +490,7 @@ def amix(
395
490
  dropout_transition: Float = Default(2.0),
396
491
  weights: String = Default("1 1"),
397
492
  normalize: Boolean = Default(True),
398
- extra_options: dict[str, Any] = None,
493
+ extra_options: dict[str, Any] | None = None,
399
494
  ) -> AudioStream:
400
495
  """
401
496
 
@@ -422,14 +517,16 @@ def amix(
422
517
  typings_output=("audio",),
423
518
  ),
424
519
  *streams,
425
- **{
426
- "inputs": inputs,
427
- "duration": duration,
428
- "dropout_transition": dropout_transition,
429
- "weights": weights,
430
- "normalize": normalize,
431
- }
432
- | (extra_options or {}),
520
+ **merge(
521
+ {
522
+ "inputs": inputs,
523
+ "duration": duration,
524
+ "dropout_transition": dropout_transition,
525
+ "weights": weights,
526
+ "normalize": normalize,
527
+ },
528
+ extra_options,
529
+ ),
433
530
  )
434
531
  return filter_node.audio(0)
435
532
 
@@ -445,7 +542,7 @@ def amovie(
445
542
  discontinuity: Duration = Default(0.0),
446
543
  dec_threads: Int = Default(0),
447
544
  format_opts: Dictionary = Default(None),
448
- extra_options: dict[str, Any] = None,
545
+ extra_options: dict[str, Any] | None = None,
449
546
  ) -> FilterNode:
450
547
  """
451
548
 
@@ -476,18 +573,20 @@ def amovie(
476
573
  typings_input="[StreamType.audio] * len(streams.split('+'))",
477
574
  typings_output="[StreamType.audio] * len(streams.split('+'))",
478
575
  ),
479
- **{
480
- "filename": filename,
481
- "format_name": format_name,
482
- "stream_index": stream_index,
483
- "seek_point": seek_point,
484
- "streams": streams,
485
- "loop": loop,
486
- "discontinuity": discontinuity,
487
- "dec_threads": dec_threads,
488
- "format_opts": format_opts,
489
- }
490
- | (extra_options or {}),
576
+ **merge(
577
+ {
578
+ "filename": filename,
579
+ "format_name": format_name,
580
+ "stream_index": stream_index,
581
+ "seek_point": seek_point,
582
+ "streams": streams,
583
+ "loop": loop,
584
+ "discontinuity": discontinuity,
585
+ "dec_threads": dec_threads,
586
+ "format_opts": format_opts,
587
+ },
588
+ extra_options,
589
+ ),
491
590
  )
492
591
 
493
592
  return filter_node
@@ -503,7 +602,8 @@ def anoisesrc(
503
602
  | Default = Default("white"),
504
603
  seed: Int64 = Default(-1),
505
604
  nb_samples: Int = Default(1024),
506
- extra_options: dict[str, Any] = None,
605
+ density: Double = Default(0.05),
606
+ extra_options: dict[str, Any] | None = None,
507
607
  ) -> AudioStream:
508
608
  """
509
609
 
@@ -516,6 +616,7 @@ def anoisesrc(
516
616
  color: set noise color (from 0 to 5) (default white)
517
617
  seed: set random seed (from -1 to UINT32_MAX) (default -1)
518
618
  nb_samples: set the number of samples per requested frame (from 1 to INT_MAX) (default 1024)
619
+ density: set density (from 0 to 1) (default 0.05)
519
620
 
520
621
  Returns:
521
622
  default: the audio stream
@@ -526,15 +627,18 @@ def anoisesrc(
526
627
  """
527
628
  filter_node = filter_node_factory(
528
629
  FFMpegFilterDef(name="anoisesrc", typings_input=(), typings_output=("audio",)),
529
- **{
530
- "sample_rate": sample_rate,
531
- "amplitude": amplitude,
532
- "duration": duration,
533
- "color": color,
534
- "seed": seed,
535
- "nb_samples": nb_samples,
536
- }
537
- | (extra_options or {}),
630
+ **merge(
631
+ {
632
+ "sample_rate": sample_rate,
633
+ "amplitude": amplitude,
634
+ "duration": duration,
635
+ "color": color,
636
+ "seed": seed,
637
+ "nb_samples": nb_samples,
638
+ "density": density,
639
+ },
640
+ extra_options,
641
+ ),
538
642
  )
539
643
  return filter_node.audio(0)
540
644
 
@@ -545,7 +649,7 @@ def anullsrc(
545
649
  sample_rate: String = Default("44100"),
546
650
  nb_samples: Int = Default(1024),
547
651
  duration: Duration = Default(-1e-06),
548
- extra_options: dict[str, Any] = None,
652
+ extra_options: dict[str, Any] | None = None,
549
653
  ) -> AudioStream:
550
654
  """
551
655
 
@@ -566,13 +670,15 @@ def anullsrc(
566
670
  """
567
671
  filter_node = filter_node_factory(
568
672
  FFMpegFilterDef(name="anullsrc", typings_input=(), typings_output=("audio",)),
569
- **{
570
- "channel_layout": channel_layout,
571
- "sample_rate": sample_rate,
572
- "nb_samples": nb_samples,
573
- "duration": duration,
574
- }
575
- | (extra_options or {}),
673
+ **merge(
674
+ {
675
+ "channel_layout": channel_layout,
676
+ "sample_rate": sample_rate,
677
+ "nb_samples": nb_samples,
678
+ "duration": duration,
679
+ },
680
+ extra_options,
681
+ ),
576
682
  )
577
683
  return filter_node.audio(0)
578
684
 
@@ -581,7 +687,7 @@ def astreamselect(
581
687
  *streams: AudioStream,
582
688
  inputs: Int = Auto("len(streams)"),
583
689
  map: String = Default(None),
584
- extra_options: dict[str, Any] = None,
690
+ extra_options: dict[str, Any] | None = None,
585
691
  ) -> FilterNode:
586
692
  """
587
693
 
@@ -606,11 +712,13 @@ def astreamselect(
606
712
  typings_output="[StreamType.audio] * len(re.findall(r'\\d+', str(map)))",
607
713
  ),
608
714
  *streams,
609
- **{
610
- "inputs": inputs,
611
- "map": map,
612
- }
613
- | (extra_options or {}),
715
+ **merge(
716
+ {
717
+ "inputs": inputs,
718
+ "map": map,
719
+ },
720
+ extra_options,
721
+ ),
614
722
  )
615
723
 
616
724
  return filter_node
@@ -629,7 +737,7 @@ def avsynctest(
629
737
  fg: Color = Default("white"),
630
738
  bg: Color = Default("black"),
631
739
  ag: Color = Default("gray"),
632
- extra_options: dict[str, Any] = None,
740
+ extra_options: dict[str, Any] | None = None,
633
741
  ) -> tuple[
634
742
  AudioStream,
635
743
  VideoStream,
@@ -663,20 +771,22 @@ def avsynctest(
663
771
  FFMpegFilterDef(
664
772
  name="avsynctest", typings_input=(), typings_output=("audio", "video")
665
773
  ),
666
- **{
667
- "size": size,
668
- "framerate": framerate,
669
- "samplerate": samplerate,
670
- "amplitude": amplitude,
671
- "period": period,
672
- "delay": delay,
673
- "cycle": cycle,
674
- "duration": duration,
675
- "fg": fg,
676
- "bg": bg,
677
- "ag": ag,
678
- }
679
- | (extra_options or {}),
774
+ **merge(
775
+ {
776
+ "size": size,
777
+ "framerate": framerate,
778
+ "samplerate": samplerate,
779
+ "amplitude": amplitude,
780
+ "period": period,
781
+ "delay": delay,
782
+ "cycle": cycle,
783
+ "duration": duration,
784
+ "fg": fg,
785
+ "bg": bg,
786
+ "ag": ag,
787
+ },
788
+ extra_options,
789
+ ),
680
790
  )
681
791
  return (
682
792
  filter_node.audio(0),
@@ -698,7 +808,7 @@ def bm3d(
698
808
  ref: Boolean = Default(False),
699
809
  planes: Int = Default(7),
700
810
  enable: String = Default(None),
701
- extra_options: dict[str, Any] = None,
811
+ extra_options: dict[str, Any] | None = None,
702
812
  ) -> VideoStream:
703
813
  """
704
814
 
@@ -732,21 +842,23 @@ def bm3d(
732
842
  typings_output=("video",),
733
843
  ),
734
844
  *streams,
735
- **{
736
- "sigma": sigma,
737
- "block": block,
738
- "bstep": bstep,
739
- "group": group,
740
- "range": range,
741
- "mstep": mstep,
742
- "thmse": thmse,
743
- "hdthr": hdthr,
744
- "estim": estim,
745
- "ref": ref,
746
- "planes": planes,
747
- "enable": enable,
748
- }
749
- | (extra_options or {}),
845
+ **merge(
846
+ {
847
+ "sigma": sigma,
848
+ "block": block,
849
+ "bstep": bstep,
850
+ "group": group,
851
+ "range": range,
852
+ "mstep": mstep,
853
+ "thmse": thmse,
854
+ "hdthr": hdthr,
855
+ "estim": estim,
856
+ "ref": ref,
857
+ "planes": planes,
858
+ "enable": enable,
859
+ },
860
+ extra_options,
861
+ ),
750
862
  )
751
863
  return filter_node.video(0)
752
864
 
@@ -759,7 +871,7 @@ def buffer(
759
871
  pix_fmt: Pix_fmt = Default("none"),
760
872
  sar: Rational = Default("0/1"),
761
873
  time_base: Rational = Default("0/1"),
762
- extra_options: dict[str, Any] = None,
874
+ extra_options: dict[str, Any] | None = None,
763
875
  ) -> VideoStream:
764
876
  """
765
877
 
@@ -782,15 +894,17 @@ def buffer(
782
894
  """
783
895
  filter_node = filter_node_factory(
784
896
  FFMpegFilterDef(name="buffer", typings_input=(), typings_output=("video",)),
785
- **{
786
- "width": width,
787
- "video_size": video_size,
788
- "height": height,
789
- "pix_fmt": pix_fmt,
790
- "sar": sar,
791
- "time_base": time_base,
792
- }
793
- | (extra_options or {}),
897
+ **merge(
898
+ {
899
+ "width": width,
900
+ "video_size": video_size,
901
+ "height": height,
902
+ "pix_fmt": pix_fmt,
903
+ "sar": sar,
904
+ "time_base": time_base,
905
+ },
906
+ extra_options,
907
+ ),
794
908
  )
795
909
  return filter_node.video(0)
796
910
 
@@ -808,7 +922,7 @@ def cellauto(
808
922
  start_full: Boolean = Default(False),
809
923
  full: Boolean = Default(True),
810
924
  stitch: Boolean = Default(True),
811
- extra_options: dict[str, Any] = None,
925
+ extra_options: dict[str, Any] | None = None,
812
926
  ) -> VideoStream:
813
927
  """
814
928
 
@@ -836,20 +950,22 @@ def cellauto(
836
950
  """
837
951
  filter_node = filter_node_factory(
838
952
  FFMpegFilterDef(name="cellauto", typings_input=(), typings_output=("video",)),
839
- **{
840
- "filename": filename,
841
- "pattern": pattern,
842
- "rate": rate,
843
- "size": size,
844
- "rule": rule,
845
- "random_fill_ratio": random_fill_ratio,
846
- "random_seed": random_seed,
847
- "scroll": scroll,
848
- "start_full": start_full,
849
- "full": full,
850
- "stitch": stitch,
851
- }
852
- | (extra_options or {}),
953
+ **merge(
954
+ {
955
+ "filename": filename,
956
+ "pattern": pattern,
957
+ "rate": rate,
958
+ "size": size,
959
+ "rule": rule,
960
+ "random_fill_ratio": random_fill_ratio,
961
+ "random_seed": random_seed,
962
+ "scroll": scroll,
963
+ "start_full": start_full,
964
+ "full": full,
965
+ "stitch": stitch,
966
+ },
967
+ extra_options,
968
+ ),
853
969
  )
854
970
  return filter_node.video(0)
855
971
 
@@ -861,7 +977,7 @@ def color(
861
977
  rate: Video_rate = Default("25"),
862
978
  duration: Duration = Default(-1e-06),
863
979
  sar: Rational = Default("1/1"),
864
- extra_options: dict[str, Any] = None,
980
+ extra_options: dict[str, Any] | None = None,
865
981
  ) -> VideoStream:
866
982
  """
867
983
 
@@ -883,14 +999,69 @@ def color(
883
999
  """
884
1000
  filter_node = filter_node_factory(
885
1001
  FFMpegFilterDef(name="color", typings_input=(), typings_output=("video",)),
886
- **{
887
- "color": color,
888
- "size": size,
889
- "rate": rate,
890
- "duration": duration,
891
- "sar": sar,
892
- }
893
- | (extra_options or {}),
1002
+ **merge(
1003
+ {
1004
+ "color": color,
1005
+ "size": size,
1006
+ "rate": rate,
1007
+ "duration": duration,
1008
+ "sar": sar,
1009
+ },
1010
+ extra_options,
1011
+ ),
1012
+ )
1013
+ return filter_node.video(0)
1014
+
1015
+
1016
+ def color_vulkan(
1017
+ *,
1018
+ color: Color = Default("black"),
1019
+ size: Image_size = Default("1920x1080"),
1020
+ rate: Video_rate = Default("60"),
1021
+ duration: Duration = Default(-1e-06),
1022
+ sar: Rational = Default("1/1"),
1023
+ format: String = Default(None),
1024
+ out_range: Int
1025
+ | Literal["full", "limited", "jpeg", "mpeg", "tv", "pc"]
1026
+ | Default = Default(0),
1027
+ extra_options: dict[str, Any] | None = None,
1028
+ ) -> VideoStream:
1029
+ """
1030
+
1031
+ Generate a constant color (Vulkan)
1032
+
1033
+ Args:
1034
+ color: set color (default "black")
1035
+ size: set video size (default "1920x1080")
1036
+ rate: set video rate (default "60")
1037
+ duration: set video duration (default -0.000001)
1038
+ sar: set video sample aspect ratio (from 0 to INT_MAX) (default 1/1)
1039
+ format: Output video format (software format of hardware frames)
1040
+ out_range: Output colour range (from 0 to 2) (default 0) (from 0 to 2) (default 0)
1041
+
1042
+ Returns:
1043
+ default: the video stream
1044
+
1045
+ References:
1046
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#color_005fvulkan)
1047
+
1048
+ """
1049
+ filter_node = filter_node_factory(
1050
+ FFMpegFilterDef(
1051
+ name="color_vulkan", typings_input=(), typings_output=("video",)
1052
+ ),
1053
+ **merge(
1054
+ {
1055
+ "color": color,
1056
+ "size": size,
1057
+ "rate": rate,
1058
+ "duration": duration,
1059
+ "sar": sar,
1060
+ "format": format,
1061
+ "out_range": out_range,
1062
+ },
1063
+ extra_options,
1064
+ ),
894
1065
  )
895
1066
  return filter_node.video(0)
896
1067
 
@@ -902,7 +1073,7 @@ def colorchart(
902
1073
  sar: Rational = Default("1/1"),
903
1074
  patch_size: Image_size = Default("64x64"),
904
1075
  preset: Int | Literal["reference", "skintones"] | Default = Default("reference"),
905
- extra_options: dict[str, Any] = None,
1076
+ extra_options: dict[str, Any] | None = None,
906
1077
  ) -> VideoStream:
907
1078
  """
908
1079
 
@@ -924,14 +1095,16 @@ def colorchart(
924
1095
  """
925
1096
  filter_node = filter_node_factory(
926
1097
  FFMpegFilterDef(name="colorchart", typings_input=(), typings_output=("video",)),
927
- **{
928
- "rate": rate,
929
- "duration": duration,
930
- "sar": sar,
931
- "patch_size": patch_size,
932
- "preset": preset,
933
- }
934
- | (extra_options or {}),
1098
+ **merge(
1099
+ {
1100
+ "rate": rate,
1101
+ "duration": duration,
1102
+ "sar": sar,
1103
+ "patch_size": patch_size,
1104
+ "preset": preset,
1105
+ },
1106
+ extra_options,
1107
+ ),
935
1108
  )
936
1109
  return filter_node.video(0)
937
1110
 
@@ -943,7 +1116,7 @@ def colorspectrum(
943
1116
  duration: Duration = Default(-1e-06),
944
1117
  sar: Rational = Default("1/1"),
945
1118
  type: Int | Literal["black", "white", "all"] | Default = Default("black"),
946
- extra_options: dict[str, Any] = None,
1119
+ extra_options: dict[str, Any] | None = None,
947
1120
  ) -> VideoStream:
948
1121
  """
949
1122
 
@@ -967,14 +1140,16 @@ def colorspectrum(
967
1140
  FFMpegFilterDef(
968
1141
  name="colorspectrum", typings_input=(), typings_output=("video",)
969
1142
  ),
970
- **{
971
- "size": size,
972
- "rate": rate,
973
- "duration": duration,
974
- "sar": sar,
975
- "type": type,
976
- }
977
- | (extra_options or {}),
1143
+ **merge(
1144
+ {
1145
+ "size": size,
1146
+ "rate": rate,
1147
+ "duration": duration,
1148
+ "sar": sar,
1149
+ "type": type,
1150
+ },
1151
+ extra_options,
1152
+ ),
978
1153
  )
979
1154
  return filter_node.video(0)
980
1155
 
@@ -985,7 +1160,7 @@ def concat(
985
1160
  v: Int = Default(1),
986
1161
  a: Int = Default(0),
987
1162
  unsafe: Boolean = Default(False),
988
- extra_options: dict[str, Any] = None,
1163
+ extra_options: dict[str, Any] | None = None,
989
1164
  ) -> FilterNode:
990
1165
  """
991
1166
 
@@ -1012,13 +1187,15 @@ def concat(
1012
1187
  typings_output="[StreamType.video]*int(v) + [StreamType.audio]*int(a)",
1013
1188
  ),
1014
1189
  *streams,
1015
- **{
1016
- "n": n,
1017
- "v": v,
1018
- "a": a,
1019
- "unsafe": unsafe,
1020
- }
1021
- | (extra_options or {}),
1190
+ **merge(
1191
+ {
1192
+ "n": n,
1193
+ "v": v,
1194
+ "a": a,
1195
+ "unsafe": unsafe,
1196
+ },
1197
+ extra_options,
1198
+ ),
1022
1199
  )
1023
1200
 
1024
1201
  return filter_node
@@ -1034,7 +1211,7 @@ def decimate(
1034
1211
  ppsrc: Boolean = Default(False),
1035
1212
  chroma: Boolean = Default(True),
1036
1213
  mixed: Boolean = Default(False),
1037
- extra_options: dict[str, Any] = None,
1214
+ extra_options: dict[str, Any] | None = None,
1038
1215
  ) -> VideoStream:
1039
1216
  """
1040
1217
 
@@ -1064,17 +1241,19 @@ def decimate(
1064
1241
  typings_output=("video",),
1065
1242
  ),
1066
1243
  *streams,
1067
- **{
1068
- "cycle": cycle,
1069
- "dupthresh": dupthresh,
1070
- "scthresh": scthresh,
1071
- "blockx": blockx,
1072
- "blocky": blocky,
1073
- "ppsrc": ppsrc,
1074
- "chroma": chroma,
1075
- "mixed": mixed,
1076
- }
1077
- | (extra_options or {}),
1244
+ **merge(
1245
+ {
1246
+ "cycle": cycle,
1247
+ "dupthresh": dupthresh,
1248
+ "scthresh": scthresh,
1249
+ "blockx": blockx,
1250
+ "blocky": blocky,
1251
+ "ppsrc": ppsrc,
1252
+ "chroma": chroma,
1253
+ "mixed": mixed,
1254
+ },
1255
+ extra_options,
1256
+ ),
1078
1257
  )
1079
1258
  return filter_node.video(0)
1080
1259
 
@@ -1097,7 +1276,7 @@ def fieldmatch(
1097
1276
  blockx: Int = Default(16),
1098
1277
  blocky: Int = Default(16),
1099
1278
  combpel: Int = Default(80),
1100
- extra_options: dict[str, Any] = None,
1279
+ extra_options: dict[str, Any] | None = None,
1101
1280
  ) -> VideoStream:
1102
1281
  """
1103
1282
 
@@ -1133,34 +1312,79 @@ def fieldmatch(
1133
1312
  typings_output=("video",),
1134
1313
  ),
1135
1314
  *streams,
1136
- **{
1137
- "order": order,
1138
- "mode": mode,
1139
- "ppsrc": ppsrc,
1140
- "field": field,
1141
- "mchroma": mchroma,
1142
- "y0": y0,
1143
- "scthresh": scthresh,
1144
- "combmatch": combmatch,
1145
- "combdbg": combdbg,
1146
- "cthresh": cthresh,
1147
- "chroma": chroma,
1148
- "blockx": blockx,
1149
- "blocky": blocky,
1150
- "combpel": combpel,
1151
- }
1152
- | (extra_options or {}),
1315
+ **merge(
1316
+ {
1317
+ "order": order,
1318
+ "mode": mode,
1319
+ "ppsrc": ppsrc,
1320
+ "field": field,
1321
+ "mchroma": mchroma,
1322
+ "y0": y0,
1323
+ "scthresh": scthresh,
1324
+ "combmatch": combmatch,
1325
+ "combdbg": combdbg,
1326
+ "cthresh": cthresh,
1327
+ "chroma": chroma,
1328
+ "blockx": blockx,
1329
+ "blocky": blocky,
1330
+ "combpel": combpel,
1331
+ },
1332
+ extra_options,
1333
+ ),
1153
1334
  )
1154
1335
  return filter_node.video(0)
1155
1336
 
1156
1337
 
1338
+ def flite(
1339
+ *,
1340
+ list_voices: Boolean = Default(False),
1341
+ nb_samples: Int = Default(512),
1342
+ text: String = Default(None),
1343
+ textfile: String = Default(None),
1344
+ v: String = Default("kal"),
1345
+ extra_options: dict[str, Any] | None = None,
1346
+ ) -> AudioStream:
1347
+ """
1348
+
1349
+ Synthesize voice from text using libflite.
1350
+
1351
+ Args:
1352
+ list_voices: list voices and exit (default false)
1353
+ nb_samples: set number of samples per frame (from 0 to INT_MAX) (default 512)
1354
+ text: set text to speak
1355
+ textfile: set filename of the text to speak
1356
+ v: set voice (default "kal")
1357
+
1358
+ Returns:
1359
+ default: the audio stream
1360
+
1361
+ References:
1362
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#flite)
1363
+
1364
+ """
1365
+ filter_node = filter_node_factory(
1366
+ FFMpegFilterDef(name="flite", typings_input=(), typings_output=("audio",)),
1367
+ **merge(
1368
+ {
1369
+ "list_voices": list_voices,
1370
+ "nb_samples": nb_samples,
1371
+ "text": text,
1372
+ "textfile": textfile,
1373
+ "v": v,
1374
+ },
1375
+ extra_options,
1376
+ ),
1377
+ )
1378
+ return filter_node.audio(0)
1379
+
1380
+
1157
1381
  def frei0r_src(
1158
1382
  *,
1159
1383
  size: Image_size = Default("320x240"),
1160
1384
  framerate: Video_rate = Default("25"),
1161
1385
  filter_name: String = Default(None),
1162
1386
  filter_params: String = Default(None),
1163
- extra_options: dict[str, Any] = None,
1387
+ extra_options: dict[str, Any] | None = None,
1164
1388
  ) -> VideoStream:
1165
1389
  """
1166
1390
 
@@ -1181,13 +1405,15 @@ def frei0r_src(
1181
1405
  """
1182
1406
  filter_node = filter_node_factory(
1183
1407
  FFMpegFilterDef(name="frei0r_src", typings_input=(), typings_output=("video",)),
1184
- **{
1185
- "size": size,
1186
- "framerate": framerate,
1187
- "filter_name": filter_name,
1188
- "filter_params": filter_params,
1189
- }
1190
- | (extra_options or {}),
1408
+ **merge(
1409
+ {
1410
+ "size": size,
1411
+ "framerate": framerate,
1412
+ "filter_name": filter_name,
1413
+ "filter_params": filter_params,
1414
+ },
1415
+ extra_options,
1416
+ ),
1191
1417
  )
1192
1418
  return filter_node.video(0)
1193
1419
 
@@ -1215,7 +1441,7 @@ def gradients(
1215
1441
  type: Int | Literal["linear", "radial", "circular", "spiral"] | Default = Default(
1216
1442
  "linear"
1217
1443
  ),
1218
- extra_options: dict[str, Any] = None,
1444
+ extra_options: dict[str, Any] | None = None,
1219
1445
  ) -> VideoStream:
1220
1446
  """
1221
1447
 
@@ -1251,28 +1477,30 @@ def gradients(
1251
1477
  """
1252
1478
  filter_node = filter_node_factory(
1253
1479
  FFMpegFilterDef(name="gradients", typings_input=(), typings_output=("video",)),
1254
- **{
1255
- "size": size,
1256
- "rate": rate,
1257
- "c0": c0,
1258
- "c1": c1,
1259
- "c2": c2,
1260
- "c3": c3,
1261
- "c4": c4,
1262
- "c5": c5,
1263
- "c6": c6,
1264
- "c7": c7,
1265
- "x0": x0,
1266
- "y0": y0,
1267
- "x1": x1,
1268
- "y1": y1,
1269
- "nb_colors": nb_colors,
1270
- "seed": seed,
1271
- "duration": duration,
1272
- "speed": speed,
1273
- "type": type,
1274
- }
1275
- | (extra_options or {}),
1480
+ **merge(
1481
+ {
1482
+ "size": size,
1483
+ "rate": rate,
1484
+ "c0": c0,
1485
+ "c1": c1,
1486
+ "c2": c2,
1487
+ "c3": c3,
1488
+ "c4": c4,
1489
+ "c5": c5,
1490
+ "c6": c6,
1491
+ "c7": c7,
1492
+ "x0": x0,
1493
+ "y0": y0,
1494
+ "x1": x1,
1495
+ "y1": y1,
1496
+ "nb_colors": nb_colors,
1497
+ "seed": seed,
1498
+ "duration": duration,
1499
+ "speed": speed,
1500
+ "type": type,
1501
+ },
1502
+ extra_options,
1503
+ ),
1276
1504
  )
1277
1505
  return filter_node.video(0)
1278
1506
 
@@ -1286,7 +1514,7 @@ def guided(
1286
1514
  guidance: Int | Literal["off", "on"] | Default = Default("off"),
1287
1515
  planes: Int = Default(1),
1288
1516
  enable: String = Default(None),
1289
- extra_options: dict[str, Any] = None,
1517
+ extra_options: dict[str, Any] | None = None,
1290
1518
  ) -> VideoStream:
1291
1519
  """
1292
1520
 
@@ -1315,16 +1543,18 @@ def guided(
1315
1543
  typings_output=("video",),
1316
1544
  ),
1317
1545
  *streams,
1318
- **{
1319
- "radius": radius,
1320
- "eps": eps,
1321
- "mode": mode,
1322
- "sub": sub,
1323
- "guidance": guidance,
1324
- "planes": planes,
1325
- "enable": enable,
1326
- }
1327
- | (extra_options or {}),
1546
+ **merge(
1547
+ {
1548
+ "radius": radius,
1549
+ "eps": eps,
1550
+ "mode": mode,
1551
+ "sub": sub,
1552
+ "guidance": guidance,
1553
+ "planes": planes,
1554
+ "enable": enable,
1555
+ },
1556
+ extra_options,
1557
+ ),
1328
1558
  )
1329
1559
  return filter_node.video(0)
1330
1560
 
@@ -1335,7 +1565,7 @@ def haldclutsrc(
1335
1565
  rate: Video_rate = Default("25"),
1336
1566
  duration: Duration = Default(-1e-06),
1337
1567
  sar: Rational = Default("1/1"),
1338
- extra_options: dict[str, Any] = None,
1568
+ extra_options: dict[str, Any] | None = None,
1339
1569
  ) -> VideoStream:
1340
1570
  """
1341
1571
 
@@ -1358,13 +1588,15 @@ def haldclutsrc(
1358
1588
  FFMpegFilterDef(
1359
1589
  name="haldclutsrc", typings_input=(), typings_output=("video",)
1360
1590
  ),
1361
- **{
1362
- "level": level,
1363
- "rate": rate,
1364
- "duration": duration,
1365
- "sar": sar,
1366
- }
1367
- | (extra_options or {}),
1591
+ **merge(
1592
+ {
1593
+ "level": level,
1594
+ "rate": rate,
1595
+ "duration": duration,
1596
+ "sar": sar,
1597
+ },
1598
+ extra_options,
1599
+ ),
1368
1600
  )
1369
1601
  return filter_node.video(0)
1370
1602
 
@@ -1377,7 +1609,7 @@ def headphone(
1377
1609
  type: Int | Literal["time", "freq"] | Default = Default("freq"),
1378
1610
  size: Int = Default(1024),
1379
1611
  hrir: Int | Literal["stereo", "multich"] | Default = Default("stereo"),
1380
- extra_options: dict[str, Any] = None,
1612
+ extra_options: dict[str, Any] | None = None,
1381
1613
  ) -> AudioStream:
1382
1614
  """
1383
1615
 
@@ -1405,15 +1637,17 @@ def headphone(
1405
1637
  typings_output=("audio",),
1406
1638
  ),
1407
1639
  *streams,
1408
- **{
1409
- "map": map,
1410
- "gain": gain,
1411
- "lfe": lfe,
1412
- "type": type,
1413
- "size": size,
1414
- "hrir": hrir,
1415
- }
1416
- | (extra_options or {}),
1640
+ **merge(
1641
+ {
1642
+ "map": map,
1643
+ "gain": gain,
1644
+ "lfe": lfe,
1645
+ "type": type,
1646
+ "size": size,
1647
+ "hrir": hrir,
1648
+ },
1649
+ extra_options,
1650
+ ),
1417
1651
  )
1418
1652
  return filter_node.audio(0)
1419
1653
 
@@ -1471,7 +1705,7 @@ def hilbert(
1471
1705
  "kaiser",
1472
1706
  ]
1473
1707
  | Default = Default("blackman"),
1474
- extra_options: dict[str, Any] = None,
1708
+ extra_options: dict[str, Any] | None = None,
1475
1709
  ) -> AudioStream:
1476
1710
  """
1477
1711
 
@@ -1492,13 +1726,15 @@ def hilbert(
1492
1726
  """
1493
1727
  filter_node = filter_node_factory(
1494
1728
  FFMpegFilterDef(name="hilbert", typings_input=(), typings_output=("audio",)),
1495
- **{
1496
- "sample_rate": sample_rate,
1497
- "taps": taps,
1498
- "nb_samples": nb_samples,
1499
- "win_func": win_func,
1500
- }
1501
- | (extra_options or {}),
1729
+ **merge(
1730
+ {
1731
+ "sample_rate": sample_rate,
1732
+ "taps": taps,
1733
+ "nb_samples": nb_samples,
1734
+ "win_func": win_func,
1735
+ },
1736
+ extra_options,
1737
+ ),
1502
1738
  )
1503
1739
  return filter_node.audio(0)
1504
1740
 
@@ -1507,7 +1743,7 @@ def hstack(
1507
1743
  *streams: VideoStream,
1508
1744
  inputs: Int = Auto("len(streams)"),
1509
1745
  shortest: Boolean = Default(False),
1510
- extra_options: dict[str, Any] = None,
1746
+ extra_options: dict[str, Any] | None = None,
1511
1747
  ) -> VideoStream:
1512
1748
  """
1513
1749
 
@@ -1531,11 +1767,55 @@ def hstack(
1531
1767
  typings_output=("video",),
1532
1768
  ),
1533
1769
  *streams,
1534
- **{
1535
- "inputs": inputs,
1536
- "shortest": shortest,
1537
- }
1538
- | (extra_options or {}),
1770
+ **merge(
1771
+ {
1772
+ "inputs": inputs,
1773
+ "shortest": shortest,
1774
+ },
1775
+ extra_options,
1776
+ ),
1777
+ )
1778
+ return filter_node.video(0)
1779
+
1780
+
1781
+ def hstack_vaapi(
1782
+ *streams: VideoStream,
1783
+ inputs: Int = Default(2),
1784
+ shortest: Boolean = Default(False),
1785
+ height: Int = Default(0),
1786
+ extra_options: dict[str, Any] | None = None,
1787
+ ) -> VideoStream:
1788
+ """
1789
+
1790
+ "VA-API" hstack
1791
+
1792
+ Args:
1793
+ inputs: Set number of inputs (from 2 to 65535) (default 2)
1794
+ shortest: Force termination when the shortest input terminates (default false)
1795
+ height: Set output height (0 to use the height of input 0) (from 0 to 65535) (default 0)
1796
+
1797
+ Returns:
1798
+ default: the video stream
1799
+
1800
+ References:
1801
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#hstack_005fvaapi)
1802
+
1803
+ """
1804
+ filter_node = filter_node_factory(
1805
+ FFMpegFilterDef(
1806
+ name="hstack_vaapi",
1807
+ typings_input="[StreamType.video] * int(inputs)",
1808
+ typings_output=("video",),
1809
+ ),
1810
+ *streams,
1811
+ **merge(
1812
+ {
1813
+ "inputs": inputs,
1814
+ "shortest": shortest,
1815
+ "height": height,
1816
+ },
1817
+ extra_options,
1818
+ ),
1539
1819
  )
1540
1820
  return filter_node.video(0)
1541
1821
 
@@ -1546,7 +1826,7 @@ def interleave(
1546
1826
  duration: Int | Literal["longest", "shortest", "first"] | Default = Default(
1547
1827
  "longest"
1548
1828
  ),
1549
- extra_options: dict[str, Any] = None,
1829
+ extra_options: dict[str, Any] | None = None,
1550
1830
  ) -> VideoStream:
1551
1831
  """
1552
1832
 
@@ -1570,11 +1850,13 @@ def interleave(
1570
1850
  typings_output=("video",),
1571
1851
  ),
1572
1852
  *streams,
1573
- **{
1574
- "nb_inputs": nb_inputs,
1575
- "duration": duration,
1576
- }
1577
- | (extra_options or {}),
1853
+ **merge(
1854
+ {
1855
+ "nb_inputs": nb_inputs,
1856
+ "duration": duration,
1857
+ },
1858
+ extra_options,
1859
+ ),
1578
1860
  )
1579
1861
  return filter_node.video(0)
1580
1862
 
@@ -1584,7 +1866,7 @@ def join(
1584
1866
  inputs: Int = Auto("len(streams)"),
1585
1867
  channel_layout: String = Default("stereo"),
1586
1868
  map: String = Default(None),
1587
- extra_options: dict[str, Any] = None,
1869
+ extra_options: dict[str, Any] | None = None,
1588
1870
  ) -> AudioStream:
1589
1871
  """
1590
1872
 
@@ -1609,16 +1891,425 @@ def join(
1609
1891
  typings_output=("audio",),
1610
1892
  ),
1611
1893
  *streams,
1612
- **{
1613
- "inputs": inputs,
1614
- "channel_layout": channel_layout,
1615
- "map": map,
1616
- }
1617
- | (extra_options or {}),
1894
+ **merge(
1895
+ {
1896
+ "inputs": inputs,
1897
+ "channel_layout": channel_layout,
1898
+ "map": map,
1899
+ },
1900
+ extra_options,
1901
+ ),
1902
+ )
1903
+ return filter_node.audio(0)
1904
+
1905
+
1906
+ def ladspa(
1907
+ *streams: AudioStream,
1908
+ file: String = Default(None),
1909
+ plugin: String = Default(None),
1910
+ controls: String = Default(None),
1911
+ sample_rate: Int = Default(44100),
1912
+ nb_samples: Int = Default(1024),
1913
+ duration: Duration = Default(-1e-06),
1914
+ latency: Boolean = Default(False),
1915
+ extra_options: dict[str, Any] | None = None,
1916
+ ) -> AudioStream:
1917
+ """
1918
+
1919
+ Apply LADSPA effect.
1920
+
1921
+ Args:
1922
+ file: set library name or full path
1923
+ plugin: set plugin name
1924
+ controls: set plugin options
1925
+ sample_rate: set sample rate (from 1 to INT_MAX) (default 44100)
1926
+ nb_samples: set the number of samples per requested frame (from 1 to INT_MAX) (default 1024)
1927
+ duration: set audio duration (default -0.000001)
1928
+ latency: enable latency compensation (default false)
1929
+
1930
+ Returns:
1931
+ default: the audio stream
1932
+
1933
+ References:
1934
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#ladspa)
1935
+
1936
+ """
1937
+ filter_node = filter_node_factory(
1938
+ FFMpegFilterDef(
1939
+ name="ladspa", typings_input="[StreamType.audio]", typings_output=("audio",)
1940
+ ),
1941
+ *streams,
1942
+ **merge(
1943
+ {
1944
+ "file": file,
1945
+ "plugin": plugin,
1946
+ "controls": controls,
1947
+ "sample_rate": sample_rate,
1948
+ "nb_samples": nb_samples,
1949
+ "duration": duration,
1950
+ "latency": latency,
1951
+ },
1952
+ extra_options,
1953
+ ),
1618
1954
  )
1619
1955
  return filter_node.audio(0)
1620
1956
 
1621
1957
 
1958
+ def libplacebo(
1959
+ *streams: VideoStream,
1960
+ inputs: Int = Auto("len(streams)"),
1961
+ w: String = Default("iw"),
1962
+ h: String = Default("ih"),
1963
+ fps: String = Default("none"),
1964
+ crop_x: String = Default("(iw-cw"),
1965
+ crop_y: String = Default("(ih-ch"),
1966
+ crop_w: String = Default("iw"),
1967
+ crop_h: String = Default("ih"),
1968
+ pos_x: String = Default("(ow-pw"),
1969
+ pos_y: String = Default("(oh-ph"),
1970
+ pos_w: String = Default("ow"),
1971
+ pos_h: String = Default("oh"),
1972
+ format: String = Default(None),
1973
+ force_original_aspect_ratio: Int
1974
+ | Literal["disable", "decrease", "increase"]
1975
+ | Default = Default("disable"),
1976
+ force_divisible_by: Int = Default(1),
1977
+ normalize_sar: Boolean = Default(False),
1978
+ pad_crop_ratio: Float = Default(0.0),
1979
+ fillcolor: String = Default("black"),
1980
+ corner_rounding: Float = Default(0.0),
1981
+ extra_opts: Dictionary = Default(None),
1982
+ colorspace: Int
1983
+ | Literal[
1984
+ "auto",
1985
+ "gbr",
1986
+ "bt709",
1987
+ "unknown",
1988
+ "bt470bg",
1989
+ "smpte170m",
1990
+ "smpte240m",
1991
+ "ycgco",
1992
+ "bt2020nc",
1993
+ "bt2020c",
1994
+ "ictcp",
1995
+ ]
1996
+ | Default = Default("auto"),
1997
+ range: Int
1998
+ | Literal[
1999
+ "auto", "unspecified", "unknown", "limited", "tv", "mpeg", "full", "pc", "jpeg"
2000
+ ]
2001
+ | Default = Default("auto"),
2002
+ color_primaries: Int
2003
+ | Literal[
2004
+ "auto",
2005
+ "bt709",
2006
+ "unknown",
2007
+ "bt470m",
2008
+ "bt470bg",
2009
+ "smpte170m",
2010
+ "smpte240m",
2011
+ "film",
2012
+ "bt2020",
2013
+ "smpte428",
2014
+ "smpte431",
2015
+ "smpte432",
2016
+ "p22",
2017
+ "ebu3213",
2018
+ ]
2019
+ | Default = Default("auto"),
2020
+ color_trc: Int
2021
+ | Literal[
2022
+ "auto",
2023
+ "bt709",
2024
+ "unknown",
2025
+ "bt470m",
2026
+ "bt470bg",
2027
+ "smpte170m",
2028
+ "smpte240m",
2029
+ "linear",
2030
+ "4",
2031
+ "bt1361e",
2032
+ "1",
2033
+ "10",
2034
+ "12",
2035
+ "smpte2084",
2036
+ "b67",
2037
+ ]
2038
+ | Default = Default("auto"),
2039
+ upscaler: String = Default("spline36"),
2040
+ downscaler: String = Default("mitchell"),
2041
+ frame_mixer: String = Default("none"),
2042
+ lut_entries: Int = Default(0),
2043
+ antiringing: Float = Default(0.0),
2044
+ sigmoid: Boolean = Default(True),
2045
+ apply_filmgrain: Boolean = Default(True),
2046
+ apply_dolbyvision: Boolean = Default(True),
2047
+ deband: Boolean = Default(False),
2048
+ deband_iterations: Int = Default(1),
2049
+ deband_threshold: Float = Default(4.0),
2050
+ deband_radius: Float = Default(16.0),
2051
+ deband_grain: Float = Default(6.0),
2052
+ brightness: Float = Default(0.0),
2053
+ contrast: Float = Default(1.0),
2054
+ saturation: Float = Default(1.0),
2055
+ hue: Float = Default(0.0),
2056
+ gamma: Float = Default(1.0),
2057
+ peak_detect: Boolean = Default(True),
2058
+ smoothing_period: Float = Default(100.0),
2059
+ minimum_peak: Float = Default(1.0),
2060
+ scene_threshold_low: Float = Default(5.5),
2061
+ scene_threshold_high: Float = Default(10.0),
2062
+ percentile: Float = Default(99.995),
2063
+ gamut_mode: Int
2064
+ | Literal[
2065
+ "clip",
2066
+ "perceptual",
2067
+ "relative",
2068
+ "saturation",
2069
+ "absolute",
2070
+ "desaturate",
2071
+ "darken",
2072
+ "warn",
2073
+ "linear",
2074
+ ]
2075
+ | Default = Default("perceptual"),
2076
+ tonemapping: Int
2077
+ | Literal[
2078
+ "auto",
2079
+ "clip",
2080
+ "40",
2081
+ "10",
2082
+ "2390",
2083
+ "2446a",
2084
+ "spline",
2085
+ "reinhard",
2086
+ "mobius",
2087
+ "hable",
2088
+ "gamma",
2089
+ "linear",
2090
+ ]
2091
+ | Default = Default("auto"),
2092
+ tonemapping_param: Float = Default(0.0),
2093
+ inverse_tonemapping: Boolean = Default(False),
2094
+ tonemapping_lut_size: Int = Default(256),
2095
+ contrast_recovery: Float = Default(0.3),
2096
+ contrast_smoothness: Float = Default(3.5),
2097
+ desaturation_strength: Float = Default(-1.0),
2098
+ desaturation_exponent: Float = Default(-1.0),
2099
+ gamut_warning: Boolean = Default(False),
2100
+ gamut_clipping: Boolean = Default(False),
2101
+ intent: Int
2102
+ | Literal["perceptual", "relative", "absolute", "saturation"]
2103
+ | Default = Default("perceptual"),
2104
+ tonemapping_mode: Int
2105
+ | Literal["auto", "rgb", "max", "hybrid", "luma"]
2106
+ | Default = Default("auto"),
2107
+ tonemapping_crosstalk: Float = Default(0.04),
2108
+ overshoot: Float = Default(0.05),
2109
+ hybrid_mix: Float = Default(0.2),
2110
+ dithering: Int
2111
+ | Literal["none", "blue", "ordered", "ordered_fixed", "white"]
2112
+ | Default = Default("blue"),
2113
+ dither_lut_size: Int = Default(6),
2114
+ dither_temporal: Boolean = Default(False),
2115
+ cones: Flags | Literal["l", "m", "s"] | Default = Default("0"),
2116
+ cone_strength: Float = Default(0.0),
2117
+ custom_shader_path: String = Default(None),
2118
+ custom_shader_bin: Binary = Default(None),
2119
+ skip_aa: Boolean = Default(False),
2120
+ polar_cutoff: Float = Default(0.0),
2121
+ disable_linear: Boolean = Default(False),
2122
+ disable_builtin: Boolean = Default(False),
2123
+ force_icc_lut: Boolean = Default(False),
2124
+ force_dither: Boolean = Default(False),
2125
+ disable_fbos: Boolean = Default(False),
2126
+ extra_options: dict[str, Any] | None = None,
2127
+ ) -> VideoStream:
2128
+ """
2129
+
2130
+ Apply various GPU filters from libplacebo
2131
+
2132
+ Args:
2133
+ inputs: Number of inputs (from 1 to INT_MAX) (default 1)
2134
+ w: Output video frame width (default "iw")
2135
+ h: Output video frame height (default "ih")
2136
+ fps: Output video frame rate (default "none")
2137
+ crop_x: Input video crop x (default "(iw-cw)/2")
2138
+ crop_y: Input video crop y (default "(ih-ch)/2")
2139
+ crop_w: Input video crop w (default "iw")
2140
+ crop_h: Input video crop h (default "ih")
2141
+ pos_x: Output video placement x (default "(ow-pw)/2")
2142
+ pos_y: Output video placement y (default "(oh-ph)/2")
2143
+ pos_w: Output video placement w (default "ow")
2144
+ pos_h: Output video placement h (default "oh")
2145
+ format: Output video format
2146
+ force_original_aspect_ratio: decrease or increase w/h if necessary to keep the original AR (from 0 to 2) (default disable)
2147
+ force_divisible_by: enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used (from 1 to 256) (default 1)
2148
+ normalize_sar: force SAR normalization to 1:1 by adjusting pos_x/y/w/h (default false)
2149
+ pad_crop_ratio: ratio between padding and cropping when normalizing SAR (0=pad, 1=crop) (from 0 to 1) (default 0)
2150
+ fillcolor: Background fill color (default "black")
2151
+ corner_rounding: Corner rounding radius (from 0 to 1) (default 0)
2152
+ extra_opts: Pass extra libplacebo-specific options using a :-separated list of key=value pairs
2153
+ colorspace: select colorspace (from -1 to 14) (default auto)
2154
+ range: select color range (from -1 to 2) (default auto)
2155
+ color_primaries: select color primaries (from -1 to 22) (default auto)
2156
+ color_trc: select color transfer (from -1 to 18) (default auto)
2157
+ upscaler: Upscaler function (default "spline36")
2158
+ downscaler: Downscaler function (default "mitchell")
2159
+ frame_mixer: Frame mixing function (default "none")
2160
+ lut_entries: Number of scaler LUT entries (from 0 to 256) (default 0)
2161
+ antiringing: Antiringing strength (for non-EWA filters) (from 0 to 1) (default 0)
2162
+ sigmoid: Enable sigmoid upscaling (default true)
2163
+ apply_filmgrain: Apply film grain metadata (default true)
2164
+ apply_dolbyvision: Apply Dolby Vision metadata (default true)
2165
+ deband: Enable debanding (default false)
2166
+ deband_iterations: Deband iterations (from 0 to 16) (default 1)
2167
+ deband_threshold: Deband threshold (from 0 to 1024) (default 4)
2168
+ deband_radius: Deband radius (from 0 to 1024) (default 16)
2169
+ deband_grain: Deband grain (from 0 to 1024) (default 6)
2170
+ brightness: Brightness boost (from -1 to 1) (default 0)
2171
+ contrast: Contrast gain (from 0 to 16) (default 1)
2172
+ saturation: Saturation gain (from 0 to 16) (default 1)
2173
+ hue: Hue shift (from -3.14159 to 3.14159) (default 0)
2174
+ gamma: Gamma adjustment (from 0 to 16) (default 1)
2175
+ peak_detect: Enable dynamic peak detection for HDR tone-mapping (default true)
2176
+ smoothing_period: Peak detection smoothing period (from 0 to 1000) (default 100)
2177
+ minimum_peak: Peak detection minimum peak (from 0 to 100) (default 1)
2178
+ scene_threshold_low: Scene change low threshold (from -1 to 100) (default 5.5)
2179
+ scene_threshold_high: Scene change high threshold (from -1 to 100) (default 10)
2180
+ percentile: Peak detection percentile (from 0 to 100) (default 99.995)
2181
+ gamut_mode: Gamut-mapping mode (from 0 to 8) (default perceptual)
2182
+ tonemapping: Tone-mapping algorithm (from 0 to 11) (default auto)
2183
+ tonemapping_param: Tunable parameter for some tone-mapping functions (from 0 to 100) (default 0)
2184
+ inverse_tonemapping: Inverse tone mapping (range expansion) (default false)
2185
+ tonemapping_lut_size: Tone-mapping LUT size (from 2 to 1024) (default 256)
2186
+ contrast_recovery: HDR contrast recovery strength (from 0 to 3) (default 0.3)
2187
+ contrast_smoothness: HDR contrast recovery smoothness (from 1 to 32) (default 3.5)
2188
+ desaturation_strength: Desaturation strength (from -1 to 1) (default -1)
2189
+ desaturation_exponent: Desaturation exponent (from -1 to 10) (default -1)
2190
+ gamut_warning: Highlight out-of-gamut colors (default false)
2191
+ gamut_clipping: Enable desaturating colorimetric gamut clipping (default false)
2192
+ intent: Rendering intent (from 0 to 3) (default perceptual)
2193
+ tonemapping_mode: Tone-mapping mode (from 0 to 4) (default auto)
2194
+ tonemapping_crosstalk: Crosstalk factor for tone-mapping (from 0 to 0.3) (default 0.04)
2195
+ overshoot: Tone-mapping overshoot margin (from 0 to 1) (default 0.05)
2196
+ hybrid_mix: Tone-mapping hybrid LMS mixing coefficient (from 0 to 1) (default 0.2)
2197
+ dithering: Dither method to use (from -1 to 3) (default blue)
2198
+ dither_lut_size: Dithering LUT size (from 1 to 8) (default 6)
2199
+ dither_temporal: Enable temporal dithering (default false)
2200
+ cones: Colorblindness adaptation model (default 0)
2201
+ cone_strength: Colorblindness adaptation strength (from 0 to 10) (default 0)
2202
+ custom_shader_path: Path to custom user shader (mpv .hook format)
2203
+ custom_shader_bin: Custom user shader as binary (mpv .hook format)
2204
+ skip_aa: Skip anti-aliasing (default false)
2205
+ polar_cutoff: Polar LUT cutoff (from 0 to 1) (default 0)
2206
+ disable_linear: Disable linear scaling (default false)
2207
+ disable_builtin: Disable built-in scalers (default false)
2208
+ force_icc_lut: Deprecated, does nothing (default false)
2209
+ force_dither: Force dithering (default false)
2210
+ disable_fbos: Force-disable FBOs (default false)
2211
+
2212
+ Returns:
2213
+ default: the video stream
2214
+
2215
+ References:
2216
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#libplacebo)
2217
+
2218
+ """
2219
+ filter_node = filter_node_factory(
2220
+ FFMpegFilterDef(
2221
+ name="libplacebo",
2222
+ typings_input="[StreamType.video] * int(inputs)",
2223
+ typings_output=("video",),
2224
+ ),
2225
+ *streams,
2226
+ **merge(
2227
+ {
2228
+ "inputs": inputs,
2229
+ "w": w,
2230
+ "h": h,
2231
+ "fps": fps,
2232
+ "crop_x": crop_x,
2233
+ "crop_y": crop_y,
2234
+ "crop_w": crop_w,
2235
+ "crop_h": crop_h,
2236
+ "pos_x": pos_x,
2237
+ "pos_y": pos_y,
2238
+ "pos_w": pos_w,
2239
+ "pos_h": pos_h,
2240
+ "format": format,
2241
+ "force_original_aspect_ratio": force_original_aspect_ratio,
2242
+ "force_divisible_by": force_divisible_by,
2243
+ "normalize_sar": normalize_sar,
2244
+ "pad_crop_ratio": pad_crop_ratio,
2245
+ "fillcolor": fillcolor,
2246
+ "corner_rounding": corner_rounding,
2247
+ "extra_opts": extra_opts,
2248
+ "colorspace": colorspace,
2249
+ "range": range,
2250
+ "color_primaries": color_primaries,
2251
+ "color_trc": color_trc,
2252
+ "upscaler": upscaler,
2253
+ "downscaler": downscaler,
2254
+ "frame_mixer": frame_mixer,
2255
+ "lut_entries": lut_entries,
2256
+ "antiringing": antiringing,
2257
+ "sigmoid": sigmoid,
2258
+ "apply_filmgrain": apply_filmgrain,
2259
+ "apply_dolbyvision": apply_dolbyvision,
2260
+ "deband": deband,
2261
+ "deband_iterations": deband_iterations,
2262
+ "deband_threshold": deband_threshold,
2263
+ "deband_radius": deband_radius,
2264
+ "deband_grain": deband_grain,
2265
+ "brightness": brightness,
2266
+ "contrast": contrast,
2267
+ "saturation": saturation,
2268
+ "hue": hue,
2269
+ "gamma": gamma,
2270
+ "peak_detect": peak_detect,
2271
+ "smoothing_period": smoothing_period,
2272
+ "minimum_peak": minimum_peak,
2273
+ "scene_threshold_low": scene_threshold_low,
2274
+ "scene_threshold_high": scene_threshold_high,
2275
+ "percentile": percentile,
2276
+ "gamut_mode": gamut_mode,
2277
+ "tonemapping": tonemapping,
2278
+ "tonemapping_param": tonemapping_param,
2279
+ "inverse_tonemapping": inverse_tonemapping,
2280
+ "tonemapping_lut_size": tonemapping_lut_size,
2281
+ "contrast_recovery": contrast_recovery,
2282
+ "contrast_smoothness": contrast_smoothness,
2283
+ "desaturation_strength": desaturation_strength,
2284
+ "desaturation_exponent": desaturation_exponent,
2285
+ "gamut_warning": gamut_warning,
2286
+ "gamut_clipping": gamut_clipping,
2287
+ "intent": intent,
2288
+ "tonemapping_mode": tonemapping_mode,
2289
+ "tonemapping_crosstalk": tonemapping_crosstalk,
2290
+ "overshoot": overshoot,
2291
+ "hybrid_mix": hybrid_mix,
2292
+ "dithering": dithering,
2293
+ "dither_lut_size": dither_lut_size,
2294
+ "dither_temporal": dither_temporal,
2295
+ "cones": cones,
2296
+ "cone-strength": cone_strength,
2297
+ "custom_shader_path": custom_shader_path,
2298
+ "custom_shader_bin": custom_shader_bin,
2299
+ "skip_aa": skip_aa,
2300
+ "polar_cutoff": polar_cutoff,
2301
+ "disable_linear": disable_linear,
2302
+ "disable_builtin": disable_builtin,
2303
+ "force_icc_lut": force_icc_lut,
2304
+ "force_dither": force_dither,
2305
+ "disable_fbos": disable_fbos,
2306
+ },
2307
+ extra_options,
2308
+ ),
2309
+ )
2310
+ return filter_node.video(0)
2311
+
2312
+
1622
2313
  def life(
1623
2314
  *,
1624
2315
  filename: String = Default(None),
@@ -1632,7 +2323,7 @@ def life(
1632
2323
  life_color: Color = Default("white"),
1633
2324
  death_color: Color = Default("black"),
1634
2325
  mold_color: Color = Default("black"),
1635
- extra_options: dict[str, Any] = None,
2326
+ extra_options: dict[str, Any] | None = None,
1636
2327
  ) -> VideoStream:
1637
2328
  """
1638
2329
 
@@ -1660,20 +2351,22 @@ def life(
1660
2351
  """
1661
2352
  filter_node = filter_node_factory(
1662
2353
  FFMpegFilterDef(name="life", typings_input=(), typings_output=("video",)),
1663
- **{
1664
- "filename": filename,
1665
- "size": size,
1666
- "rate": rate,
1667
- "rule": rule,
1668
- "random_fill_ratio": random_fill_ratio,
1669
- "random_seed": random_seed,
1670
- "stitch": stitch,
1671
- "mold": mold,
1672
- "life_color": life_color,
1673
- "death_color": death_color,
1674
- "mold_color": mold_color,
1675
- }
1676
- | (extra_options or {}),
2354
+ **merge(
2355
+ {
2356
+ "filename": filename,
2357
+ "size": size,
2358
+ "rate": rate,
2359
+ "rule": rule,
2360
+ "random_fill_ratio": random_fill_ratio,
2361
+ "random_seed": random_seed,
2362
+ "stitch": stitch,
2363
+ "mold": mold,
2364
+ "life_color": life_color,
2365
+ "death_color": death_color,
2366
+ "mold_color": mold_color,
2367
+ },
2368
+ extra_options,
2369
+ ),
1677
2370
  )
1678
2371
  return filter_node.video(0)
1679
2372
 
@@ -1685,7 +2378,7 @@ def limitdiff(
1685
2378
  reference: Boolean = Default(False),
1686
2379
  planes: Int = Default(15),
1687
2380
  enable: String = Default(None),
1688
- extra_options: dict[str, Any] = None,
2381
+ extra_options: dict[str, Any] | None = None,
1689
2382
  ) -> VideoStream:
1690
2383
  """
1691
2384
 
@@ -1712,18 +2405,66 @@ def limitdiff(
1712
2405
  typings_output=("video",),
1713
2406
  ),
1714
2407
  *streams,
1715
- **{
1716
- "threshold": threshold,
1717
- "elasticity": elasticity,
1718
- "reference": reference,
1719
- "planes": planes,
1720
- "enable": enable,
1721
- }
1722
- | (extra_options or {}),
2408
+ **merge(
2409
+ {
2410
+ "threshold": threshold,
2411
+ "elasticity": elasticity,
2412
+ "reference": reference,
2413
+ "planes": planes,
2414
+ "enable": enable,
2415
+ },
2416
+ extra_options,
2417
+ ),
1723
2418
  )
1724
2419
  return filter_node.video(0)
1725
2420
 
1726
2421
 
2422
+ def lv2(
2423
+ *streams: AudioStream,
2424
+ plugin: String = Default(None),
2425
+ controls: String = Default(None),
2426
+ sample_rate: Int = Default(44100),
2427
+ nb_samples: Int = Default(1024),
2428
+ duration: Duration = Default(-1e-06),
2429
+ extra_options: dict[str, Any] | None = None,
2430
+ ) -> AudioStream:
2431
+ """
2432
+
2433
+ Apply LV2 effect.
2434
+
2435
+ Args:
2436
+ plugin: set plugin uri
2437
+ controls: set plugin options
2438
+ sample_rate: set sample rate (from 1 to INT_MAX) (default 44100)
2439
+ nb_samples: set the number of samples per requested frame (from 1 to INT_MAX) (default 1024)
2440
+ duration: set audio duration (default -0.000001)
2441
+
2442
+ Returns:
2443
+ default: the audio stream
2444
+
2445
+ References:
2446
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#lv2)
2447
+
2448
+ """
2449
+ filter_node = filter_node_factory(
2450
+ FFMpegFilterDef(
2451
+ name="lv2", typings_input="[StreamType.audio]", typings_output=("audio",)
2452
+ ),
2453
+ *streams,
2454
+ **merge(
2455
+ {
2456
+ "plugin": plugin,
2457
+ "controls": controls,
2458
+ "sample_rate": sample_rate,
2459
+ "nb_samples": nb_samples,
2460
+ "duration": duration,
2461
+ },
2462
+ extra_options,
2463
+ ),
2464
+ )
2465
+ return filter_node.audio(0)
2466
+
2467
+
1727
2468
  def mandelbrot(
1728
2469
  *,
1729
2470
  size: Image_size = Default("640x480"),
@@ -1744,7 +2485,7 @@ def mandelbrot(
1744
2485
  inner: Int
1745
2486
  | Literal["black", "period", "convergence", "mincol"]
1746
2487
  | Default = Default("mincol"),
1747
- extra_options: dict[str, Any] = None,
2488
+ extra_options: dict[str, Any] | None = None,
1748
2489
  ) -> VideoStream:
1749
2490
  """
1750
2491
 
@@ -1775,23 +2516,25 @@ def mandelbrot(
1775
2516
  """
1776
2517
  filter_node = filter_node_factory(
1777
2518
  FFMpegFilterDef(name="mandelbrot", typings_input=(), typings_output=("video",)),
1778
- **{
1779
- "size": size,
1780
- "rate": rate,
1781
- "maxiter": maxiter,
1782
- "start_x": start_x,
1783
- "start_y": start_y,
1784
- "start_scale": start_scale,
1785
- "end_scale": end_scale,
1786
- "end_pts": end_pts,
1787
- "bailout": bailout,
1788
- "morphxf": morphxf,
1789
- "morphyf": morphyf,
1790
- "morphamp": morphamp,
1791
- "outer": outer,
1792
- "inner": inner,
1793
- }
1794
- | (extra_options or {}),
2519
+ **merge(
2520
+ {
2521
+ "size": size,
2522
+ "rate": rate,
2523
+ "maxiter": maxiter,
2524
+ "start_x": start_x,
2525
+ "start_y": start_y,
2526
+ "start_scale": start_scale,
2527
+ "end_scale": end_scale,
2528
+ "end_pts": end_pts,
2529
+ "bailout": bailout,
2530
+ "morphxf": morphxf,
2531
+ "morphyf": morphyf,
2532
+ "morphamp": morphamp,
2533
+ "outer": outer,
2534
+ "inner": inner,
2535
+ },
2536
+ extra_options,
2537
+ ),
1795
2538
  )
1796
2539
  return filter_node.video(0)
1797
2540
 
@@ -1808,7 +2551,7 @@ def mergeplanes(
1808
2551
  map2p: Int = Default(0),
1809
2552
  map3s: Int = Default(0),
1810
2553
  map3p: Int = Default(0),
1811
- extra_options: dict[str, Any] = None,
2554
+ extra_options: dict[str, Any] | None = None,
1812
2555
  ) -> VideoStream:
1813
2556
  """
1814
2557
 
@@ -1840,19 +2583,21 @@ def mergeplanes(
1840
2583
  typings_output=("video",),
1841
2584
  ),
1842
2585
  *streams,
1843
- **{
1844
- "mapping": mapping,
1845
- "format": format,
1846
- "map0s": map0s,
1847
- "map0p": map0p,
1848
- "map1s": map1s,
1849
- "map1p": map1p,
1850
- "map2s": map2s,
1851
- "map2p": map2p,
1852
- "map3s": map3s,
1853
- "map3p": map3p,
1854
- }
1855
- | (extra_options or {}),
2586
+ **merge(
2587
+ {
2588
+ "mapping": mapping,
2589
+ "format": format,
2590
+ "map0s": map0s,
2591
+ "map0p": map0p,
2592
+ "map1s": map1s,
2593
+ "map1p": map1p,
2594
+ "map2s": map2s,
2595
+ "map2p": map2p,
2596
+ "map3s": map3s,
2597
+ "map3p": map3p,
2598
+ },
2599
+ extra_options,
2600
+ ),
1856
2601
  )
1857
2602
  return filter_node.video(0)
1858
2603
 
@@ -1867,7 +2612,7 @@ def mix(
1867
2612
  "longest"
1868
2613
  ),
1869
2614
  enable: String = Default(None),
1870
- extra_options: dict[str, Any] = None,
2615
+ extra_options: dict[str, Any] | None = None,
1871
2616
  ) -> VideoStream:
1872
2617
  """
1873
2618
 
@@ -1895,15 +2640,17 @@ def mix(
1895
2640
  typings_output=("video",),
1896
2641
  ),
1897
2642
  *streams,
1898
- **{
1899
- "inputs": inputs,
1900
- "weights": weights,
1901
- "scale": scale,
1902
- "planes": planes,
1903
- "duration": duration,
1904
- "enable": enable,
1905
- }
1906
- | (extra_options or {}),
2643
+ **merge(
2644
+ {
2645
+ "inputs": inputs,
2646
+ "weights": weights,
2647
+ "scale": scale,
2648
+ "planes": planes,
2649
+ "duration": duration,
2650
+ "enable": enable,
2651
+ },
2652
+ extra_options,
2653
+ ),
1907
2654
  )
1908
2655
  return filter_node.video(0)
1909
2656
 
@@ -1919,7 +2666,7 @@ def movie(
1919
2666
  discontinuity: Duration = Default(0.0),
1920
2667
  dec_threads: Int = Default(0),
1921
2668
  format_opts: Dictionary = Default(None),
1922
- extra_options: dict[str, Any] = None,
2669
+ extra_options: dict[str, Any] | None = None,
1923
2670
  ) -> FilterNode:
1924
2671
  """
1925
2672
 
@@ -1950,18 +2697,20 @@ def movie(
1950
2697
  typings_input="[StreamType.video] * len(streams.split('+'))",
1951
2698
  typings_output="[StreamType.video] * len(streams.split('+'))",
1952
2699
  ),
1953
- **{
1954
- "filename": filename,
1955
- "format_name": format_name,
1956
- "stream_index": stream_index,
1957
- "seek_point": seek_point,
1958
- "streams": streams,
1959
- "loop": loop,
1960
- "discontinuity": discontinuity,
1961
- "dec_threads": dec_threads,
1962
- "format_opts": format_opts,
1963
- }
1964
- | (extra_options or {}),
2700
+ **merge(
2701
+ {
2702
+ "filename": filename,
2703
+ "format_name": format_name,
2704
+ "stream_index": stream_index,
2705
+ "seek_point": seek_point,
2706
+ "streams": streams,
2707
+ "loop": loop,
2708
+ "discontinuity": discontinuity,
2709
+ "dec_threads": dec_threads,
2710
+ "format_opts": format_opts,
2711
+ },
2712
+ extra_options,
2713
+ ),
1965
2714
  )
1966
2715
 
1967
2716
  return filter_node
@@ -1987,7 +2736,7 @@ def mptestsrc(
1987
2736
  ]
1988
2737
  | Default = Default("all"),
1989
2738
  max_frames: Int64 = Default(30),
1990
- extra_options: dict[str, Any] = None,
2739
+ extra_options: dict[str, Any] | None = None,
1991
2740
  ) -> VideoStream:
1992
2741
  """
1993
2742
 
@@ -2008,13 +2757,15 @@ def mptestsrc(
2008
2757
  """
2009
2758
  filter_node = filter_node_factory(
2010
2759
  FFMpegFilterDef(name="mptestsrc", typings_input=(), typings_output=("video",)),
2011
- **{
2012
- "rate": rate,
2013
- "duration": duration,
2014
- "test": test,
2015
- "max_frames": max_frames,
2016
- }
2017
- | (extra_options or {}),
2760
+ **merge(
2761
+ {
2762
+ "rate": rate,
2763
+ "duration": duration,
2764
+ "test": test,
2765
+ "max_frames": max_frames,
2766
+ },
2767
+ extra_options,
2768
+ ),
2018
2769
  )
2019
2770
  return filter_node.video(0)
2020
2771
 
@@ -2025,7 +2776,7 @@ def nullsrc(
2025
2776
  rate: Video_rate = Default("25"),
2026
2777
  duration: Duration = Default(-1e-06),
2027
2778
  sar: Rational = Default("1/1"),
2028
- extra_options: dict[str, Any] = None,
2779
+ extra_options: dict[str, Any] | None = None,
2029
2780
  ) -> VideoStream:
2030
2781
  """
2031
2782
 
@@ -2046,13 +2797,58 @@ def nullsrc(
2046
2797
  """
2047
2798
  filter_node = filter_node_factory(
2048
2799
  FFMpegFilterDef(name="nullsrc", typings_input=(), typings_output=("video",)),
2049
- **{
2050
- "size": size,
2051
- "rate": rate,
2052
- "duration": duration,
2053
- "sar": sar,
2054
- }
2055
- | (extra_options or {}),
2800
+ **merge(
2801
+ {
2802
+ "size": size,
2803
+ "rate": rate,
2804
+ "duration": duration,
2805
+ "sar": sar,
2806
+ },
2807
+ extra_options,
2808
+ ),
2809
+ )
2810
+ return filter_node.video(0)
2811
+
2812
+
2813
+ def openclsrc(
2814
+ *,
2815
+ source: String = Default(None),
2816
+ kernel: String = Default(None),
2817
+ size: Image_size = Default(None),
2818
+ format: Pix_fmt = Default("none"),
2819
+ rate: Video_rate = Default("25"),
2820
+ extra_options: dict[str, Any] | None = None,
2821
+ ) -> VideoStream:
2822
+ """
2823
+
2824
+ Generate video using an OpenCL program
2825
+
2826
+ Args:
2827
+ source: OpenCL program source file
2828
+ kernel: Kernel name in program
2829
+ size: Video size
2830
+ format: Video format (default none)
2831
+ rate: Video frame rate (default "25")
2832
+
2833
+ Returns:
2834
+ default: the video stream
2835
+
2836
+ References:
2837
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#openclsrc)
2838
+
2839
+ """
2840
+ filter_node = filter_node_factory(
2841
+ FFMpegFilterDef(name="openclsrc", typings_input=(), typings_output=("video",)),
2842
+ **merge(
2843
+ {
2844
+ "source": source,
2845
+ "kernel": kernel,
2846
+ "size": size,
2847
+ "format": format,
2848
+ "rate": rate,
2849
+ },
2850
+ extra_options,
2851
+ ),
2056
2852
  )
2057
2853
  return filter_node.video(0)
2058
2854
 
@@ -2063,7 +2859,7 @@ def pal100bars(
2063
2859
  rate: Video_rate = Default("25"),
2064
2860
  duration: Duration = Default(-1e-06),
2065
2861
  sar: Rational = Default("1/1"),
2066
- extra_options: dict[str, Any] = None,
2862
+ extra_options: dict[str, Any] | None = None,
2067
2863
  ) -> VideoStream:
2068
2864
  """
2069
2865
 
@@ -2084,13 +2880,15 @@ def pal100bars(
2084
2880
  """
2085
2881
  filter_node = filter_node_factory(
2086
2882
  FFMpegFilterDef(name="pal100bars", typings_input=(), typings_output=("video",)),
2087
- **{
2088
- "size": size,
2089
- "rate": rate,
2090
- "duration": duration,
2091
- "sar": sar,
2092
- }
2093
- | (extra_options or {}),
2883
+ **merge(
2884
+ {
2885
+ "size": size,
2886
+ "rate": rate,
2887
+ "duration": duration,
2888
+ "sar": sar,
2889
+ },
2890
+ extra_options,
2891
+ ),
2094
2892
  )
2095
2893
  return filter_node.video(0)
2096
2894
 
@@ -2101,7 +2899,7 @@ def pal75bars(
2101
2899
  rate: Video_rate = Default("25"),
2102
2900
  duration: Duration = Default(-1e-06),
2103
2901
  sar: Rational = Default("1/1"),
2104
- extra_options: dict[str, Any] = None,
2902
+ extra_options: dict[str, Any] | None = None,
2105
2903
  ) -> VideoStream:
2106
2904
  """
2107
2905
 
@@ -2122,13 +2920,15 @@ def pal75bars(
2122
2920
  """
2123
2921
  filter_node = filter_node_factory(
2124
2922
  FFMpegFilterDef(name="pal75bars", typings_input=(), typings_output=("video",)),
2125
- **{
2126
- "size": size,
2127
- "rate": rate,
2128
- "duration": duration,
2129
- "sar": sar,
2130
- }
2131
- | (extra_options or {}),
2923
+ **merge(
2924
+ {
2925
+ "size": size,
2926
+ "rate": rate,
2927
+ "duration": duration,
2928
+ "sar": sar,
2929
+ },
2930
+ extra_options,
2931
+ ),
2132
2932
  )
2133
2933
  return filter_node.video(0)
2134
2934
 
@@ -2138,7 +2938,7 @@ def premultiply(
2138
2938
  planes: Int = Default(15),
2139
2939
  inplace: Boolean = Default(False),
2140
2940
  enable: String = Default(None),
2141
- extra_options: dict[str, Any] = None,
2941
+ extra_options: dict[str, Any] | None = None,
2142
2942
  ) -> VideoStream:
2143
2943
  """
2144
2944
 
@@ -2163,12 +2963,71 @@ def premultiply(
2163
2963
  typings_output=("video",),
2164
2964
  ),
2165
2965
  *streams,
2166
- **{
2167
- "planes": planes,
2168
- "inplace": inplace,
2169
- "enable": enable,
2170
- }
2171
- | (extra_options or {}),
2966
+ **merge(
2967
+ {
2968
+ "planes": planes,
2969
+ "inplace": inplace,
2970
+ "enable": enable,
2971
+ },
2972
+ extra_options,
2973
+ ),
2974
+ )
2975
+ return filter_node.video(0)
2976
+
2977
+
2978
+ def program_opencl(
2979
+ *streams: VideoStream,
2980
+ source: String = Default(None),
2981
+ kernel: String = Default(None),
2982
+ inputs: Int = Default(1),
2983
+ size: Image_size = Default(None),
2984
+ eof_action: Int | Literal["repeat", "endall", "pass"] | Default = Default("repeat"),
2985
+ shortest: Boolean = Default(False),
2986
+ repeatlast: Boolean = Default(True),
2987
+ ts_sync_mode: Int | Literal["default", "nearest"] | Default = Default("default"),
2988
+ extra_options: dict[str, Any] | None = None,
2989
+ ) -> VideoStream:
2990
+ """
2991
+
2992
+ Filter video using an OpenCL program
2993
+
2994
+ Args:
2995
+ source: OpenCL program source file
2996
+ kernel: Kernel name in program
2997
+ inputs: Number of inputs (from 1 to INT_MAX) (default 1)
2998
+ size: Video size
2999
+ eof_action: Action to take when encountering EOF from secondary input (from 0 to 2) (default repeat)
3000
+ shortest: force termination when the shortest input terminates (default false)
3001
+ repeatlast: extend last frame of secondary streams beyond EOF (default true)
3002
+ ts_sync_mode: How strictly to sync streams based on secondary input timestamps (from 0 to 1) (default default)
3003
+
3004
+ Returns:
3005
+ default: the video stream
3006
+
3007
+ References:
3008
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#program_005fopencl)
3009
+
3010
+ """
3011
+ filter_node = filter_node_factory(
3012
+ FFMpegFilterDef(
3013
+ name="program_opencl",
3014
+ typings_input="[StreamType.video] * int(inputs)",
3015
+ typings_output=("video",),
3016
+ ),
3017
+ *streams,
3018
+ **merge(
3019
+ {
3020
+ "source": source,
3021
+ "kernel": kernel,
3022
+ "inputs": inputs,
3023
+ "size": size,
3024
+ "eof_action": eof_action,
3025
+ "shortest": shortest,
3026
+ "repeatlast": repeatlast,
3027
+ "ts_sync_mode": ts_sync_mode,
3028
+ },
3029
+ extra_options,
3030
+ ),
2172
3031
  )
2173
3032
  return filter_node.video(0)
2174
3033
 
@@ -2180,7 +3039,7 @@ def rgbtestsrc(
2180
3039
  duration: Duration = Default(-1e-06),
2181
3040
  sar: Rational = Default("1/1"),
2182
3041
  complement: Boolean = Default(False),
2183
- extra_options: dict[str, Any] = None,
3042
+ extra_options: dict[str, Any] | None = None,
2184
3043
  ) -> VideoStream:
2185
3044
  """
2186
3045
 
@@ -2202,14 +3061,16 @@ def rgbtestsrc(
2202
3061
  """
2203
3062
  filter_node = filter_node_factory(
2204
3063
  FFMpegFilterDef(name="rgbtestsrc", typings_input=(), typings_output=("video",)),
2205
- **{
2206
- "size": size,
2207
- "rate": rate,
2208
- "duration": duration,
2209
- "sar": sar,
2210
- "complement": complement,
2211
- }
2212
- | (extra_options or {}),
3064
+ **merge(
3065
+ {
3066
+ "size": size,
3067
+ "rate": rate,
3068
+ "duration": duration,
3069
+ "sar": sar,
3070
+ "complement": complement,
3071
+ },
3072
+ extra_options,
3073
+ ),
2213
3074
  )
2214
3075
  return filter_node.video(0)
2215
3076
 
@@ -2221,7 +3082,7 @@ def sierpinski(
2221
3082
  seed: Int64 = Default(-1),
2222
3083
  jump: Int = Default(100),
2223
3084
  type: Int | Literal["carpet", "triangle"] | Default = Default("carpet"),
2224
- extra_options: dict[str, Any] = None,
3085
+ extra_options: dict[str, Any] | None = None,
2225
3086
  ) -> VideoStream:
2226
3087
  """
2227
3088
 
@@ -2243,14 +3104,16 @@ def sierpinski(
2243
3104
  """
2244
3105
  filter_node = filter_node_factory(
2245
3106
  FFMpegFilterDef(name="sierpinski", typings_input=(), typings_output=("video",)),
2246
- **{
2247
- "size": size,
2248
- "rate": rate,
2249
- "seed": seed,
2250
- "jump": jump,
2251
- "type": type,
2252
- }
2253
- | (extra_options or {}),
3107
+ **merge(
3108
+ {
3109
+ "size": size,
3110
+ "rate": rate,
3111
+ "seed": seed,
3112
+ "jump": jump,
3113
+ "type": type,
3114
+ },
3115
+ extra_options,
3116
+ ),
2254
3117
  )
2255
3118
  return filter_node.video(0)
2256
3119
 
@@ -2266,7 +3129,7 @@ def signature(
2266
3129
  th_xh: Int = Default(116),
2267
3130
  th_di: Int = Default(0),
2268
3131
  th_it: Double = Default(0.5),
2269
- extra_options: dict[str, Any] = None,
3132
+ extra_options: dict[str, Any] | None = None,
2270
3133
  ) -> VideoStream:
2271
3134
  """
2272
3135
 
@@ -2297,18 +3160,20 @@ def signature(
2297
3160
  typings_output=("video",),
2298
3161
  ),
2299
3162
  *streams,
2300
- **{
2301
- "detectmode": detectmode,
2302
- "nb_inputs": nb_inputs,
2303
- "filename": filename,
2304
- "format": format,
2305
- "th_d": th_d,
2306
- "th_dc": th_dc,
2307
- "th_xh": th_xh,
2308
- "th_di": th_di,
2309
- "th_it": th_it,
2310
- }
2311
- | (extra_options or {}),
3163
+ **merge(
3164
+ {
3165
+ "detectmode": detectmode,
3166
+ "nb_inputs": nb_inputs,
3167
+ "filename": filename,
3168
+ "format": format,
3169
+ "th_d": th_d,
3170
+ "th_dc": th_dc,
3171
+ "th_xh": th_xh,
3172
+ "th_di": th_di,
3173
+ "th_it": th_it,
3174
+ },
3175
+ extra_options,
3176
+ ),
2312
3177
  )
2313
3178
  return filter_node.video(0)
2314
3179
 
@@ -2325,7 +3190,7 @@ def sinc(
2325
3190
  round: Boolean = Default(False),
2326
3191
  hptaps: Int = Default(0),
2327
3192
  lptaps: Int = Default(0),
2328
- extra_options: dict[str, Any] = None,
3193
+ extra_options: dict[str, Any] | None = None,
2329
3194
  ) -> AudioStream:
2330
3195
  """
2331
3196
 
@@ -2352,19 +3217,21 @@ def sinc(
2352
3217
  """
2353
3218
  filter_node = filter_node_factory(
2354
3219
  FFMpegFilterDef(name="sinc", typings_input=(), typings_output=("audio",)),
2355
- **{
2356
- "sample_rate": sample_rate,
2357
- "nb_samples": nb_samples,
2358
- "hp": hp,
2359
- "lp": lp,
2360
- "phase": phase,
2361
- "beta": beta,
2362
- "att": att,
2363
- "round": round,
2364
- "hptaps": hptaps,
2365
- "lptaps": lptaps,
2366
- }
2367
- | (extra_options or {}),
3220
+ **merge(
3221
+ {
3222
+ "sample_rate": sample_rate,
3223
+ "nb_samples": nb_samples,
3224
+ "hp": hp,
3225
+ "lp": lp,
3226
+ "phase": phase,
3227
+ "beta": beta,
3228
+ "att": att,
3229
+ "round": round,
3230
+ "hptaps": hptaps,
3231
+ "lptaps": lptaps,
3232
+ },
3233
+ extra_options,
3234
+ ),
2368
3235
  )
2369
3236
  return filter_node.audio(0)
2370
3237
 
@@ -2376,7 +3243,7 @@ def sine(
2376
3243
  sample_rate: Int = Default(44100),
2377
3244
  duration: Duration = Default(0.0),
2378
3245
  samples_per_frame: String = Default("1024"),
2379
- extra_options: dict[str, Any] = None,
3246
+ extra_options: dict[str, Any] | None = None,
2380
3247
  ) -> AudioStream:
2381
3248
  """
2382
3249
 
@@ -2398,14 +3265,16 @@ def sine(
2398
3265
  """
2399
3266
  filter_node = filter_node_factory(
2400
3267
  FFMpegFilterDef(name="sine", typings_input=(), typings_output=("audio",)),
2401
- **{
2402
- "frequency": frequency,
2403
- "beep_factor": beep_factor,
2404
- "sample_rate": sample_rate,
2405
- "duration": duration,
2406
- "samples_per_frame": samples_per_frame,
2407
- }
2408
- | (extra_options or {}),
3268
+ **merge(
3269
+ {
3270
+ "frequency": frequency,
3271
+ "beep_factor": beep_factor,
3272
+ "sample_rate": sample_rate,
3273
+ "duration": duration,
3274
+ "samples_per_frame": samples_per_frame,
3275
+ },
3276
+ extra_options,
3277
+ ),
2409
3278
  )
2410
3279
  return filter_node.audio(0)
2411
3280
 
@@ -2416,7 +3285,7 @@ def smptebars(
2416
3285
  rate: Video_rate = Default("25"),
2417
3286
  duration: Duration = Default(-1e-06),
2418
3287
  sar: Rational = Default("1/1"),
2419
- extra_options: dict[str, Any] = None,
3288
+ extra_options: dict[str, Any] | None = None,
2420
3289
  ) -> VideoStream:
2421
3290
  """
2422
3291
 
@@ -2437,13 +3306,15 @@ def smptebars(
2437
3306
  """
2438
3307
  filter_node = filter_node_factory(
2439
3308
  FFMpegFilterDef(name="smptebars", typings_input=(), typings_output=("video",)),
2440
- **{
2441
- "size": size,
2442
- "rate": rate,
2443
- "duration": duration,
2444
- "sar": sar,
2445
- }
2446
- | (extra_options or {}),
3309
+ **merge(
3310
+ {
3311
+ "size": size,
3312
+ "rate": rate,
3313
+ "duration": duration,
3314
+ "sar": sar,
3315
+ },
3316
+ extra_options,
3317
+ ),
2447
3318
  )
2448
3319
  return filter_node.video(0)
2449
3320
 
@@ -2454,7 +3325,7 @@ def smptehdbars(
2454
3325
  rate: Video_rate = Default("25"),
2455
3326
  duration: Duration = Default(-1e-06),
2456
3327
  sar: Rational = Default("1/1"),
2457
- extra_options: dict[str, Any] = None,
3328
+ extra_options: dict[str, Any] | None = None,
2458
3329
  ) -> VideoStream:
2459
3330
  """
2460
3331
 
@@ -2477,13 +3348,15 @@ def smptehdbars(
2477
3348
  FFMpegFilterDef(
2478
3349
  name="smptehdbars", typings_input=(), typings_output=("video",)
2479
3350
  ),
2480
- **{
2481
- "size": size,
2482
- "rate": rate,
2483
- "duration": duration,
2484
- "sar": sar,
2485
- }
2486
- | (extra_options or {}),
3351
+ **merge(
3352
+ {
3353
+ "size": size,
3354
+ "rate": rate,
3355
+ "duration": duration,
3356
+ "sar": sar,
3357
+ },
3358
+ extra_options,
3359
+ ),
2487
3360
  )
2488
3361
  return filter_node.video(0)
2489
3362
 
@@ -2492,7 +3365,7 @@ def streamselect(
2492
3365
  *streams: VideoStream,
2493
3366
  inputs: Int = Auto("len(streams)"),
2494
3367
  map: String = Default(None),
2495
- extra_options: dict[str, Any] = None,
3368
+ extra_options: dict[str, Any] | None = None,
2496
3369
  ) -> FilterNode:
2497
3370
  """
2498
3371
 
@@ -2517,11 +3390,13 @@ def streamselect(
2517
3390
  typings_output="[StreamType.video] * len(re.findall(r'\\d+', str(map)))",
2518
3391
  ),
2519
3392
  *streams,
2520
- **{
2521
- "inputs": inputs,
2522
- "map": map,
2523
- }
2524
- | (extra_options or {}),
3393
+ **merge(
3394
+ {
3395
+ "inputs": inputs,
3396
+ "map": map,
3397
+ },
3398
+ extra_options,
3399
+ ),
2525
3400
  )
2526
3401
 
2527
3402
  return filter_node
@@ -2534,7 +3409,7 @@ def testsrc(
2534
3409
  duration: Duration = Default(-1e-06),
2535
3410
  sar: Rational = Default("1/1"),
2536
3411
  decimals: Int = Default(0),
2537
- extra_options: dict[str, Any] = None,
3412
+ extra_options: dict[str, Any] | None = None,
2538
3413
  ) -> VideoStream:
2539
3414
  """
2540
3415
 
@@ -2556,14 +3431,16 @@ def testsrc(
2556
3431
  """
2557
3432
  filter_node = filter_node_factory(
2558
3433
  FFMpegFilterDef(name="testsrc", typings_input=(), typings_output=("video",)),
2559
- **{
2560
- "size": size,
2561
- "rate": rate,
2562
- "duration": duration,
2563
- "sar": sar,
2564
- "decimals": decimals,
2565
- }
2566
- | (extra_options or {}),
3434
+ **merge(
3435
+ {
3436
+ "size": size,
3437
+ "rate": rate,
3438
+ "duration": duration,
3439
+ "sar": sar,
3440
+ "decimals": decimals,
3441
+ },
3442
+ extra_options,
3443
+ ),
2567
3444
  )
2568
3445
  return filter_node.video(0)
2569
3446
 
@@ -2575,7 +3452,7 @@ def testsrc2(
2575
3452
  duration: Duration = Default(-1e-06),
2576
3453
  sar: Rational = Default("1/1"),
2577
3454
  alpha: Int = Default(255),
2578
- extra_options: dict[str, Any] = None,
3455
+ extra_options: dict[str, Any] | None = None,
2579
3456
  ) -> VideoStream:
2580
3457
  """
2581
3458
 
@@ -2597,14 +3474,16 @@ def testsrc2(
2597
3474
  """
2598
3475
  filter_node = filter_node_factory(
2599
3476
  FFMpegFilterDef(name="testsrc2", typings_input=(), typings_output=("video",)),
2600
- **{
2601
- "size": size,
2602
- "rate": rate,
2603
- "duration": duration,
2604
- "sar": sar,
2605
- "alpha": alpha,
2606
- }
2607
- | (extra_options or {}),
3477
+ **merge(
3478
+ {
3479
+ "size": size,
3480
+ "rate": rate,
3481
+ "duration": duration,
3482
+ "sar": sar,
3483
+ "alpha": alpha,
3484
+ },
3485
+ extra_options,
3486
+ ),
2608
3487
  )
2609
3488
  return filter_node.video(0)
2610
3489
 
@@ -2614,7 +3493,7 @@ def unpremultiply(
2614
3493
  planes: Int = Default(15),
2615
3494
  inplace: Boolean = Default(False),
2616
3495
  enable: String = Default(None),
2617
- extra_options: dict[str, Any] = None,
3496
+ extra_options: dict[str, Any] | None = None,
2618
3497
  ) -> VideoStream:
2619
3498
  """
2620
3499
 
@@ -2639,12 +3518,14 @@ def unpremultiply(
2639
3518
  typings_output=("video",),
2640
3519
  ),
2641
3520
  *streams,
2642
- **{
2643
- "planes": planes,
2644
- "inplace": inplace,
2645
- "enable": enable,
2646
- }
2647
- | (extra_options or {}),
3521
+ **merge(
3522
+ {
3523
+ "planes": planes,
3524
+ "inplace": inplace,
3525
+ "enable": enable,
3526
+ },
3527
+ extra_options,
3528
+ ),
2648
3529
  )
2649
3530
  return filter_node.video(0)
2650
3531
 
@@ -2653,7 +3534,7 @@ def vstack(
2653
3534
  *streams: VideoStream,
2654
3535
  inputs: Int = Auto("len(streams)"),
2655
3536
  shortest: Boolean = Default(False),
2656
- extra_options: dict[str, Any] = None,
3537
+ extra_options: dict[str, Any] | None = None,
2657
3538
  ) -> VideoStream:
2658
3539
  """
2659
3540
 
@@ -2677,11 +3558,55 @@ def vstack(
2677
3558
  typings_output=("video",),
2678
3559
  ),
2679
3560
  *streams,
2680
- **{
2681
- "inputs": inputs,
2682
- "shortest": shortest,
2683
- }
2684
- | (extra_options or {}),
3561
+ **merge(
3562
+ {
3563
+ "inputs": inputs,
3564
+ "shortest": shortest,
3565
+ },
3566
+ extra_options,
3567
+ ),
3568
+ )
3569
+ return filter_node.video(0)
3570
+
3571
+
3572
+ def vstack_vaapi(
3573
+ *streams: VideoStream,
3574
+ inputs: Int = Default(2),
3575
+ shortest: Boolean = Default(False),
3576
+ width: Int = Default(0),
3577
+ extra_options: dict[str, Any] | None = None,
3578
+ ) -> VideoStream:
3579
+ """
3580
+
3581
+ "VA-API" vstack
3582
+
3583
+ Args:
3584
+ inputs: Set number of inputs (from 2 to 65535) (default 2)
3585
+ shortest: Force termination when the shortest input terminates (default false)
3586
+ width: Set output width (0 to use the width of input 0) (from 0 to 65535) (default 0)
3587
+
3588
+ Returns:
3589
+ default: the video stream
3590
+
3591
+ References:
3592
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#vstack_005fvaapi)
3593
+
3594
+ """
3595
+ filter_node = filter_node_factory(
3596
+ FFMpegFilterDef(
3597
+ name="vstack_vaapi",
3598
+ typings_input="[StreamType.video] * int(inputs)",
3599
+ typings_output=("video",),
3600
+ ),
3601
+ *streams,
3602
+ **merge(
3603
+ {
3604
+ "inputs": inputs,
3605
+ "shortest": shortest,
3606
+ "width": width,
3607
+ },
3608
+ extra_options,
3609
+ ),
2685
3610
  )
2686
3611
  return filter_node.video(0)
2687
3612
 
@@ -2696,7 +3621,7 @@ def xmedian(
2696
3621
  repeatlast: Boolean = Default(True),
2697
3622
  ts_sync_mode: Int | Literal["default", "nearest"] | Default = Default("default"),
2698
3623
  enable: String = Default(None),
2699
- extra_options: dict[str, Any] = None,
3624
+ extra_options: dict[str, Any] | None = None,
2700
3625
  ) -> VideoStream:
2701
3626
  """
2702
3627
 
@@ -2726,17 +3651,19 @@ def xmedian(
2726
3651
  typings_output=("video",),
2727
3652
  ),
2728
3653
  *streams,
2729
- **{
2730
- "inputs": inputs,
2731
- "planes": planes,
2732
- "percentile": percentile,
2733
- "eof_action": eof_action,
2734
- "shortest": shortest,
2735
- "repeatlast": repeatlast,
2736
- "ts_sync_mode": ts_sync_mode,
2737
- "enable": enable,
2738
- }
2739
- | (extra_options or {}),
3654
+ **merge(
3655
+ {
3656
+ "inputs": inputs,
3657
+ "planes": planes,
3658
+ "percentile": percentile,
3659
+ "eof_action": eof_action,
3660
+ "shortest": shortest,
3661
+ "repeatlast": repeatlast,
3662
+ "ts_sync_mode": ts_sync_mode,
3663
+ "enable": enable,
3664
+ },
3665
+ extra_options,
3666
+ ),
2740
3667
  )
2741
3668
  return filter_node.video(0)
2742
3669
 
@@ -2748,7 +3675,7 @@ def xstack(
2748
3675
  grid: Image_size = Default(None),
2749
3676
  shortest: Boolean = Default(False),
2750
3677
  fill: String = Default("none"),
2751
- extra_options: dict[str, Any] = None,
3678
+ extra_options: dict[str, Any] | None = None,
2752
3679
  ) -> VideoStream:
2753
3680
  """
2754
3681
 
@@ -2775,14 +3702,67 @@ def xstack(
2775
3702
  typings_output=("video",),
2776
3703
  ),
2777
3704
  *streams,
2778
- **{
2779
- "inputs": inputs,
2780
- "layout": layout,
2781
- "grid": grid,
2782
- "shortest": shortest,
2783
- "fill": fill,
2784
- }
2785
- | (extra_options or {}),
3705
+ **merge(
3706
+ {
3707
+ "inputs": inputs,
3708
+ "layout": layout,
3709
+ "grid": grid,
3710
+ "shortest": shortest,
3711
+ "fill": fill,
3712
+ },
3713
+ extra_options,
3714
+ ),
3715
+ )
3716
+ return filter_node.video(0)
3717
+
3718
+
3719
+ def xstack_vaapi(
3720
+ *streams: VideoStream,
3721
+ inputs: Int = Default(2),
3722
+ shortest: Boolean = Default(False),
3723
+ layout: String = Default(None),
3724
+ grid: Image_size = Default(None),
3725
+ grid_tile_size: Image_size = Default(None),
3726
+ fill: String = Default("none"),
3727
+ extra_options: dict[str, Any] | None = None,
3728
+ ) -> VideoStream:
3729
+ """
3730
+
3731
+ "VA-API" xstack
3732
+
3733
+ Args:
3734
+ inputs: Set number of inputs (from 2 to 65535) (default 2)
3735
+ shortest: Force termination when the shortest input terminates (default false)
3736
+ layout: Set custom layout
3737
+ grid: set fixed size grid layout
3738
+ grid_tile_size: set tile size in grid layout
3739
+ fill: Set the color for unused pixels (default "none")
3740
+
3741
+ Returns:
3742
+ default: the video stream
3743
+
3744
+ References:
3745
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#xstack_005fvaapi)
3746
+
3747
+ """
3748
+ filter_node = filter_node_factory(
3749
+ FFMpegFilterDef(
3750
+ name="xstack_vaapi",
3751
+ typings_input="[StreamType.video] * int(inputs)",
3752
+ typings_output=("video",),
3753
+ ),
3754
+ *streams,
3755
+ **merge(
3756
+ {
3757
+ "inputs": inputs,
3758
+ "shortest": shortest,
3759
+ "layout": layout,
3760
+ "grid": grid,
3761
+ "grid_tile_size": grid_tile_size,
3762
+ "fill": fill,
3763
+ },
3764
+ extra_options,
3765
+ ),
2786
3766
  )
2787
3767
  return filter_node.video(0)
2788
3768
 
@@ -2793,7 +3773,7 @@ def yuvtestsrc(
2793
3773
  rate: Video_rate = Default("25"),
2794
3774
  duration: Duration = Default(-1e-06),
2795
3775
  sar: Rational = Default("1/1"),
2796
- extra_options: dict[str, Any] = None,
3776
+ extra_options: dict[str, Any] | None = None,
2797
3777
  ) -> VideoStream:
2798
3778
  """
2799
3779
 
@@ -2814,12 +3794,102 @@ def yuvtestsrc(
2814
3794
  """
2815
3795
  filter_node = filter_node_factory(
2816
3796
  FFMpegFilterDef(name="yuvtestsrc", typings_input=(), typings_output=("video",)),
2817
- **{
2818
- "size": size,
2819
- "rate": rate,
2820
- "duration": duration,
2821
- "sar": sar,
2822
- }
2823
- | (extra_options or {}),
3797
+ **merge(
3798
+ {
3799
+ "size": size,
3800
+ "rate": rate,
3801
+ "duration": duration,
3802
+ "sar": sar,
3803
+ },
3804
+ extra_options,
3805
+ ),
3806
+ )
3807
+ return filter_node.video(0)
3808
+
3809
+
3810
+ def zoneplate(
3811
+ *,
3812
+ size: Image_size = Default("320x240"),
3813
+ rate: Video_rate = Default("25"),
3814
+ duration: Duration = Default(-1e-06),
3815
+ sar: Rational = Default("1/1"),
3816
+ precision: Int = Default(10),
3817
+ xo: Int = Default(0),
3818
+ yo: Int = Default(0),
3819
+ to: Int = Default(0),
3820
+ k0: Int = Default(0),
3821
+ kx: Int = Default(0),
3822
+ ky: Int = Default(0),
3823
+ kt: Int = Default(0),
3824
+ kxt: Int = Default(0),
3825
+ kyt: Int = Default(0),
3826
+ kxy: Int = Default(0),
3827
+ kx2: Int = Default(0),
3828
+ ky2: Int = Default(0),
3829
+ kt2: Int = Default(0),
3830
+ ku: Int = Default(0),
3831
+ kv: Int = Default(0),
3832
+ extra_options: dict[str, Any] | None = None,
3833
+ ) -> VideoStream:
3834
+ """
3835
+
3836
+ Generate zone-plate.
3837
+
3838
+ Args:
3839
+ size: set video size (default "320x240")
3840
+ rate: set video rate (default "25")
3841
+ duration: set video duration (default -0.000001)
3842
+ sar: set video sample aspect ratio (from 0 to INT_MAX) (default 1/1)
3843
+ precision: set LUT precision (from 4 to 16) (default 10)
3844
+ xo: set X-axis offset (from INT_MIN to INT_MAX) (default 0)
3845
+ yo: set Y-axis offset (from INT_MIN to INT_MAX) (default 0)
3846
+ to: set T-axis offset (from INT_MIN to INT_MAX) (default 0)
3847
+ k0: set 0-order phase (from INT_MIN to INT_MAX) (default 0)
3848
+ kx: set 1-order X-axis phase (from INT_MIN to INT_MAX) (default 0)
3849
+ ky: set 1-order Y-axis phase (from INT_MIN to INT_MAX) (default 0)
3850
+ kt: set 1-order T-axis phase (from INT_MIN to INT_MAX) (default 0)
3851
+ kxt: set X-axis*T-axis product phase (from INT_MIN to INT_MAX) (default 0)
3852
+ kyt: set Y-axis*T-axis product phase (from INT_MIN to INT_MAX) (default 0)
3853
+ kxy: set X-axis*Y-axis product phase (from INT_MIN to INT_MAX) (default 0)
3854
+ kx2: set 2-order X-axis phase (from INT_MIN to INT_MAX) (default 0)
3855
+ ky2: set 2-order Y-axis phase (from INT_MIN to INT_MAX) (default 0)
3856
+ kt2: set 2-order T-axis phase (from INT_MIN to INT_MAX) (default 0)
3857
+ ku: set 0-order U-color phase (from INT_MIN to INT_MAX) (default 0)
3858
+ kv: set 0-order V-color phase (from INT_MIN to INT_MAX) (default 0)
3859
+
3860
+ Returns:
3861
+ default: the video stream
3862
+
3863
+ References:
3864
+ [FFmpeg Documentation](https://ffmpeg.org/ffmpeg-filters.html#zoneplate)
3865
+
3866
+ """
3867
+ filter_node = filter_node_factory(
3868
+ FFMpegFilterDef(name="zoneplate", typings_input=(), typings_output=("video",)),
3869
+ **merge(
3870
+ {
3871
+ "size": size,
3872
+ "rate": rate,
3873
+ "duration": duration,
3874
+ "sar": sar,
3875
+ "precision": precision,
3876
+ "xo": xo,
3877
+ "yo": yo,
3878
+ "to": to,
3879
+ "k0": k0,
3880
+ "kx": kx,
3881
+ "ky": ky,
3882
+ "kt": kt,
3883
+ "kxt": kxt,
3884
+ "kyt": kyt,
3885
+ "kxy": kxy,
3886
+ "kx2": kx2,
3887
+ "ky2": ky2,
3888
+ "kt2": kt2,
3889
+ "ku": ku,
3890
+ "kv": kv,
3891
+ },
3892
+ extra_options,
3893
+ ),
2824
3894
  )
2825
3895
  return filter_node.video(0)