Sunday, March 22, 2015

Join two videos using ffmpeg and fade filter

Imagine that you retrieved your video from your camera, tablet, mobile phone, Internet and converted it to mpeg. After resizing and encoding of 43.8 Mbps 1920x1080 input video produced by Canon camera we can end up with some more modest resolution. Using Avidemux we can precisely find and cut segments from one keyframe to another. You can append those segments like this:

ffmpeg -i sa0.mpg -i sa1.mpg -filter_complex \
 "[0:0] [0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]" \
 -map '[v]' -map '[a]' -c:v mpeg2video -q:v 2 out.mpg


We want video quality 2, we want mpeg video codecs, and we want both video and audio to be in output. Audio will be default mp2 to match video, since we didn't specify any. ffmpeg will print to standard output how it “understands” our instructions:

Output #0, mpeg, to 'out.mpg':
  Metadata:
    encoder         : Lavf55.3.100
    Stream #0:0: Video: mpeg2video, yuv420p, 960x540 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 90k tbn, 29.97 tbc
    Stream #0:1: Audio: mp2, 44100 Hz, stereo, s16, 128 kb/s


Whatever we didn't specify ffmpeg will or pick up from input video or adjust to match output container. I assume here that both videos are from the same original video and for that reason I didn't resize or resample videos, if that is required one can do it as preprocessing. That will append our two videos but it will be rather abrupt and not very smooth event. Luckily ffmpeg got rich library of filters and we can fade out and in to make smooth transition between two segments. We can fade just video or we can fade both, video and audio.

ffmpeg -i sa0.mpg\
 -vf fade=out:8928:36 -af afade=t=out:st=297.5:d=1.5\
 -c:v mpeg2video -q:v 2 output1.mpg


This is the first segment and we want to fade out last 36 frames and also last 1,5 seconds of audio. Video fade parameters are expressed in frames, start at frame and fade duration in frames, audio afade is about the same but in seconds. If we do not want to fade audio track we will omit audio filter story. Now we want to fade in next segment:

ffmpeg -i sa1.mpg\
 -vf fade=in:0:36 -af afade=t=in:st=0:d=1.5\
 -vcodec mpeg2video -q:v 2 output2.mpg


Starting from zero we fade in 36 frames of video and 1,5 seconds of audio signal. After we join those two segments we will have smooth fade out and in transition:

ffmpeg -i output1.mpg -i output2.mpg -filter_complex \
 "[0:0] [0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]" \
 -map '[v]' -map '[a]' -c:v mpeg2video -q:v 2 out.mpg


The same as we did without fading.

No comments:

Post a Comment