Blog

How to * with FFmpeg

How to * with FFmpg

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
  • 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 contact 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!

Leave a Reply

Your email address will not be published. Required fields are marked *