I'm trying to add a music intro and outro to a video. When the music is playing, a particular image should be shown as well, both before and after.

If I could overlap x seconds of the music with the video as well, that'd be even better.

I've done this sort of thing with only an audio file, but not sure how to do it with video.

So example, let's say I have a 30-second intro and a 30-second outro, each of which I wish to overlap by 10 seconds with the video.

So for 20 seconds, the image should show. Then the video should start for the last 10 seconds of the intro.

Then the first 10 seconds of outro will begin during the last 10 seconds of the video, and for the final 20 seconds of the outro, the image will appear.

Any help would be appreciated.


Step 1 Get the duration of the main file.

ffprobe main.mp4 -show_entries format=duration -of compact=nk=1:p=0 -v 0

This will print out a single value, like this


which is the duration in seconds.

Step 2 Perform the concat

ffmpeg -i main.mp4 -i intro.mp4 -i outro.mp4 \
  -filter_complex "[1]trim=0:20,setpts=PTS-STARTPTS[pre]; \
                   [2]trim=10,setpts=PTS-STARTPTS[post]; \
                   [pre][0][post]concat=n=3:v=1:a=0[v]; \
                   [1:a][0:a]acrossfade=d=10[a1];[a1][2:a]acrossfade=d=10[a]" \
  -map '[v]' -map '[a]' out.mp4

Since the video and audio from the intro/outro are treated differently, in terms of duration, we perform two separate concats.

First, the intro video is trimmed to leave out the last ten seconds. The outro is trimmed to leave out its first ten seconds. Then those two trimmed segments are sandwiched with the main video stream in the first concat.

For audio, the crossfades are performed in two stages. First, the intro with the main audio. Then, that result with the outro audio. Duration of crossfade is 10 seconds.

In case, the intro/outro music and image are separate files, use

ffmpeg -i main.mp4 -i intro.mp3 -i outro.mp3 \
       -loop 1 -framerate X -t 20 -i pre.jpg -loop 1 -framerate X -t 20 -i post.jpg \
  -filter_complex "[3][0][4]concat=n=3:v=1:a=0[v]; \
                   [1:a][0:a]acrossfade=d=10[a1];[a1][2:a]acrossfade=d=10[a]" \
  -map '[v]' -map '[a]' out.mp4

Here, X should be replaced with the framerate of the main file. The images should be of the same resolution as the video.

  • Really awesome, thanks. Just a few things that are a bit off:
    – devbanana
    Oct 12 '17 at 11:48
  • Sorry submitted too soon. So basically the audio of the video isn't being mixed with the audio of the last X seconds of the intro. So the intro plays, ends, then the video starts playing from that many seconds in. The other issue, I want to know if it is possible to set the bitrate of the intro/outro. The bitrate of the video's audio isn't great, so right now it's I think the intro/outro is matching that bitrate. The intro/outro are actually wav files.
    – devbanana
    Oct 12 '17 at 11:49
  • Here's the command I'm using. I actually needed the intro to overlap at 36 seconds, and the outro at 49 seconds. The duration of the video is 1977 seconds, so I'm using 1977-49 = 1928...let me know if this is wrong. ffmpeg -i "$video" -i "$intro" -i "$outro" \ -loop 1 -framerate 25 -t 36 -i $logo -loop 1 -framerate 25 -t 49 -i $logo \ -filter_complex "[3][0][4]concat=n=3:v=1:a=0[v]; \ [0:a]atrim=36:1928,asetpts=PTS-STARTPTS[amain]; \ [1:a][amain][2:a]concat=n=3:v=0:a=1[a]" \ -map '[v]' -map '[a]' out.mp4
    – devbanana
    Oct 12 '17 at 11:54
  • Modified commands to mix the audio streams. Input codecs don't affect the result of the output. Of course, if the input sample rate, bit depth or quality is low, then output can't sound better than that; only match it, at best.
    – Gyan
    Oct 12 '17 at 12:55
  • Thanks. Testing that now. Final question: will the first 10 seconds of the video stream appear? I only want the logo for the first 20 seconds, before the video begins. I'm visually impaired so I can't see what the visual output is, only hear the audio output. Just wanted to verify. Thanks for your help :)
    – devbanana
    Oct 12 '17 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.