The short answer

An MPEG-4 (.mp4) container with H.264 codec will get you 97% coverage on current browsers across desktop and mobile, although there are some caveats. To address those you could also serve WebM (.webm) container with VP9 codec.

In this post:

What video formats do browsers support?

MPEG-4/H.264WebMAV1Ogg/TheoraHEVC/H.265
% Support96.62%95.38%72.89%36.98%19.52%
IE 11YesPartial#2NoPartialAlmost#7
Edge 96YesYesYesYesNo
FF 95YesYesYesYesNo
Chr. 96YesYesYesYesNo
Saf. 15.2YesAlmost#3NoNoYes
Op. 82YesYesYesYesNo
iOS 15.2YesAlmost#4 #5NoNoYes
O.Mini allNoNoNoNoNo
And. 96YesYesYesNoNo#8
BB 10YesNoNoNoNo
O.Mob 64YesYesYesNoNo#8
Chr/And. 96YesYesYesNoNo#8
FF/And. 95Almost#1YesNo#6YesNo
IE.Mob 11YesPartialNoPartialNo
UC 12.12AlmostYesNoYesNo
SS 15.0YesYesYesNoNo#8
QQ 10.4YesYesNoYesNo
baidu 7.12YesYesNoNoNo
Kai 2.5YesYesNoYesNo
Data from caniuse.com

Every browser supports MPEG-4/H.264 (MPEG-4 container with H.264 codec) except Opera Mini, which doesn’t support video at all, so no great loss there.

Firefox on Android supports MPEG-4/H.264 but doesn’t support hardware acceleration. Videos will work but will have an impact on battery life and possibly playback performance.

UC Browser was popular on mobile devices in 2017 in India and China but has since lost almost all its market share to Chrome. It’s unlikely you need to worry about this browser.

How to convert video to MP4

I find it easiest to use the command line. For that ffmpeg is the best tool. Install it on MacOS with:

brew install ffmpeg

Then run the following command:

1
2
3
4
5
6
7
8
ffmpeg \
  -i "input.mov" \
  -vcodec libx264 \
  -pix_fmt yuv420p \
  -profile:v baseline \
  -level 3 \
  -movflags faststart \
  "output.mp4"
  1. Run ffmpeg. The trailing \ means “continue the command on the next line”.
  2. Your input file.
  3. Sets the codec to H.264.
  4. Ensure compatibility with Apple Quicktime.
  5. Use only base H.264 features to ensure widest compatibility.
  6. Set H.264 quality level. 1 is the lowest and 6 the highest.
  7. Move video metadata to the start of the file, so the browser can immediately know the dimensions and length of the video. Find more details here.

How to convert video to WebM

1
2
3
4
5
6
ffmpeg -i input.mov -c:v libvpx-vp9 -pass 1 -b:v 1000K -threads 8 -speed 4 \
  -tile-columns 6 -frame-parallel 1 \
  -an -f webm /dev/null
ffmpeg -i input.mov -c:v libvpx-vp9 -pass 2 -b:v 1000K -threads 8 -speed 1 \
  -tile-columns 6 -frame-parallel 1 -auto-alt-ref 1 -lag-in-frames 25 \
  -c:a libopus -b:a 64k -f webm output.webm

The recomended approach for WebM/VP9 is a two-pass approach, hence the two calls to ffmpeg above.

  1. Call ffmpeg with VP9 codec, for the first pass, at the given video bitrate, with 8 threads, at a faster speed.
  2. Enable parallel processing
  3. Disable audio for first pass, use webm format, and output nothing.
    • The first pass creates a log file called ffmpeg2pass-0.log. The second pass uses this information.
  4. Same as 1 but a higher-quality speed.
  5. Same as 2, and set auto-alt-ref and lag-in-frames to enhance quality.
  6. Use Opus audio codec, with given audio bitrate.

How to generate a video thumbnail

You can also generate a thumbnail/poster image that the browser shows before it downloads the video:

1
2
3
4
5
ffmpeg \
    -i input.mp4 \
    -ss 00:00:14.435 \
    -vframes 1 \
    out.png
  1. Run ffmpeg.
  2. Your input file.
  3. The time through the video to create the image from, in Hours:Minutes:Seconds.Milliseconds.
  4. Extract one frame of video.

How to embed video

The minimal code, with video controls, but without a thumbnail:

<video controls src="output.mp4" type="video/mp4">
    Your browser doesn't support video.
</video>

And to add a thumbnail image, and multiple video formats:

<video controls poster="out.png" >
  <source src="output.webm" type="video/webm" />
  <source src="output.mp4" type="video/mp4">
  Your browser doesn't support video.
</video>

The browser uses the first source it supports, and so WebM/VP9 should be listed first as it is higher quality than MPEG-4/H.264.

More information

You can find more (very detailed!) information at the following links: