×

With the decline of Flash and the explosive rise of mobile devices, more and more content is being delivered as HTML5 video. We even saw in our last post about how you can optimize the speed of your site by replacing animated GIF video clips with HTML5 videos. However, video files themselves have a number of optimizations that you can make to improve their performance. One of the most important is that video files must be properly optimized for streaming online as HTML5 video. Without this optimization videos can be delayed for hundreds of milliseconds and megabytes of bandwidth can be wasted by visitors just trying to play your videos. In this post I will show you how to optimize your video files for fast streaming.

How MP4 Streaming Works

As discussed in our last post, HTML5 video is a cross-browser way to watch video without needing a plug-in like Flash. As of 2016, H.264 encoded video stored in an MP4 container file (which I’ll just simply call an MP4 video) has emerged as the standard format for all online HTML5 video. So when we talk about optimizing HTML5 video, what we are really talking about is how to optimize an MP4 video for faster playback. And the way we do that has to do with the structure of the MP4 file, and how streaming video works.

MP4 files consist of chunks of data called atoms. There are atoms to store things like subtitles or chapters, as well as obvious things like the video and audio data. Meta data about where the video and audio atoms are, as well as information about how to play the video like the dimensions and frames per second, is all stored in a special atom called the moov atom. You can think of the moov atom as a kind of table of contents for the MP4 file.

When you play a video, the program looks through the MP4 file, locates the moov atom , and then uses that to find the start of the audio and video data and begin playing. Unfortunately, atoms can appear in any order, so the program doesn’t know where the moov atom will be ahead of time. Searching to find the moov works fine if you already have the entire video file. However another option is needed when you don’t have the entire video yet, such as when you are streaming HTML5 video. That’s the whole point of streaming a video! You can start watching it without having to download the entire video first.

When streaming, your browser requests the video and starts receiving the beginning of the file. It looks to see if the moov atom is near the start. If the moov atom is not near the start, it must either download the entire file to try and find the moov, or the browser can download small different pieces of the video file, starting with data from the very end, in an attempt to find the moov atom.

All this seeking around trying to find the moov wastes time and bandwidth. Unfortunately, the video cannot play until the moov is located. We can see in the screen shot below a waterfall chart of a browser trying to stream an unoptimized MP4 file using HTML5 video:

mp4-no-moov

You can see the browser makes 3 requests before it can start playing the video. In the first request, the browser downloads the first 552 KB of the video using an HTTP range request. We can tell this by the 206 Partial Content HTTP response code, and by digging in and looking at the request headers. However the moov atom is not there so the browser cannot start to play the video. Next, the browser requests the final 21 KB of the video file using another range request. This does contain the moov atom, telling the browser where the video and audio streams start. Finally, the browser makes a third and final request to get the audio/video data and can start to play the video. This has wasted over half a megabyte of bandwidth and delayed the start of the video by 210 ms! Simply because the browser couldn’t find the moov atom.

It gets even worse if you haven’t configured your server to support HTTP range requests; the browser can’t skip around to find the moov and must download the entire file. This is yet another reason why your should optimize your site with partial download support.

The ideal way to prepare a MP4 video for HTML5 streaming is to organize the file so that the moov is at the very beginning. This way the browser can avoid downloading the entire movie or waste time making additional requests in an attempt to find the moov. The waterfall of a website with a streaming-optimized video looks like this:

mp4-fast-start

With moov at the start of the file, the video will load and play faster, resulting in a better user experience.

Optimizing MP4 for faster streaming

We have seen that to optimize a video for HTML5 streaming, you need to reorganize the MP4 atoms so the moov atom is at the start. So how do we do that? Most video encoding software has an “optimize for web” or “optimize for streaming” option which does this very thing. You should look at your video encoding settings when creating video to ensure it is optimized. For example, in the screenshot below, we see the open source video encoder Handbrake which has an option “Web Optimized”, which places the moov atom at the start:

handbrake

This is a workable solution if you are creating the MP4 file from the original source video, but what if you already have an MP4 file?

