# Encoding Video ### Installing Install FFmpeg with homebrew. You'll need to install it with a couple flags for webm and the AAC audio codec. ```shell 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. ```shell brew reinstall ffmpeg --with-opus ``` [FFmpeg options](https://ffmpeg.org/ffmpeg.html#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](https://trac.ffmpeg.org/wiki/Encode/H.264) can walk you through some of the H.264 specific options. ```shell 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. ```shell 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](https://trac.ffmpeg.org/wiki/Encode/VP8) 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. ```shell 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 :smile::clap: You can check out Google's [VP9 encoding guide](https://sites.google.com/a/webmproject.org/wiki/ffmpeg/vp9-encoding-guide) for their recommend settings or the [FFmpeg VP9 guide](https://trac.ffmpeg.org/wiki/Encode/VP9). Here's an example from the FFmpeg guide: ```shell 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. ```shell ffmpeg -i -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 -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](http://www.jwplayer.com/html5/) and caniuse for [mp4](http://caniuse.com/#feat=mpeg4) and [webm](http://caniuse.com/#feat=webm). Edge 14+ has [partial support](https://blogs.windows.com/msedgedev/2016/04/18/webm-vp9-and-opus-support-in-microsoft-edge/) 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. ```html ``` ## Creating thumbnail images from the video Here's their [guide](https://trac.ffmpeg.org/wiki/Create%20a%20thumbnail%20image%20every%20X%20seconds%20of%20the%20video). Output a single frame from the video. ```shell ffmpeg -i input.mp4 -ss 00:00:14.435 -vframes 1 out.png ``` Output one image every second as a jpg. ```shell 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.