Skip to content

Commit

Permalink
Add filter_ and filter_multi functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kkroening committed May 28, 2017
1 parent e14e9e5 commit 637a2a5
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 21 deletions.
6 changes: 6 additions & 0 deletions doc/html/genindex.html
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ <h2 id="F">F</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#module-ffmpeg">ffmpeg (module)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#ffmpeg.filter_">filter_() (in module ffmpeg)</a>
</li>
<li><a href="index.html#ffmpeg.filter_multi">filter_multi() (in module ffmpeg)</a>
</li>
</ul></td>
</tr></table>
Expand Down
56 changes: 56 additions & 0 deletions doc/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,62 @@ <h1>ffmpeg-python: Python bindings for FFmpeg<a class="headerlink" href="#ffmpeg
<p>Official documentation: <a class="reference external" href="https://ffmpeg.org/ffmpeg-filters.html#drawbox">drawbox</a></p>
</dd></dl>

<dl class="function">
<dt id="ffmpeg.filter_">
<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>
<dd><p>Apply custom single-source filter.</p>
<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
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
and arguments to ffmpeg verbatim.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>parent_node</strong> – Source stream to apply filter to.</li>
<li><strong>filter_name</strong> – ffmpeg filter name, e.g. <cite>colorchannelmixer</cite></li>
<li><strong>*args</strong> – list of args to pass to ffmpeg verbatim</li>
<li><strong>**kwargs</strong> – list of keyword-args to pass to ffmpeg verbatim</li>
</ul>
</td>
</tr>
</tbody>
</table>
<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.).
For custom multi-source filters, see <code class="docutils literal"><span class="pre">filter_multi</span></code> instead.</p>
<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>
<p class="rubric">Example</p>
<p><code class="docutils literal"><span class="pre">ffmpeg.input('in.mp4').filter_('hflip').output('out.mp4').run()</span></code></p>
</dd></dl>

<dl class="function">
<dt id="ffmpeg.filter_multi">
<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>
<dd><p>Apply custom multi-source filter.</p>
<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
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
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>
<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
(e.g. <code class="docutils literal"><span class="pre">ffmpeg.input('in.mp4').filter_('hflip')</span></code>)</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>parent_nodes</strong> – List of source streams to apply filter to.</li>
<li><strong>filter_name</strong> – ffmpeg filter name, e.g. <cite>concat</cite></li>
<li><strong>*args</strong> – list of args to pass to ffmpeg verbatim</li>
<li><strong>**kwargs</strong> – list of keyword-args to pass to ffmpeg verbatim</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>For custom single-source filters, see <code class="docutils literal"><span class="pre">filter_multi</span></code> instead.</p>
<p class="rubric">Example</p>
<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>
</dd></dl>

<dl class="function">
<dt id="ffmpeg.hflip">
<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>
Expand Down
6 changes: 2 additions & 4 deletions doc/html/objects.inv
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@
# Project: ffmpeg-python
# Version:
# The remainder of this file is compressed using zlib.
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��=ڴ#
�L"7b
���h��ħ�`�A�3�A�*0��q�E����༾VO�s��Q:�aNS�� �",-����J����/���P>�]�^�<�Zn�{��
�)�e���|O�
xڕ��j�0�O1�^]�W`���B@�Nb ��8��>}� ݅B�'e���D��>���4> �!������޽�Z�
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-
Expand Down
2 changes: 1 addition & 1 deletion doc/html/searchindex.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 64 additions & 10 deletions ffmpeg/_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,58 @@
)


@operator()
def filter_(parent_node, filter_name, *args, **kwargs):
"""Apply custom single-source filter.
``filter_`` is normally used by higher-level filter functions such as ``hflip``, but if a filter implementation
is missing from ``fmpeg-python``, you can call ``filter_`` directly to have ``fmpeg-python`` pass the filter name
and arguments to ffmpeg verbatim.
Args:
parent_node: Source stream to apply filter to.
filter_name: ffmpeg filter name, e.g. `colorchannelmixer`
*args: list of args to pass to ffmpeg verbatim
**kwargs: list of keyword-args to pass to ffmpeg verbatim
This function is used internally by all of the other single-source filters (e.g. ``hflip``, ``crop``, etc.).
For custom multi-source filters, see ``filter_multi`` instead.
The function name is suffixed with ``_`` in order avoid confusion with the standard python ``filter`` function.
Example:
``ffmpeg.input('in.mp4').filter_('hflip').output('out.mp4').run()``
"""
return FilterNode([parent_node], filter_name, *args, **kwargs)


