8000 Add `filter_` and `filter_multi` functions · Powercoder64/ffmpeg-python@637a2a5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 637a2a5

Browse files
committed
Add filter_ and filter_multi functions
1 parent e14e9e5 commit 637a2a5

File tree

6 files changed

+131
-21
lines changed

6 files changed

+131
-21
lines changed

doc/html/genindex.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ <h2 id="F">F</h2>
9090
<table style="width: 100%" class="indextable genindextable"><tr>
9191
<td style="width: 33%; vertical-align: top;"><ul>
9292
<li><a href="index.html#module-ffmpeg">ffmpeg (module)</a>
93+
</li>
94+
</ul></td>
95+
<td style="width: 33%; vertical-align: top;"><ul>
96+
<li><a href="index.html#ffmpeg.filter_">filter_() (in module ffmpeg)</a>
97+
</li>
98+
<li><a href="index.html#ffmpeg.filter_multi">filter_multi() (in module ffmpeg)</a>
9399
</li>
94100
</ul></td>
95101
</tr></table>

doc/html/index.html

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,62 @@ <h1>ffmpeg-python: Python bindings for FFmpeg<a class="headerlink" href="#ffmpeg
121121
<p>Official documentation: <a class="reference external" href="https://ffmpeg.org/ffmpeg-filters.html#drawbox">drawbox</a></p>
122122
</dd></dl>
123123

