I have a single video (~10 mins) and two audio files (~2 mins each). I want to add one audio file to the beginning and the other one to the end of the video keeping the middle of the video silent. Can this be accomplished without re-encoding (at least the video) and, if so, how?
1 Answers
There are several methods to do this.
apad + concat filter
Use apad to extend audio1 with silent audio, and then concat filter to concatenate it with audio2:
ffmpeg -i video -i audio1 -i audio2 -filter_complex "[1:a]apad=pad_dur=360[a1];[a1][2:a]concat=n=2:v=0:a=1[a]" -map 0:v -map "[a]" -c:v copy output.mp4
anullsrc + concat demuxer
This can allow you to avoid re-encoding anything but it is slightly more complicated as it takes several steps. Note that all inputs must have the same format, channel layout, and sample rate.
Make 8 minute silence with anullsrc:
ffmpeg -f lafvi -i anullsrc=channel_layout=stereo:sample_rate=44100 -t 00:08:00 silence.m4aMake
input.txtcontaining:file 'audio1.m4a' file 'silence.m4a' file 'audio2.m4a'Concatenate with the concat demuxer:
ffmpeg -i video.mp4 -f concat -i input.txt -map 0:v -map 1:a -c copy output.mp4
adelay + amix
You can use adelay to add a delay to audio2, and then downmix audio1 and audio2 with amix:
ffmpeg -i video -i audio1 -i audio2 -filter_complex "[2:a]adelay=480s:all=1[a2];[1:a][a2]amix[a]" -map 0:v -map "[a]" -c:v copy output.mp4
You will need at least FFmpeg 4.2 to use this newer adelay syntax. Otherwise you will have to declare the delay in milliseconds and do so for each individual channel (each separated by a
|).Note that the output will be affected by audio volume normalization. This means that it will be quieter than its individual segments. See amix filter volume issue with inputs of different duration for various solutions.
Getting durations
You can use ffprobe to get the durations of each input which is especially helpful for scripted usage.
- 63,280
