Raspberry Pi Camera Live Streaming

I recently bought a Camera Module for the Raspberry Pi. One of the main reasons for getting one was to see if I could set up a live stream from the camera that would be accessible from a web browser or mobile device – partly because it seemed like an interesting project, and partly so I can keep an eye on our dog while I’m away from the house.

It turned out that this was very achievable, but it does require quite a bit of configuration to get things working. I thought I’d document my process here, in the hope that my experiences might help anyone else trying to get a live stream up and running from their Raspberry Pi.

I’m using the following software to enable the live stream:

  • Raspbian
  • FFmpeg
  • libx264
  • nginx with rtmp
  • Safari (OS X or iOS)

Assuming that you have a Raspbian installation up & running, I’ll run through the configuration of the other items below.

libx264

Compiling the libx264 library from source is relatively straightforward. You will need git installed to check out the latest version. Use the following commands to check out, compile & install libx264:

git clone git://git.videolan.org/x264.git
cd x264/
./configure --enable-static --enable-shared
make
make install
ldconfig

FFmpeg

Compiling FFmpeg can take a long time – it took about 5 hours to complete on my Raspberry – and will use a significant amount of memory. While compiling this on a Raspberry Pi Model A (with 256Mb of RAM), the compile eventually failed due to a lack of memory.

To get around this, you can increase the size of the swap file in Raspbian by editing the contents of /etc/dphys-swapfile using vi (or your favourite text editor).

By default, it will look like this:

CONF_SWAPSIZE=100

In my case, increasing the swap size to 1024 solved the problem, but you can increase or decrease this based on your environment. You will need to reboot for this to take effect.

Another change that may help is to decrease the amount of memory the Raspberry allocates to the GPU. By default 128Mb of RAM is allocated to the GPU – for a headless server, this seems a bit excessive.

To change the memory split, start raspi-config from a terminal window:

sudo raspi-config

Then navigate to Advanced Options then Memory Split. Reduce this to 16, hit Ok, then close the tool. You will need to reboot for this to take effect as well.

Once you’ve made these changes, you can check out, compile and install FFmpeg using the following commands:

git clone git://source.ffmpeg.org/ffmpeg.git
cd ffmpeg
./configure --enable-gpl --enable-libx264 --enable-nonfree
make
make install
ldconfig

As mentioned earlier, this will take about 5 hours to complete.

nginx

I’m using the nginx web server to host my live streaming. As with FFmpeg, the version of nginx in the Raspbian repositories does not currently have all of the required features, so it needs to be build from source. I’m also using the nginx-rtmp-module plugin for nginx to enable support for the live stream.

The first step is to check out the current version of both nginx and nginx-rtmp-module, then compile and install them. This can be achieved using the following commands:

git clone https://github.com/nginx/nginx.git /usr/src/nginx
git clone https://github.com/arut/nginx-rtmp-module.git /usr/src/nginx-rtmp-module
cd /usr/src/nginx
./configure --sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_ssl_module \
--without-http_proxy_module \
--add-module=/usr/src/nginx-rtmp-module
make
make install

Once the installation is complete, you’ll need to setup the nginx configuration file. Open /etc/nginx/nginx.conf in a text editor. My nginx.conf file is as follows:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
            root /var/www;
            index  index.html index.htm;
        }

        location /hls {
          types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
          }
          root /var/www;
          index index.html;
          add_header Cache-Control no-cache;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

rtmp {
    server {
        listen 1935;

        chunk_size 4000;

        application hls {
            live on;
            hls on;
            hls_path /var/www/hls;
        }
    }
}

If it doesn’t already exist, create the /var/www and /var/www/hls directories.

sudo mkdir /var/www
sudo mkdir /var/www/hls

Once this has completed, you should be able to start nginx:

sudo /etc/init.d/nginx start

The final step here is to create a HTML file to access the video stream. Create a file, e.g. /var/www/index.html and paste the following;

 <html>
  <body>
    <video controls="controls" width="1280" height="720" autoplay="autoplay" >
      <source src="hls/live.m3u8" type="application/x-mpegURL" />
    </video>
  </body>
</html>

Starting the stream

With nginx running, and your Raspberry Pi Camera attached, start the stream by running the following:

cd /var/www
raspivid -w 1280 -h 720 -fps 25 -t 0 -b 1800000 -o - | ffmpeg -y -f h264 -i - -c:v copy -map 0:0 -f flv -rtmp_buffer 100 -rtmp_live live rtmp://localhost:1935/hls/live

By default, this will start a 720p stream.

You can adjust the width (-w), height (-h), fps (-fps) and bitrate (-b) to suit your network speed. You can also add -vf and/or -hf if you need to rotate the image.

Watching the stream

Using Safari (either on OS X or using an iOS device), navigate to http://your.raspberry.pi.address/index.html

If all has gone to plan, this will show the video feed from your Raspberry Pi Camera! There will be a processing delay of 15-20 seconds. Not sure if this can be improved or not, but I’m open to suggestions!

Advertisements

6 thoughts on “Raspberry Pi Camera Live Streaming”

  1. Hello John! You wrote that the processing delay is 15 to 20 seconds. I assume that this is only when you start streaming. What video latency do you get? I tried with different resolution and FPS settings and the best I could get was about 1 second delay over Cat 6 cable. I wonder if ArchLinux would help…
    – Alex

    1. Hi Alex,
      The video latency on my setup is still 15-20 seconds on average. I’m using a wireless network adapter on the Raspberry, rather than wired, so that may be contributing to it. I’ll experiment over the weekend.
      J

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s