124+
<dl class="function">
125+
<dt id="ffmpeg.filter_">
126+
<code class="descclassname">ffmpeg.</code><code class="descname">filter_</code><span class="sig-paren">(</span><em>parent_node</em>, <em>filter_name</em>, <em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#ffmpeg.filter_" title="Permalink to this definition"></a></dt>
127+
<dd><p>Apply custom single-source filter.</p>
128+
<p><code class="docutils literal"><span class="pre">filter_</span></code> is normally used by higher-level filter functions such as <code class="docutils literal"><span class="pre">hflip</span></code>, but if a filter implementation
129+
is missing from <code class="docutils literal"><span class="pre">fmpeg-python</span></code>, you can call <code class="docutils literal"><span class="pre">filter_</span></code> directly to have <code class="docutils literal"><span class="pre">fmpeg-python</span></code> pass the filter name
130+
and arguments to ffmpeg verbatim.</p>
131+
<table class="docutils field-list" frame="void" rules="none">
132+
<col class="field-name" />
133+
<col class="field-body" />
134+
<tbody valign="top">
135+
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
136+
<li><strong>parent_node</strong> – Source stream to apply filter to.</li>
137+
<li><strong>filter_name</strong> – ffmpeg filter name, e.g. <cite>colorchannelmixer</cite></li>
138+
<li><strong>*args</strong> – list of args to pass to ffmpeg verbatim</li>
139+
<li><strong>**kwargs</strong> – list of keyword-args to pass to ffmpeg verbatim</li>
140+
</ul>
141+
</td>
142+
</tr>
143+
</tbody>
144+
</table>
145+
<p>This function is used internally by all of the other single-source filters (e.g. <code class="docutils literal"><span class="pre">hflip</span></code>, <code class="docutils literal"><span class="pre">crop</span></code>, etc.).
146+
For custom multi-source filters, see <code class="docutils literal"><span class="pre">filter_multi</span></code> instead.</p>
147+
<p>The function name is suffixed with <code class="docutils literal"><span class="pre">_</span></code> in order avoid confusion with the standard python <code class="docutils literal"><span class="pre">filter</span></code> function.</p>
148+
<p class="rubric">Example</p>
149+
<p><code class="docutils literal"><span class="pre">ffmpeg.input('in.mp4').filter_('hflip').output('out.mp4').run()</span></code></p>
150+
</dd></dl>
151+
152+
<dl class="function">
153+
<dt id="ffmpeg.filter_multi">
154+
<code class="descclassname">ffmpeg.</code><code class="descname">filter_multi</code><span class="sig-paren">(</span><em>parent_nodes</em>, <em>filter_name</em>, <em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#ffmpeg.filter_multi" title="Permalink to this definition"></a></dt>
155+
<dd><p>Apply custom multi-source filter.</p>
156+
<p>This is nearly identical to the <code class="docutils literal"><span class="pre">filter</span></code> function except that it allows filters to be applied to multiple
157+
streams. It’s normally used by higher-level filter functions such as <code class="docutils literal"><span class="pre">concat</span></code>, but if a filter implementation
158+
is missing from <code class="docutils literal"><span class="pre">fmpeg-python</span></code>, you can call <code class="docutils literal"><span class="pre">filter_multi</span></code> directly.</p>
159+
<p>Note that because it applies to multiple streams, it can’t be used as an operator, unlike the <code class="docutils literal"><span class="pre">filter</span></code> function
160+
(e.g. <code class="docutils literal"><span class="pre">ffmpeg.input('in.mp4').filter_('hflip')</span></code>)</p>
161+
<table class="docutils field-list" frame="void" rules="none">
162+
<col class="field-name" />
163+
<col class="field-body" />
164+
<tbody valign="top">
165+
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
166+
<li><strong>parent_nodes</strong> – List of source streams to apply filter to.</li>
167+
<li><strong>filter_name</strong> – ffmpeg filter name, e.g. <cite>concat</cite></li>
168+
<li><strong>*args</strong> – list of args to pass to ffmpeg verbatim</li>
169+
<li><strong>**kwargs</strong> – list of keyword-args to pass to ffmpeg verbatim</li>
170+
</ul>
171+
</td>
172+
</tr>
173+
</tbody>
174+
</table>
175+
<p>For custom single-source filters, see <code class="docutils literal"><span class="pre">filter_multi</span></code> instead.</p>
176+
<p class="rubric">Example</p>
177+
<p><code class="docutils literal"><span class="pre">ffmpeg.filter_multi(ffmpeg.input('in1.mp4'),</span> <span class="pre">ffmpeg.input('in2.mp4'),</span> <span class="pre">'concat',</span> <span class="pre">n=2).output('out.mp4').run()</span></code></p>
178+
</dd></dl>
179+
124180
<dl class="function">
125181
<dt id="ffmpeg.hflip">
126182
<code class="descclassname">ffmpeg.</code><code class="descname">hflip</code><span class="sig-paren">(</span><em>parent_node</em><span class="sig-paren">)</span><a class="headerlink" href="#ffmpeg.hflip" title="Permalink to this definition"></a></dt>

doc/html/objects.inv

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,5 @@
22
# Project: ffmpeg-python
33
# Version:
44
# The remainder of this file is compressed using zlib.
5-
xڍ����0�O1�{�l�>@����>@�:��d&Ĥ�>��A����I�|�3!Fk�@��}v_`���0$�>J�����<t�8v�"B��q��L]�Lp|���SID���-O"k0]U4��� �E�RȲMy�����M[���0:5��=ڴ#
6-
�L"7b
7-
���h��ħ�`�A�3�A�*0��q�E����༾VO�s��Q:�aNS�� �",-����J����/���P>�]�^�<�Zn�{��
8-
�)�e���|O�
5+
xڕ��j�0�O1�^]�W`���B@�Nb ��8��>}� ݅B�'e���D��>���4> �!������޽�Z�
6+
u�wx� �:ogL[Tg����c�)E�b��waYmcj�c}vlE�ܪd&��Q&3����eo�c2؆�k@6m�2z���"��d�FJ�DnB���q�^o�����I�^���Ʃ�g8�������aC�7� J�:.<j�_�[���o�!�岑j=���K},�~��]:O�����(��?��U���Mp-

doc/html/searchindex.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ffmpeg/_filters.py

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,58 @@
44
)
55

66

7+
@operator()
8+
def filter_(parent_node, filter_name, *args, **kwargs):
9+
"""Apply custom single-source filter.
10+
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
20+
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.
25+
26+
Example:
27+
28+
``ffmpeg.input('in.mp4').filter_('hflip').output('out.mp4').run()``
29+
"""
30+
return FilterNode([parent_node], filter_name, *args, **kwargs)
31+
32+
33+
def filter_multi(parent_nodes, filter_name, *args, **kwargs):
34+
"""Apply custom multi-source filter.
35+
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.
39+
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')``)
42+
43+
Args:
44+
parent_nodes: List of source streams to apply filter to.
45+
filter_name: ffmpeg filter name, e.g. `concat`
46+
*args: list of args to pass to ffmpeg verbatim
47+
**kwargs: list of keyword-args to pass to ffmpeg verbatim
48+
49+
For custom single-source filters, see ``filter_multi`` instead.
50+
51+
Example:
52+
53+
``ffmpeg.filter_multi(ffmpeg.input('in1.mp4'), ffmpeg.input('in2.mp4'), 'concat', n=2).output('out.mp4').run()``
54+
"""
55+
return FilterNode(parent_nodes, filter_name, *args, **kwargs)
56+
57+
58+
759
@operator()
860
def setpts(parent_node, expr):
961
"""Change the PTS (presentation timestamp) of the input frames.
@@ -13,7 +65,7 @@ def setpts(parent_node, expr):
1365
1466
Official documentation: `setpts, asetpts <https://ffmpeg.org/ffmpeg-filters.html#setpts_002c-asetpts>`__
1567
"""
16-
return FilterNode([parent_node], setpts.__name__, expr)
68+
return filter_(parent_node, setpts.__name__, expr)
1769

1870

1971
@operator()
@@ -35,7 +87,7 @@ def trim(parent_node, **kwargs):
3587
3688
Official documentation: `trim <https://ffmpeg.org/ffmpeg-filters.html#trim>`__
3789
"""
38-
return FilterNode([parent_node], trim.__name__, **kwargs)
90+
return filter_(parent_node, trim.__name__, **kwargs)
3991

