I'm using ffmpeg-python for my first time. I'm trying to use the shortest=1
argument in ffmpeg.output()
, but my program keeps giving me errors when I use it.
I want to replace the audio from foo.mp4
with the audio from bar.webm
, while keeping the visuals of foo.mp4
. I got this working, but the problem is that ffmpeg.concat
by default keeps playing the audio from bar.webm
while the visuals from foo.mp4
have stopped playing. According to this FFmpeg docs page, this is the intended behaviour:
"The concat filter will use the duration of the longest stream in each segment (except the last one), and if necessary pad shorter audio streams with silence."
I want the output video to stop when the visuals stop playing, so I want it to cut off the audio, but I can't get it to work. That page also states that I should be able to add shortest
as an argument to get my desired result: "If set to 1, force the output to terminate when the shortest input terminates. Default value is 0." I can't get it to work, though. The second from the bottom line from the block of code below contains shortest=1
, which I'd expect to work, but I get this error instead:
[NULL @ 000001d50dfdea80] Unable to find a suitable output format for '1'
and 1: Invalid argument
Using shortestfoo
instead gives me this error, as expected:
Unrecognized option 'shortestfoo'.
and Error splitting the argument list: Option not found
This tells me that the shortest
argument was a possible argument, but that the 1
value that I assign to it is wrong. Setting it to None
my program runs, but the audio still won't be cut off with this set to None
, of course.
What value for shortest
should I use here? Am I correct in assessing that I'm just using the wrong value for shortest
? Many thanks!
Edit: Tried using True
instead of 1. Tried using **{'shortest': 1}
and **{'shortest': True}
. These also didn't work.
import ffmpeg
input_video_name = 'foo'
input_video_extension = '.mp4'
input_audio_name = 'bar'
input_audio_extension = '.webm'
input_video = ffmpeg.input('input videos/' + input_video_name + input_video_extension)
input_audio = ffmpeg.input('input audio/'+ input_audio_name + input_audio_extension)
stream = ffmpeg.concat(input_video, input_audio, v=1, a=1)
stream = ffmpeg.output(stream, 'output videos/' + input_video_name + '.mp4', shortest=1)
ffmpeg.run(stream)
Found the answer: This person provided a solution to my problem. I don't know why this does work, so what I was missing in my original code, though:
video_part = ffmpeg.input('video.mp4')
audio_part = ffmpeg.input('audio.mp3')
(
ffmpeg
.output(audio_part.audio, video_part.video, 'output-video.mp4', shortest=None, vcodec='copy')
.run()
)