Editing Videos with ffmpeg
This is a short and messy guide for editing files from the command line. While I do this on Linux, these commands will work on MacOS and Windows too. The reason I do this is because I am vision impaired and timeline editors are very cumbersome for me in particular. Sometimes I also feel this is faster, especially for sharing short clips scaled for chat platforms like Discord.
Create a Folder to act as a root for your project.
This is important for later when we want to concat multiple clips together.
ffmpeg -i input.mp4 -ss 00:00:00 -t 00:00:00 -async 1 -strict -2 output.mp4
Where the first timestamp is the starting point and the second timestamp is the length of the clip.
ffmpeg -i input.mp4 -y -vf fade=in:0:30 output.mp4
The fade is not a timeinput but actually the number of frames, so 30 = Half a Second on a 60FPS recording. There is a way to automate this to always be half a second, but math between shells can be kind of unreliable.
This is a little more annoying, and can be done one of two ways, I hope if there’s a better way to do this someone eventually enlightens me
ffmpeg -i input.mp4 -map 0:v:0 -c copy -f null -
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 input.mp4
These commands will tell you the total number of frames whichever input you give it.
Apply 30 Frame Fade Out by substracking 30 frames from that total.
ffmpeg -i input.mp4 -y -vf fade=out:120:30 output.mp4
Where 120 is replaced by the total number of frames.
Prefix Videos Numerically for the order you want them in.
- Creating a list for concat:
for f in ./*.mp4; do echo "file '$f'" >> project.txt; done
- Combining the Files:
ffmpeg -f concat -safe 0 -i project.txt -c copy project.mp4
Video scaling for upload limitations:
ffmpeg -i input.mp4 -vf "scale=iw/2:ih/2" output.mp4
This is exceptionally useful for Slack, Twitter and Discord, as well as more bandwidth conscious than uploading information that doesn’t need to be hundreds of megabytes when it could be tens of megabytes instead.
Export all video frames as images
ffmpeg -i "%1" frames/out-%03d.jpg
I don’t really recommend doing this but it’s possible, it will also take a LONG TIME on long videos and eat up an enormous amount of space. It’s also not really recommended on any filesystem on any OS to put more than 10,000 individual files in a single directory, so bear that in mind.
Replace Audio with music
This stuff gets into audio channels and sinks and i really recommend reading the ffmpeg doc to properly understand these commands as it would take a huge amount of technical explaination that already exists to properly explain these commands.
ffmpeg -y -stream_loop -1 -i "input_music.mp3" -i "input_video.mp4" \
-map 0:a:0 -map 1:v:0 -c:v copy -c:a aac -ac 2 -shortest output.mp4
This will replace the audio with whatever the input file is and loop it for the entirety of the video length, the original audio track will not be included. See below for just adding stock/background music to your video
Add Music to loop through the whole video
ffmpeg -i input_video.mp4 -filter_complex "amovie=input_music.mp3:loop=0,asetpts=N/SR/TB[input_music];
Then you have a background audio track that is accessible in other editors even.
While this doesn’t come off as very straight-forward or intuitive at first, it does work and for me is sometimes the better option than opening a GUI editor especially for taking just short clips to report a bug, or show off something I’m working on. I’ll also note that the most popular video editor on Linux is kdenlive, which unfortunately like most qt based applications does not handle accessibility scaling in a way that is friendly to my vision impairment. While I think it’s a fantastic piece of software, jumping through menus and configuration stuff that gtk apps typically just adopt from my main gnome config can be very frustrating.