4092

4193
@operator()
@@ -83,7 +135,7 @@ def overlay(main_parent_node, overlay_parent_node, eof_action='repeat', **kwargs
83135
Official documentation: `overlay <https://ffmpeg.org/ffmpeg-filters.html#overlay-1>`__
84136
"""
85137
kwargs['eof_action'] = eof_action
86-
return FilterNode([main_parent_node, overlay_parent_node], overlay.__name__, **kwargs)
138+
return filter_multi([main_parent_node, overlay_parent_node], overlay.__name__, **kwargs)
87139

88140

89141
@operator()
@@ -92,7 +144,7 @@ def hflip(parent_node):
92144
93145
Official documentation: `hflip <https://ffmpeg.org/ffmpeg-filters.html#hflip>`__
94146
"""
95-
return FilterNode([parent_node], hflip.__name__)
147+
return filter_(parent_node, hflip.__name__)
96148

97149

98150
@operator()
@@ -101,7 +153,7 @@ def vflip(parent_node):
101153
102154
Official documentation: `vflip <https://ffmpeg.org/ffmpeg-filters.html#vflip>`__
103155
"""
104-
return FilterNode([parent_node], vflip.__name__)
156+
return filter_(parent_node, vflip.__name__)
105157

106158

107159
@operator()
@@ -126,7 +178,7 @@ def drawbox(parent_node, x, y, width, height, color, thickness=None, **kwargs):
126178
"""
127179
if thickness:
128180
kwargs['t'] = thickness
129-
return FilterNode([parent_node], drawbox.__name__, x, y, width, height, color, **kwargs)
181+
return filter_(parent_node, drawbox.__name__, x, y, width, height, color, **kwargs)
130182

131183

132184
@operator()
@@ -156,7 +208,7 @@ def concat(*parent_nodes, **kwargs):
156208
Official documentation: `concat <https://ffmpeg.org/ffmpeg-filters.html#concat>`__
157209
"""
158210
kwargs['n'] = len(parent_nodes)
159-
return FilterNode(parent_nodes, concat.__name__, **kwargs)
211+
return filter_multi(parent_nodes, concat.__name__, **kwargs)
160212

161213

162214
@operator()
@@ -175,7 +227,7 @@ def zoompan(parent_node, **kwargs):
175227
176228
Official documentation: `zoompan <https://ffmpeg.org/ffmpeg-filters.html#zoompan>`__
177229
"""
178-
return FilterNode([parent_node], zoompan.__name__, **kwargs)
230+
return filter_(parent_node, zoompan.__name__, **kwargs)
179231

180232

181233
@operator()
@@ -190,7 +242,7 @@ def hue(parent_node, **kwargs):
190242
191243
Official documentation: `hue <https://ffmpeg.org/ffmpeg-filters.html#hue>`__
192244
"""
193-
return FilterNode([parent_node], hue.__name__, **kwargs)
245+
return filter_(parent_node, hue.__name__, **kwargs)
194246

195247

196248
@operator()
@@ -199,13 +251,15 @@ def colorchannelmixer(parent_node, *args, **kwargs):
199251
200252
Official documentation: `colorchannelmixer <https://ffmpeg.org/ffmpeg-filters.html#colorchannelmixer>`__
201253
"""
202-
return FilterNode([parent_node], colorchannelmixer.__name__, **kwargs)
254+
return filter_(parent_node, colorchannelmixer.__name__, **kwargs)
203255

204256

205257
__all__ = [
206258
'colorchannelmixer',
207259
'concat',
208260
'drawbox',
261+
'filter_',
262+
'filter_multi',
209263
'hflip',
210264
'hue',
211265
'overlay',

ffmpeg/tests/test_ffmpeg.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def test_run_failing_cmd():
142142

143143
def test_custom_filter():
144144
node = ffmpeg.input('dummy.mp4')
145-
node = FilterNode([node], 'custom_filter', 'a', 'b', kwarg1='c')
145+
node = ffmpeg.filter_(node, 'custom_filter', 'a', 'b', kwarg1='c')
146146
node = ffmpeg.output(node, 'dummy2.mp4')
147147
assert node.get_args() == [
148148
'-i', 'dummy.mp4',
@@ -153,13 +153,9 @@ def test_custom_filter():
153153

154154

155155
def test_custom_filter_fluent():
156-
@operator()
157-
def custom_filter(parent_node, arg1, arg2, kwarg1):
158-
return FilterNode([parent_node], 'custom_filter', arg1, arg2, kwarg1=kwarg1)
159-
160156
node = ffmpeg \
161157
.input('dummy.mp4') \
162-
.custom_filter('a', 'b', kwarg1='c') \
158+
.filter_('custom_filter', 'a', 'b', kwarg1='c') \
163159
.output('dummy2.mp4')
164160
assert node.get_args() == [
165161
'-i', 'dummy.mp4',

0 commit comments

Comments
 (0)
0