11from __future__ import unicode_literals
22from .nodes import (
33 FilterNode ,
4- operator ,
4+ filter_operator ,
55)
66
77
8- @operator ()
9- def filter_ ( parent_node , filter_name , * args , ** kwargs ):
10- """Apply custom single-source filter.
8+ @filter_operator ()
9+ def filter_multi_output ( stream_spec , filter_name , * args , ** kwargs ):
10+ """Apply custom filter with one or more outputs .
1111
12- ``filter_`` is normally used by higher-level filter functions such as ``hflip``, but if a filter implementation
13- is missing from ``fmpeg-python``, you can call ``filter_`` directly to have ``fmpeg-python`` pass the filter name
14- and arguments to ffmpeg verbatim.
15-
16- Args:
17- parent_node: Source stream to apply filter to.
18- filter_name: ffmpeg filter name, e.g. `colorchannelmixer`
19- *args: list of args to pass to ffmpeg verbatim
20- **kwargs: list of keyword-args to pass to ffmpeg verbatim
12+ This is the same as ``filter_`` except that the filter can produce more than one output.
2113
22- This function is used internally by all of the other single-source filters (e.g. ``hflip``, ``crop``, etc.).
23- For custom multi-source filters, see ``filter_multi`` instead.
24-
25- The function name is suffixed with ``_`` in order avoid confusion with the standard python ``filter`` function.
14+ To reference an output stream, use either the ``.stream`` operator or bracket shorthand:
2615
2716 Example:
2817
29- ``ffmpeg.input('in.mp4').filter_('hflip').output('out.mp4').run()``
18+ ```
19+ split = ffmpeg.input('in.mp4').filter_multi_output('split')
20+ split0 = split.stream(0)
21+ split1 = split[1]
22+ ffmpeg.concat(split0, split1).output('out.mp4').run()
23+ ```
3024 """
31- return FilterNode ([parent_node ], filter_name , * args , ** kwargs )
32-
25+ return FilterNode (stream_spec , filter_name , args = args , kwargs = kwargs , max_inputs = None )
3326
34- def filter_multi (parent_nodes , filter_name , * args , ** kwargs ):
35- """Apply custom multi-source filter.
3627
37- This is nearly identical to the ``filter`` function except that it allows filters to be applied to multiple
38- streams. It's normally used by higher-level filter functions such as ``concat``, but if a filter implementation
39- is missing from ``fmpeg-python``, you can call ``filter_multi`` directly .
28+ @ filter_operator ()
29+ def filter_ ( stream_spec , filter_name , * args , ** kwargs ):
30+ """Apply custom filter .
4031
41- Note that because it applies to multiple streams, it can't be used as an operator, unlike the ``filter`` function
42- (e.g. ``ffmpeg.input('in.mp4').filter_('hflip')``)
32+ ``filter_`` is normally used by higher-level filter functions such as ``hflip``, but if a filter implementation
33+ is missing from ``fmpeg-python``, you can call ``filter_`` directly to have ``fmpeg-python`` pass the filter name
34+ and arguments to ffmpeg verbatim.
4335
4436 Args:
45- parent_nodes: List of source streams to apply filter to.
46- filter_name: ffmpeg filter name, e.g. `concat `
37+ stream_spec: a Stream, list of Streams, or label-to-Stream dictionary mapping
38+ filter_name: ffmpeg filter name, e.g. `colorchannelmixer `
4739 *args: list of args to pass to ffmpeg verbatim
4840 **kwargs: list of keyword-args to pass to ffmpeg verbatim
4941
50- For custom single-source filters, see ``filter_multi `` instead .
42+ The function name is suffixed with ``_ `` in order avoid confusion with the standard python ``filter`` function .
5143
5244 Example:
5345
54- ``ffmpeg.filter_multi(ffmpeg. input('in1 .mp4'), ffmpeg.input('in2.mp4'), 'concat', n=2 ).output('out.mp4').run()``
46+ ``ffmpeg.input('in .mp4').filter_('hflip' ).output('out.mp4').run()``
5547 """
56- return FilterNode (parent_nodes , filter_name , * args , ** kwargs )
57-
48+ return filter_multi_output (stream_spec , filter_name , * args , ** kwargs ).stream ()
5849
5950
60- @operator ()
61- def setpts (parent_node , expr ):
51+ @filter_operator ()
52+ def setpts (stream , expr ):
6253 """Change the PTS (presentation timestamp) of the input frames.
6354
6455 Args:
6556 expr: The expression which is evaluated for each frame to construct its timestamp.
6657
6758 Official documentation: `setpts, asetpts <https://ffmpeg.org/ffmpeg-filters.html#setpts_002c-asetpts>`__
6859 """
69- return filter_ ( parent_node , setpts .__name__ , expr )
60+ return FilterNode ( stream , setpts .__name__ , args = [ expr ]). stream ( )
7061
7162
72- @operator ()
73- def trim (parent_node , ** kwargs ):
63+ @filter_operator ()
64+ def trim (stream , ** kwargs ):
7465 """Trim the input so that the output contains one continuous subpart of the input.
7566
7667 Args:
@@ -88,10 +79,10 @@ def trim(parent_node, **kwargs):
8879
8980 Official documentation: `trim <https://ffmpeg.org/ffmpeg-filters.html#trim>`__
9081 """
91- return filter_ ( parent_node , trim .__name__ , ** kwargs )
82+ return FilterNode ( stream , trim .__name__ , kwargs = kwargs ). stream ( )
9283
9384
94- @operator ()
85+ @filter_operator ()
9586def overlay (main_parent_node , overlay_parent_node , eof_action = 'repeat' , ** kwargs ):
9687 """Overlay one video on top of another.
9788
@@ -136,29 +127,29 @@ def overlay(main_parent_node, overlay_parent_node, eof_action='repeat', **kwargs
136127 Official documentation: `overlay <https://ffmpeg.org/ffmpeg-filters.html#overlay-1>`__
137128 """
138129 kwargs ['eof_action' ] = eof_action
139- return filter_multi ([main_parent_node , overlay_parent_node ], overlay .__name__ , ** kwargs )
130+ return FilterNode ([main_parent_node , overlay_parent_node ], overlay .__name__ , kwargs = kwargs , max_inputs = 2 ). stream ( )
140131
141132
142- @operator ()
143- def hflip (parent_node ):
133+ @filter_operator ()
134+ def hflip (stream ):
144135 """Flip the input video horizontally.
145136
146137 Official documentation: `hflip <https://ffmpeg.org/ffmpeg-filters.html#hflip>`__
147138 """
148- return filter_ ( parent_node , hflip .__name__ )
139+ return FilterNode ( stream , hflip .__name__ ). stream ( )
149140
150141
151- @operator ()
152- def vflip (parent_node ):
142+ @filter_operator ()
143+ def vflip (stream ):
153144 """Flip the input video vertically.
154145
155146 Official documentation: `vflip <https://ffmpeg.org/ffmpeg-filters.html#vflip>`__
156147 """
157- return filter_ ( parent_node , vflip .__name__ )
148+ return FilterNode ( stream , vflip .__name__ ). stream ( )
158149
159150
160- @operator ()
161- def drawbox (parent_node , x , y , width , height , color , thickness = None , ** kwargs ):
151+ @filter_operator ()
152+ def drawbox (stream , x , y , width , height , color , thickness = None , ** kwargs ):
162153 """Draw a colored box on the input image.
163154
164155 Args:
@@ -179,11 +170,11 @@ def drawbox(parent_node, x, y, width, height, color, thickness=None, **kwargs):
179170 """
180171 if thickness :
181172 kwargs ['t' ] = thickness
182- return filter_ ( parent_node , drawbox .__name__ , x , y , width , height , color , ** kwargs )
173+ return FilterNode ( stream , drawbox .__name__ , args = [ x , y , width , height , color ], kwargs = kwargs ). stream ( )
183174
184175
185- @operator ()
186- def concat (* parent_nodes , ** kwargs ):
176+ @filter_operator ()
177+ def concat (* streams , ** kwargs ):
187178 """Concatenate audio and video streams, joining them together one after the other.
188179
189180 The filter works on segments of synchronized video and audio streams. All segments must have the same number of
@@ -208,12 +199,12 @@ def concat(*parent_nodes, **kwargs):
208199
209200 Official documentation: `concat <https://ffmpeg.org/ffmpeg-filters.html#concat>`__
210201 """
211- kwargs ['n' ] = len (parent_nodes )
212- return filter_multi ( parent_nodes , concat .__name__ , ** kwargs )
202+ kwargs ['n' ] = len (streams )
203+ return FilterNode ( streams , concat .__name__ , kwargs = kwargs , max_inputs = None ). stream ( )
213204
214205
215- @operator ()
216- def zoompan (parent_node , ** kwargs ):
206+ @filter_operator ()
207+ def zoompan (stream , ** kwargs ):
217208 """Apply Zoom & Pan effect.
218209
219210 Args:
@@ -228,11 +219,11 @@ def zoompan(parent_node, **kwargs):
228219
229220 Official documentation: `zoompan <https://ffmpeg.org/ffmpeg-filters.html#zoompan>`__
230221 """
231- return filter_ ( parent_node , zoompan .__name__ , ** kwargs )
222+ return FilterNode ( stream , zoompan .__name__ , kwargs = kwargs ). stream ( )
232223
233224
234- @operator ()
235- def hue (parent_node , ** kwargs ):
225+ @filter_operator ()
226+ def hue (stream , ** kwargs ):
236227 """Modify the hue and/or the saturation of the input.
237228
238229 Args:
@@ -243,24 +234,23 @@ def hue(parent_node, **kwargs):
243234
244235 Official documentation: `hue <https://ffmpeg.org/ffmpeg-filters.html#hue>`__
245236 """
246- return filter_ ( parent_node , hue .__name__ , ** kwargs )
237+ return FilterNode ( stream , hue .__name__ , kwargs = kwargs ). stream ( )
247238
248239
249- @operator ()
250- def colorchannelmixer (parent_node , * args , ** kwargs ):
240+ @filter_operator ()
241+ def colorchannelmixer (stream , * args , ** kwargs ):
251242 """Adjust video input frames by re-mixing color channels.
252243
253244 Official documentation: `colorchannelmixer <https://ffmpeg.org/ffmpeg-filters.html#colorchannelmixer>`__
254245 """
255- return filter_ ( parent_node , colorchannelmixer .__name__ , ** kwargs )
246+ return FilterNode ( stream , colorchannelmixer .__name__ , kwargs = kwargs ). stream ( )
256247
257248
258249__all__ = [
259250 'colorchannelmixer' ,
260251 'concat' ,
261252 'drawbox' ,
262253 'filter_' ,
263- 'filter_multi' ,
264254 'hflip' ,
265255 'hue' ,
266256 'overlay' ,
0 commit comments