You can also reorganize an existing video to optimize it for web streaming as well. The open source command line video encoder FFMpeg can reorganize the structure of the MP4 file to place the moov atom at the start. Unlike the initial encoding of the video which is very time consuming and CPU intensive, reorganizing the file is an easier operation and will not alter the quality of the original video in any way. Before is an example of using ffmpeg to optimize a video named input.mp4* for streaming. The resulting video is named output.mp4

The -movflags faststart parameter is what tells ffmpeg to reorder the MP4 video atoms so that moov is at the start. We are also instructing ffmpeg to copy the video and audio data instead of re-encoding them, so nothing gets altered.

For our Rigor customers, we have added a new check to Zoompf, our performance analysis and optimization product, which will detect MP4 files which have not been optimized for HTM5 video streaming. If you just want a quick check of your site, you can use our Free Performance Report.

Conclusions

Whether you are converting animated GIF video clips to MP4, or have a bunch of existing MP4 videos, you can make those videos load and start playing much faster if you optimize the structure of the file. By reordering the atoms so the moov atom is at the start, the browser avoids sending extra HTTP range requests to skip around and try to locate the moov atom. This allows the browser to instantly start streaming the video. You can usually configure an option when initially creating your video to optimize it for streaming. If you have an existing file, you can use a program like ffmpeg to reorder the file without altering its contents.

 

Suggested Blog Posts

The Perception Gap for Poor Web Performance

E-commerce revenue continues to grow,as consumers turn away from shopping in brick-and-mortar stores to shopping online.  However, many businesses are not prepared for this growth because they do not fully understand the market and how to invest in...

Read More

Using Browser Trends to Maintain a Better Site

Because of the multifarious nature of web clients today, it’s important to consider the usage statistics when designing, implementing, and managing your site. However, misconceptions often arise when determining what browsers to design for an...

Read More

Finding Causes of Intermittent Errors from Google Webmaster Tools

Google Webmaster Tools is a web service that allows webmasters to view the status of their sites as seen by Google and the Googlebot crawlers. In addition to indexing your site structure and content, the Googlebot crawlers also record data on perform...

Read More

Optimization Options not Always Optimal

Web designers and developers are always looking for ways to speed up their page load times. Yahoo has an excellent article written on the best practices for speeding up your page. How do you know if implementing one of their suggested practices will...

Read More
  • Deepak

    Excellent article. I have been through similar process for enabling fast start on about 350,000+ mp4 videos. At that time I have used a python script (https://github.com/danielgtaylor/qtfaststart) using one of the ffmpeg library to do the conversion of all the mp4 videos.

    At that time I did not get much info about what that script was doing, your article today provided me the insight. Many thanks.

  • andy

    This is a really great article, thanks! Do you know of any GUI tools on the Mac that allows me to inspect an mp4 file to check wether it’s been optimised or not?

  • nate

    Great article, but I tried using ffmpeg with -movflags faststart instead of using Handbrake to convert a video, but the ffmpeg version didnt stream while the handbrake did. Any suggestions, or do you know if the ffmpeg commands have changed since?

    • Greg Brewton

      I downloaded ffmpeg to my laptop(10 year old Sony Vaio running Ubuntu 16.04), used the aforementioned command to optimize the .mp4, and uploaded it to my server (Old Dell Dimension 2.4ghz, 32bit, Ubuntu 16.04 server). It loaded much faster and streamed without issue on both local and remote networks – phone and laptop. Maybe check your syntax or the ffmpeg documentation for help or check the upload speed of your server, but everything worked great for me.

  • Greg Brewton

    Thanks so much, this could not have been easier. Also, ffmpeg is in the Ubuntu canonical library, so it’s as easy as sudo apt-get install ffmpeg

  • Great post and I’ve really leaned a lot from it! BTW, I think Handbrake is easy for me to convert video and ffmpeg seems a little complicated. Sometimes before, I visited http://www.tresrrr.com and find an MP4 video converter to convert video files easily.