8000 Support `concat` a/v params · yan-code1/ffmpeg-python@0f18c75 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0f18c75

Browse files
committed
Support concat a/v params
1 parent 122e7bc commit 0f18c75

File tree

3 files changed

+100
-1
lines changed

3 files changed

+100
-1
lines changed

examples/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,21 @@ out, _ = (ffmpeg
5757
)
5858
```
5959

60+
## Process audio and video simultaneously
61+
```python
62+
in1 = ffmpeg.input('in1.mp4')
63+
in2 = ffmpeg.input('in2.mp4')
64+
v1 = in1['v'].hflip()
65+
a1 = in1['a']
66+
v2 = in2['v'].filter_('reverse').filter_('hue', s=0)
67+
a2 = in2['a'].filter_('areverse').filter_('aphaser')
68+
joined = ffmpeg.concat(v1, a1, v2, a2, v=1, a=1).node
69+
v3 = joined[0]
70+
a3 = joined[1].filter_('volume', 0.8)
71+
out = ffmpeg.output(v3, a3, 'out.mp4')
72+
out.run()
73+
```
74+
6075
## [Jupyter Frame Viewer](https://github.com/kkroening/ffmpeg-python/blob/master/examples/ffmpeg-numpy.ipynb)
6176

6277
<img src="https://raw.githubusercontent.com/kkroening/ffmpeg-python/master/doc/jupyter-screenshot.png" alt="jupyter screenshot" width="75%" />

ffmpeg/_filters.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,14 @@ def concat(*streams, **kwargs):
372372
373373
Official documentation: `concat <https://ffmpeg.org/ffmpeg-filters.html#concat>`__
374374
"""
375-
kwargs['n'] = len(streams)
375+
video_stream_count = kwargs.get('v', 1)
376+
audio_stream_count = kwargs.get('a', 0)
377+
stream_count = video_stream_count + audio_stream_count
378+
if len(streams) % stream_count != 0:
379+
raise ValueError(
380+
'Expected concat input streams to have length multiple of {} (v={}, a={}); got {}'
381+
.format(stream_count, video_stream_count, audio_stream_count, len(streams)))
382+
kwargs['n'] = int(len(streams) / stream_count)
376383
return FilterNode(streams, concat.__name__, kwargs=kwargs, max_inputs=None).stream()
377384

378385

ffmpeg/tests/test_ffmpeg.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,83 @@ def _get_complex_filter_asplit_example():
221221
)
222222

223223

224+
def test_filter_concat__video_only():
225+
in1 = ffmpeg.input('in1.mp4')
226+
in2 = ffmpeg.input('in2.mp4')
227+
args = (
228+
ffmpeg
229+
.concat(in1, in2)
230+
.output('out.mp4')
231+
.get_args()
232+
)
233+
assert args == [
234+
'-i',
235+
'in1.mp4',
236+
'-i',
237+
'in2.mp4',
238+
'-filter_complex',
239+
'[0][1]concat=n=2[s0]',
240+
'-map',
241+
'[s0]',
242+
'out.mp4',
243+
]
244+
245+
246+
def test_filter_concat__audio_only():
247+
in1 = ffmpeg.input('in1.mp4')
248+
in2 = ffmpeg.input('in2.mp4')
249+
args = (
250+
ffmpeg
251+
.concat(in1, in2, v=0, a=1)
252+
.output('out.mp4')
253+
.get_args()
254+
)
255+
assert args == [
256+
'-i',
257+
'in1.mp4',
258+
'-i',
259+
'in2.mp4',
260+
'-filter_complex',
261+
'[0][1]concat=a=1:n=2:v=0[s0]',
262+
'-map',
263+
'[s0]',
264+
'out.mp4'
265+
]
266+
267+
268+
def test_filter_concat__audio_video():
269+
in1 = ffmpeg.input('in1.mp4')
270+
in2 = ffmpeg.input('in2.mp4')
271+
joined = ffmpeg.concat(in1['v'], in1['a'], in2.hflip(), in2['a'], v=1, a=1).node
272+
args = (
273+
ffmpeg
274+
.output(joined[0], joined[1], 'out.mp4')
275+
.get_args()
276+
)
277+
assert args == [
278+
'-i',
279+
'in1.mp4',
280+
'-i',
281+
'in2.mp4',
282+
'-filter_complex',
283+
'[1]hflip[s0];[0:v][0:a][s0][1:a]concat=a=1:n=2:v=1[s1][s2]',
284+
'-map',
285+
'[s1]',
286+
'-map',
287+
'[s2]',
288+
'out.mp4',
289+
]
290+
291+
292+
def test_filter_concat__wrong_stream_count():
293+
in1 = ffmpeg.input('in1.mp4')
294+
in2 = ffmpeg.input('in2.mp4')
295+
with pytest.raises(ValueError) as excinfo:
296+
ffmpeg.concat(in1['v'], in1['a'], in2.hflip(), v=1, a=1).node
297+
assert str(excinfo.value) == \
298+
'Expected concat input streams to have length multiple of 2 (v=1, a=1); got 3'
299+
300+
224301
def test_filter_asplit():
225302
out = _get_complex_filter_asplit_example()
226303
args = out.get_args()

0 commit comments

Comments
 (0)
0