How to * with FFmpeg
FFmpeg is a command-line software for multimedia file processing. I frequently use FFmpeg to batch-process multimedia files without opening big video editing software. Since I always need to google the exact commands I’m searching for, I decided to write this post to remind me (and you) of the commands for the most common scenarios.
Before you can use FFmpeg, be sure to add its path to the system paths, so you can run it in whatever folder you are working in.
Also, consider that the reported examples have file names without spaces (e.g. filename.mp4
), but if you are working with files whose names do have spaces, you should put them in double quotes (e.g. "file name.mp4"
).
In this post you will find instructions about:
- How to (re-)encode video files
- How to concatenate many files without re-encoding
- How to replace the audio track of a video
- How to extract audio from a video file
- How to change video container without re-encoding
- How to cut a video without re-encoding
- How to crop a video
Finally, if you want to edit a video without re-encoding you should consider combining what you will learn from the How to cut a video without re-encoding and How to concatenate many files sections.
How to (re-)encode video files with FFmpeg
If you want to compress a video file (and its audio stream) I usually suggest the following command:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac output.mp4
This will produce an H264 video stream with an Advanced Audio Coding audio stream. The crf
parameter goes from 0 (lossless) to 51 (abomination), with the typical values between 18 (almost indistinguishable from lossless) and 28 (small file, still good quality), and the default to 23. The lower this value is, the better the quality, but at the cost of file size.
If your audio is already encoded and you don’t want to re-encode it, you can use the copy
special codec value:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy output.mp4
Consider that re-encoding an already encoded file always ends up in quality degradation.
How to concatenate many files with FFmpeg
Let’s say you need to concatenate many video (or audio) files, but you don’t want to re-encode them in order to maintain quality unchanged, you can do this by typing:
ffmpeg -safe 0 -f concat -i list.tmp -c copy output.mp4
Where list.tmp
is a text file containing the filenames (and path, if they’re not in the folder where you are running the command) you want to stick together. The list must be in the following form:
file '.\part1.mp4'
file '.\part2.mp4'
file '.\part3.mp4'
If you are dealing with a lot of files, you can create this list automatically by writing the following batch file (sorry, I use Windows):
dir *.mp4 /b > filenames.tmp
for /f "tokens=* delims= " %%a in (filenames.tmp) do (
set /a N+=1
echo file ^'.\%%a^'>>list.tmp
)
del filenames.tmp
You can also put it together in a single batch file that will concatenate all mp4 files it will find in the folder where it is run, and also automatically delete the list.tmp
file at the end of the process:
dir *.mp4 /b > filenames.tmp
for /f "tokens=* delims= " %%a in (filenames.tmp) do (
set /a N+=1
echo file ^'.\%%a^'>>list.tmp
)
del filenames.tmp
ffmpeg -safe 0 -f concat -i list.tmp -c copy output.mp4
del list.tmp
Et voillà, a nice .bat
file that you can put in a folder of files you want to stick together and does all the work automatically when you run it. Of course, you can change the .mp4
extension in the first and penultimate lines to make it work also for other multimedia files, such as mp3, wav, mkv, and so on.
How to replace the audio track of a video with FFmpeg
If you need to replace the audio track of a video file, you can run this command:
ffmpeg -i original.mp4 -i new_audio.wav -c:a aac -c:v copy -map 0:0 -map 1:0 output.mp4
This command will generate an output.mp4
file, which is the same video from original.mp4
(no video re-encoding) but with the new_audio.wav
audio track, encoded in Advanced Audio Coding (I discourage putting uncompressed audio into video files).
How to extract audio from a video file with FFmpeg
If you need to decode the audio track of a video file as a separate .wav
file, you can run this command:
ffmpeg -i input.mp4 output.wav
This command will generate an output.wav
file, which is the decoded (PCM) audio track of the input.mp4
video file.
How to change video container without re-encoding with FFmpeg
If you have an audio/video stream encapsulated into, let’s say, an MKV, and you want to change the container to an mp4 (without re-encoding), you can run this command:
ffmpeg -i input.mkv -c copy output.mp4
The output.mp4
will contain the exact video and audio streams originally in input.mkv
, but in a mp4-compliant container.
How to cut a video without re-encoding with FFmpeg
If you want to keep only a portion of a video file, without re-encoding in order to maintain video quality unchanged, you should run this command:
ffmpeg -i whole.mp4 -ss 00:00:10 -c copy -t 00:00:30 part.mp4
This will create a part.mp4
video which is 30 seconds long and starts from the 10th second of the whole.mp4
file (timecode is in hh:mm:ss
format, the first timecode is the starting point and the second is the duration of the selected segment).
Consider that if you cut in the middle of a GOP you may have glitches at the beginning or at the end of the output file. But in my experience (and for what concerns my needs), this is rarely a big deal.
How to crop a video with FFmpeg
If you need to crop the frame of a video file, you can run this command:
ffmpeg -i fullframe.mp4 -vf "crop=256:128:64:32" -c:v libx264 -crf 18 -c:a copy cropped.mp4
This will create a cropped version of fullframe.mp4
by taking a 256x128
rectangle with the upper left corner at x = 64
, y = 32
pixel of the input file (the origin is in the upper left corner of the input file). The nice thing about the crop filter is that you can use math in the parameter string, e.g.:
ffmpeg -i fullframe.mp4 -vf "crop=in_w-32:in_h-32:16:16" -c:v libx264 -crf 18 -c:a copy cropped.mp4
will produce a cropped.mp4
video that is a 64-pixel crop from each border of the fullframe.mp4
input video.
I hope this helps, if you have comments or suggestions to improve the snippets please let me know in the comments!