Essential FFmpeg video encoding commands to convert media files using the H.264 video codec (libx264) and AAC audio standard. It is a practical solution for common post-production workflows, including how to re-encode video while using stream copy for audio to prevent quality loss.

Introduction

FFmpeg is a comprehensive, cross-platform solution utilized to record, convert, and stream audio and video. Here we demonstrate how to manipulate video and audio streams using the H.264 video codec and Advanced Audio Coding (AAC). Basically we are performing stream copying, audio re-encoding, optimization for progressive downloading via container metadata placement, and at the end we presented a standardized configuration optimized for modern web video platforms.

Methods

There are methods to consider:

  1. Re-encode the video but stream copy the audio.
  2. Re-encode the video and then re-encode audio using AAC.
  3. Optimize video for faster seeking.
  4. Recommendations for youtube deployment.

Stream Copy Audio

To re-encode the video but stream copy the audio:

ffmpeg -i input.avi -c:v libx264 -preset slow -crf 18 -c:a copy -pix_fmt yuv420p output.mkv

Re-encode Audio

If you also need to re-encode audio using AAC:

ffmpeg -i input.mov -c:v libx264 -preset slow -crf 18 -c:a aac -b:a 192k -pix_fmt yuv420p output.mkv

Optimize Fast Seeking

For MP4/M4V/MOV files, we can put the moov atom to the start of the file for faster seeking:

-movflags +faststart

An example of optimizing faster seeking when re-encoding a video and also re-encoding its audio to AAC.

ffmpeg -i input.mov -c:v libx264 -preset slow -crf 18 -c:a aac -b:a 192k -pix_fmt yuv420p -movflags +faststart output.mkv

Based on youtube’s recommended settings, we can deduce that the following options may be used:

ffmpeg \                # Calling the binary
-i input.mp4 \          # Input video file
-r 30000/1001 \         # Set the frame rate - optional
-vf scale="1920:1080" \ # Resize video - optional
-codec:v libx264 \      # X264 Video Codec
-crf 21 \               # Video Quality
-bf 2 \                 # Maximum 2 B-frames as per guideline
-flags +cgop \          # Closed GOP as per guideline
-pix_fmt yuv420p \      # Chroma subsampling 4:2:0 as per guideline
-c:a aac \              # Native FFMPEG AAC encoder
-b:a 128k \             # Audio Bitrate
-ac 2 \                 # Audio channels
-r:a 44100 \            # Audio samplerate
-map 0:v:0 \            # First file : video : first track
-map 0:a:0 \            # First file : audio : first track 
-movflags +faststart \   # Put MOOV atom at the front of the file
output.mp4

Removing optional fields result in:

ffmpeg \                # Calling the binary
-i input.mp4 \          # Input video file
-codec:v libx264 \      # X264 Video Codec
-crf 21 \               # Video Quality
-bf 2 \                 # Maximum 2 B-frames as per guideline
-flags +cgop \          # Closed GOP as per guideline
-pix_fmt yuv420p \      # Chroma subsampling 4:2:0 as per guideline
-c:a aac \              # Native FFMPEG AAC encoder
-b:a 128k \             # Audio Bitrate
-ac 2 \                 # Audio channels
-r:a 44100 \            # Audio samplerate 
-movflags faststart \   # Put MOOV atom at the front of the file
output.mp4

Or in a single line:

ffmpeg -i input.mp4 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -c:a aac -b:a 128k -ac 2 -r:a 44100 -movflags +faststart output.mp4

Note that the -c:a aac bit encodes to native FFMPEG AAC encoder instead of Fraunhofer FDK AAC codec library. To use Fraunhover SDK, instead of aac please use libfdk_aac, however it might requires you to recompile ffmpeg with --enable-libfdk-aac flag.

Sources