Preparing Video for HTTP Live Streaming

When playing video on an iPad or iPhone, you never know how good a connection you will have.  Are they on WiFi?  3G?  Worse?  And the quality of the connection could change in the middle.  How do you play video on a mobile website and have it automatically adjust the quality in response to the connection?  The answer is “HTTP Live Streaming”.

In HTTP Live Streaming, which unfortunately is only supported for Mobile and Desktop Safari (and native apps, I believe, but I’m focused on web right now), the video is broken into 10 seconds chunks that are then played like a playlist.  You can have multiple sets of these chunks at different qualities, and the browser automatically adjusts to pull the highest quality stream it currently can afford.  It’s pretty slick.

(image from Apple documentation)

There is a lot of good documentation out there, especially from Apple about how this works.  Check out  I won’t attempt to recreate all of that, but I did have a few hiccups and workarounds when I did it, so I wanted to document my steps.

1. Buy a Mac.  While the video can be placed on a server of any type (they’ll be served via HTTP), all the tools you need to encode the video in the first place are on a Mac.  (Maybe there are other tools out there, but this is what I found).

2. Install the HTTP Live Streaming Tools.  The link above for the Apple Developer site has a link to download these tools.  You need to be registered in the iOS Developer program to get to them.

3. Use your favorite program to create the video in various qualities.  The Apple documentation has a lot of suggestions on this.  I’m sure you should tweak these for your type of video.  But the idea is to slow down the data rate and frames per second for slow connections.  I received H.264 .mov files at the following qualities:

  • 990 kbps, 30 frames per second
  • 440 kbps, 30 frames per second
  • 240 kbps, 15 frames per second
  • 150 kbps, 10 frames per second

4. Put each video into its own subdirectory – it will make the later steps much easier.

5. Launch Terminal and go to the parent directory of your videos.

6.  When I tried to use the mediafilesegmenter (next step), I got an error that the video “contains edit list that the media doesn’t start at the beginning.”  So my next step was to remux the source into an mpeg2 ts container.  Maybe some videos don’t need all this (I think Handbrake may be fine), but mine came from another party.  My steps were as follows:

7. Segment the files using Apple’s mediafilesegmenter, telling it you want it to create a variant plist file.  To do this, in each directory, simply issue the following (if you’re redoing this for any reason, empty the directory first):

mediafilesegmenter –I {.ts}

This command will add a .m3u8 file, a .plist file, and all the .ts segments to your directory.

8. Now you can create the actual variable playlist.  In the parent directory, issue a command like the one below.  In this command you repeat pairs for each stream.  You specify the URL where that stream will be (once on the server) and where you can find the .plist for that stream right now.  The first pair should be the stream you want to start with (so usually a lower quality one).  This big command gets confusing with braces, so assume all the videos will be on in subdirectories named “low”, “med”, and “hi”,  and on my Mac I have those same subdirectories that also have the .plist files.

variantplaylistcreator –o myvideo.m3u8 \ low/myvideo.plist  \ med/myvideo.plist  \ hi/myvideo.plist

This will create the myvideo.m3u8 file that points to all these other streams with information about the speed needed to play each.

9. Copy the files to your web server.  You’ll need the .m3u8 file from the parent, and the filesequence .ts files and .m3u8 file from each subdirectory.

10.  After all the hard work, the easy part is getting the video to play.  Simply point your HTML5 Video tag to the parent .m3u8 file and it will do the rest.

Whew.  Hopefully it all worked and you now have video playing well at all speeds.


For more help, I found this site helpful:

2 thoughts on “Preparing Video for HTTP Live Streaming

  1. This is very helpful, but I think theres an error. In step 7 instead of

    mediafilesegmenter –I {.ts}

    I believe it should read

    mediafilesegmenter –I {new_file}.ts

    Otherwise, you are not feeding mediafilesegmenter the output of your last transcoding command.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s