Converting Video for the Web with FFMPEG

How I generate videos for this website, using ffmpeg.
, Updated: 1 min read

alternative title - “You don’t really need YouTube to host (small) videos”

Video Generation

For converting the video, we use a modified version of the mp4 script from this gist.

The only modifications we will make are adding the flag -movflags faststart. The moov atom stores information about the video required for playback, this flag moves it to the beginning of the file for streaming over http. Traditionally, it’s stored at the end of the file which is fine for local playback, but since you load the file sequentially for the web it’s advantageous to move it to the beginning. You can read more about the moov atom’s usage here.

# Here, "win98-720.m4v" is my source file, and "win98.mp4" is my destination file.
ffmpeg \
  -i "win98-720.m4v" \ # Input file
  -vcodec libx264 \ # Use the h264 video codec
  -pix_fmt yuv420p \ # Apple Quicktime support
  -profile:v baseline \ # For compatibility
  -level 3 \
  -movflags faststart \ # <- move the moov atom

Poster Generation

HTML5 Video tags also support poster images. While not strictly necessary, this allows you to override the image displayed before playback of the video. Some of the videos I’ve recorded start with an all-black screen which doesn’t look good in a <video> tag. I use this to change that:

# You may need to alter the -ss flag, which is the offset from the start of the video.
ffmpeg \
  -ss 2 \ # Start time (s)
  -i "win98.mp4" \ # Input
  -vf "select=eq(n\,0)" \
  -q:v 3 \
  "win98.mp4.poster.jpg" # Output

original idea from here.

Putting it all together:

After uploading your files somewhere, you can nicely display them on the web like this:


  <video poster="" alt="Windows 98 Install Process" controls>
    <source src="" type="video/mp4">
  <figcaption>Clean Install of Windows98 On VirtualBox.</figcaption>


Clean Install of Windows98 On VirtualBox.

Change Log

  • 7/13/2019 - Initial Revision
  • 11/5/2020 - Remove confusing `an` flag (used for the example to remove the audio, but not common cases!)

Found a typo or technical problem? file an issue!