11from __future__ import unicode_literals
22
3- from .nodes import FilterNode , operator
3+ from .nodes import FilterNode , filter_operator
44from ._utils import escape_chars
55
66
7- @operator ()
8- def filter_ ( parent_node , filter_name , * args , ** kwargs ):
9- """Apply custom single-source filter.
7+ @filter_operator ()
8+ def filter_multi_output ( stream_spec , filter_name , * args , ** kwargs ):
9+ """Apply custom filter with one or more outputs .
1010
11- ``filter_`` is normally used by higher-level filter functions such as ``hflip``, but if a filter implementation
12- is missing from ``fmpeg-python``, you can call ``filter_`` directly to have ``fmpeg-python`` pass the filter name
13- and arguments to ffmpeg verbatim.
14-
15- Args:
16- parent_node: Source stream to apply filter to.
17- filter_name: ffmpeg filter name, e.g. `colorchannelmixer`
18- *args: list of args to pass to ffmpeg verbatim
19- **kwargs: list of keyword-args to pass to ffmpeg verbatim
11+ This is the same as ``filter_`` except that the filter can produce more than one output.
2012
21- This function is used internally by all of the other single-source filters (e.g. ``hflip``, ``crop``, etc.).
22- For custom multi-source filters, see ``filter_multi`` instead.
23-
24- The function name is suffixed with ``_`` in order avoid confusion with the standard python ``filter`` function.
13+ To reference an output stream, use either the ``.stream`` operator or bracket shorthand:
2514
2615 Example:
2716
28- ``ffmpeg.input('in.mp4').filter_('hflip').output('out.mp4').run()``
17+ ```
18+ split = ffmpeg.input('in.mp4').filter_multi_output('split')
19+ split0 = split.stream(0)
20+ split1 = split[1]
21+ ffmpeg.concat(split0, split1).output('out.mp4').run()
22+ ```
2923 """
30- return FilterNode ([parent_node ], filter_name , * args , ** kwargs )
31-
24+ return FilterNode (stream_spec , filter_name , args = args , kwargs = kwargs , max_inputs = None )
3225
33- def filter_multi (parent_nodes , filter_name , * args , ** kwargs ):
34- """Apply custom multi-source filter.
3526
36- This is nearly identical to the ``filter`` function except that it allows filters to be applied to multiple
37- streams. It's normally used by higher-level filter functions such as ``concat``, but if a filter implementation
38- is missing from ``fmpeg-python``, you can call ``filter_multi`` directly .
27+ @ filter_operator ()
28+ def filter_ ( stream_spec , filter_name , * args , ** kwargs ):
29+ """Apply custom filter .
3930
40- Note that because it applies to multiple streams, it can't be used as an operator, unlike the ``filter`` function
41- (e.g. ``ffmpeg.input('in.mp4').filter_('hflip')``)
31+ ``filter_`` is normally used by higher-level filter functions such as ``hflip``, but if a filter implementation
32+ is missing from ``fmpeg-python``, you can call ``filter_`` directly to have ``fmpeg-python`` pass the filter name
33+ and arguments to ffmpeg verbatim.
4234
4335 Args:
44- parent_nodes: List of source streams to apply filter to.
45- filter_name: ffmpeg filter name, e.g. `concat `
36+ stream_spec: a Stream, list of Streams, or label-to-Stream dictionary mapping
37+ filter_name: ffmpeg filter name, e.g. `colorchannelmixer `
4638 *args: list of args to pass to ffmpeg verbatim
4739 **kwargs: list of keyword-args to pass to ffmpeg verbatim
4840
49- For custom single-source filters, see ``filter_multi `` instead .
41+ The function name is suffixed with ``_ `` in order avoid confusion with the standard python ``filter`` function .
5042
5143 Example:
5244
53- ``ffmpeg.filter_multi(ffmpeg. input('in1 .mp4'), ffmpeg.input('in2.mp4'), 'concat', n=2 ).output('out.mp4').run()``
45+ ``ffmpeg.input('in .mp4').filter_('hflip' ).output('out.mp4').run()``
5446 """
55- return FilterNode (parent_nodes , filter_name , * args , ** kwargs )
47+ return filter_multi_output (stream_spec , filter_name , * args , ** kwargs ).stream ()
48+
5649
50+ @filter_operator ()
51+ def split (stream ):
52+ return FilterNode (stream , split .__name__ )
5753
5854
59- @operator ()
60- def setpts (parent_node , expr ):
55+ @filter_operator ()
56+ def setpts (stream , expr ):
6157 """Change the PTS (presentation timestamp) of the input frames.
6258
6359 Args:
6460 expr: The expression which is evaluated for each frame to construct its timestamp.
6561
6662 Official documentation: `setpts, asetpts <https://ffmpeg.org/ffmpeg-filters.html#setpts_002c-asetpts>`__
6763 """
68- return filter_ ( parent_node , setpts .__name__ , expr )
64+ return FilterNode ( stream , setpts .__name__ , args = [ expr ]). stream ( )
6965
7066
71- @operator ()
72- def trim (parent_node , ** kwargs ):
67+ @filter_operator ()
68+ def trim (stream , ** kwargs ):
7369 """Trim the input so that the output contains one continuous subpart of the input.
7470
7571 Args:
@@ -87,10 +83,10 @@ def trim(parent_node, **kwargs):
8783
8884 Official documentation: `trim <https://ffmpeg.org/ffmpeg-filters.html#trim>`__
8985 """
90- return filter_ ( parent_node , trim .__name__ , ** kwargs )
86+ return FilterNode ( stream , trim .__name__ , kwargs = kwargs ). stream ( )
9187
9288
93- @operator ()
89+ @filter_operator ()
9490def overlay (main_parent_node , overlay_parent_node , eof_action = 'repeat' , ** kwargs ):
9591 """Overlay one video on top of another.
9692
@@ -135,29 +131,29 @@ def overlay(main_parent_node, overlay_parent_node, eof_action='repeat', **kwargs
135131 Official documentation: `overlay <https://ffmpeg.org/ffmpeg-filters.html#overlay-1>`__
136132 """
137133 kwargs ['eof_action' ] = eof_action
138- return filter_multi ([main_parent_node , overlay_parent_node ], overlay .__name__ , ** kwargs )
134+ return FilterNode ([main_parent_node , overlay_parent_node ], overlay .__name__ , kwargs = kwargs , max_inputs = 2 ). stream ( )
139135
140136
141- @operator ()
142- def hflip (parent_node ):
137+ @filter_operator ()
138+ def hflip (stream ):
143139 """Flip the input video horizontally.
144140
145141 Official documentation: `hflip <https://ffmpeg.org/ffmpeg-filters.html#hflip>`__
146142 """
147- return filter_ ( parent_node , hflip .__name__ )
143+ return FilterNode ( stream , hflip .__name__ ). stream ( )
148144
149145
150- @operator ()
151- def vflip (parent_node ):
146+ @filter_operator ()
147+ def vflip (stream ):
152148 """Flip the input video vertically.
153149
154150 Official documentation: `vflip <https://ffmpeg.org/ffmpeg-filters.html#vflip>`__
155151 """
156- return filter_ ( parent_node , vflip .__name__ )
152+ return FilterNode ( stream , vflip .__name__ ). stream ( )
157153
158154
159- @operator ()
160- def drawbox (parent_node , x , y , width , height , color , thickness = None , ** kwargs ):
155+ @filter_operator ()
156+ def drawbox (stream , x , y , width , height , color , thickness = None , ** kwargs ):
161157 """Draw a colored box on the input image.
162158
163159 Args:
@@ -178,11 +174,11 @@ def drawbox(parent_node, x, y, width, height, color, thickness=None, **kwargs):
178174 """
179175 if thickness :
180176 kwargs ['t' ] = thickness
181- return filter_ ( parent_node , drawbox .__name__ , x , y , width , height , color , ** kwargs )
177+ return FilterNode ( stream , drawbox .__name__ , args = [ x , y , width , height , color ], kwargs = kwargs ). stream ( )
182178
183179
184- @operator ()
185- def drawtext (parent_node , text = None , x = 0 , y = 0 , escape_text = True , ** kwargs ):
180+ @filter_operator ()
181+ def drawtext (stream , text = None , x = 0 , y = 0 , escape_text = True , ** kwargs ):
186182 """Draw a text string or text from a specified file on top of a video, using the libfreetype library.
187183
188184 To enable compilation of this filter, you need to configure FFmpeg with ``--enable-libfreetype``. To enable default
@@ -320,11 +316,11 @@ def drawtext(parent_node, text=None, x=0, y=0, escape_text=True, **kwargs):
320316 kwargs ['x' ] = x
321317 if y != 0 :
322318 kwargs ['y' ] = y
323- return filter_ (parent_node , drawtext .__name__ , ** kwargs )
319+ return filter_ (stream , drawtext .__name__ , ** kwargs )
324320
325321
326- @operator ()
327- def concat (* parent_nodes , ** kwargs ):
322+ @filter_operator ()
323+ def concat (* streams , ** kwargs ):
328324 """Concatenate audio and video streams, joining them together one after the other.
329325
330326 The filter works on segments of synchronized video and audio streams. All segments must have the same number of
@@ -349,12 +345,12 @@ def concat(*parent_nodes, **kwargs):
349345
350346 Official documentation: `concat <https://ffmpeg.org/ffmpeg-filters.html#concat>`__
351347 """
352- kwargs ['n' ] = len (parent_nodes )
353- return filter_multi ( parent_nodes , concat .__name__ , ** kwargs )
348+ kwargs ['n' ] = len (streams )
349+ return FilterNode ( streams , concat .__name__ , kwargs = kwargs , max_inputs = None ). stream ( )
354350
355351
356- @operator ()
357- def zoompan (parent_node , ** kwargs ):
352+ @filter_operator ()
353+ def zoompan (stream , ** kwargs ):
358354 """Apply Zoom & Pan effect.
359355
360356 Args:
@@ -369,11 +365,11 @@ def zoompan(parent_node, **kwargs):
369365
370366 Official documentation: `zoompan <https://ffmpeg.org/ffmpeg-filters.html#zoompan>`__
371367 """
372- return filter_ ( parent_node , zoompan .__name__ , ** kwargs )
368+ return FilterNode ( stream , zoompan .__name__ , kwargs = kwargs ). stream ( )
373369
374370
375- @operator ()
376- def hue (parent_node , ** kwargs ):
371+ @filter_operator ()
372+ def hue (stream , ** kwargs ):
377373 """Modify the hue and/or the saturation of the input.
378374
379375 Args:
@@ -384,24 +380,23 @@ def hue(parent_node, **kwargs):
384380
385381 Official documentation: `hue <https://ffmpeg.org/ffmpeg-filters.html#hue>`__
386382 """
387- return filter_ ( parent_node , hue .__name__ , ** kwargs )
383+ return FilterNode ( stream , hue .__name__ , kwargs = kwargs ). stream ( )
388384
389385
390- @operator ()
391- def colorchannelmixer (parent_node , * args , ** kwargs ):
386+ @filter_operator ()
387+ def colorchannelmixer (stream , * args , ** kwargs ):
392388 """Adjust video input frames by re-mixing color channels.
393389
394390 Official documentation: `colorchannelmixer <https://ffmpeg.org/ffmpeg-filters.html#colorchannelmixer>`__
395391 """
396- return filter_ ( parent_node , colorchannelmixer .__name__ , ** kwargs )
392+ return FilterNode ( stream , colorchannelmixer .__name__ , kwargs = kwargs ). stream ( )
397393
398394
399395__all__ = [
400396 'colorchannelmixer' ,
401397 'concat' ,
402398 'drawbox' ,
403399 'filter_' ,
404- 'filter_multi' ,
405400 'hflip' ,
406401 'hue' ,
407402 'overlay' ,
0 commit comments