Merge pull request #97 from kkroening/concat-av

Support `concat` a/v params
This commit is contained in:
Karl Kroening 2018-06-30 02:23:47 -07:00 committed by GitHub
commit 7c872c56b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 1 deletions

View File

@ -57,6 +57,21 @@ out, _ = (ffmpeg
)
```
## Process audio and video simultaneously
```python
in1 = ffmpeg.input('in1.mp4')
in2 = ffmpeg.input('in2.mp4')
v1 = in1['v'].hflip()
a1 = in1['a']
v2 = in2['v'].filter_('reverse').filter_('hue', s=0)
a2 = in2['a'].filter_('areverse').filter_('aphaser')
joined = ffmpeg.concat(v1, a1, v2, a2, v=1, a=1).node
v3 = joined[0]
a3 = joined[1].filter_('volume', 0.8)
out = ffmpeg.output(v3, a3, 'out.mp4')
out.run()
```
## [Jupyter Frame Viewer](https://github.com/kkroening/ffmpeg-python/blob/master/examples/ffmpeg-numpy.ipynb)
<img src="https://raw.githubusercontent.com/kkroening/ffmpeg-python/master/doc/jupyter-screenshot.png" alt="jupyter screenshot" width="75%" />

View File

@ -372,7 +372,14 @@ def concat(*streams, **kwargs):
Official documentation: `concat <https://ffmpeg.org/ffmpeg-filters.html#concat>`__
"""
kwargs['n'] = len(streams)
video_stream_count = kwargs.get('v', 1)
audio_stream_count = kwargs.get('a', 0)
stream_count = video_stream_count + audio_stream_count
if len(streams) % stream_count != 0:
raise ValueError(
'Expected concat input streams to have length multiple of {} (v={}, a={}); got {}'
.format(stream_count, video_stream_count, audio_stream_count, len(streams)))
kwargs['n'] = int(len(streams) / stream_count)
return FilterNode(streams, concat.__name__, kwargs=kwargs, max_inputs=None).stream()

View File

@ -221,6 +221,83 @@ def _get_complex_filter_asplit_example():
)
def test_filter_concat__video_only():
in1 = ffmpeg.input('in1.mp4')
in2 = ffmpeg.input('in2.mp4')
args = (
ffmpeg
.concat(in1, in2)
.output('out.mp4')
.get_args()
)
assert args == [
'-i',
'in1.mp4',
'-i',
'in2.mp4',
'-filter_complex',
'[0][1]concat=n=2[s0]',
'-map',
'[s0]',
'out.mp4',
]
def test_filter_concat__audio_only():
in1 = ffmpeg.input('in1.mp4')
in2 = ffmpeg.input('in2.mp4')
args = (
ffmpeg
.concat(in1, in2, v=0, a=1)
.output('out.mp4')
.get_args()
)
assert args == [
'-i',
'in1.mp4',
'-i',
'in2.mp4',
'-filter_complex',
'[0][1]concat=a=1:n=2:v=0[s0]',
'-map',
'[s0]',
'out.mp4'
]
def test_filter_concat__audio_video():
in1 = ffmpeg.input('in1.mp4')
in2 = ffmpeg.input('in2.mp4')
joined = ffmpeg.concat(in1['v'], in1['a'], in2.hflip(), in2['a'], v=1, a=1).node
args = (
ffmpeg
.output(joined[0], joined[1], 'out.mp4')
.get_args()
)
assert args == [
'-i',
'in1.mp4',
'-i',
'in2.mp4',
'-filter_complex',
'[1]hflip[s0];[0:v][0:a][s0][1:a]concat=a=1:n=2:v=1[s1][s2]',
'-map',
'[s1]',
'-map',
'[s2]',
'out.mp4',
]
def test_filter_concat__wrong_stream_count():
in1 = ffmpeg.input('in1.mp4')
in2 = ffmpeg.input('in2.mp4')
with pytest.raises(ValueError) as excinfo:
ffmpeg.concat(in1['v'], in1['a'], in2.hflip(), v=1, a=1).node
assert str(excinfo.value) == \
'Expected concat input streams to have length multiple of 2 (v=1, a=1); got 3'
def test_filter_asplit():
out = _get_complex_filter_asplit_example()
args = out.get_args()