Development

Doing 2 pass encoding with FFmpeg

Understanding what two-pass video encoding is, why use it and how to do two-pass video encoding with FFmpeg.

Two-pass compared to one-pass

Two-pass media encoding means on the first pass of encoding, information is gathered and used in the second pass to perform optimized encoding.

Using two-pass encoding gives you control over the output file size. You can calculate this as bitrate = file size / duration.

One-pass encoding will do the encoding on the fly based on the parameters given to it.

Two-pass encoding will take longer as it goes over the video twice, look at two-pass encoding being the method to achieve a set file size and one-pass encoding to achieve a set quality.

How to do two-pass encoding with FFmpeg

Doing a simple two-pass encode with FFMpeg:

-b:v is the video bitrate.

-maxrate is maximum bitrate allowed (Optional).

-minrate is minimum bitrate allowed (Optional).

-bufsize is the video amount to enforce these rules for(Optional).

K = Kbit/s and M = Mbit/s.

ffmpeg -y -i input.mkv -c:v libx264 -b:v 2M -maxrate 3M -bufsize 1M -pass 1 -f mp4 NUL ^
 && ffmpeg -i input.mkv -c:v libx264 -b:v 2M -maxrate 3M -bufsize 1M -pass 2 output.mkv

Note If using Linux replace NUL with /dev/null and ^ with \.

The above command will do a two-pass encode for 2 Mbit/s with the max bitrate allowed being 3 Mbit/s. These rules are enforced for each 1 Mbit of video.

Example usage

source.mkv is a 31 second, 371 Megabyte, 720p video file with a bitrate of 98.295 Mbit/s. This is an extremely high bitrate for a resolution of 1280x720p, it is downscaled from 4k, 120 Mbps H.265/HEVC drone footage.

To get this into a 20 Megabyte file the calculation is:

Megabytes / duration x 8 = Megabits

Multiplying by 8 turns Megabytes into Megabits.

20 / 31 = 0.645 x 8 = 5.16

Now this in the FFmpeg two-pass encode command is:

ffmpeg -y -i source.mkv -c:v libx264 -b:v 5.16M -maxrate 6M -bufsize 2M -pass 1 -f mp4 NUL ^
&& ffmpeg -i source.mkv -c:v libx264 -b:v 5.16M -maxrate 6M -bufsize 2M -pass 2 output.mkv

For maxrate I rounded up to the next whole number just to give the encoding some legroom.

The video file size was 19.3 MB or 20,300,906 bytes. This is 351 Megabytes smaller than the source.

The source screenshot cropped
The output screenshot cropped

The output video as MP4:

 

For further documentation look here.

Share

Recent Posts

Kennington reservoir drained drone images

A drained and empty Kennington reservoir images from a drone in early July 2024. The…

1 year ago

Merrimu Reservoir drone images

Merrimu Reservoir from drone. Click images to view larger.

1 year ago

FTP getting array of file details such as size using PHP

Using FTP and PHP to get an array of file details such as size and…

2 years ago

Creating Laravel form requests

Creating and using Laravel form requests to create cleaner code, separation and reusability for your…

2 years ago

Improving the default Laravel login and register views

Improving the default Laravel login and register views in such a simple manner but making…

2 years ago

Laravel validation for checking if value exists in the database

Laravel validation for checking if a field value exists in the database. The validation rule…

2 years ago