inline Make a WEBM as a Gif alternative

Originally published on May 20th, 2020 (Last updated on May 20th, 2020)

Require­ment: ffm­peg must be com­piled with the --enable-libvpx-flag!

Sim­i­lar to the high-qual­i­ty Gif guide we cut the input Video down to it’s rel­e­vant parts, remove any audio, pick an appro­pri­ate frame-rate and scale it down for the use-case:

ffmpeg -ss <start> -i <video-file> -t <length> -filter_complex "[0:v] fps=30,scale=620:-2" -map v cut.mp4

A few things are hap­pen­ing in this sin­gle com­mand, lets break it down:

  1. Before the input, we spec­i­fy the seek-posi­tion (absolute) to start at.
  2. Then, the input file is specified
  3. After the input-file, the length of the out­put is spec­i­fied (rel­a­tive)
  4. Then, apply a fil­ter to cre­ate a new video out­put stream which…
  5. takes the only video stream from the first input file (the Video) …
  6. sets it’s FPS to 30
  7. scales it down to 620px width, keep­ing the aspect ratio (by spec­i­fy­ing -2 for height. We use -2 here to guar­an­tee that the height is divid­able by two).
  8. For the out­put, we dis­card every­thing except the sin­gle fil­tered video stream.
  9. The out­put is then writ­ten to the cut.mp4-file.

This time, no palette is required. Instead, since we’re using WEBM v9, a dou­ble pass encod­ing is rec­om­mend­ed for bet­ter qual­i­ty and small­er files:

# First pass (note that the output file is NOT required, only the .log file that is also created in this step!)
ffmpeg -i cut.mp4 -c:v libvpx-vp9 -pass 1 -b:v 1000K -threads 8 -speed 4 -tile-columns 6 -frame-parallel 1 -an -f webm discard.tmp
# Second pass (which ouputs the final file)
ffmpeg -i cut.mp4 -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 -f webm out.webm

The first com­mand runs the first pass (denot­ed by the -pass 1 argu­ment). It’s out­put file can be dis­card­ed, only the ffmpeg2pass-0.log (or sim­i­lar) file which is also cre­at­ed is impor­tant. It will be used implic­it­ly on the sec­ond pass!

The sec­ond com­mand runs the final sec­ond pass (denot­ed by -pass 2 argu­ment). Here, the infor­ma­tion from the first pass is used to cre­ate the final out­put file.

All addi­tion­al argu­ments for both pass­es are tak­en from Googles offi­cial rec­om­men­da­tion for VOD, which I’ll repeat here for prosperity:

  • c:v libvpx-vp9 tells FFm­peg to encode the video in VP9.
  • b:v 1000K tells FFm­peg to encode the video with a tar­get of 1000 kilobits.
  • Most of the cur­rent VP9 decoders use tile-based, mul­ti-thread­ed decod­ing. In order for the decoders to take advan­tage of mul­ti­ple cores, the encoder must set tile-columns and frame-parallel.
  • Set­ting auto-alt-ref and lag-in-frames >= 12 will turn on VP9’s alt-ref frames, a VP9 fea­ture that enhances quality.
  • speed 4 tells VP9 to encode real­ly fast, sac­ri­fic­ing qual­i­ty. Use­ful to speed up the first pass.
  • speed 1 is a good speed vs. qual­i­ty com­pro­mise. Pro­duces out­put qual­i­ty typ­i­cal­ly very close to speed 0, but usu­al­ly encodes much faster.
  • Mul­ti-thread­ed encod­ing may be used if -threads > 1 and -tile-columns > 0


No com­ment sec­tion here 😄

You can reach me over at @knuth_dev or send me an Email.