def filter_multi(parent_nodes, filter_name, *args, **kwargs):
"""Apply custom multi-source filter.
This is nearly identical to the ``filter`` function except that it allows filters to be applied to multiple
streams. It's normally used by higher-level filter functions such as ``concat``, but if a filter implementation
is missing from ``fmpeg-python``, you can call ``filter_multi`` directly.
Note that because it applies to multiple streams, it can't be used as an operator, unlike the ``filter`` function
(e.g. ``ffmpeg.input('in.mp4').filter_('hflip')``)
Args:
parent_nodes: List of source streams to apply filter to.
filter_name: ffmpeg filter name, e.g. `concat`
*args: list of args to pass to ffmpeg verbatim
**kwargs: list of keyword-args to pass to ffmpeg verbatim
For custom single-source filters, see ``filter_multi`` instead.
Example:
``ffmpeg.filter_multi(ffmpeg.input('in1.mp4'), ffmpeg.input('in2.mp4'), 'concat', n=2).output('out.mp4').run()``
"""
return FilterNode(parent_nodes, filter_name, *args, **kwargs)



@operator()
def setpts(parent_node, expr):
"""Change the PTS (presentation timestamp) of the input frames.
Expand All @@ -13,7 +65,7 @@ def setpts(parent_node, expr):
Official documentation: `setpts, asetpts <https://ffmpeg.org/ffmpeg-filters.html#setpts_002c-asetpts>`__
"""
return FilterNode([parent_node], setpts.__name__, expr)
return filter_(parent_node, setpts.__name__, expr)


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


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


@operator()
Expand All @@ -92,7 +144,7 @@ def hflip(parent_node):
Official documentation: `hflip <https://ffmpeg.org/ffmpeg-filters.html#hflip>`__
"""
return FilterNode([parent_node], hflip.__name__)
return filter_(parent_node, hflip.__name__)


@operator()
Expand All @@ -101,7 +153,7 @@ def vflip(parent_node):
Official documentation: `vflip <https://ffmpeg.org/ffmpeg-filters.html#vflip>`__
"""
return FilterNode([parent_node], vflip.__name__)
return filter_(parent_node, vflip.__name__)


@operator()
Expand All @@ -126,7 +178,7 @@ def drawbox(parent_node, x, y, width, height, color, thickness=None, **kwargs):
"""
if thickness:
kwargs['t'] = thickness
return FilterNode([parent_node], drawbox.__name__, x, y, width, height, color, **kwargs)
return filter_(parent_node, drawbox.__name__, x, y, width, height, color, **kwargs)


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


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


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


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


__all__ = [
'colorchannelmixer',
'concat',
'drawbox',
'filter_',
'filter_multi',
'hflip',
'hue',
'overlay',
Expand Down
8 changes: 2 additions & 6 deletions ffmpeg/tests/test_ffmpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def test_run_failing_cmd():

def test_custom_filter():
node = ffmpeg.input('dummy.mp4')
node = FilterNode([node], 'custom_filter', 'a', 'b', kwarg1='c')
node = ffmpeg.filter_(node, 'custom_filter', 'a', 'b', kwarg1='c')
node = ffmpeg.output(node, 'dummy2.mp4')
assert node.get_args() == [
'-i', 'dummy.mp4',
Expand All @@ -153,13 +153,9 @@ def test_custom_filter():


def test_custom_filter_fluent():
@operator()
def custom_filter(parent_node, arg1, arg2, kwarg1):
return FilterNode([parent_node], 'custom_filter', arg1, arg2, kwarg1=kwarg1)

node = ffmpeg \
.input('dummy.mp4') \
.custom_filter('a', 'b', kwarg1='c') \
.filter_('custom_filter', 'a', 'b', kwarg1='c') \
.output('dummy2.mp4')
assert node.get_args() == [
'-i', 'dummy.mp4',
Expand Down

0 comments on commit 637a2a5

Please sign in to comment.