Video streaming with a Raspberry Pi, Gstreamer and Nginx

I purchased a RPi Camera for Xmas, and I could not wait for testing it with my personal aquarium. Of course, if you browse the web, you'll see I'm not the first one to try it with their aquatic pets. In any case, below I share with you some notes that can be helpful for setting up a low-CPU consuming web-streaming using a domestic Raspberry Pi (with Raspbian in my case).

The resources I mostly followed:

However, instead of compiling all the newer versions of gstreamer (as pointed in the first link), I was lucky enough to find a repository with new enough versions that could be added to /etc/apt/sources.list.

deb . main

Sadly, a very useful and specific gstreamer module, gst-rpicamsrc, seems to be missing from that repository. So, you'll need to build that by yourself. If planning to do more compiling for this or other projects, a distcc introduction can be of your interest —and I think it's worth the effort.

Another requirement is building Nginx and its rmtp module. Nginx is available from default repositories, but not the latter module. More details about the Nginx server configuration can be found in the 4th link (or at the directives documentation of the module).

I must tell that, at the time of writing, I have not explored all the interesting possible options, such as enabling video on demand, storing screenshots, etc.

As reference, this is the (executed from Nginx configuration) I'm currently using:

You can decide to fine-tune the bitrate, framerate, width/height of capture or rotation (depending how you placed your RPi Camera).

Default streaming is in RTMP, which is not very HTTP handy, but thanks again to Nginx, this can be presented as HLS as well. By doing this, it turns to be easier to move your stream throughout any different Nginx reverse proxies and present it to the casual web visitor without having to recur to an external application such as VLC media player.

As a last step, since we're not dealing with out-of-the-box HTML5 video (sic, something to investigate in the future), we must necessarily use a HTML5 video player, such as Video.js (hls module and example) for allowing the visitors to play the stream.

As example, you can see one of my fish tanks surveilled live.

Tip: Fallback streaming

When the aquarium lights go off I also switch off the recording (e.g. by turning off the Raspberry Pi). In case you wanted to show always 'something' to the world, it's possible to define a fallback streaming. As far as you define the streaming behind another Nginx proxy (this must be always on), simply point to a backup server. That backup server can contain some video snapshots and a m3u8 file you previously generated (from /tmp/hls directory in our previous configuration).