I have a video file (with audio) and I want to prepend a few seconds of still background (i.e. black) image without sound. I'm trying to do this with ffmpeg-python, but no success yet.
First thing I stumbled upon is the missing support for the color input file (see my remark here), however, I can work around that by creating a black PNG image and loading that in, e.g. using ffmpeg.input("black.png", t=10).
However, now I need to concatenate the background video with the original video, but I can't because the background video doesn't have audio, and concat requires a matching number of audio/video streams. So then I found the aevalsrc filter in ffmpeg, which generates a (silent) audio stream, but I can't make it work with ffmpeg-python, since it is a filter that doesn't require input. E.g. this doesn't work:
stream = ffmpeg.input("black.png", t=10)
stream.filter("aevalsrc", exprs="0", duration=10)
Is there any way to achieve such a thing?
Not yet. #62 is indeed the feature that addresses this but it's not quite ready for production yet. I haven't had time to work on it but will make a mental note to bump priority.
Ok, good to hear. Let me know if I can help somehow.
For those also wanting this feature, I have worked around it by creating a simple black .png file and an small .mp3 file with no sound. Then I load them in with ffmpeg.input(filename, ...) and a certain duration. Of course a bit hacky, but this way at least it is possible with ffmpeg-python.
Any updates on this?
... I found another workaround.
ffmpeg-python creates a list of arguments and calls ffmpeg with that list in the end. The simple idea is to patch this list before it gets executed:
stream = ffmpeg.input("black.mp4") # this file does not need to exist
# ... do your fades and overlays...
ffmpegargs = patch(ffmpeg.compile(stream, overwrite_output=True))
out = subprocess.run(ffmpegargs, capture_output=True)
# done!
def patch(args): # replaces placeholder file with
for i, arg in enumerate(arglist):
if arg == 'black.mp4':
arglist[i] = 'color=black:size={0:d}x{1:d}:duration={2:.3f}:rate={3:.3f}'.format(...'
return arglist[:i-1] + ['-f', 'lavfi'] + arglist[i-1:]
return arglist
This trick also works nicely in other cases.
Best,
Bid
Most helpful comment
Any updates on this?