FFmpeg - Encoding Optimal Videos for Streaming: Difference between revisions

From PiRho Knowledgebase
Jump to navigationJump to search
Created page with "* [Container Formats](#container-formats) * [Audio](#audio) * [Video](#video) * [Subtitles](#subtitles) * [Metadata](#metadata) * [References](#references) * [To Do](#to-do) We use a MPEG-4 Part 14 container, AAC audio and H.264 video. The preferred subtitle format is still being debated.<br/> This combination is compatible with 'dumb players', the HTML5 'video' element and the streaming protocols: RTSP, RTMP, DASH, HLS, MSS & HDS.<br/> == Container Formats == MPEG-4..."
 
Dex (talk | contribs)
mNo edit summary
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
* [Container Formats](#container-formats)
[[Category:FFmpeg]] [[Category:Streaming]]
* [Audio](#audio)
''A practical guide to producing highly compatible MP4 files using FFmpeg. This article explains container choice, codec selection, bitrate strategy, advanced x264 controls, and the real‑world constraints of web browsers, media players, and streaming protocols.''<br/>
* [Video](#video)
Modern streaming requires video files that are lightweight to decode, efficient to deliver, and universally compatible across browsers, mobile devices, TVs, and older “dumb players”. For maximum interoperability, this guide standardises on the MP4 container using H.264 (AVC) video and AAC audio, with optional external subtitles for broadest playback support.
* [Subtitles](#subtitles)
* [Metadata](#metadata)
* [References](#references)
* [To Do](#to-do)


We use a MPEG-4 Part 14 container, AAC audio and H.264 video. The preferred subtitle format is still being debated.<br/>
This article provides a practical, engineering‑driven approach to encoding optimal MP4 files using FFmpeg. It explains container and codec choices, bitrate selection, profile and level constraints, subtitle considerations, and advanced x264 tuning options. The focus is on producing files that stream smoothly, start quickly, and reliably play on the widest range of hardware and software environments.


This combination is compatible with 'dumb players', the HTML5 'video' element and the streaming protocols: RTSP, RTMP, DASH, HLS, MSS & HDS.<br/>
== Context ==
In theory, the MP4 container can hold almost any audio or video codec through private streams. In practice, however, real‑world media players support only a narrow subset. This becomes especially restrictive on older hardware, low‑power embedded devices, and simplified “dumb players” that ship with fixed decoding silicon.
 
Because of this, streaming workflows benefit from predictable, widely supported formats. H.264 video and AAC audio remain the most universally playable combination across browsers, TVs, set‑top boxes, consoles, mobile devices, and legacy players. Even though newer codecs exist, their hardware support is inconsistent and often fragmented across vendors and platforms.
 
Choosing MP4 with H.264 + AAC also simplifies distribution across multiple delivery methods. The same encoded file can be used for direct playback, progressive download, and HTTP‑based streaming formats such as HLS, DASH, and MSS. It also avoids the need for per‑device transcoding, reduces CPU load during playback, and improves battery performance on mobile devices.
 
These constraints and behaviours shape the recommendations in the rest of this article: aim for formats that are easy to decode, fast to start, compatible across environments, and efficient to stream over typical home broadband and mobile networks.


== Container Formats ==
== Container Formats ==
MPEG-4 Part 14 is the most widely supported container format (here on referred to as MP4).<br/>
The MP4 container (MPEG‑4 Part 14) is the most broadly supported media container across hardware decoders, software players, web browsers, and embedded “dumb players”. While MP4 can technically store almost any codec using private streams, most real‑world playback devices only recognise a much smaller set of audio and video formats. This makes MP4 ideal for streaming workflows where consistency and compatibility matter.


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.<br/>
MP4 is also the preferred container for HTML5 playback. Although the <nowiki><video></nowiki> element can theoretically support a wider range of codecs, browser vendors only guarantee universal support for MP4 containing H.264 video and AAC audio. This gives MP4 a practical advantage over more flexible containers like MKV, especially when targeting mobile devices or older embedded players.


Common media player devices have a fairly short list of supported codecs. Old media player software often has an even shorter list.<br/>
=== Why MP4? ===
MP4 offers:
* Wide hardware decode support 
* Efficient seeking and streaming behaviour 
* Compatibility with major streaming protocols (HLS, DASH, MSS, RTMP, RTSP) 
* Predictable behaviour across browsers, smart TVs, consoles, and older chipsets 
* Support for fast-start optimisation via <code>-movflags +faststart</code>


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.<br/>
These characteristics make MP4 the safest default container for general-purpose streaming and file delivery.


=== Common Video File Extensions ===
=== Common Video File Extensions ===
* .AVI = Audio Video Interleave: Developed by Microsoft, Outdated
; <code>.AVI</code> 
* .FLV = Flash Video: Developed by Adobe, Outdated
: One of Microsoft’s earliest container formats. Very limited, outdated, and unsuitable for modern streaming.
* .MKV = Matroska: Open Format, Current
 
* .MOV = QuickTime File Format: Developed by Apple, Outdated
; <code>.FLV</code> 
* .MP4 = MPEG version 4: Developed by ISO/IEC Moving Picture Experts Group, Current
: Flash Video format (Adobe). Obsolete now that Flash has been discontinued.
* .WebM = Developed by Google, Current
 
* .WMV = Windows Media Video, Developed by Microsoft, Outdated
; <code>.MKV</code> 
: The Matroska container. Modern, highly flexible, and open. Excellent for archival and advanced features, but not universally supported across hardware players or browsers.
 
; <code>.MOV</code> 
: Apple’s QuickTime container. Historically important but largely superseded by MP4.
 
; <code>.MP4</code> 
: ISO/IEC standard and the current mainstream format for streaming, web video, and device playback.
 
; <code>.WebM</code> 
: Google’s modern open container, typically paired with VP8/VP9/AV1 codecs. Excellent for web environments but less supported in hardware decoders.
 
; <code>.WMV</code> 
: Microsoft’s legacy Windows Media Video container. Outdated and largely unsupported in modern ecosystems.
 
=== Outputting an MP4 File ===
The most direct MP4 output command is:


=== Output MP4 file ===
<pre>
<pre>
ffmpeg -i <input.file> -f mp4 <output.file>
ffmpeg -i input -f mp4 output.mp4
</pre>
</pre>


This command will automatically transcode all source streams. Audio will be transcoded using AAC and video using H.264.<br/>
FFmpeg will automatically:
* transcode video to H.264
* transcode audio to AAC 
unless you explicitly specify alternative codecs.
 
This makes the basic MP4 output command a reliable default for converting arbitrary media into a streaming‑friendly format.


== Audio ==
== Audio ==
Of all the audio codecs supported by the MP4 container, AAC has the balance of best quality compression and media player compatibility.<br/>
AAC (Advanced Audio Coding) provides the best balance of quality, compression efficiency, and hardware compatibility for MP4‑based streaming. Although the MP4 container can technically hold many different audio codecs, real‑world media players—especially older or embedded systems—often support only a very limited subset. This makes AAC the safest and most predictable choice for both direct playback and streaming scenarios.


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.<br/>
Some devices only support a single audio track, and others only support stereo AAC. To maximise compatibility, always ensure:
* The **stereo AAC track is the first audio track**
* It is marked as the **default track**
* Bitrates are chosen appropriately for the target device class


Some media players only support stereo AAC. Make sure that the default audio track is stereo, or it might be transcoded on the fly.<br/>
These small decisions help prevent issues where a player either selects the wrong track or fails to play audio entirely.


=== MP4 Compatible Audio Codecs ===
=== MP4 Compatible Audio Codecs ===
* MPEG-1 Audio Layer 1
Although AAC is recommended, MP4 technically supports a wide range of audio formats:
* MPEG-1 Audio Layer 2
 
* MPEG-1 Audio Layer 3
* MPEG‑1 Audio Layer
* AAC
* MPEG‑1 Audio Layer II 
---
* MPEG‑1 Audio Layer III (MP3) 
* AC-3
* AAC
* E-AC-3
* AC‑3 
* Dolby TrueHD
* E‑AC‑3 
---
* Dolby TrueHD
* DTS
* DTS
* DTS-HD
* DTS‑HD 
---
* Opus
* Opus
* FLAC
* FLAC
* ALAC
* ALAC
* MLP
* MLP
* ALS
* ALS
* SLS
* SLS
* LPCM
* LPCM
* DV Audio
* DV Audio
* AMR
* AMR
 
In practice, support across actual playback devices is highly inconsistent. AAC remains the only codec with broad, reliable compatibility.
 
=== Recommended AAC Bitrate ===
For perceptually transparent audio (i.e., indistinguishable from the source to most listeners), a good rule of thumb is:
 
* **64 kbit/s per channel**
* Stereo → **128 kbit/s**
* 5.1 surround → **384 kbit/s**


=== AAC Bitrate ===
These values balance quality against streaming efficiency and align well with consumer playback hardware.
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).<br/>


Reference: [FFmpeg - Encode/AAC] (https://trac.ffmpeg.org/wiki/Encode/AAC)
=== Transcode Audio to Stereo AAC ===
Use this command to convert any input to a standard stereo AAC track:


=== Transcode audio to stereo AAC track ===
<pre>
<pre>
ffmpeg -i <input.file> -c:a libfdk_aac -ac 2 -b:a 128k -f mp4 <output.file>
ffmpeg -i input \
  -c:a libfdk_aac \
  -ac 2 \
  -b:a 128k \
  -f mp4 output.mp4
</pre>
</pre>


=== Transcode a 5.1 audio track to 1 stereo AAC track and 1 5.1 AAC track, setting the stereo track as default ===
This produces a widely compatible stereo track suitable for web video, mobile playback, and legacy devices.
 
=== Transcode a 5.1 Track to Both Stereo and 5.1 AAC ===
If you want to include both stereo and surround sound, while ensuring the stereo track is selected by default, use:
 
<pre>
<pre>
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>
ffmpeg -i input \
  -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.mp4
</pre>
</pre>
This layout:
* Preserves the surround track 
* Ensures maximum compatibility 
* Guarantees the stereo AAC track is selected automatically 
This two‑track approach works well for online platforms and local playback environments where the device capabilities are unknown.


== Video ==
== Video ==
Of all the video codecs supported by the MP4 container, H.264 has the balance of best quality compression and media player compatibility.<br/>
H.264 (AVC) remains the most universally compatible video codec for MP4 files. While the MP4 container can technically house a wide range of video formats, real hardware and embedded players often only support a very narrow subset. H.264 strikes the ideal balance between compression efficiency, quality, and decoder availability across browsers, smart TVs, mobile devices, and low‑power “dumb players.”
 
Newer codecs such as HEVC, VP9, and AV1 offer superior compression, but hardware support is inconsistent, and older devices may fail to decode them entirely. For maximum reach, H.264 continues to be the safest and most predictable option.


=== MP4 Compatible Video Codecs ===
=== MP4 Compatible Video Codecs ===
* MPEG-H HEVC (H.265)
MP4 can support many different video formats, though device support varies greatly:
* MPEG-4 AVC (H.264)
 
* MPEG-4 Visual
* MPEG‑H HEVC (H.265)
* MPEG-2 Video
* MPEG‑4 AVC (H.264)
* MPEG-1 Video
* MPEG‑4 Visual
* H.263
* MPEG‑2 Video
---
* MPEG‑1 Video
* VC-1
* H.263
---
* VC‑1 
* VP8
* VP8
* VP9
* VP9
* AV1
* AV1
---
* M‑JPEG 
* M-JPEG
* JPEG 2000
* JPEG 2000
 
Despite this broad technical compatibility, H.264 is by far the most reliably supported across modern and legacy players.


=== Transcode Video to H.264 ===
=== Transcode Video to H.264 ===
The simplest way to encode video for maximum compatibility is:
<pre>
<pre>
ffmpeg -i <input.file> -c:v libx264 -f mp4 <output.file>
ffmpeg -i input -c:v libx264 -f mp4 output.mp4
</pre>
</pre>


Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264)
This ensures the output file contains:
* H.264 video (widely supported) 
* AAC audio (if paired with matching audio settings) 
 
Unless overridden, this produces a safe baseline encode suitable for most platforms.


=== H.264 Profile ===
=== 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.<br/>
Profiles determine which H.264 features are available to the encoder and required by the decoder.
 
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.<br/>


* 240p/360p: baseline
* **Baseline Profile** 
* 432p+: high
  Used by the oldest and lowest‑power devices. Suitable for low‑resolution video (240p / 360p). 
  Restrictive and less efficient — use only when necessary.


Reference: [Wikipedia - Advanced Video Coding](https://en.wikipedia.org/wiki/Advanced_Video_Coding)  
* **High Profile** 
Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#h264profile)
  More efficient and higher quality. Supported by virtually all modern devices.   
  Recommended for all resolutions **432p and above**.


=== H.264 Level ===
=== 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.<br/>
H.264 Levels constrain parameters such as maximum resolution, bitrate, and frame rate.
Selecting the **lowest viable level** ensures the highest compatibility, especially with older players.


* 240p: 2.1
Recommended levels:
* 360p/432p: 3.0
* **240p → Level 2.1** 
* 480p/576p/720p: 3.1
* **360p / 432p → Level 3.0** 
* 1080p: 4.0
* **480p / 576p / 720p → Level 3.1** 
* **1080p → Level 4.0**


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#h264level)
Choosing higher levels unnecessarily can cause playback failures on older chipsets.


=== Bitrate ===
=== Bitrate ===
Target 4:3 bitrates:<br/>
Bitrate has a significant effect on visual quality and streaming stability. 
Use the dedicated tables in the next section to select appropriate bitrates for both **4:3** and **16:9** content.
 
For now, remember:
* Too low → visible artefacts and banding 
* Too high → increased buffering, incompatible with some decoders 
* Always match bitrate, profile, and level to the resolution and target devices 
 
Bitrate is deeply tied to buffer sizes, maximum peak rates, and motion complexity — all of which are addressed in the following sections.
 
== H.264 Profiles & Levels ==
H.264 provides multiple profiles and levels that define what encoding tools are used and what capabilities a decoder must support. Choosing the correct combination is essential for ensuring compatibility across different classes of media players, especially older hardware and embedded “dumb players.”
 
Profiles determine the *feature set* of the encoder and decoder. 
Levels determine the *constraints*, such as maximum resolution, bitrate, and frame rate.
 
Selecting the lowest profile and level that meets your needs maximises compatibility while maintaining efficient playback.
 
=== H.264 Profiles ===
The three most commonly encountered profiles are:
 
; **Baseline Profile**
: Designed for low‑power devices and older hardware. 
  Supports only the simplest encoding tools. 
  Recommended for low‑resolution content such as **240p** and **360p**.
 
; **Main Profile**
: More capable than Baseline but less widely relevant today. 
  Typically used for broadcast workflows, but largely superseded by High Profile.
 
; **High Profile**
: The most efficient and widely supported profile for modern devices. 
  Recommended for all resolutions **432p and above**, including HD and Full HD. 
  Provides significantly better compression efficiency than Baseline.
 
In practice:
* Use **Baseline** only when targeting very old or extremely low‑power devices. 
* Use **High Profile** for almost all modern streaming applications.
 
=== H.264 Levels ===
Levels impose strict limits on:
* Maximum frame size 
* Maximum bitrate 
* Maximum frame rate 
* Decoder buffer size 
 
Choosing an unnecessarily high level can cause playback failures on older chipsets, even if the file appears to play correctly on modern systems.
 
Recommended levels for common resolutions:
 
; **240p → Level 2.1**
: Sufficient for small frame sizes and low bitrates.
 
; **360p / 432p → Level 3.0**
: Appropriate for medium‑resolution SD content.
 
; **480p / 576p / 720p → Level 3.1**
: Suitable for standard-definition and 720p HD.
 
; **1080p → Level 4.0**
: Required for Full HD at typical streaming bitrates.
 
Choosing the lowest possible level that satisfies your resolution keeps the output maximally compatible with older playback devices.
 
=== Why Profiles and Levels Matter ===
* Using too *high* a profile may reduce compatibility with older or embedded devices. 
* Using too *high* a level may cause the decoder to reject the file outright. 
* Using too *low* a level or profile may prevent the encoder from using tools needed for efficient compression.
 
Correctly selected profiles and levels ensure:
* Smooth playback 
* Reduced buffering 
* Lower CPU/GPU load 
* Widespread compatibility across browsers, smart TVs, set‑top boxes, and mobile devices
 
== Bitrate Selection ==
Bitrate determines both visual quality and streaming performance. Too low, and compression artefacts become obvious; too high, and playback may stutter on low‑power devices or unreliable networks. The tables below provide practical, field‑tested targets for both **4:3** and **16:9** content at various resolutions.


| Name | Resolution | Link (Mbps) | Bitrate (Mbps) | Video (kbps) | Audio (kbps) |
These values balance:
| ----------------- | ------------- | ------------- | ----------------- | ------------- | ------------- |
* H.264 encoder efficiency 
| 240p | 320x240 | 1.0 | 0.64 | 576 | 64 |
* Typical broadband and mobile network constraints 
| 360p | 480x360 | 1.2 | 0.77 | 704 | 64 |
* Hardware decoder capabilities across legacy and modern devices 
| 480p | 640x480 | 1.5 | 0.96 | 896 | 64 |
* Consistent perceptual quality for general-purpose streaming 
| 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:<br/>
Use the lowest bitrate that preserves a clean image without visible macroblocking, and adjust upward only for high‑motion or high‑detail content.


| Name | Resolution | Link (Mbps) | Bitrate (Mbps) | Video (kbps) | Audio (kbps) |
=== 4:3 Target Bitrates ===
| ----------------- | ------------- | ------------- | ----------------- | ------------- | ------------- |
{| class="wikitable"
| 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
! Name !! Resolution !! Link (Mbps) !! Bitrate (Mbps) !! Video (kbps) !! Audio (kbps)
| 360p | 640x360 | 1.5 | 0.96 | 896 | 64 |
|-
| 432p | 768x432 | 1.8 | 1.15 | 1088 | 64 |
| 240p || 320×240 || 1.0 || 0.64 || 576 || 64
| 480p | 848x480 | 2.0 | 1.28 | 1216 | 64 | // Not exactly 16:9.
|-
| 480p HQ | 848x480 | 2.5 | 1.60 | 1536 | 64 |
| 360p || 480×360 || 1.2 || 0.77 || 704 || 64
| 576p | 1024x576 | 3.0 | 1.92 | 1856 | 64 |
|-
| 576p HQ | 1024x576 | 3.5 | 2.24 | 2176 | 64 |
| 480p || 640×480 || 1.5 || 0.96 || 896 || 64
| 720p | 1280x720 | 4.0 | 2.56 | 2496 | 64 |
|-
| 720p HQ | 1280x720 | 5.0 | 3.20 | 3072 | 128 |
| 480p HQ || 640×480 || 2.0 || 1.28 || 1216 || 64
| 1080p | 1920x1080 | 8.0 | 5.12 | 4992 | 128 |
|-
| 1080p HQ | 1920x1080 | 12.0 | 7.68 | 7552 | 128 |
| 576p || 768×576 || 2.3 || 1.47 || 1408 || 64
| 1080p Superbit | 1920x1080 | N/A | 20.32 | 20000 | 320 |
|-
| 576p HQ || 768×576 || 2.5 || 1.60 || 1536 || 64
|-
| 720p || 960×720 || 3.0 || 1.92 || 1856 || 64
|-
| 720p HQ || 960×720 || 4.0 || 2.56 || 2432 || 128
|-
| 1080p || 1440×1080 || 6.0 || 3.84 || 3712 || 128
|-
| 1080p HQ || 1440×1080 || 9.0 || 5.76 || 5632 || 128
|-
| 1080p Superbit || 1440×1080 || N/A || 20.32 || 20000 || 320
|}


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/)
=== 16:9 Target Bitrates ===
{| class="wikitable"
! Name !! Resolution !! Link (Mbps) !! Bitrate (Mbps) !! Video (kbps) !! Audio (kbps)
|-
| 240p || 424×240 || 1.0 || 0.64 || 576 || 64
|-
| 360p || 640×360 || 1.5 || 0.96 || 896 || 64
|-
| 432p || 768×432 || 1.8 || 1.15 || 1088 || 64
|-
| 480p || 848×480 || 2.0 || 1.28 || 1216 || 64
|-
| 480p HQ || 848×480 || 2.5 || 1.60 || 1536 || 64
|-
| 576p || 1024×576 || 3.0 || 1.92 || 1856 || 64
|-
| 576p HQ || 1024×576 || 3.5 || 2.24 || 2176 || 64
|-
| 720p || 1280×720 || 4.0 || 2.56 || 2496 || 64
|-
| 720p HQ || 1280×720 || 5.0 || 3.20 || 3072 || 128
|-
| 1080p || 1920×1080 || 8.0 || 5.12 || 4992 || 128
|-
| 1080p HQ || 1920×1080 || 12.0 || 7.68 || 7552 || 128
|-
| 1080p Superbit || 1920×1080 || N/A || 20.32 || 20000 || 320
|}


// Investigate the inclusion of 288p and 144p instead of 240p
; Note:
: 424×240 and 848×480 are not mathematically exact 16:9. 
: 426×240 is a closer 16:9 match for low‑resolution 240p content.
 
=== 2‑Pass Encoding Example ===
For achieving the best quality at a fixed target bitrate:


==== Transcode video at chosen bitrate with 2-pass encoding ====
<pre>
<pre>
ffmpeg -i <input.file> -c:v libx264 -b:v 4992k -preset veryslow -pass 1 -an -f null /dev/null && \
ffmpeg -i input \
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>
  -c:v libx264 -b:v 4992k -preset veryslow -pass 1 -an -f null /dev/null && \
ffmpeg -i input \
  -c:v libx264 -b:v 4992k -preset veryslow -pass 2 \
  -c:a libfdk_aac -ac 2 -b:a 128k \
  -f mp4 output.mp4
</pre>
</pre>


Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#twopass)
This workflow:
* Analyses motion and complexity on pass 1 
* Allocates bits optimally on pass 2 
* Preserves detail more effectively at the same bitrate 


=== Maximum Bitrate ===
=== Maximum Bitrate ===
* 240p-1080p: -maxrate:v = double the target bitrate
* 240p–1080p: <code>-maxrate</code> should be **double** the target bitrate
* 1080p Superbit: -maxrate:v = 25Mbps
* 1080p Superbit: <code>-maxrate</code> should be **25 Mbps**


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#peakbitrate)
=== Buffer Size ===
* 240p / 360p → <code>-bufsize</code> = 256k 
* 432p–1080p → <code>-bufsize</code> ≈ 1.5 seconds of video 
* 1080p Superbit → <code>-bufsize</code> ≈ 30 Mbit 


=== Buffer Size ===
== Presets, Tune & Colourspace ==
* 240p/360p: -bufsize:v = 256k
FFmpeg’s x264 encoder exposes a wide range of parameters that control the trade‑off between encoding speed and output quality. Rather than configuring every option manually, x264 provides a set of predefined “presets” and “tunes” that adjust groups of settings together.
* 432p-1080p: -bufsize:v = 1.5 second
 
* 1080p Superbit: -bufsize:v = 30Mbit
Using the correct preset and tune ensures good compression efficiency, stable quality across different content types, and predictable encode times.
 
=== FFmpeg Presets ===
A preset represents a collection of encoder settings that balance encoding speed against compression efficiency. Slower presets take longer to encode but deliver better visual quality at the same bitrate.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#peakbitrate)
Common presets (from fastest to slowest):
* ultrafast 
* superfast 
* veryfast 
* faster 
* fast 
* medium 
* slow 
* slower 
* veryslow 
* placebo (not recommended; extremely slow with little practical gain)


## FFmpeg Preset
General guidance:
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'.<br/>
* Use the **slowest preset you have patience for**.
* For high‑quality streaming, **veryslow** offers excellent efficiency with predictable results.


Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#Preset)
Choosing a slower preset reduces file size for the same quality, or increases quality at a fixed bitrate, by allowing the encoder to search more possibilities.


=== FFmpeg Tune ===
=== 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.<br/>
Tunes let you optimise the encoder for specific types of content. They adjust psycho‑visual optimisations, motion estimation behaviour, and noise handling.
 
Recommended tunes:
* <code>film</code> — for live‑action material 
  (Optimises for natural grain, fine detail, and motion characteristics.)
* <code>animation</code> — for animated content 
  (Optimises for sharp edges, flat colours, and low‑noise frames.)


Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#Tune)
Use a tune only when the content clearly matches one of these categories. Leaving the tune unset is perfectly fine for mixed‑content or general‑purpose encoding.


=== Colourspace ===
=== Colourspace ===
For maximum compatibility across hardware decoders, web browsers, and older media players, always ensure the video is encoded using **yuv420p**.
Many devices will fail to play content encoded in yuv422p or yuv444p, even if the container and codec are otherwise valid.
Convert the colourspace explicitly:
<pre>
<pre>
ffmpeg -i <input.file> -c:v libx264 -filter:v format=yuv420p -f mp4 <output.file>
ffmpeg -i input \
  -c:v libx264 \
  -filter:v format=yuv420p \
  -f mp4 output.mp4
</pre>
</pre>


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#colorspacetagging)
This guarantees broad playback support, especially in HTML5 environments and set‑top boxes.
Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#Encodingfordumbplayers)
 
== Framerate ==
Framerate determines how many images (frames) are displayed per second. Different broadcast standards, playback devices, and capture sources use different framerates, and choosing the correct one is essential for smooth playback and broad compatibility.
 
Older or embedded media players can struggle with unusually high framerates, even if the resolution and bitrate are otherwise within specification. For maximum compatibility across streaming devices, stick to the framerates commonly associated with the source format unless you have a specific reason to change them.
 
=== PAL and NTSC Standards ===
The two dominant historical broadcast standards define the baseline expectations for framerate:
 
* **PAL** 
  Uses **25 fps**, with **50 fps** being suitable for HD and UHD content when higher motion clarity is desired.
  Common in Europe, Australia, and many parts of Asia and Africa.
 
* **NTSC** 
  Uses **29.97 fps**, with **59.94 fps** being used for HD and UHD.
  Common in North America, Japan, South Korea, and some regions of South America.
 
These framerates are deeply ingrained into the decoding hardware of many devices, especially older set‑top boxes and TVs.


=== Framerate ===
Blu‑ray formats also allow **30 fps** and **60 fps**, but some low‑power players may still struggle with these higher rates.
PAL uses 25fps, though 50fps can be used for HD and UHD video.<br/>


NTSC uses 29.97, though 59.94fps can be used for HD and UHD video.<br/>
=== High‑Framerate Considerations ===
Some devices—particularly older mobile chipsets, embedded systems, and legacy televisions—may fail to decode or smooth‑play high‑framerate content, even when the codec and level are supported.


Blu-Ray may also be encoded as 30fps or 60fps.<br/>
For maximum compatibility:
* Prefer **25 fps** (PAL sources) 
* Prefer **29.97 fps** (NTSC sources) 
* Use **50 fps / 59.94 fps** only when targeting modern hardware


Some media players cannot reproduce high framerates.<br/>
=== Change Video Framerate ===
To convert a video to a specific framerate:


==== Change Video Framerate ====
<pre>
<pre>
ffmpeg -i <input.file> -c:v libx264 -filter:v fps=25 -f mp4 <output.file>
ffmpeg -i input \
  -c:v libx264 \
  -filter:v fps=25 \
  -f mp4 output.mp4
</pre>
</pre>


Reference: [FFmpeg - Changing the frame rate](https://trac.ffmpeg.org/wiki/ChangingFrameRate)
This command re‑encodes the video at the desired framerate, ensuring consistent playback across devices and streaming environments.


=== Resolution ===
== Resolution ==
Interlaced video needs to be de-interlaced.<br/>
Resolution defines the pixel dimensions of the video and has a direct impact on compatibility, quality, and bitrate requirements. Different legacy standards (VCD, SVCD, PAL, NTSC) and modern formats (HD, Full HD, UHD) come with established resolutions that many devices still expect.


Anamorphic widescreen should be expanded to 16:9 resolution.<br/>
When preparing streaming‑ready MP4 files, ensure the resolution is correct for the content. This includes de‑interlacing older material, expanding anamorphic sources to square pixels, and choosing resolutions appropriate for the target devices.


Resolutions of common media formats:<br/>
=== Important Notes ===
* **Interlaced video must be de‑interlaced** to avoid visible combing artefacts and uneven motion. Many hardware players assume progressive content.
* **Anamorphic widescreen should be expanded** to a proper 16:9 square‑pixel resolution. Storing anamorphic video without correction may cause distorted playback.
* **Stick to standardised resolutions** wherever possible to ensure predictable decoder behaviour and maximum compatibility.


| Format | Resolution | Aspect Ratio |
=== Common Resolutions by Format ===
| ------------- | ------------- | ------------- |
The following table lists widely recognised resolutions for legacy and modern media formats:
| 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 ====
; **VCD – PAL** 
- [Wikipedia - Standard-definition television](https://en.wikipedia.org/wiki/Standard-definition_television)
: 288p (4:3)
- [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 ====
; **VCD – NTSC** 
<pre>
: 240p (4:3)
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>
 
</pre>
; **SVCD – PAL**
: 576i (4:3)


Reference: [superuser - Ffmpeg upscale and letterbox a video](https://superuser.com/questions/891145/ffmpeg-upscale-and-letterbox-a-video)
; **SVCD – NTSC** 
: 480i (4:3)


=== x264 Options ===
; **SD – PAL** 
: 576i (4:3 or 16:9)


==== Quantizer-Curve Compression ====
; **SD – NTSC** 
qcomp=0.9<br/>
: 480i (4:3 or 16:9)


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#quantizercurvecompression)
; **HD** 
: 720p (16:9)


==== Minimum Quantization ====
; **Full HD** 
qpmin=3<br/>
: 1080p (16:9)


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#minimumquantization)
; **UHD** 
: 2160p (16:9)


==== Per-Macroblock Bitrate-Control Lookahead ====
=== Change Resolution and Add Letterbox ===
rc_lookahead=60<br/>
When converting between resolutions or preparing content for a specific aspect ratio, FFmpeg’s scaling and padding filters allow precise control over the output.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#permacroblockbitratecontrollookahead)
The following example:
* Scales the input video while preserving aspect ratio 
* Adds a letterbox (black bars) to fit a target size 
* Ensures correct centring and padding 


==== Scene-Change Detection ====
<pre>
scenecut=40<br/>
ffmpeg -i input \
  -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.mp4
</pre>


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#scenechangedetection)
This example targets a **640×480 (4:3)** output frame with proper letterboxing while maintaining the original aspect ratio of the input.


==== Maximum Keyframe Interval ====
=== Notes on Handling Aspect Ratios ===
keyint = 12 seconds (360 frames at 30fps)<br/>
* The `sar` (sample aspect ratio) value is important for correcting anamorphic sources. 
* `scale` calculates the largest possible size that fits inside the target frame without cropping. 
* `pad` adds black bars to fill any unused space, preserving the intended composition.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#maximumkeyframeinterval)
These techniques are especially useful when converting archival material, preparing video for older devices, or ensuring predictable behaviour across diverse playback environments.


==== Minimum Keyframe Interval ====
== Advanced x264 Options ==
min-keyint=1<br/>
While presets and tunes provide broad optimisation, x264 also exposes many low‑level encoder controls that allow fine‑tuning of quality, motion handling, and compression behaviour. These settings influence how efficiently bits are allocated, how motion is predicted, and how consistently quality is maintained across different types of scenes.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#minimumkeyframeinterval)
The options below reflect proven, practical configurations suitable for high‑quality streaming, balanced efficiency, and broad compatibility with both modern and legacy decoders.


==== Motion-Estimation Search Pattern ====
=== Quantizer & Rate Control ===
me=umh<br/>


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#motionestimationsearchpattern)
; <code>qcomp=0.9</code>
: Adjusts quantizer curve compression. A higher value allocates bits more evenly, reducing noticeable quality dips in complex scenes.


==== Motion-Estimation Search Range ====
; <code>qpmin=3</code>
* 240p-720p: me_range=32
: Sets the minimum quantiser value, limiting how much compression can aggressively reduce detail. Helps maintain consistency in flat‑coloured regions.
* 1080p: me_range=48


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#motionestimationsearchrange)
; <code>rc_lookahead=60</code>
: Determines how many future frames the encoder analyses for rate control. Long lookahead improves bitrate distribution and aids in anticipating motion.


==== Sub-Pixel Motion-Vector Refinement ====
=== Motion Analysis ===
subme=10<br/>


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#subpixelmotionvectorrefinement)
; <code>me=umh</code>
: Enables Uneven Multi‑Hexagon motion estimation, which provides high‑quality motion matching at the cost of additional encoding time.


==== Predicted Motion Vectors ====
; <code>me_range=32</code> (240p–720p) 
direct=auto<br/>
; <code>me_range=48</code> (1080p)
: Defines the radius for motion search. Higher resolutions benefit from a wider search range to capture large movements accurately.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#predictedmotionvectors)
; <code>subme=10</code>
: Enables the most precise sub‑pixel motion refinement. This significantly improves detail during motion but increases encode time.


==== Number of Reference Frames ====
; <code>direct=auto</code>
ref=4<br/>
: Automatically selects the most efficient direct‑mode motion vector prediction method.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#numberofreferenceframes)
=== Scene and Frame Structure ===


==== B-Frames as Reference Frames ====
; <code>scenecut=40</code>
b_pyramid=none<br/>
: Adjusts sensitivity to scene changes. Helps insert keyframes where a sharp cut occurs, improving seekability and visual clarity.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#bframesasreferenceframes)
; <code>keyint=360</code> (at 30fps)
: Sets the maximum interval between keyframes (12 seconds). Balances streaming efficiency with good random‑access behaviour.


==== P-Frame Early Skip Detection ====
; <code>min-keyint=1</code>
* 240p-1080p: fast_pskip=1
: Ensures the encoder can place a keyframe at a genuine scene change without artificial restrictions.
* 1080p Superbit: fast_pskip=0


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#pframeearlyskipdetection)
=== Reference Frames & B‑Frame Behaviour ===


==== Adaptive Number of B-Frames ====
; <code>ref=4</code>
* 240p/360p: b_adapt=0
: Specifies the number of reference frames. More references improve compression but may reduce decoder compatibility on very old hardware.
* 432p+: b_adapt=2


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#adaptivenumberofbframes)
; <code>b_pyramid=none</code>
: Disables hierarchical B‑frames. This setting maximises compatibility with older devices and “dumb players.


==== Maximum Number of B-Frames ====
; <code>b_adapt=0</code> (240p / 360p
* 240p/360p: bframes=0
; <code>b_adapt=2</code> (432p and above)
* 432p-1080p: bframes=3
: Controls how B‑frames are placed. Adaptive placement (value 2) improves efficiency at higher resolutions.
* 1080p Superbit: bframes=5


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#maximumnumberofbframes)
; <code>bframes=0</code> (240p / 360p) 
; <code>bframes=3</code> (432p–1080p) 
; <code>bframes=5</code> (1080p Superbit)
: Determines how many B‑frames may appear consecutively. Higher values improve compression at higher resolutions.


==== Rate-Distortion Optimization ====
; <code>fast_pskip=1</code> 
trellis=2<br/>
: Enables early skip detection for P‑frames. 
; <code>fast_pskip=0</code> for 1080p Superbit 
: Disabling improves fidelity but increases file size.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#ratedistortionoptimization)
=== Psycho‑Visual Enhancements ===


==== Psycho-Visual Optimization ====
; <code>psy_rd=1.0</code>
psy_rd=1.0<br/>
: Controls psycho‑visual rate‑distortion optimisation. Helps preserve natural detail and edges.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#psychovisualoptimization)
; <code>trellis=2</code>
: Enables full trellis quantization for optimal transform coefficient decisions. Significantly improves compression efficiency.


==== DCT-Based Decimation ====
; <code>no-dct-decimate=1</code>
no-dct-decimate=1<br/>
: Prevents the encoder from removing DCT blocks it deems unnecessary. Helps preserve texture in detailed scenes.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#dctbaseddecimation)
=== Deblocking ===


==== Deblocking ====
; <code>deblock=0:0</code> (240p–1080p)
* 240p-1080p: deblock=0,0
: Neutral deblocking filter values suitable for most scenarios.
* 1080p Superbit: deblock=-2,-1


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#deblocking)
; <code>deblock=-2:-1</code> (1080p Superbit)
: Stronger sharpened detail for high‑bitrate, high‑quality encodes.


=== Partitions ===
=== Partitions ===
* 240p/360p: p4x4 = on
Partitions control how the encoder breaks frames into blocks for motion estimation.
* 432p+: p4x4 = off
 
; <code>p4x4 = on</code> (240p / 360p
: Smaller blocks help preserve detail at low resolutions.
 
; <code>p4x4 = off</code> (432p and above) 
: Disabling improves efficiency without noticeable quality loss at higher resolutions.
 
Example command for disabling 4×4 partitions at higher resolutions:


<pre>
<pre>
ffmpeg -i <input.file> -c:v libx264 -partitions -partp8x8,+partp4x4,-partb8x8,-parti8x8,-parti4x4 -f mp4 <output.file>
ffmpeg -i input -c:v libx264 \
  -partitions -partp8x8,+partp4x4,-partb8x8,-parti8x8,-parti4x4 \
  -f mp4 output.mp4
</pre>
</pre>


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#_4x4partitionsinpframes)
=== Summary ===
These advanced settings provide fine‑grain control over how x264 encodes motion, distributes bits, handles scene transitions, and maintains visual quality. While presets and tunes handle broad optimisation, these parameters allow for highly refined encodes suitable for professional archiving, high‑motion content, and advanced streaming scenarios.
 
== Subtitles ==
Subtitles are an important part of accessibility and content localisation. However, the MP4 container offers limited support for embedded subtitle formats, and different playback devices vary widely in what they accept. For maximum compatibility across browsers, TVs, mobile devices, and “dumb players,” it is often best to distribute subtitles as external files rather than relying on embedded streams.


=== 2-Pass Encoding ===
MP4 technically supports a small set of subtitle types, but real‑world device support is inconsistent. Image‑based formats such as VobSub are more universally recognised in MP4 than text‑based formats, but still not guaranteed. Many players support only a single embedded subtitle track.


Reference: [Lighterra - Video Encoding Settings for H.264 Excellence](https://www.lighterra.com/papers/videoencodingh264/#encodingstrategyandpasses)
For these reasons:
Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#twopass)
* Prefer **external subtitles** whenever possible 
* Use **VobSub** for image‑based subtitles 
* Use **SubRip (SRT)** or **WebVTT** for text‑based subtitles 
* Avoid relying on multiple embedded subtitle tracks 


== Subtitles ==
=== MP4 Compatible Subtitle Formats ===
MP4 has limited support for embedded subtitles. Only VobSub, which is image based, is supported and widely playable.<br/>
MP4 can contain the following subtitle types, though playback support varies:


There are some media players which only support 1 embedded subtitle track.<br/>
* WebVTT 
* TTXT 
* VobSub 
* SubRip (wrapped as TTXT) 
* PGS (wrapped as VobSub)


It is best to include subtitles as an external file.<br/>
Because support is inconsistent, embedding subtitles inside MP4 should be avoided unless you know the target players can handle them.


We prefer VobSub for image based subtitles and SubRip for text based subtitles, though others are supported.<br/>
=== Recommended Approaches ===
* **VobSub** is generally the safest embedded format (image‑based). 
* **SubRip (.srt)** is widely supported as an external file and easy to edit. 
* **WebVTT** works well for modern browsers but may fail on older media players.


Reference: [Emby Documentation - Subtitles](https://emby.media/support/articles/Subtitles.html) 
When in doubt, distribute both **SRT** and **VobSub** versions externally for maximum compatibility.
Reference: [Kodi Wiki - Subtitles](https://kodi.wiki/view/Subtitles)


=== MP4 Compatible Subtitle Formats ===
=== Extract Text‑Based Subtitles (SubRip) ===
* WebVTT
Use this command to extract text subtitles:
* TTXT
* VobSub
* SubRip as TTXT
* PGS as VobSub


=== Extract Image Based Subtitles ===
<pre>
<pre>
ffmpeg -i <input.file> -f subrip <output.file>
ffmpeg -i input \
  -f subrip output.srt
</pre>
</pre>


=== Extract Image Based Subtitles ===
This produces a clean, editable `.srt` file suitable for most software players.
 
=== Extract Image‑Based Subtitles (VobSub / DVD Subtitles) ===
To extract image‑based subtitle tracks:
 
<pre>
<pre>
ffmpeg -i <input.file> -f dvd_subtitle <output.file>
ffmpeg -i input \
  -f dvd_subtitle output.sub
</pre>
</pre>


Reference: [FFmpeg - ExtractSubtitles](https://trac.ffmpeg.org/wiki/ExtractSubtitles)
This generates `.sub` and `.idx` files, preserving the original graphical subtitles exactly as they appear on disc‑based media.


== Metadata ==
=== Notes on Multiple Subtitle Tracks ===
=== Strip All Metadata ===
* Many players support **only one** embedded subtitle stream. 
<pre>
* Some legacy devices cannot detect text‑based subtitles inside MP4.
ffmpeg -i <input.file> -map_metadata -1 -fflags +bitexact -flags:v +bitexact -flags:a +bitexact -f mp4 <output.file>
* For broadest compatibility, always include subtitles externally when delivering media to unknown or mixed playback environments.
</pre>
 
This approach ensures maximum reliability and avoids unexpected behaviour during playback.


Reference: [Strip metadata from all formats with FFmpeg](https://superuser.com/questions/441361/strip-metadata-from-all-formats-with-ffmpeg)
== Optimising MP4 for Streaming ==
When streaming MP4 files over the web—especially via progressive download—it is essential that playback can begin as quickly as possible. By default, MP4 files store the “moov atom” (the index that describes the structure of the file) at the end of the file. This means a player must download the entire file before it can begin playback.


=== Add Title Tag ===
To enable immediate playback while the rest of the file is still downloading, the moov atom must be moved to the beginning of the file. FFmpeg provides a simple flag to achieve this.
<pre>
ffmpeg -i <input.file> -metadata title="flibble" -f mp4 <output.file>
</pre>


=== Add Year Tag ===
=== Enable Faststart Optimisation ===
<pre>
Add the following option to your FFmpeg output command:
ffmpeg -i <input.file> -metadata date=0 -f mp4 <output.file>
</pre>


=== Add Language Tags ===
<pre>
<pre>
ffmpeg -i <input.file> -metadata:s:a:0 language=eng -metadata:s:v:0 language=eng -f mp4 <output.file>
-movflags +faststart
</pre>
</pre>


Reference: [stackoverflow - ffmpeg: set the language of an audio stream](https://stackoverflow.com/questions/44351606/ffmpeg-set-the-language-of-an-audio-stream)
This instructs FFmpeg to:
* relocate the moov atom to the start of the MP4 file 
* reorder internal metadata for optimal streaming 
* ensure playback can begin as soon as enough data has buffered 


=== Set Default Track ===
This optimisation is critical for:
* HTML5 <nowiki><video></nowiki> playback 
* Embedded website video players 
* Mobile streaming 
* Any file served via progressive download 
* Environments where users expect instant playback responsiveness 


== Optimise Video for Streaming ==
`faststart` does not affect the audio or video data itself—it only reorganises metadata to improve load behaviour.
<pre>
ffmpeg -i <input.file> -movflags +faststart -f mp4 <output.file>
</pre>


Reference: [FFmpeg - H.264 Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264)
This option should be considered **mandatory** for any MP4 intended for online distribution.


== References ==
== References ==
[Wikipedia - Comparison of video container formats](https://en.wikipedia.org/wiki/Comparison_of_video_container_formats)
* [[https://en.wikipedia.org/wiki/Comparison_of_video_container_formats Wikipedia Comparison of video container formats]]
[List of True 16:9 Resolutions](https://pacoup.com/2011/06/12/list-of-true-169-resolutions/)
* [[https://trac.ffmpeg.org/wiki/Encode/AAC FFmpeg – AAC Encoding Guide]]
* [[https://trac.ffmpeg.org/wiki/Encode/H.264 FFmpeg – H.264 Video Encoding Guide]]
* [[https://trac.ffmpeg.org/wiki/ChangingFrameRate FFmpeg – Changing the Frame Rate]]
* [[https://trac.ffmpeg.org/wiki/ExtractSubtitles FFmpeg – Extracting Subtitles]]
* [[https://superuser.com/questions/891145/ffmpeg-upscale-and-letterbox-a-video SuperUser – FFmpeg upscale and letterbox a video]]
* [[https://superuser.com/questions/441361/strip-metadata-from-all-formats-with-ffmpeg SuperUser – Strip metadata from all formats with FFmpeg]]
* [[https://stackoverflow.com/questions/44351606/ffmpeg-set-the-language-of-an-audio-stream StackOverflow – Set the language of an audio stream]]
* [[https://www.lighterra.com/papers/videoencodingh264/ Lighterra – Video Encoding Settings for H.264 Excellence]]
* [[https://emby.media/support/articles/Subtitles.html Emby Documentation – Subtitles]]
* [[https://kodi.wiki/view/Subtitles Kodi Wiki – Subtitles]]
* [[https://en.wikipedia.org/wiki/Standard-definition_television Wikipedia – Standard‑Definition Television]]
* [[https://en.wikipedia.org/wiki/Video_CD Wikipedia – Video CD]]
* [[https://en.wikipedia.org/wiki/Super_Video_CD Wikipedia – Super Video CD]]
* [[https://forum.videohelp.com/threads/947-SVCD-specification-supported-resolutions VideoHelp Forum – SVCD Supported Resolutions]]
* [[https://en.wikipedia.org/wiki/DVD-Video Wikipedia – DVD‑Video]]
* [[https://en.wikipedia.org/wiki/Blu-ray Wikipedia – Blu‑ray]]
* [[https://pacoup.com/2011/06/12/list-of-true-169-resolutions/ List of True 16:9 Resolutions]]
* [[https://wiki.multimedia.cx/index.php/FFmpeg_Metadata FFmpeg Metadata – QuickTime/MP4/M4A etc.]]
* [[https://tvrdb.com/ TVRDb – Television Reference Database]]
* [[https://genome.ch.bbc.co.uk/ BBC Genome Project]]
* [[https://www.thetvdb.com/ TheTVDB]]
* [[https://kodi.wiki/view/NFO_files/TV_shows Kodi NFO Format – TV Shows]]
* [[https://kodi.wiki/view/NFO_files/Episodes Kodi NFO Format – Episodes]]
* [[https://kodi.wiki/view/NFO_files/Movies Kodi NFO Format – Movies]]
* [[https://nfo-maker.com/ NFO Maker Tool]]
* [[https://superuser.com/questions/891145/ffmpeg-upscale-and-letterbox-a-video SuperUser – Letterboxing Discussion]]
* [[https://www.reddit.com/r/ffmpeg/comments/vp6n7z/fixing_aspect_ratio_with_ffmpeg/ Reddit – Fixing Aspect Ratio with FFmpeg]]


== To Do ==
== To Do ==
* Add documentation for converting interlaced to progressive
The following enhancements and additions are planned to extend this article and improve coverage of related encoding and metadata workflows. These items are retained for future development and technical expansion.
** https://forum.videohelp.com/threads/405931-FFMPEG-Deinterlace
 
* Add documentation for expanding anamorphic widescreen
* Add documentation for converting interlaced video to progressive formats 
** https://www.reddit.com/r/ffmpeg/comments/vp6n7z/fixing_aspect_ratio_with_ffmpeg/
  * Resources include VideoHelp forum discussions and FFmpeg deinterlacing examples.
* Add documentation for MP4 tags
 
** https://wiki.multimedia.cx/index.php/FFmpeg_Metadata#QuickTime/MOV/MP4/M4A/et_al
* Add documentation for expanding anamorphic widescreen to proper square‑pixel resolutions 
* Add documentation for finding TV Listings
  * Useful references include FFmpeg aspect‑ratio correction techniques and community guides.
** TVRDb - https://tvrdb.com/
 
** BBC Archive - https://genome.ch.bbc.co.uk/
* Add documentation for MP4 metadata fields 
** TVDB - https://www.thetvdb.com/
  * Especially QuickTime/MOV/MP4 tag behaviour (title, year, language, sort order, etc.).
* Add documentation for nfo files
 
** TV Shows - https://kodi.wiki/view/NFO_files/TV_shows
* Add documentation for finding authoritative TV listings 
** Episodes - https://kodi.wiki/view/NFO_files/Episodes
  * TVRDb
** Movies - https://kodi.wiki/view/NFO_files/Movies
  * BBC Genome 
* Add documentation for creating nfo files
  * TheTVDB 
** NFO Maker - https://nfo-maker.com/
 
** Ember Media Manager
* Add documentation for creating NFO files for media libraries 
* Decide whether to use SubRip or WebVTT as standard text-based subtitles
  * TV Shows (Kodi format) 
** WebVTT will not work with older media players.
  * Episodes
** Some media players don't support VobSub either!
  * Movies
* Document 2 pass encoding
  * Tools such as NFO Maker and Ember Media Manager
* Review 'setsar=1:1'
 
* Add 288p (PAL VCD, 4:3) to target bitrates
* Decide whether SubRip (SRT) or WebVTT should be used as the standard text‑based subtitle format 
* Add 4k UHD target bitrates
  * Considerations include legacy player compatibility and browser support.
 
* Document full two‑pass encoding workflows in greater detail 
  * Including pass‑log management and advanced bitrate‑control strategy.
 
* Review the use of <code>setsar=1:1</code> 
  * Clarify when sample‑aspect‑ratio overrides are beneficial or undesirable.
 
* Add 288p (PAL VCD 4:3) to the target‑bitrate tables 
  * Ensures full coverage of legacy SD formats.
 
* Add 4K UHD target‑bitrate recommendations 
  * Including considerations for HDR, high motion content, and decoder limitations.

Latest revision as of 14:28, 14 March 2026

A practical guide to producing highly compatible MP4 files using FFmpeg. This article explains container choice, codec selection, bitrate strategy, advanced x264 controls, and the real‑world constraints of web browsers, media players, and streaming protocols.
Modern streaming requires video files that are lightweight to decode, efficient to deliver, and universally compatible across browsers, mobile devices, TVs, and older “dumb players”. For maximum interoperability, this guide standardises on the MP4 container using H.264 (AVC) video and AAC audio, with optional external subtitles for broadest playback support.

This article provides a practical, engineering‑driven approach to encoding optimal MP4 files using FFmpeg. It explains container and codec choices, bitrate selection, profile and level constraints, subtitle considerations, and advanced x264 tuning options. The focus is on producing files that stream smoothly, start quickly, and reliably play on the widest range of hardware and software environments.

Context

In theory, the MP4 container can hold almost any audio or video codec through private streams. In practice, however, real‑world media players support only a narrow subset. This becomes especially restrictive on older hardware, low‑power embedded devices, and simplified “dumb players” that ship with fixed decoding silicon.

Because of this, streaming workflows benefit from predictable, widely supported formats. H.264 video and AAC audio remain the most universally playable combination across browsers, TVs, set‑top boxes, consoles, mobile devices, and legacy players. Even though newer codecs exist, their hardware support is inconsistent and often fragmented across vendors and platforms.

Choosing MP4 with H.264 + AAC also simplifies distribution across multiple delivery methods. The same encoded file can be used for direct playback, progressive download, and HTTP‑based streaming formats such as HLS, DASH, and MSS. It also avoids the need for per‑device transcoding, reduces CPU load during playback, and improves battery performance on mobile devices.

These constraints and behaviours shape the recommendations in the rest of this article: aim for formats that are easy to decode, fast to start, compatible across environments, and efficient to stream over typical home broadband and mobile networks.

Container Formats

The MP4 container (MPEG‑4 Part 14) is the most broadly supported media container across hardware decoders, software players, web browsers, and embedded “dumb players”. While MP4 can technically store almost any codec using private streams, most real‑world playback devices only recognise a much smaller set of audio and video formats. This makes MP4 ideal for streaming workflows where consistency and compatibility matter.

MP4 is also the preferred container for HTML5 playback. Although the <video> element can theoretically support a wider range of codecs, browser vendors only guarantee universal support for MP4 containing H.264 video and AAC audio. This gives MP4 a practical advantage over more flexible containers like MKV, especially when targeting mobile devices or older embedded players.

Why MP4?

MP4 offers:

  • Wide hardware decode support
  • Efficient seeking and streaming behaviour
  • Compatibility with major streaming protocols (HLS, DASH, MSS, RTMP, RTSP)
  • Predictable behaviour across browsers, smart TVs, consoles, and older chipsets
  • Support for fast-start optimisation via -movflags +faststart

These characteristics make MP4 the safest default container for general-purpose streaming and file delivery.

Common Video File Extensions

.AVI
One of Microsoft’s earliest container formats. Very limited, outdated, and unsuitable for modern streaming.
.FLV
Flash Video format (Adobe). Obsolete now that Flash has been discontinued.
.MKV
The Matroska container. Modern, highly flexible, and open. Excellent for archival and advanced features, but not universally supported across hardware players or browsers.
.MOV
Apple’s QuickTime container. Historically important but largely superseded by MP4.
.MP4
ISO/IEC standard and the current mainstream format for streaming, web video, and device playback.
.WebM
Google’s modern open container, typically paired with VP8/VP9/AV1 codecs. Excellent for web environments but less supported in hardware decoders.
.WMV
Microsoft’s legacy Windows Media Video container. Outdated and largely unsupported in modern ecosystems.

Outputting an MP4 File

The most direct MP4 output command is:

ffmpeg -i input -f mp4 output.mp4

FFmpeg will automatically:

  • transcode video to H.264
  • transcode audio to AAC

unless you explicitly specify alternative codecs.

This makes the basic MP4 output command a reliable default for converting arbitrary media into a streaming‑friendly format.

Audio

AAC (Advanced Audio Coding) provides the best balance of quality, compression efficiency, and hardware compatibility for MP4‑based streaming. Although the MP4 container can technically hold many different audio codecs, real‑world media players—especially older or embedded systems—often support only a very limited subset. This makes AAC the safest and most predictable choice for both direct playback and streaming scenarios.

Some devices only support a single audio track, and others only support stereo AAC. To maximise compatibility, always ensure:

  • The **stereo AAC track is the first audio track**
  • It is marked as the **default track**
  • Bitrates are chosen appropriately for the target device class

These small decisions help prevent issues where a player either selects the wrong track or fails to play audio entirely.

MP4 Compatible Audio Codecs

Although AAC is recommended, MP4 technically supports a wide range of audio formats:

  • MPEG‑1 Audio Layer I
  • MPEG‑1 Audio Layer II
  • MPEG‑1 Audio Layer III (MP3)
  • AAC
  • AC‑3
  • E‑AC‑3
  • Dolby TrueHD
  • DTS
  • DTS‑HD
  • Opus
  • FLAC
  • ALAC
  • MLP
  • ALS
  • SLS
  • LPCM
  • DV Audio
  • AMR

In practice, support across actual playback devices is highly inconsistent. AAC remains the only codec with broad, reliable compatibility.

Recommended AAC Bitrate

For perceptually transparent audio (i.e., indistinguishable from the source to most listeners), a good rule of thumb is:

  • **64 kbit/s per channel**
  • Stereo → **128 kbit/s**
  • 5.1 surround → **384 kbit/s**

These values balance quality against streaming efficiency and align well with consumer playback hardware.

Transcode Audio to Stereo AAC

Use this command to convert any input to a standard stereo AAC track:

ffmpeg -i input \
  -c:a libfdk_aac \
  -ac 2 \
  -b:a 128k \
  -f mp4 output.mp4

This produces a widely compatible stereo track suitable for web video, mobile playback, and legacy devices.

Transcode a 5.1 Track to Both Stereo and 5.1 AAC

If you want to include both stereo and surround sound, while ensuring the stereo track is selected by default, use:

ffmpeg -i input \
  -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.mp4

This layout:

  • Preserves the surround track
  • Ensures maximum compatibility
  • Guarantees the stereo AAC track is selected automatically

This two‑track approach works well for online platforms and local playback environments where the device capabilities are unknown.

Video

H.264 (AVC) remains the most universally compatible video codec for MP4 files. While the MP4 container can technically house a wide range of video formats, real hardware and embedded players often only support a very narrow subset. H.264 strikes the ideal balance between compression efficiency, quality, and decoder availability across browsers, smart TVs, mobile devices, and low‑power “dumb players.”

Newer codecs such as HEVC, VP9, and AV1 offer superior compression, but hardware support is inconsistent, and older devices may fail to decode them entirely. For maximum reach, H.264 continues to be the safest and most predictable option.

MP4 Compatible Video Codecs

MP4 can support many different video formats, though device support varies greatly:

  • 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

Despite this broad technical compatibility, H.264 is by far the most reliably supported across modern and legacy players.

Transcode Video to H.264

The simplest way to encode video for maximum compatibility is:

ffmpeg -i input -c:v libx264 -f mp4 output.mp4

This ensures the output file contains:

  • H.264 video (widely supported)
  • AAC audio (if paired with matching audio settings)

Unless overridden, this produces a safe baseline encode suitable for most platforms.

H.264 Profile

Profiles determine which H.264 features are available to the encoder and required by the decoder.

  • **Baseline Profile**
 Used by the oldest and lowest‑power devices. Suitable for low‑resolution video (240p / 360p).  
 Restrictive and less efficient — use only when necessary.
  • **High Profile**
 More efficient and higher quality. Supported by virtually all modern devices.  
 Recommended for all resolutions **432p and above**.

H.264 Level

H.264 Levels constrain parameters such as maximum resolution, bitrate, and frame rate. Selecting the **lowest viable level** ensures the highest compatibility, especially with older players.

Recommended levels:

  • **240p → Level 2.1**
  • **360p / 432p → Level 3.0**
  • **480p / 576p / 720p → Level 3.1**
  • **1080p → Level 4.0**

Choosing higher levels unnecessarily can cause playback failures on older chipsets.

Bitrate

Bitrate has a significant effect on visual quality and streaming stability. Use the dedicated tables in the next section to select appropriate bitrates for both **4:3** and **16:9** content.

For now, remember:

  • Too low → visible artefacts and banding
  • Too high → increased buffering, incompatible with some decoders
  • Always match bitrate, profile, and level to the resolution and target devices

Bitrate is deeply tied to buffer sizes, maximum peak rates, and motion complexity — all of which are addressed in the following sections.

H.264 Profiles & Levels

H.264 provides multiple profiles and levels that define what encoding tools are used and what capabilities a decoder must support. Choosing the correct combination is essential for ensuring compatibility across different classes of media players, especially older hardware and embedded “dumb players.”

Profiles determine the *feature set* of the encoder and decoder. Levels determine the *constraints*, such as maximum resolution, bitrate, and frame rate.

Selecting the lowest profile and level that meets your needs maximises compatibility while maintaining efficient playback.

H.264 Profiles

The three most commonly encountered profiles are:

**Baseline Profile**
Designed for low‑power devices and older hardware.
 Supports only the simplest encoding tools.  
 Recommended for low‑resolution content such as **240p** and **360p**.
**Main Profile**
More capable than Baseline but less widely relevant today.
 Typically used for broadcast workflows, but largely superseded by High Profile.
**High Profile**
The most efficient and widely supported profile for modern devices.
 Recommended for all resolutions **432p and above**, including HD and Full HD.  
 Provides significantly better compression efficiency than Baseline.

In practice:

  • Use **Baseline** only when targeting very old or extremely low‑power devices.
  • Use **High Profile** for almost all modern streaming applications.

H.264 Levels

Levels impose strict limits on:

  • Maximum frame size
  • Maximum bitrate
  • Maximum frame rate
  • Decoder buffer size

Choosing an unnecessarily high level can cause playback failures on older chipsets, even if the file appears to play correctly on modern systems.

Recommended levels for common resolutions:

**240p → Level 2.1**
Sufficient for small frame sizes and low bitrates.
**360p / 432p → Level 3.0**
Appropriate for medium‑resolution SD content.
**480p / 576p / 720p → Level 3.1**
Suitable for standard-definition and 720p HD.
**1080p → Level 4.0**
Required for Full HD at typical streaming bitrates.

Choosing the lowest possible level that satisfies your resolution keeps the output maximally compatible with older playback devices.

Why Profiles and Levels Matter

  • Using too *high* a profile may reduce compatibility with older or embedded devices.
  • Using too *high* a level may cause the decoder to reject the file outright.
  • Using too *low* a level or profile may prevent the encoder from using tools needed for efficient compression.

Correctly selected profiles and levels ensure:

  • Smooth playback
  • Reduced buffering
  • Lower CPU/GPU load
  • Widespread compatibility across browsers, smart TVs, set‑top boxes, and mobile devices

Bitrate Selection

Bitrate determines both visual quality and streaming performance. Too low, and compression artefacts become obvious; too high, and playback may stutter on low‑power devices or unreliable networks. The tables below provide practical, field‑tested targets for both **4:3** and **16:9** content at various resolutions.

These values balance:

  • H.264 encoder efficiency
  • Typical broadband and mobile network constraints
  • Hardware decoder capabilities across legacy and modern devices
  • Consistent perceptual quality for general-purpose streaming

Use the lowest bitrate that preserves a clean image without visible macroblocking, and adjust upward only for high‑motion or high‑detail content.

4:3 Target Bitrates

Name Resolution Link (Mbps) Bitrate (Mbps) Video (kbps) Audio (kbps)
240p 320×240 1.0 0.64 576 64
360p 480×360 1.2 0.77 704 64
480p 640×480 1.5 0.96 896 64
480p HQ 640×480 2.0 1.28 1216 64
576p 768×576 2.3 1.47 1408 64
576p HQ 768×576 2.5 1.60 1536 64
720p 960×720 3.0 1.92 1856 64
720p HQ 960×720 4.0 2.56 2432 128
1080p 1440×1080 6.0 3.84 3712 128
1080p HQ 1440×1080 9.0 5.76 5632 128
1080p Superbit 1440×1080 N/A 20.32 20000 320

16:9 Target Bitrates

Name Resolution Link (Mbps) Bitrate (Mbps) Video (kbps) Audio (kbps)
240p 424×240 1.0 0.64 576 64
360p 640×360 1.5 0.96 896 64
432p 768×432 1.8 1.15 1088 64
480p 848×480 2.0 1.28 1216 64
480p HQ 848×480 2.5 1.60 1536 64
576p 1024×576 3.0 1.92 1856 64
576p HQ 1024×576 3.5 2.24 2176 64
720p 1280×720 4.0 2.56 2496 64
720p HQ 1280×720 5.0 3.20 3072 128
1080p 1920×1080 8.0 5.12 4992 128
1080p HQ 1920×1080 12.0 7.68 7552 128
1080p Superbit 1920×1080 N/A 20.32 20000 320
Note
424×240 and 848×480 are not mathematically exact 16:9.
426×240 is a closer 16:9 match for low‑resolution 240p content.

2‑Pass Encoding Example

For achieving the best quality at a fixed target bitrate:

ffmpeg -i input \
  -c:v libx264 -b:v 4992k -preset veryslow -pass 1 -an -f null /dev/null && \
ffmpeg -i input \
  -c:v libx264 -b:v 4992k -preset veryslow -pass 2 \
  -c:a libfdk_aac -ac 2 -b:a 128k \
  -f mp4 output.mp4

This workflow:

  • Analyses motion and complexity on pass 1
  • Allocates bits optimally on pass 2
  • Preserves detail more effectively at the same bitrate

Maximum Bitrate

  • 240p–1080p: -maxrate should be **double** the target bitrate
  • 1080p Superbit: -maxrate should be **25 Mbps**

Buffer Size

  • 240p / 360p → -bufsize = 256k
  • 432p–1080p → -bufsize ≈ 1.5 seconds of video
  • 1080p Superbit → -bufsize ≈ 30 Mbit

Presets, Tune & Colourspace

FFmpeg’s x264 encoder exposes a wide range of parameters that control the trade‑off between encoding speed and output quality. Rather than configuring every option manually, x264 provides a set of predefined “presets” and “tunes” that adjust groups of settings together.

Using the correct preset and tune ensures good compression efficiency, stable quality across different content types, and predictable encode times.

FFmpeg Presets

A preset represents a collection of encoder settings that balance encoding speed against compression efficiency. Slower presets take longer to encode but deliver better visual quality at the same bitrate.

Common presets (from fastest to slowest):

  • ultrafast
  • superfast
  • veryfast
  • faster
  • fast
  • medium
  • slow
  • slower
  • veryslow
  • placebo (not recommended; extremely slow with little practical gain)

General guidance:

  • Use the **slowest preset you have patience for**.
  • For high‑quality streaming, **veryslow** offers excellent efficiency with predictable results.

Choosing a slower preset reduces file size for the same quality, or increases quality at a fixed bitrate, by allowing the encoder to search more possibilities.

FFmpeg Tune

Tunes let you optimise the encoder for specific types of content. They adjust psycho‑visual optimisations, motion estimation behaviour, and noise handling.

Recommended tunes:

  • film — for live‑action material
 (Optimises for natural grain, fine detail, and motion characteristics.)
  • animation — for animated content
 (Optimises for sharp edges, flat colours, and low‑noise frames.)

Use a tune only when the content clearly matches one of these categories. Leaving the tune unset is perfectly fine for mixed‑content or general‑purpose encoding.

Colourspace

For maximum compatibility across hardware decoders, web browsers, and older media players, always ensure the video is encoded using **yuv420p**.

Many devices will fail to play content encoded in yuv422p or yuv444p, even if the container and codec are otherwise valid.

Convert the colourspace explicitly:

ffmpeg -i input \
  -c:v libx264 \
  -filter:v format=yuv420p \
  -f mp4 output.mp4

This guarantees broad playback support, especially in HTML5 environments and set‑top boxes.

Framerate

Framerate determines how many images (frames) are displayed per second. Different broadcast standards, playback devices, and capture sources use different framerates, and choosing the correct one is essential for smooth playback and broad compatibility.

Older or embedded media players can struggle with unusually high framerates, even if the resolution and bitrate are otherwise within specification. For maximum compatibility across streaming devices, stick to the framerates commonly associated with the source format unless you have a specific reason to change them.

PAL and NTSC Standards

The two dominant historical broadcast standards define the baseline expectations for framerate:

  • **PAL**
 Uses **25 fps**, with **50 fps** being suitable for HD and UHD content when higher motion clarity is desired.  
 Common in Europe, Australia, and many parts of Asia and Africa.
  • **NTSC**
 Uses **29.97 fps**, with **59.94 fps** being used for HD and UHD.  
 Common in North America, Japan, South Korea, and some regions of South America.

These framerates are deeply ingrained into the decoding hardware of many devices, especially older set‑top boxes and TVs.

Blu‑ray formats also allow **30 fps** and **60 fps**, but some low‑power players may still struggle with these higher rates.

High‑Framerate Considerations

Some devices—particularly older mobile chipsets, embedded systems, and legacy televisions—may fail to decode or smooth‑play high‑framerate content, even when the codec and level are supported.

For maximum compatibility:

  • Prefer **25 fps** (PAL sources)
  • Prefer **29.97 fps** (NTSC sources)
  • Use **50 fps / 59.94 fps** only when targeting modern hardware

Change Video Framerate

To convert a video to a specific framerate:

ffmpeg -i input \
  -c:v libx264 \
  -filter:v fps=25 \
  -f mp4 output.mp4

This command re‑encodes the video at the desired framerate, ensuring consistent playback across devices and streaming environments.

Resolution

Resolution defines the pixel dimensions of the video and has a direct impact on compatibility, quality, and bitrate requirements. Different legacy standards (VCD, SVCD, PAL, NTSC) and modern formats (HD, Full HD, UHD) come with established resolutions that many devices still expect.

When preparing streaming‑ready MP4 files, ensure the resolution is correct for the content. This includes de‑interlacing older material, expanding anamorphic sources to square pixels, and choosing resolutions appropriate for the target devices.

Important Notes

  • **Interlaced video must be de‑interlaced** to avoid visible combing artefacts and uneven motion. Many hardware players assume progressive content.
  • **Anamorphic widescreen should be expanded** to a proper 16:9 square‑pixel resolution. Storing anamorphic video without correction may cause distorted playback.
  • **Stick to standardised resolutions** wherever possible to ensure predictable decoder behaviour and maximum compatibility.

Common Resolutions by Format

The following table lists widely recognised resolutions for legacy and modern media formats:

**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)

Change Resolution and Add Letterbox

When converting between resolutions or preparing content for a specific aspect ratio, FFmpeg’s scaling and padding filters allow precise control over the output.

The following example:

  • Scales the input video while preserving aspect ratio
  • Adds a letterbox (black bars) to fit a target size
  • Ensures correct centring and padding
ffmpeg -i input \
  -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.mp4

This example targets a **640×480 (4:3)** output frame with proper letterboxing while maintaining the original aspect ratio of the input.

Notes on Handling Aspect Ratios

  • The `sar` (sample aspect ratio) value is important for correcting anamorphic sources.
  • `scale` calculates the largest possible size that fits inside the target frame without cropping.
  • `pad` adds black bars to fill any unused space, preserving the intended composition.

These techniques are especially useful when converting archival material, preparing video for older devices, or ensuring predictable behaviour across diverse playback environments.

Advanced x264 Options

While presets and tunes provide broad optimisation, x264 also exposes many low‑level encoder controls that allow fine‑tuning of quality, motion handling, and compression behaviour. These settings influence how efficiently bits are allocated, how motion is predicted, and how consistently quality is maintained across different types of scenes.

The options below reflect proven, practical configurations suitable for high‑quality streaming, balanced efficiency, and broad compatibility with both modern and legacy decoders.

Quantizer & Rate Control

qcomp=0.9
Adjusts quantizer curve compression. A higher value allocates bits more evenly, reducing noticeable quality dips in complex scenes.
qpmin=3
Sets the minimum quantiser value, limiting how much compression can aggressively reduce detail. Helps maintain consistency in flat‑coloured regions.
rc_lookahead=60
Determines how many future frames the encoder analyses for rate control. Long lookahead improves bitrate distribution and aids in anticipating motion.

Motion Analysis

me=umh
Enables Uneven Multi‑Hexagon motion estimation, which provides high‑quality motion matching at the cost of additional encoding time.
me_range=32 (240p–720p)
me_range=48 (1080p)
Defines the radius for motion search. Higher resolutions benefit from a wider search range to capture large movements accurately.
subme=10
Enables the most precise sub‑pixel motion refinement. This significantly improves detail during motion but increases encode time.
direct=auto
Automatically selects the most efficient direct‑mode motion vector prediction method.

Scene and Frame Structure

scenecut=40
Adjusts sensitivity to scene changes. Helps insert keyframes where a sharp cut occurs, improving seekability and visual clarity.
keyint=360 (at 30fps)
Sets the maximum interval between keyframes (12 seconds). Balances streaming efficiency with good random‑access behaviour.
min-keyint=1
Ensures the encoder can place a keyframe at a genuine scene change without artificial restrictions.

Reference Frames & B‑Frame Behaviour

ref=4
Specifies the number of reference frames. More references improve compression but may reduce decoder compatibility on very old hardware.
b_pyramid=none
Disables hierarchical B‑frames. This setting maximises compatibility with older devices and “dumb players.”
b_adapt=0 (240p / 360p)
b_adapt=2 (432p and above)
Controls how B‑frames are placed. Adaptive placement (value 2) improves efficiency at higher resolutions.
bframes=0 (240p / 360p)
bframes=3 (432p–1080p)
bframes=5 (1080p Superbit)
Determines how many B‑frames may appear consecutively. Higher values improve compression at higher resolutions.
fast_pskip=1
Enables early skip detection for P‑frames.
fast_pskip=0 for 1080p Superbit
Disabling improves fidelity but increases file size.

Psycho‑Visual Enhancements

psy_rd=1.0
Controls psycho‑visual rate‑distortion optimisation. Helps preserve natural detail and edges.
trellis=2
Enables full trellis quantization for optimal transform coefficient decisions. Significantly improves compression efficiency.
no-dct-decimate=1
Prevents the encoder from removing DCT blocks it deems unnecessary. Helps preserve texture in detailed scenes.

Deblocking

deblock=0:0 (240p–1080p)
Neutral deblocking filter values suitable for most scenarios.
deblock=-2:-1 (1080p Superbit)
Stronger sharpened detail for high‑bitrate, high‑quality encodes.

Partitions

Partitions control how the encoder breaks frames into blocks for motion estimation.

p4x4 = on (240p / 360p)
Smaller blocks help preserve detail at low resolutions.
p4x4 = off (432p and above)
Disabling improves efficiency without noticeable quality loss at higher resolutions.

Example command for disabling 4×4 partitions at higher resolutions:

ffmpeg -i input -c:v libx264 \
  -partitions -partp8x8,+partp4x4,-partb8x8,-parti8x8,-parti4x4 \
  -f mp4 output.mp4

Summary

These advanced settings provide fine‑grain control over how x264 encodes motion, distributes bits, handles scene transitions, and maintains visual quality. While presets and tunes handle broad optimisation, these parameters allow for highly refined encodes suitable for professional archiving, high‑motion content, and advanced streaming scenarios.

Subtitles

Subtitles are an important part of accessibility and content localisation. However, the MP4 container offers limited support for embedded subtitle formats, and different playback devices vary widely in what they accept. For maximum compatibility across browsers, TVs, mobile devices, and “dumb players,” it is often best to distribute subtitles as external files rather than relying on embedded streams.

MP4 technically supports a small set of subtitle types, but real‑world device support is inconsistent. Image‑based formats such as VobSub are more universally recognised in MP4 than text‑based formats, but still not guaranteed. Many players support only a single embedded subtitle track.

For these reasons:

  • Prefer **external subtitles** whenever possible
  • Use **VobSub** for image‑based subtitles
  • Use **SubRip (SRT)** or **WebVTT** for text‑based subtitles
  • Avoid relying on multiple embedded subtitle tracks

MP4 Compatible Subtitle Formats

MP4 can contain the following subtitle types, though playback support varies:

  • WebVTT
  • TTXT
  • VobSub
  • SubRip (wrapped as TTXT)
  • PGS (wrapped as VobSub)

Because support is inconsistent, embedding subtitles inside MP4 should be avoided unless you know the target players can handle them.

Recommended Approaches

  • **VobSub** is generally the safest embedded format (image‑based).
  • **SubRip (.srt)** is widely supported as an external file and easy to edit.
  • **WebVTT** works well for modern browsers but may fail on older media players.

When in doubt, distribute both **SRT** and **VobSub** versions externally for maximum compatibility.

Extract Text‑Based Subtitles (SubRip)

Use this command to extract text subtitles:

ffmpeg -i input \
  -f subrip output.srt

This produces a clean, editable `.srt` file suitable for most software players.

Extract Image‑Based Subtitles (VobSub / DVD Subtitles)

To extract image‑based subtitle tracks:

ffmpeg -i input \
  -f dvd_subtitle output.sub

This generates `.sub` and `.idx` files, preserving the original graphical subtitles exactly as they appear on disc‑based media.

Notes on Multiple Subtitle Tracks

  • Many players support **only one** embedded subtitle stream.
  • Some legacy devices cannot detect text‑based subtitles inside MP4.
  • For broadest compatibility, always include subtitles externally when delivering media to unknown or mixed playback environments.

This approach ensures maximum reliability and avoids unexpected behaviour during playback.

Optimising MP4 for Streaming

When streaming MP4 files over the web—especially via progressive download—it is essential that playback can begin as quickly as possible. By default, MP4 files store the “moov atom” (the index that describes the structure of the file) at the end of the file. This means a player must download the entire file before it can begin playback.

To enable immediate playback while the rest of the file is still downloading, the moov atom must be moved to the beginning of the file. FFmpeg provides a simple flag to achieve this.

Enable Faststart Optimisation

Add the following option to your FFmpeg output command:

-movflags +faststart

This instructs FFmpeg to:

  • relocate the moov atom to the start of the MP4 file
  • reorder internal metadata for optimal streaming
  • ensure playback can begin as soon as enough data has buffered

This optimisation is critical for:

  • HTML5 <video> playback
  • Embedded website video players
  • Mobile streaming
  • Any file served via progressive download
  • Environments where users expect instant playback responsiveness

`faststart` does not affect the audio or video data itself—it only reorganises metadata to improve load behaviour.

This option should be considered **mandatory** for any MP4 intended for online distribution.

References

To Do

The following enhancements and additions are planned to extend this article and improve coverage of related encoding and metadata workflows. These items are retained for future development and technical expansion.

  • Add documentation for converting interlaced video to progressive formats
 * Resources include VideoHelp forum discussions and FFmpeg deinterlacing examples.
  • Add documentation for expanding anamorphic widescreen to proper square‑pixel resolutions
 * Useful references include FFmpeg aspect‑ratio correction techniques and community guides.
  • Add documentation for MP4 metadata fields
 * Especially QuickTime/MOV/MP4 tag behaviour (title, year, language, sort order, etc.).
  • Add documentation for finding authoritative TV listings
 * TVRDb  
 * BBC Genome  
 * TheTVDB  
  • Add documentation for creating NFO files for media libraries
 * TV Shows (Kodi format)  
 * Episodes  
 * Movies  
 * Tools such as NFO Maker and Ember Media Manager
  • Decide whether SubRip (SRT) or WebVTT should be used as the standard text‑based subtitle format
 * Considerations include legacy player compatibility and browser support.
  • Document full two‑pass encoding workflows in greater detail
 * Including pass‑log management and advanced bitrate‑control strategy.
  • Review the use of setsar=1:1
 * Clarify when sample‑aspect‑ratio overrides are beneficial or undesirable.
  • Add 288p (PAL VCD 4:3) to the target‑bitrate tables
 * Ensures full coverage of legacy SD formats.
  • Add 4K UHD target‑bitrate recommendations
 * Including considerations for HDR, high motion content, and decoder limitations.