Documentation

Working With FFmpeg

Introduction

This guide describes how to create MP4 and WebM video files with FFmpeg so they can be used with Radiant Media Player (and HTML5 video in general) for on-demand progressive download streaming or pass on to a packager (like Shaka packager, MP4Box or Wowza Streaming Engine) for on-demand HLS or MPEG-DASH streaming. This guide also provides encoding tables for adaptive bitrate streaming for each codec. FFmpeg is a free and open-source software to transcode video and audio content.

General instruction for installing FFmpeg can be found here. Make sure you have the latest release version available for better results. Guidelines for compiling FFmpeg can be found here.

Enabling some encoding/decoding options with FFmpeg can trigger licensing requirements depending on your use-case. Radiant Media Player does not provide licensing for encoding/decoding media content. This guide is information only.

This guide will present encoding tables (a.k.a. encoding ladders) for each video codec. These tables are to be considered as indication for you to find the best ABR ladder for your streaming project. For production purposes you will likely want to use 2-pass encoding for your media files. This guide shows command line example for 1-pass encoding, you will need to adapat those command lines for 2-pass encoding for best results.

On-demand video transcoding to MP4 with AVC (H.264) video and AAC-LC audio - keyframes aligned renditions

In this section we will review how to produce MP4 files that work on devices where H.264 video and AAC-LC audio are supported. Specifically we will produce keyframes aligned video files at different bitrates and resolutions. This is a requirement for proper adaptive bitrate streaming in MPEG-DASH and HLS.

We use a 16:9 UHD 24 fps MOV input video file named input.mov. If you need a sample to play around, can get one from blender.org site.

ffmpeg -i input.mov -s 640x360 -c:v libx264 -b:v 560k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-low.mp4

Explanation:

  • -i input.mov: this is our input video file
  • -s 640x360: we tell FFmpeg to resize our input file to 640x360 while transcoding
  • -c:v libx264: we tell FFmpeg to use x264 as the video encoding library
  • -b:v 650k: the target video bitrate should be 650 kbps
  • -r 24: we want a constant framerate at 24 fps (which is the same as our source video file in this case)
  • -x264opts keyint=48:min-keyint=48:no-scenecut: we should have one keyframe every 48 frames (every 2 seconds). The keyframe injection should be constant
  • -profile:v main: we want H.264 main profile which is supported by most devices on the market while offering good transcoding quality and options
  • -preset fast: we use a fast preset for x264 transcoding
  • -movflags +faststart: the file should be web ready (moov box before mdat box)
  • -c:a libfdk_aac: we use libfdk_aac as our audio encoding library (note: your can also use -c:a aac if libfdk_aac is not included in your FFmpeg build - libfdk_aac will likely produce better results though)
  • -b:a 128k: the target audio bitrate should be 128 kbps
  • -ac 2: we want a stereo (2 audio channels) output
  • out-low.mp4: our output file should be a MP4 file named out-low.mp4

Once we have created our first rendition we can create others at different resolutions and bitrates.

ffmpeg -i input.mov -s 960x540 -c:v libx264 -b:v 1260k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-med.mp4
ffmpeg -i input.mov -s 1280x720 -c:v libx264 -b:v 2224k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-high.mp4
ffmpeg -i input.mov -s 1920x1080 -c:v libx264 -b:v 5050k -r 24 -x264opts keyint=48:min-keyint=48:no-scenecut -profile:v main -preset fast -movflags +faststart -c:a libfdk_aac -b:a 128k -ac 2 out-max.mp4

Encoding table for AVC (H.264) video:

Resolution Frame rate (fps) Video Bitrate (bps) Targeted bits/pixel
320x180 (16:9 SD) 24 140 000 0.1
480x270 (16:9 SD) 24 315 000 0.1
640x360 (16:9 SD) 24 560 000 0.1
960x540 (16:9 SD) 24 1 260 000 0.1
1280x720 (16:9 HD ready) 24 2 224 000 0.1
1920x1080 (16:9 Full HD) 24 5 050 000 0.1
2560x1440 (16:9 QHD) 24 9 000 000 0.1
3840x2160 (16:9 UHD) 24 20 000 000 0.1

A 0.1 bits/pixel ratio at 24 fps is generally a good compromise for H.264 encoding.

Feel free to play around with the numerous audio and video encoding settings that provide FFmpeg. An AAC encoding guide is available here. A H.264 encoding guide is available here.

On-demand video transcoding to MP4 with HEVC (H.265) video and HE-AACv2 audio - keyframes aligned renditions

Now that you know about H.264 encoding we can go ahead with H.265 encoding. H.265 claims to reduce file size up to 50% versus H.264 without loss of quality (in reality H.265 most notable gains are obtained at lower and higher bitrate). HE-AACv2 is a newer version of AAC which works well for low bitrate audio encoding.

Here is a FFmpeg command line that will produce H.265/HE-AACv2 content:

ffmpeg -i input.mov -s 640x360 -c:v libx265 -b:v 334k -r 24 -x265-params "keyint=48:min-keyint=48:no-open-gop=1:no-scenecut=1" -preset fast -movflags +faststart -c:a libfdk_aac -profile:a aac_he_v2 -b:a 96k -ac 2 out-low.mp4

Encoding table for HEVC (H.265) video:

