FFmpeg - Encoding Optimal Videos for Streaming
We use a MPEG-4 Part 14 container, AAC audio and H.264 video. The preferred subtitle format is still being debated.
This combination is compatible with 'dumb players', the HTML5 'video' element and the streaming protocols: RTSP, RTMP, DASH, HLS, MSS & HDS.
Container Formats
MPEG-4 Part 14 is the most widely supported container format (here on referred to as MP4).
MP4 has quite a good list of official codecs but, this doesn't mean that ALL mediaplayers support them. Technically, MP4 can contain a stream of nearly any type using Private Streams.
Common media player devices have a fairly short list of supported codecs. Old media player software often has an even shorter list.
The HTML5 Video element basically only supports an MP4 container with AVC encoded video, AAC encoded audio and subtitles in WebVTT format. This is down to web browser compatibility, the element itself could support any codec and WhatWG actually suggests others.
Common Video File Extensions
- .AVI = Audio Video Interleave: Developed by Microsoft, Outdated
- .FLV = Flash Video: Developed by Adobe, Outdated
- .MKV = Matroska: Open Format, Current
- .MOV = QuickTime File Format: Developed by Apple, Outdated
- .MP4 = MPEG version 4: Developed by ISO/IEC Moving Picture Experts Group, Current
- .WebM = Developed by Google, Current
- .WMV = Windows Media Video, Developed by Microsoft, Outdated
Output MP4 file
ffmpeg -i <input.file> -f mp4 <output.file>
This command will automatically transcode all source streams. Audio will be transcoded using AAC and video using H.264.
Audio
Of all the audio codecs supported by the MP4 container, AAC has the balance of best quality compression and media player compatibility.
Some media players only support accessing a single audio track. Make sure that the default audio track is the first audio track in the file and that it is marked as default.
Some media players only support stereo AAC. Make sure that the default audio track is stereo, or it might be transcoded on the fly.
MP4 Compatible Audio Codecs
- MPEG-1 Audio Layer 1
- MPEG-1 Audio Layer 2
- MPEG-1 Audio Layer 3
- AAC
---
- AC-3
- E-AC-3
- Dolby TrueHD
---
- DTS
- DTS-HD
---
- Opus
- FLAC
- ALAC
- MLP
- ALS
- SLS
- LPCM
- DV Audio
- AMR
AAC Bitrate
As a rule of thumb, for audible transparency, use 64 kBit/s for each channel (so 128 kBit/s for stereo, 384 kBit/s for 5.1 surround sound).
Reference: [FFmpeg - Encode/AAC] (https://trac.ffmpeg.org/wiki/Encode/AAC)
Transcode audio to stereo AAC track
ffmpeg -i <input.file> -c:a libfdk_aac -ac 2 -b:a 128k -f mp4 <output.file>
Transcode a 5.1 audio track to 1 stereo AAC track and 1 5.1 AAC track, setting the stereo track as default
ffmpeg -i <input.file> -map 0:v -map 0:a:0 -c:a:0 libfdk_aac -ac:a:0 2 -b:a:0 128k -disposition:a:0 default -c:a:1 libfdk_aac -b:a:1 384k -f mp4 <output.file>
Video
Of all the video codecs supported by the MP4 container, H.264 has the balance of best quality compression and media player compatibility.
MP4 Compatible Video Codecs
- MPEG-H HEVC (H.265)
- MPEG-4 AVC (H.264)
- MPEG-4 Visual
- MPEG-2 Video
- MPEG-1 Video
- H.263
---
- VC-1
---
- VP8
- VP9
- AV1
---
- M-JPEG
- JPEG 2000
Transcode Video to H.264
ffmpeg -i <input.file> -c:v libx264 -f mp4 <output.file>
Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264)
H.264 Profile
The Baseline profile is supported by all media players that can consume MP4. That said, this profile is restrictive and in-efficient so is best reserved for low resolution video for low-powered mobile devices.
High Profile may be used for any resolution and is widely supported so should be used for higher resolution videos to be consumed by more powerful devices.
- 240p/360p: baseline
- 432p+: high
Reference: [Wikipedia - Advanced Video Coding](https://en.wikipedia.org/wiki/Advanced_Video_Coding) Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#h264profile)
H.264 Level
The more limited Media Players don't support all H.264 levels. For maximum compatibility it's best to use the lowest possible level for the given resolution.
- 240p: 2.1
- 360p/432p: 3.0
- 480p/576p/720p: 3.1
- 1080p: 4.0
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#h264level)
Bitrate
Target 4:3 bitrates:
| Name | Resolution | Link (Mbps) | Bitrate (Mbps) | Video (kbps) | Audio (kbps) | | ----------------- | ------------- | ------------- | ----------------- | ------------- | ------------- | | 240p | 320x240 | 1.0 | 0.64 | 576 | 64 | | 360p | 480x360 | 1.2 | 0.77 | 704 | 64 | | 480p | 640x480 | 1.5 | 0.96 | 896 | 64 | | 480p HQ | 640x480 | 2.0 | 1.28 | 1216 | 64 | | 576p | 768x576 | 2.3 | 1.47 | 1408 | 64 | | 576p HQ | 768x576 | 2.5 | 1.60 | 1536 | 64 | | 720p | 960x720 | 3.0 | 1.92 | 1856 | 64 | | 720p HQ | 960x720 | 4.0 | 2.56 | 2432 | 128 | | 1080p | 1440x1080 | 6.0 | 3.84 | 3712 | 128 | | 1080p HQ | 1440x1080 | 9.0 | 5.76 | 5632 | 128 | | 1080p Superbit | 1440x1080 | N/A | 20.32 | 20000 | 320 |
Target 16:9 bitrates:
| Name | Resolution | Link (Mbps) | Bitrate (Mbps) | Video (kbps) | Audio (kbps) | | ----------------- | ------------- | ------------- | ----------------- | ------------- | ------------- | | 240p | 424x240 | 1.0 | 0.64 | 576 | 64 | // Not exactly 16:9. Perhaps 426×240 would be a better resolution, being a bit closer to 16:9 | 360p | 640x360 | 1.5 | 0.96 | 896 | 64 | | 432p | 768x432 | 1.8 | 1.15 | 1088 | 64 | | 480p | 848x480 | 2.0 | 1.28 | 1216 | 64 | // Not exactly 16:9. | 480p HQ | 848x480 | 2.5 | 1.60 | 1536 | 64 | | 576p | 1024x576 | 3.0 | 1.92 | 1856 | 64 | | 576p HQ | 1024x576 | 3.5 | 2.24 | 2176 | 64 | | 720p | 1280x720 | 4.0 | 2.56 | 2496 | 64 | | 720p HQ | 1280x720 | 5.0 | 3.20 | 3072 | 128 | | 1080p | 1920x1080 | 8.0 | 5.12 | 4992 | 128 | | 1080p HQ | 1920x1080 | 12.0 | 7.68 | 7552 | 128 | | 1080p Superbit | 1920x1080 | N/A | 20.32 | 20000 | 320 |
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/)
// Investigate the inclusion of 288p and 144p instead of 240p
Transcode video at chosen bitrate with 2-pass encoding
ffmpeg -i <input.file> -c:v libx264 -b:v 4992k -preset veryslow -pass 1 -an -f null /dev/null && \ ffmpeg -i <input.file> -c:v libx264 -b:v 4992k -preset veryslow -pass 2 -c:a libfdk_aac -ac 2 -b:a:0 128k -f mp4 <output.file>
Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#twopass)
Maximum Bitrate
- 240p-1080p: -maxrate:v = double the target bitrate
- 1080p Superbit: -maxrate:v = 25Mbps
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#peakbitrate)
Buffer Size
- 240p/360p: -bufsize:v = 256k
- 432p-1080p: -bufsize:v = 1.5 second
- 1080p Superbit: -bufsize:v = 30Mbit
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#peakbitrate)
- FFmpeg Preset
A preset is a collection of options that will provide a certain encoding speed to compression ratio. Use the slowest preset that you have patience for. We use 'veryslow'.
Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#Preset)
FFmpeg Tune
You can optionally use 'tune' to change settings based upon the specifics of your input. We use 'animation' and 'film' for animated and live action videos respectively.
Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#Tune)
Colourspace
ffmpeg -i <input.file> -c:v libx264 -filter:v format=yuv420p -f mp4 <output.file>
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#colorspacetagging) Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#Encodingfordumbplayers)
Framerate
PAL uses 25fps, though 50fps can be used for HD and UHD video.
NTSC uses 29.97, though 59.94fps can be used for HD and UHD video.
Blu-Ray may also be encoded as 30fps or 60fps.
Some media players cannot reproduce high framerates.
Change Video Framerate
ffmpeg -i <input.file> -c:v libx264 -filter:v fps=25 -f mp4 <output.file>
Reference: [FFmpeg - Changing the frame rate](https://trac.ffmpeg.org/wiki/ChangingFrameRate)
Resolution
Interlaced video needs to be de-interlaced.
Anamorphic widescreen should be expanded to 16:9 resolution.
Resolutions of common media formats:
| Format | Resolution | Aspect Ratio | | ------------- | ------------- | ------------- | | VCD - PAL | 288p | 4:3 | | VCD - NTSC | 240p | 4:3 | | SVCD - PAL | 576i | 4:3 | | SVCD - NTSC | 480i | 4:3 | | SD - PAL | 576i | 4:3 or 16:9 | | SD - NTSC | 480i | 4:3 or 16:9 | | HD | 720p | 16:9 | | Full HD | 1080p | 16:9 | | UHD | 2160p | 16:9 |
References
- [Wikipedia - Standard-definition television](https://en.wikipedia.org/wiki/Standard-definition_television) - [Wikipedia - Video CD](https://en.wikipedia.org/wiki/Video_CD) - [Wikipedia - Super Video CD](https://en.wikipedia.org/wiki/Super_Video_CD) - [VideoHelp Forum - SVCD specification supported resolutions](https://forum.videohelp.com/threads/947-SVCD-specification-supported-resolutions) - [Wikipedia - DVD-Video](https://en.wikipedia.org/wiki/DVD-Video) - [Wikipedia - Blu-ray](https://en.wikipedia.org/wiki/Blu-ray)
Change Resolution and add Letterbox
ffmpeg -i <input.file> -c:v libx264 -filter:v "scale=(iw*sar)*min(640/(iw*sar)\,480/ih):ih*min(640/(iw*sar)\,480/ih), pad=640:480:(640-iw*min(640/iw\,480/ih))/2:(480-ih*min(640/iw\,480/ih))/2" -f mp4 <output.file>
Reference: [superuser - Ffmpeg upscale and letterbox a video](https://superuser.com/questions/891145/ffmpeg-upscale-and-letterbox-a-video)
x264 Options
Quantizer-Curve Compression
qcomp=0.9
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#quantizercurvecompression)
Minimum Quantization
qpmin=3
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#minimumquantization)
Per-Macroblock Bitrate-Control Lookahead
rc_lookahead=60
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#permacroblockbitratecontrollookahead)
Scene-Change Detection
scenecut=40
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#scenechangedetection)
Maximum Keyframe Interval
keyint = 12 seconds (360 frames at 30fps)
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#maximumkeyframeinterval)
Minimum Keyframe Interval
min-keyint=1
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#minimumkeyframeinterval)
Motion-Estimation Search Pattern
me=umh
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#motionestimationsearchpattern)
Motion-Estimation Search Range
- 240p-720p: me_range=32
- 1080p: me_range=48
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#motionestimationsearchrange)
Sub-Pixel Motion-Vector Refinement
subme=10
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#subpixelmotionvectorrefinement)
Predicted Motion Vectors
direct=auto
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#predictedmotionvectors)
Number of Reference Frames
ref=4
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#numberofreferenceframes)
B-Frames as Reference Frames
b_pyramid=none
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#bframesasreferenceframes)
P-Frame Early Skip Detection
- 240p-1080p: fast_pskip=1
- 1080p Superbit: fast_pskip=0
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#pframeearlyskipdetection)
Adaptive Number of B-Frames
- 240p/360p: b_adapt=0
- 432p+: b_adapt=2
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#adaptivenumberofbframes)
Maximum Number of B-Frames
- 240p/360p: bframes=0
- 432p-1080p: bframes=3
- 1080p Superbit: bframes=5
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#maximumnumberofbframes)
Rate-Distortion Optimization
trellis=2
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#ratedistortionoptimization)
Psycho-Visual Optimization
psy_rd=1.0
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#psychovisualoptimization)
DCT-Based Decimation
no-dct-decimate=1
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#dctbaseddecimation)
Deblocking
- 240p-1080p: deblock=0,0
- 1080p Superbit: deblock=-2,-1
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#deblocking)
Partitions
- 240p/360p: p4x4 = on
- 432p+: p4x4 = off
ffmpeg -i <input.file> -c:v libx264 -partitions -partp8x8,+partp4x4,-partb8x8,-parti8x8,-parti4x4 -f mp4 <output.file>
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#_4x4partitionsinpframes)
2-Pass Encoding
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#encodingstrategyandpasses) Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#twopass)
Subtitles
MP4 has limited support for embedded subtitles. Only VobSub, which is image based, is supported and widely playable.
There are some media players which only support 1 embedded subtitle track.
It is best to include subtitles as an external file.
We prefer VobSub for image based subtitles and SubRip for text based subtitles, though others are supported.
Reference: [Emby Documentation - Subtitles](https://emby.media/support/articles/Subtitles.html) Reference: [Kodi Wiki - Subtitles](https://kodi.wiki/view/Subtitles)
MP4 Compatible Subtitle Formats
- WebVTT
- TTXT
- VobSub
- SubRip as TTXT
- PGS as VobSub
Extract Image Based Subtitles
ffmpeg -i <input.file> -f subrip <output.file>
Extract Image Based Subtitles
ffmpeg -i <input.file> -f dvd_subtitle <output.file>
Reference: [FFmpeg - ExtractSubtitles](https://trac.ffmpeg.org/wiki/ExtractSubtitles)
Metadata
Strip All Metadata
ffmpeg -i <input.file> -map_metadata -1 -fflags +bitexact -flags:v +bitexact -flags:a +bitexact -f mp4 <output.file>
Reference: [Strip metadata from all formats with FFmpeg](https://superuser.com/questions/441361/strip-metadata-from-all-formats-with-ffmpeg)
Add Title Tag
ffmpeg -i <input.file> -metadata title="flibble" -f mp4 <output.file>
Add Year Tag
ffmpeg -i <input.file> -metadata date=0 -f mp4 <output.file>
Add Language Tags
ffmpeg -i <input.file> -metadata:s:a:0 language=eng -metadata:s:v:0 language=eng -f mp4 <output.file>
Reference: [stackoverflow - ffmpeg: set the language of an audio stream](https://stackoverflow.com/questions/44351606/ffmpeg-set-the-language-of-an-audio-stream)
Set Default Track
Optimise Video for Streaming
ffmpeg -i <input.file> -movflags +faststart -f mp4 <output.file>
Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264)
References
[Wikipedia - Comparison of video container formats](https://en.wikipedia.org/wiki/Comparison_of_video_container_formats) [List of True 16:9 Resolutions](https://pacoup.com/2011/06/12/list-of-true-169-resolutions/)
To Do
- Add documentation for converting interlaced to progressive
- Add documentation for expanding anamorphic widescreen
- Add documentation for MP4 tags
- Add documentation for finding TV Listings
- TVRDb - https://tvrdb.com/
- BBC Archive - https://genome.ch.bbc.co.uk/
- TVDB - https://www.thetvdb.com/
- Add documentation for nfo files
- TV Shows - https://kodi.wiki/view/NFO_files/TV_shows
- Episodes - https://kodi.wiki/view/NFO_files/Episodes
- Movies - https://kodi.wiki/view/NFO_files/Movies
- Add documentation for creating nfo files
- NFO Maker - https://nfo-maker.com/
- Ember Media Manager
- Decide whether to use SubRip or WebVTT as standard text-based subtitles
- WebVTT will not work with older media players.
- Some media players don't support VobSub either!
- Document 2 pass encoding
- Review 'setsar=1:1'
- Add 288p (PAL VCD, 4:3) to target bitrates
- Add 4k UHD target bitrates