Video player improvements

We got some reports of videos not working on iOS. We’ve made some fixes and now have an Apple device to test with.

Videos should play on just about any platform now; if you’re having any trouble, please let us know.

Details

When we started this site, I knew very little about hosting video. But I’d heard of MPEG-DASH, and it seemed like a good way to ensure that users with slower internet connections get acceptable performance. Encoding a video file in DASH format splits it into hundreds of smaller video files so that you can skip into the middle of a video without loading the entire thing, and has multiple redundant encodings of the same video at different compression levels so that slower clients can download lower-quality video instead of waiting longer for higher-resolution video to download.

Most web clients don’t support DASH natively, so we used a JavaScript client – Google’s Shaka player. Unfortunately, it turns out that even this approach is still unsupported by iOS. To support iPads and the like, we need to use Apple’s own streaming format, HLS.

Fortunately, HTML now makes it easy to provide video in multiple formats: Update (2018 Aug 4): We originally included only DASH, HLS, and MP4; we have since added WebM to accommodate some older versions of Firefox.

<video poster="static-image.jpg" controls>
  <source type="application/dash+xml" src="dash/manifest.mpd">
  <source type="application/x-mpegURL" src="hls/index.m3u8">
  <source type="video/mp4" src="video.mp4">
  <source type="video/webm" src="video.webm">
</video>

This leaves it up to the web browser to choose which of those formats it is capable of playing. The video/mp4 and video/webm options are the final fallbacks; they don’t have the performance advantages of the streaming formats, but are much more widely supported. And since we now provide the MP4/WebM files directly, you can download our videos and play them offline.

To complete this mini-tutorial on video hosting, I should also mention how we produce the DASH and HLS encoded versions of our videos. I thought this was going to be complicated, but it turns out that ffmpeg can handle it easily.

To produce a DASH encoding of a video:

mkdir dash
ffmpeg -i video.mp4 -f dash dash/manifest.mpd

To produce an HLS encoding of a video:

mkdir hls
ffmpeg -i video.mp4 -f hls -hls_list_size 0 hls/index.m3u8