Resolution Frame rate (fps) Video Bitrate (bps) Targeted bits/pixel
320x180 (16:9 SD) 24 83 000 0.06
480x270 (16:9 SD) 24 187 000 0.06
640x360 (16:9 SD) 24 334 000 0.06
960x540 (16:9 SD) 24 750 000 0.06
1280x720 (16:9 HD ready) 24 1 330 000 0.06
1920x1080 (16:9 Full HD) 24 3 000 000 0.06
2560x1440 (16:9 QHD) 24 5 350 000 0.06
3840x2160 (16:9 UHD) 24 12 000 000 0.06

A 0.06 bits/pixel ratio at 24 fps is generally a good compromise for H.265 encoding.

A H.265 encoding guide is available here.

On-demand video transcoding to MP4 with AV1 video and AAC audio

AOMedia Video 1 (AV1) is an open, royalty-free video coding format designed for video transmissions over the Internet. It was developed as a successor to VP9 by the Alliance for Open Media (AOMedia)

AV1 promises to offer 10-20% better quality than HEVC at similar bitrate and 20-30% better quality than VP9 at similar bitrate.

A guide for encoding with AV1 and FFmpeg is available here.

In the below example we use constrained quality (CQ) mode. We output to a MP4 container while using AAC for audio encoding. Note that it is possible to output to WebM container with OPUS audio as well. In our example we are setting 1 keyframe every 4 seconds. Our source is a 4K video at 24 FPS.

Here is a FFmpeg command line that will produce AV1/AAC content:

ffmpeg -i input.mov -s 640x360 -c:v libsvtav1 -minrate 139k -maxrate 416k -b:v 277k -crf 36 -preset 4 -r 24 -g 96 -keyint_min 96 -movflags +faststart -c:a aac -b:a 128k -ac 2 av1-360p.mp4

Encoding table for AV1 video:

Resolution Frame rate (fps) Average video bitrate (kbps) Minimun bitrate (kbps) Maximum bitrate (kbps) Target Quality (CQ - CRF) Targeted bits/pixel
320x180 (16:9 SD) 24 (or 25, 30) 70 35 105 38 0.05
480x270 (16:9 SD) 24 (or 25, 30) 156 78 234 37 0.05
640x360 (16:9 SD) 24 (or 25, 30) 277 139 416 36 0.05
960x540 (16:9 SD) 24 (or 25, 30) 627 314 941 34 0.05
1280x720 (16:9 HD ready) 24 (or 25, 30) 1110 555 1667 32 0.05
1920x1080 (16:9 Full HD) 24 (or 25, 30) 2500 1250 3750 31 0.05
2560x1440 (16:9 QHD) 24 (or 25, 30) 4450 2225 6675 24 0.05
3840x2160 (16:9 UHD) 24 (or 25, 30) 9990 4995 14985 15 0.05

A 0.05 bits/pixel ratio at 24 fps is generally a good compromise for AV1 encoding.

On-demand video transcoding to WebM with VP9 video and opus audio

VP9 is an open and royalty-free video coding format developed by Google. VP9 is the successor to VP8 and competes mainly with MPEG's High Efficiency Video Coding (HEVC/H.265).

A guide to VP9 encoding with FFmpeg is available here. Google has also made a guide available here.

In the below example we use constrained quality (CQ) mode. This mode is recommended when encoding VP9 files for on-demand viewing. This can get quite complex as we use tile-columns/threads as well, so please read Google guide for more details. In our example we use single pass encoding but you may want to use 2-pass encoding for better results in production. We are setting 1 keyframe every 4 seconds. Our source is a 4K video at 24 FPS.

Here is a FFmpeg command line that will produce VP9/Opus content:

ffmpeg -i input.mov -s 640x360 -c:v libvpx-vp9 -minrate 168k -maxrate 503k -b:v 335k -tile-columns 1 -g 96 -keyint_min 96 -threads 4 -quality good -speed 4 -crf 36 -c:a libopus -b:a 96k -ac 2 out-low.webm

Encoding table for VP9 video:

Resolution Frame rate (fps) Video Bitrate (kbps) Min Bitrate (kbps) Max Bitrate (kbps) Target Quality (CQ - CRF) tile-columns value Number of threads Targeted bits/pixel
320x180 (16:9 SD) 24 (or 25, 30) 84 42 126 38 0 2 0.06
480x270 (16:9 SD) 24 (or 25, 30) 188 94 282 37 0 2 0.06
640x360 (16:9 SD) 24 (or 25, 30) 335 168 503 36 1 4 0.06
960x540 (16:9 SD) 24 (or 25, 30) 750 375 113 34 1 4 0.06
1280x720 (16:9 HD ready) 24 (or 25, 30) 1340 670 2010 32 2 8 0.06
1920x1080 (16:9 Full HD) 24 (or 25, 30) 3000 1500 4500 31 2 8 0.06
2560x1440 (16:9 QHD) 24 (or 25, 30) 5350 2675 8025 24 3 16 0.06
3840x2160 (16:9 UHD) 24 (or 25, 30) 12000 6000 18000 15 3 16 0.06

A 0.06 bits/pixel ratio at 24 fps is generally a good compromise for VP9 encoding.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License.

©2015-2024 Radiant Media Player. All Rights Reserved.