Some time ago I prepared a PC that was responsible for batch encoding of movies to formats suitable for web players (such as. Video.jsexternal link , JW Playerexternal link , Flowplayerexternal link , etc.)

I used HandBrake for conversion to MP4 format (becase this soft was the fastest one) and ffmpeg (aka avconv in new version) for two pass encoding to WEBM.

Below are commands used by me for that conversion:

  • MP4
HandBrakeCLI -e x264  -q 20.0 -a 1 -E faac -B 64 -6 mono -R 44.1 -D 0.0 -f mp4 --strict-anamorphic -m -x ref=1:weightp=1:subq=2:rc-lookahead=10:trellis=0:8x8dct=0 -O -i "input_file.avi" -o "output_file.mp4"
  • WEBM
avconv -y -i "input_file.avi" -codec:v libvpx -b:v 600k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 4 -an -pass 1 -f webm /dev/null
avconv -y -i "input_file.avi" -codec:v libvpx -b:v 600k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 4 -codec:a libvorbis -b:a 96k -pass 2 -f webm "output_file.webm"

Nginx configuration for MP4

I used configuration similar to that below for MP4 pseudostreaming and to protect direct urls to videos from linking on other sites (links will expire after sometime). There is also example usage of limit_rate clause that will slow down downloading of a file (it’s still two times bigger than video streaming speed so should be enough).

location ~ \.m(p4|4v)$ {
  ## This must match the URI part related to the MD5 hash and expiration time.
  secure_link $arg_ticket,$arg_e;

  ## The MD5 hash is built from our secret token, the URI($path in PHP) and our expiration time.
  secure_link_md5 somerandomtext$uri$arg_e;

  ## If the hash is incorrect then $secure_link is a null string.
  if ($secure_link = "") {
    return 403;

  ## The current local time is greater than the specified expiration time.
  if ($secure_link = "0") {
    return 403;

  ## If everything is ok $secure_link is 1.
  mp4_buffer_size     10m;
  mp4_max_buffer_size 1024m;

  limit_rate          1024k;
  limit_rate_after    5m;
Sources link link