Web-Ready Video: Encoding Settings That Play Everywhere
The video settings that play in every browser: MP4, H.264, AAC, yuv420p and faststart. When to remux and when to re-encode, with FFmpeg commands and one API call.
When delivering video to users on the web, optimizing files for playback is critical. If a video takes too long to load, freezes while buffering, or fails to play entirely on mobile devices, user retention drops immediately.
Creating a truly web-compatible video requires understanding video containers, audio and video codecs, metadata placement, and compression metrics.
In this guide, we walk through the best practices for encoding web-ready video and how to automate this process in the cloud.
1. What Makes a Video “Web-Ready”?
A standard “web-ready” video file must meet strict requirements to ensure it plays across all modern web browsers (Chrome, Safari, Firefox, Edge) and mobile operating systems (iOS and Android) without requiring proprietary plugins.
The industry-standard baseline configuration is:
- Video Container:
MP4 - Video Codec:
H.264(specifically using the High or Main Profile) - Audio Codec:
AAC(Advanced Audio Coding, Low Complexity/LC profile) - Pixel Format:
YUV 4:2:0(8-bit chroma subsampling, specified asyuv420pin FFmpeg)
The Baseline FFmpeg command
To convert a raw input video into this web-ready configuration:
ffmpeg -i source.mov -c:v libx264 -profile:v high -level 4.1 -pix_fmt yuv420p -c:a aac -b:a 128k -movflags +faststart output.mp42. The Critical faststart Option
Even if you use the correct MP4/H.264 codec configuration, your video might still lag on startup. By default, encoders write index metadata (the moov atom, which outlines the video structure and frame positions) at the very end of the file.
When a browser loads an MP4 file, it cannot start playing until it has parsed this moov atom. If it is located at the end of the file, the browser must download the entire video before playing the first frame.
The Solution: Faststart
You must relocate the moov atom to the beginning of the file. In FFmpeg, this is done using the -movflags +faststart flag.
ffmpeg -i input.mov -c:v libx264 -movflags +faststart output.mp4With faststart configured, the browser reads the metadata in the first few kilobytes of the download, enabling progressive download playback (playing the video while the rest of the file downloads in the background).
3. Remuxing vs. Re-encoding
Transcoding a video requires high CPU resources. However, many videos uploaded by users are already encoded in H.264/AAC; they are simply wrapped in an incompatible container format (like .mov, .mkv, or .ts) or lack faststart optimization.
Instead of running a full, heavy transcode, you can perform stream copying (or “remuxing”). This copies the audio and video packages directly into a new .mp4 container wrapper without re-encoding the actual frames.
The Remuxing CLI Command
ffmpeg -i source.mov -c:v copy -c:a copy -movflags +faststart output.mp4- The Advantage: Stream copying does not decode or encode any frames, so it uses a small fraction of the CPU time of a re-encode and finishes much sooner. On metered compute, that is a much smaller bill.
- The Disadvantage: If the input audio/video codecs are not already web-compatible (e.g. ProRes video or PCM audio), stream copying will fail or produce unplayable files.
4. Automation with Xora’s webReady Recipe
Manually checking every upload to decide whether it requires a full transcode or a simple stream-copied remux is complex to build.
Xora handles this automatically with the webReady recipe. Xora probes the upload first, then picks the cheapest path that still plays in browsers:
- Already web-ready: H.264 video, AAC/MP3 audio, MP4/MOV container, a reasonable bitrate and
faststartalready present. Xora returns your original URL (passthrough) and runs no FFmpeg at all. - Compatible codecs, no faststart: Xora stream-copies into MP4 and moves the metadata to the front (
faststart_remux). - Incompatible codecs or a very high bitrate: Xora re-encodes to H.264/AAC MP4 with fast-decode settings and one keyframe per second (
web_encode).
See the webReady reference for the exact rules.
Example API Request Using the Recipe
{ "mode": "recipe", "input": { "url": "https://example.com/uploaded-file.mkv" }, "output": { "format": "mp4" }, "recipe": { "name": "webReady" }}With webReady, every upload ends up as an MP4 that modern browsers can play progressively, and you only pay for a re-encode when the file actually needs one.
What it costs
A remux uses little machine time, so the cost is mostly the size of the output. For example, making a 500 MB file web-ready with a remux uses about 5.2 credits (0.2 processing + 5 output). A re-encode costs more, because it uses more machine time. Failed and rejected jobs cost nothing. See pricing.
Related
- webReady recipe reference.
- Convert MOV to MP4 with FFmpeg: remux or re-encode, step by step.
- ffprobe API: check the codecs of a file from its URL.
- FFmpeg cheat sheet: the common commands, each as an API call.
Frequently asked questions
What is the best video format for the web?
MP4 with H.264 video, AAC audio and the yuv420p pixel format plays in all current browsers on desktop and mobile. Add -movflags +faststart so playback can start before the whole file has downloaded.
What does -movflags +faststart do?
It moves the MP4 index (the moov atom) to the start of the file. A browser needs the index before it can play, so with the index at the start, playback can begin while the rest of the file downloads.
Do I have to re-encode a video to make it web-ready?
Not always. If the file already has H.264 video and AAC audio, a remux with -c copy -movflags +faststart is enough. Re-encode only when the codecs or the pixel format do not play in browsers, for example HEVC, ProRes or 10-bit video.
Why does my MP4 play in VLC but not in the browser?
VLC plays almost any codec, browsers do not. The MP4 probably has HEVC or ProRes video, a 10-bit or 4:2:2 pixel format, or PCM audio. Re-encode to H.264 with -pix_fmt yuv420p and AAC audio.