Encoding a Video for HTML5 using ffmpeg

Problem:

You have a video file and want to encode it to support all three HTML5 codecs currently available (WebM, Theora and H.264) on the majority of devices.

Solution

You can use ffmpeg for this task.

On Linux, you can use the following bash script, assuming you have installed ffmpeg

#!/bin/bash
#Strip the path and the extension from the filename
strippedFilename=$(echo $1 | rev | cut -d/ -f1 | cut -d. -f2- | rev)
resolution=640x360
#Encode H.264
avconv -i $1 -b 1500k -vcodec libx264 -vpre slow -vpre baseline -g 30 -s $resolution ${strippedFilename}.mp4
#Encode WebM
avconv -i $1 -b 1500k -vcodec libvpx -acodec libvorbis -ab 160000 -f webm -g 30 -s $resolution ${strippedFilename}.webm
#Encode Theora
avconv -i $1 -b 1500k -vcodec libtheora -acodec libvorbis -ab 160000 -g 30 -s $resolution ${strippedFilename}.ogv
#Extract a thumbnail image
avconv -i $1 -ss 00:10 -vframes 1 -r 1 -s $resolution -f image2 ${strippedFilename}.jpg

 

Remember to adjust the resolution variable (or remove the -s option completely if you want to use the original) depending on your desired video quality. 640x480 seems like a good solution to me if bandwidth matters more than quality. It’s even viewable on 2G connections if you let it load for a view seconds.

Note that avconv is the replacement for the ffmpeg tool in newer version. ffmpeg itself is deprecated. If you have an older version of ffmpeg, simply replace all occurrences of avconv by ffmpeg in the script above.

The script also creates a thumbnail image, see the last command.

You can also use this modified version of the script hat doesn’t strip the double extension or the directory, for example when encoding video.avi,  you would get video.avi.mp4 instead of video.mp4. Use the modified version when you need to encode a file that already has one of the extensions to generate (.mp4, .ogv or .webm) and you need to have this file in the current directory.

#!/bin/bash
#Encode H.264
avconv -i $1 -b 1500k -vcodec libx264 -vpre slow -vpre baseline -g 30 -s 640x360 $1.mp4
#Encode WebM
avconv -i $1 -b 1500k -vcodec libvpx -acodec libvorbis -ab 160000 -f webm -g 30 -s 640x360 $1.webm
#Encode Theora
avconv -i $1 -b 1500k -vcodec libtheora -acodec libvorbis -ab 160000 -g 30 -s 640x360 $1.ogv
#Extract a thumbnail image
avconv -i $1 -ss 00:10 -vframes 1 -r 1 -s 640x360 -f image2 $1.jpg

The commands were taken from this blog entry and modified to work on Linux appropriately. See the original post for a Windows solution.