The current model of video streaming, as implemented by netflix, iTunes, etc. requires the viewer to decide what they want to watch, then play the content starting from the beginning. This is a distinctly different model than television, where video is being "streamed" continuously, and the viewer starts watching whatever happens to be on at that time.

Companies like Pandora have recognized the value in the latter model. People get fatigued by decisions, and want to view entertainment content as a relaxation tool. Adding more decisions to the process is counter productive to this end.

This is a quick tool to present local video content over http in the television viewing model.


This uses HTTP Live Streaming. This tool takes existing video content, converts it to the MPEG2 transport stream used by HLS, segments the stream into 10 second chunks, and creates a .m3u8 playlist file that is continuously updated with the "current" stream.

The m3u8 playlist is a sliding window into a cache of MPEG2 ts segments. Every 10 seconds, the last entry is removed, along with the actual MPEG2 segment, and the next segment is appended to the playlist. When the number of available cached segments is below a certain threshold, the next media file is converted into the cached MPEG2 segments, ready for addition to the playlist file. This allows the segment cache size to be constrained by the threshold amount.


This is a simple .c file, intended to be run from the streaming directory. It looks in a directory named input for the media files. It traverses the entire directory hierarchy in input, following symlinks. I typically make symlinks into my iTunes library. It then creates multiple streamdir# directories which contain the transport segments for a given media file input. It will then generate a playlist.m3u8 file that is continuously updated. The process will run in the foreground and print current activities to stdout.


generator.c: The code

This uses ffmpeg for repackaging media files into MPEG2 transport streams, and m3u8-segmenter to segment the stream.
It is also necessary to serve the m3u8 file via html using something like the following:
    <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>

    <video src="playlist.m3u8" controls autoplay>


Keep the playlist size small. Clients can start from pretty much anywhere in the playlist, so a small playlist means: 1) clients are more likely to see the same thing, and 2) if a client falls off either end of the playlist for some reason, it'll restart from somewhere else in the current playlist. Restricting the size of the playlist means the client will restart closer to where they were.

Sequence numbers don't seem to mean much. When clients restart due to an error or the user leaving and coming back, they don't seem to use the sequence number for anything. This code updates the sequence number, but I haven't found that it affects client behavior.

Segmenting doesn't necessarily segment anywhere near the desired play length (apple recommends 10s segments). Segments seem to be up to 50% off from the specified segmenting interval. This needs to be taken into account when updating the playlist to add more entries on demand.

There's no technical reason to reencode content (assuming the original content is playable by the client). The audio and video content can be repackaged from the source into the mpegts container without reencoding because the EXT-X-DISCONTINUITY tag in the m3u8 playlist indicates to the client that a different resolution/bitrate/encoding file is coming up.

Updated April 24 2013