Video into H.264 / MPEG-4 AVC

Problem

Transcode a video file by using the H.264 codec for dissemination purposes.

Solution

ffmpeg \
    -i input_file \
    -c:v libx264 \
    -preset veryslow \
    -crf 18 \
    -pix_fmt yuv420p \
    -c:a copy \
    output_file

Generic command

ffmpeg \
    -i input_file \
    -c:v libx264 \
    -preset preset_value \
    -crf constant_rate_factor \
    -pix_fmt yuv420p \
    -c:a copy \
    output_file

Command syntax

ffmpeg
starts the command
-i input_file
path, name and extension of the input file
-c:v libx264
The library libx264 re-encodes the video stream using the H.264 video codec.
-preset preset_value
A slower encoding preset means a better compression rate.
-crf constant_rate_factor
A parameter of 18 means a “visually lossless” compression.
-pix_fmt yuv420p
The pixel format for “YUV” colour space with 4:2:0 chroma subsampling and planar colour alignment is chosen for best compatibility.
-c:a copy
re-encodes the audio stream using the same audio codec
output_file
path, name and extension of the output file

Discussion

The video codec is specified by -codec:video, which may be abbreviated as -c:v (or -codec:v or -c:video). We advise to avoid the alias -vcodec. If the source should be RGB, then you might choose the video codec libx264rgb rather than libx264.

Possible -preset values for the H.264 codec include veryslow, slow, medium, fast and veryfast. Slower encoding means that more time is needed, but the compression rate is better.

You can use the parameter -qp 18 (quantisation parameter) rather than -crf 18 (constant rate factor) which gives a similar “visually lossless” result. The range of the scale for crf and qp for 8-bit is from 0 to 51, where 0 is lossless, approximately 18 is “visually lossless”, 23 is the default value and 51 is worst possible. For 10-bit the range is from 0 to 63. Most of the non-FFmpeg-based players cannot decode H.264 files holding lossless content.

yuv420p is a common 8-bit and yuv420p10le a 10-bit pixel format. The library libx264 supports both, but you cannot combine 8-bit and 10-bit in the same command, you need two commands.

By default the library libx264 will use the chroma subsampling scheme that matches closest the input file’s chroma subsampling. This can result in the “YUV” colour space with 4:4:4 or 4:2:2 or 4:2:0 chroma subsampling. Many of the non-FFmpeg-based players cannot decode H.264 files having a different chroma subsampling than 4:2:0. Therefore, in order to allow possibly all players to read the file, we suggest use to the yuv420p pixel format for dissemination purposes. And, as sadly usual in the computer world, “YUV” stands for the colour space Y′CBCR and not for Y′UV, which is used for PAL video.

You may add the parameter -movflags +faststart allowing to start playing before the whole file is loaded.

The audio codec is specified by -codec:audio, which is usually abbreviated as -c:a (-codec:a or -c:audio are also possible). We advise to avoid the alias -acodec. For silent videos you can replace -c:a copy by -an, for video with sound you may choose another audio codec.

Often the MP4 container (.mp4) is choses for wrapping H.264, but others are possible. If MP4 is chosen, then the audio codec should be Advanced Audio Coding (-c:a aac).

 

A Bash script allowing to perform this transcoding is included in our collection Bash Script for Audiovisual Preservation.


2021-01-02