Skip to content

Instantly share code, notes, and snippets.

@davo
Forked from Vestride/encoding-video.md
Created May 11, 2017 23:04
Show Gist options
  • Save davo/30098fe96545ed8ebb4b2c9a91e34af6 to your computer and use it in GitHub Desktop.
Save davo/30098fe96545ed8ebb4b2c9a91e34af6 to your computer and use it in GitHub Desktop.
Encoding video for the web

Encoding Video

Installing

Install FFmpeg with homebrew. You'll need to install it with a couple flags for webm and the AAC audio codec.

brew install ffmpeg --with-libvpx --with-libvorbis --with-fdk-aacc --with-opus

If you already have ffmpeg installed, but not with the other libraries, use the reinstall command.

brew reinstall ffmpeg --with-opus

FFmpeg options. The -c:v option is an alias for -vcodec and -c:a is an alias for -acodec. -crf is Constant Rate Factor.

Constant Rate Factor

This method allows the encoder to attempt to achieve a certain output quality for the whole file when output file size is of less importance. This provides maximum compression efficiency with a single pass. Each frame gets the bitrate it needs to keep the requested quality level. The downside is that you can't tell it to get a specific filesize or not go over a specific size or bitrate.

Convert to MP4

When converting to an MP4, you want to use the h264 video codec and the aac audio codec because IE11 and earlier only support this combination. The FFmpeg and H.264 Encoding Guide can walk you through some of the H.264 specific options.

ffmpeg -i input.mov -vcodec h264 -acodec aac -strict -2 output.mp4

For maximum compatibility, use the profile option. This may, however, increase the bit rate quite a bit. You can disable the audio stream with the -an option. -pix_fmt yuv420p is for Apple Quicktime support.

In this example, input.mov is converted to output.mp4 with maximum compatibility, with Quicktime support, and without an audio stream.

ffmpeg -an -i input.mov -vcodec libx264 -pix_fmt yuv420p -profile:v baseline -level 3 output.mp4

Convert to WebM

VP8

libvpx is the VP8 video encoder for ​WebM. FFmpeg and WebM Encoding Guide will walk you through webm specifics.

In this example, input.mov is converted to output.webm with a constant rate factor of 10 (lower is higher quality) at a bitrate of 1M. Changing the bitrate to something lower (e.g. 700K) will result in lower file sizes and lower quality. If your video does not have audio, you may leave off the -acodec libvorbis part.

ffmpeg -i input.mov -vcodec libvpx -qmin 0 -qmax 50 -crf 10 -b:v 1M -acodec libvorbis output.webm

VP9

VP9 can encode videos at half the file size 😄👏 You can check out Google's VP9 encoding guide for their recommend settings or the FFmpeg VP9 guide.

Here's an example from the FFmpeg guide:

ffmpeg -i input.mov -vcodec libvpx-vp9 -b:v 1M -acodec libvorbis output.webm

And here's Google's "Best Quality (Slowest) Recommended Settings". You need to run the first line(s). It will create a log file (and warn you the out.webm is empty). On the second pass, the video will be output.

ffmpeg -i <source> -c:v libvpx-vp9 -pass 1 -b:v 1000K -threads 1 -speed 4 \
  -tile-columns 0 -frame-parallel 0 -auto-alt-ref 1 -lag-in-frames 25 \
  -g 9999 -aq-mode 0 -an -f webm /dev/null


ffmpeg -i <source> -c:v libvpx-vp9 -pass 2 -b:v 1000K -threads 1 -speed 0 \
  -tile-columns 0 -frame-parallel 0 -auto-alt-ref 1 -lag-in-frames 25 \
  -g 9999 -aq-mode 0 -c:a libopus -b:a 64k -f webm out.webm

Support

As of January 2015, all major browsers support MP4.

Data current as of March 2017. Sourced from jwplayer's research and caniuse for mp4 and webm.

Edge 14+ has partial support for VP9

Browser H264 H265 VP8 VP9 AAC MP3 VORBIS OPUS
Chrome for Desktop 30+ - 30+ 30+ 30+ 30+ 30+ 33+
Chrome for Android 30+ - 30+ 30+ 30+ 30+ 30+ -
IE 9+ - - - 9+ 9+ - -
IE Mobile 10+ - - - 10+ 10+ - -
Edge 12+ - - 14+ 12+ 12+ - 14+
Firefox for Desktop 22+ - 20+ 28+ 22+ 22+ 20+ 20+
Firefox for Android 20+ - 20+ 28+ 20+ - 20+ 20+
Safari for Mac 3+ - - - 3+ 3+ - -
Safari for iOS 3+ - - - 3+ 3+ - -
Opera for Desktop 25+ - 11+ 16+ - - 11+ 12+
Android Stock Browser 2.3+ - 4.0+ - 2.3+ 2.3+ 4.0+ -

Recommended markup

Since all browsers except Opera support MP4, we can use WebM's VP9 codec for modern browsers and fall back to MP4s for the rest.

<video>
  <source src="path/to/video.webm" type="video/webm; codecs=vp9,vorbis">
  <source src="path/to/video.mp4" type="video/mp4">
</video>

Creating thumbnail images from the video

Here's their guide. Output a single frame from the video.

ffmpeg -i input.mp4 -ss 00:00:14.435 -vframes 1 out.png

Output one image every second as a jpg.

ffmpeg -i input.mp4 -vf fps=1 out%3d.jpg

Reversing a video

FFmpeg cannot reverse a video by itself. One way to reverse a video is to use After Effects' Time-Reverse Layer.

  • Open After Effects. Drag your clip in to the project and then into the timeline.
  • Right click on your video clip layer and choose Time.
  • From the Time menu, choose Time-Reverse Layer ⌥⌘R
  • Export lossless as an .mov. (Choose Composition and then Add to render queue).
  • Not sure if required - Convert to h.264 mp4 with and Adobe Media Encoder
  • Following encoding steps as usual.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment