As I started shooting videos from my drone, a pattern I repeatedly see is that I want to extract bits of a video for posting. Since I can’t be bothered to install dedicated video editing tools to do that, am learning how to do that in ffmpeg. Turns out it is pretty straight forward
Cut video
$ ffmpeg -i <InputVideo.mp4>\
-ss <start_from_seconds>\
-t <end_at_seconds>\
-c copy
<OutputVideo.mp4>
-ss
start_from_seconds - this is the start time point in original video-t
end_at_seconds - end time point in the original videoAdd Audio
This works by selecting 2 inputs and composing the output with stream selection using -map
. Eg: -map 0:v
selects video stream from first input. -shortest
makes the output length be the shortest of the two inputs (which usually is the case for my videos). Finally we specify the OutputFile.mp4
where we want it to go.
$ ffmpeg -i VideoInput.mp4\
-i AudioInput.mp3\
-map 0:v\
-map 1:a\
-c copy\
-shortest\
OutputFile.mp4
Adding Fadeout
Once I have the video slice with audio added, the last part to add a nice fade out effect. I prefer to start reducing the volume of audio first and then start fading video out to black. Here is a small piece of shell code that helps with that.
# Video Fade duration in seconds
v_fade_duration=2
# Audio fade duration
a_fade_duration=4
# Obtain from shell or set for actual values
input_file=$1
output_file=$2
# probe the duration to help compute actual start point in video
duration=$(ffprobe -select_streams v -show_streams "$1" 2>/dev/null |
awk -F= '$input_file == "duration"{print $2}')
v_final_cut=$(bc -l <<< "$duration - $v_fade_duration")
a_final_cut=$(bc -l <<< "$duration - $a_fade_duration")
# magic
ffmpeg -i "$1" \
-filter:v "fade=out:st=$v_final_cut:d=$v_fade_duration" \
-af "afade=t=out:st=$a_final_cut:d=$a_fade_duration" \
-c:v libx264 -crf 22 -preset veryfast -strict -2 "$output_file"