Raspberry Pi Streaming video

Introduction

Raspberry Pis1 and their camera modules2 are a popular and cheap way to stream video on the Internet. Anything video related on the web always seems to be messy though, and although there are lots of articles discussing this on the web, I found it far from trivial to set up. Perhaps the most useful article was on StackExchange3

One reason that the task is difficult is simply that there isn’t an approach which is best for everyone. So let’s begin by deciding what we want, and what we don’t care about.

I want to stream video from the Raspberry Pi’s camera to iOS and MacOS clients.

I don’t care too much about the latency as long as it’s less than about 30s.

I don’t want to install any software on the clients, and use as much ‘standard’ software on the Pi as possible.

Grabbing video with raspivid

Although there are many recipes for online video streaming, they all use raspivid to get data from the camera and save it in H.2644 format. Raspivid is a fine choice because it knows how to use the VideoCore 45 hardware in the Pi’s GPU to encode the video efficiently.

Getting the video into H.264 bodes well for displaying it on Apple hardware: both iOS and MacOS know how to decode it without any extra software.

In essence this takes the H.264 stream on STDIN and saves it in one second clips to files in $base/segments. It also keeps a playlist for those segments in $base/stream.m3u8. For more details, see the documentation for ffmpeg.10

Note that ffmpeg is clever enough to reuse files for the clips, so we won’t gradually fill the disk.

The biggest problem with this approach is latency. By working in discrete blocks each a second long, we might expect a few seconds of latency, but in practice 10--20s seems common. Perhaps different parameters would improve this.

raspivid -ih

You may recall the -ih option to raspivid which inserts PPS and SPS headers on every I-frame. I don’t understand in detail what this means, but if you don’t specify it you’ll find that clients which connect to the webcam quickly work, whilst laggards won’t.

Debugging this problem can be fun, because it manifests itself as a system which works well in testing, but then fails when you reload the stream a bit later. Given that the window when it works depends on the clip length, it is also easy to think the problem lies there.

ffmpeg versions

At time of writing, December 2013, it’s claimed that Raspbian ship an old version of ffmpeg which doesn’t support segmenting, so you’ll need to compile your own. This takes many hours, and runs out of memory on Pis with only 256MB of RAM (model A and version 1 model B).

raspivid -segment

Although ffmpeg can do all manner of video conversions, it’s clear that here it’s not doing very much. Perhaps raspivid will learn how to segment the video itself.

In fact, it’s well on the way! The most recent commit11 to the software appears to allow just that. As yet though, there’s no support for generating the .m3u8 playlist though. Still, if you’re reading this in 2014 or later, it might be worth checking before you spend ages compiling ffmpeg.