FFmpeg - Encoding Optimal Videos for Streaming: Difference between revisions
No edit summary |
mNo edit summary |
||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
[[Category:FFmpeg]] | [[Category:FFmpeg]] [[Category:Streaming]] | ||
[[Category:Streaming]] | ''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/> | ||
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 | 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 == | == 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 | 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. | ||
=== 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> | |||
These characteristics make MP4 the safest default container for general-purpose streaming and file delivery. | |||
=== Common Video File Extensions === | === Common Video File Extensions === | ||
; <code>.AVI</code> | |||
: One of Microsoft’s earliest container formats. Very limited, outdated, and unsuitable for modern streaming. | |||
; <code>.FLV</code> | |||
: Flash Video format (Adobe). Obsolete now that Flash has been discontinued. | |||
; <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: | |||
<pre> | <pre> | ||
ffmpeg -i | ffmpeg -i input -f mp4 output.mp4 | ||
</pre> | </pre> | ||
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 == | ||
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 | 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 === | === MP4 Compatible Audio Codecs === | ||
* | Although AAC is recommended, MP4 technically supports a wide range of audio formats: | ||
* | |||
* | * MPEG‑1 Audio Layer I | ||
* AAC | * MPEG‑1 Audio Layer II | ||
* MPEG‑1 Audio Layer III (MP3) | |||
* | * AAC | ||
* | * AC‑3 | ||
* Dolby TrueHD | * E‑AC‑3 | ||
* Dolby TrueHD | |||
* DTS | * DTS | ||
* | * 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** | |||
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: | |||
<pre> | <pre> | ||
ffmpeg -i | ffmpeg -i input \ | ||
-c:a libfdk_aac \ | |||
-ac 2 \ | |||
-b:a 128k \ | |||
-f mp4 output.mp4 | |||
</pre> | </pre> | ||
=== Transcode a 5.1 | 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 | 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 == | ||
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 === | ||
* | 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 | ||
* H.263 | * MPEG‑2 Video | ||
* MPEG‑1 Video | |||
* | * H.263 | ||
* VC‑1 | |||
* VP8 | * VP8 | ||
* VP9 | * VP9 | ||
* AV1 | * AV1 | ||
* 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 | ffmpeg -i input -c:v libx264 -f mp4 output.mp4 | ||
</pre> | </pre> | ||
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 === | ||
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 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. | |||
* 240p | Recommended levels: | ||
* 360p/432p | * **240p → Level 2.1** | ||
* 480p/576p/720p | * **360p / 432p → Level 3.0** | ||
* 1080p | * **480p / 576p / 720p → Level 3.1** | ||
* **1080p → Level 4.0** | |||
Choosing higher levels unnecessarily can cause playback failures on older chipsets. | |||
=== Bitrate === | === 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. | |||
Target | === 4:3 Target Bitrates === | ||
{| class="wikitable" | |||
! 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 | |||
|} | |||
| Name | === 16:9 Target Bitrates === | ||
| - | {| class="wikitable" | ||
| | ! Name !! Resolution !! Link (Mbps) !! Bitrate (Mbps) !! Video (kbps) !! Audio (kbps) | ||
| 360p | |- | ||
| 432p | | 240p || 424×240 || 1.0 || 0.64 || 576 || 64 | ||
| 480p | |- | ||
| 480p HQ | | 360p || 640×360 || 1.5 || 0.96 || 896 || 64 | ||
| 576p | |- | ||
| 576p HQ | | 432p || 768×432 || 1.8 || 1.15 || 1088 || 64 | ||
| 720p | |- | ||
| 720p HQ | | 480p || 848×480 || 2.0 || 1.28 || 1216 || 64 | ||
| 1080p | |- | ||
| 1080p HQ | | 480p HQ || 848×480 || 2.5 || 1.60 || 1536 || 64 | ||
| 1080p Superbit | | |- | ||
| 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: | |||
<pre> | <pre> | ||
ffmpeg -i | ffmpeg -i input \ | ||
ffmpeg -i | -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> | ||
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: <code>-maxrate</code> should be **double** the target bitrate | ||
* 1080p Superbit: -maxrate | * 1080p Superbit: <code>-maxrate</code> should be **25 Mbps** | ||
=== 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 | |||
== 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 === | === 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: | |||
* <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.) | |||
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 | ffmpeg -i input \ | ||
-c:v libx264 \ | |||
-filter:v format=yuv420p \ | |||
-f mp4 output.mp4 | |||
</pre> | </pre> | ||
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: | |||
<pre> | <pre> | ||
ffmpeg -i | ffmpeg -i input \ | ||
-c:v libx264 \ | |||
-filter:v fps=25 \ | |||
-f mp4 output.mp4 | |||
</pre> | </pre> | ||
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. | |||
Anamorphic widescreen should be expanded to 16:9 resolution. | === 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. | |||
Resolutions | === 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 | |||
== | <pre> | ||
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> | |||
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 === | ||
; <code>qcomp=0.9</code> | |||
: Adjusts quantizer curve compression. A higher value allocates bits more evenly, reducing noticeable quality dips in complex scenes. | |||
= | ; <code>qpmin=3</code> | ||
: Sets the minimum quantiser value, limiting how much compression can aggressively reduce detail. Helps maintain consistency in flat‑coloured regions. | |||
; <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. | |||
=== | === Motion Analysis === | ||
; <code>me=umh</code> | |||
: Enables Uneven Multi‑Hexagon motion estimation, which provides high‑quality motion matching at the cost of additional encoding time. | |||
= | ; <code>me_range=32</code> (240p–720p) | ||
; <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. | |||
; <code>subme=10</code> | |||
: Enables the most precise sub‑pixel motion refinement. This significantly improves detail during motion but increases encode time. | |||
= | ; <code>direct=auto</code> | ||
: Automatically selects the most efficient direct‑mode motion vector prediction method. | |||
=== Scene and Frame Structure === | |||
= | ; <code>scenecut=40</code> | ||
: Adjusts sensitivity to scene changes. Helps insert keyframes where a sharp cut occurs, improving seekability and visual clarity. | |||
; <code>keyint=360</code> (at 30fps) | |||
: Sets the maximum interval between keyframes (12 seconds). Balances streaming efficiency with good random‑access behaviour. | |||
; <code>min-keyint=1</code> | |||
: Ensures the encoder can place a keyframe at a genuine scene change without artificial restrictions. | |||
Reference | === Reference Frames & B‑Frame Behaviour === | ||
= | ; <code>ref=4</code> | ||
: Specifies the number of reference frames. More references improve compression but may reduce decoder compatibility on very old hardware. | |||
; <code>b_pyramid=none</code> | |||
: Disables hierarchical B‑frames. This setting maximises compatibility with older devices and “dumb players.” | |||
= | ; <code>b_adapt=0</code> (240p / 360p) | ||
; <code>b_adapt=2</code> (432p and above) | |||
: Controls how B‑frames are placed. Adaptive placement (value 2) improves efficiency at higher resolutions. | |||
; <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. | |||
= | ; <code>fast_pskip=1</code> | ||
: Enables early skip detection for P‑frames. | |||
; <code>fast_pskip=0</code> for 1080p Superbit | |||
: Disabling improves fidelity but increases file size. | |||
=== Psycho‑Visual Enhancements === | |||
; <code>psy_rd=1.0</code> | |||
psy_rd=1.0< | : Controls psycho‑visual rate‑distortion optimisation. Helps preserve natural detail and edges. | ||
; <code>trellis=2</code> | |||
: Enables full trellis quantization for optimal transform coefficient decisions. Significantly improves compression efficiency. | |||
; <code>no-dct-decimate=1</code> | |||
no-dct-decimate=1< | : Prevents the encoder from removing DCT blocks it deems unnecessary. Helps preserve texture in detailed scenes. | ||
=== Deblocking === | |||
; <code>deblock=0:0</code> (240p–1080p) | |||
: Neutral deblocking filter values suitable for most scenarios. | |||
; <code>deblock=-2:-1</code> (1080p Superbit) | |||
: Stronger sharpened detail for high‑bitrate, high‑quality encodes. | |||
=== Partitions === | === Partitions === | ||
Partitions control how the encoder breaks frames into blocks for motion estimation. | |||
; <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 | ffmpeg -i input -c:v libx264 \ | ||
-partitions -partp8x8,+partp4x4,-partb8x8,-parti8x8,-parti4x4 \ | |||
-f mp4 output.mp4 | |||
</pre> | </pre> | ||
=== 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 | 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: | |||
<pre> | <pre> | ||
ffmpeg -i | ffmpeg -i input \ | ||
-f subrip output.srt | |||
</pre> | </pre> | ||
=== Extract | 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 | ffmpeg -i input \ | ||
-f dvd_subtitle output.sub | |||
</pre> | </pre> | ||
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: | |||
<pre> | <pre> | ||
-movflags +faststart | |||
</pre> | </pre> | ||
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 <nowiki><video></nowiki> 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 == | == References == | ||
[Wikipedia | * [[https://en.wikipedia.org/wiki/Comparison_of_video_container_formats Wikipedia – Comparison of video container formats]] | ||
[ | * [[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. | ||
* | |||
* Add documentation for expanding anamorphic widescreen | * Add documentation for converting interlaced video to progressive formats | ||
* | * Resources include VideoHelp forum discussions and FFmpeg deinterlacing examples. | ||
* Add documentation for MP4 | |||
* | * Add documentation for expanding anamorphic widescreen to proper square‑pixel resolutions | ||
* Add documentation for finding TV | * 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 | |||
* Add documentation for finding authoritative TV listings | |||
* | * TVRDb | ||
* BBC Genome | |||
* | * TheTVDB | ||
* Add documentation for creating NFO files for media libraries | |||
* Decide whether | * TV Shows (Kodi format) | ||
* | * Episodes | ||
* Movies | |||
* Document | * Tools such as NFO Maker and Ember Media Manager | ||
* Review | |||
* Add 288p (PAL VCD | * Decide whether SubRip (SRT) or WebVTT should be used as the standard text‑based subtitle format | ||
* Add | * 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:
-maxrateshould be **double** the target bitrate - 1080p Superbit:
-maxrateshould 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=0for 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
- [Wikipedia – Comparison of video container formats]
- [FFmpeg – AAC Encoding Guide]
- [FFmpeg – H.264 Video Encoding Guide]
- [FFmpeg – Changing the Frame Rate]
- [FFmpeg – Extracting Subtitles]
- [SuperUser – FFmpeg upscale and letterbox a video]
- [SuperUser – Strip metadata from all formats with FFmpeg]
- [StackOverflow – Set the language of an audio stream]
- [Lighterra – Video Encoding Settings for H.264 Excellence]
- [Emby Documentation – Subtitles]
- [Kodi Wiki – Subtitles]
- [Wikipedia – Standard‑Definition Television]
- [Wikipedia – Video CD]
- [Wikipedia – Super Video CD]
- [VideoHelp Forum – SVCD Supported Resolutions]
- [Wikipedia – DVD‑Video]
- [Wikipedia – Blu‑ray]
- [List of True 16:9 Resolutions]
- [FFmpeg Metadata – QuickTime/MP4/M4A etc.]
- [TVRDb – Television Reference Database]
- [BBC Genome Project]
- [TheTVDB]
- [Kodi NFO Format – TV Shows]
- [Kodi NFO Format – Episodes]
- [Kodi NFO Format – Movies]
- [NFO Maker Tool]
- [SuperUser – Letterboxing Discussion]
- [Reddit – Fixing Aspect Ratio with FFmpeg]
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.