Raspberry Pi Live Streaming with USB Webcam

For the past week, I was looking for a live streaming solution to broadcast video from a USB webcam that connects to Raspberry Pi. This post will help you set up a live streaming server on Raspberry Pi step by step.

Installing FFmpeg on Raspberry Pi

My first try was to type in ‘sudo apt-get install ffmpeg‘ on the command line. Then I got the error message: Package ‘ffmpeg’ has no installation candidate.

Fornatutely, we can get the source code of FFmpeg from GitHub and build it ourselves referring to the article – FFMPEG for Raspberry Pi.

Before building FFmpeg, you have to build dependent codec libraries. Assume you want to stream video in Ogg format, you need the video codec libtheora, which depends on libogg-1.3.1 and libvorbis-1.3.3.

Run the following commands to build and install FFmpeg:

wget http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.3.tar.gz
tar -xf libvorbis-1.3.3.tar.gz
cd libvorbis-1.3.3/
./configure --host=arm-unknown-linux-gnueabi --enable-static
make
sudo make install
 
wget http://downloads.xiph.org/releases/ogg/libogg-1.3.1.tar.gz
tar -xf libogg-1.3.1.tar.gz 
cd libogg-1.3.1/
./configure --host=arm-unknown-linux-gnueabi --enable-static
make
sudo make install
 
wget http://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2
tar -xf libtheora-1.1.1.tar.bz2 
cd libtheora-1.1.1/
./configure --host=arm-unknown-linux-gnueabi --enable-static
make
sudo make install
 
git clone git://git.videolan.org/x264
cd x264
./configure --host=arm-unknown-linux-gnueabi --enable-static --disable-opencl
make
sudo make install
 
git clone https://github.com/FFmpeg/FFmpeg.git
cd ffmpeg
sudo ./configure --arch=armel --target-os=linux --enable-gpl --enable-libx264 --enable-nonfree --enable-libtheora --enable-libvorbis
make
sudo make install

Live Streaming with FFServer

Once FFmpeg installed, you can run ffserver. By default, ffserver loads a configuration file /etc/ffserver.conf. On Raspberry Pi, you need to create it manually. Please refer to ffserver sample page. Here is my configuration for Ogg format:

HTTPPort 9090
HTTPBindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 100000
#NoDaemon
 
<Feed feed1.ffm>
        File /tmp/feed1.ffm
        FileMaxSize 200K
        ACL allow 127.0.0.1
</Feed>
 
<Stream test.ogg>
        Format ogg
        Feed feed1.ffm
 
        VideoCodec libtheora
        VideoFrameRate 24
        VideoBitRate 512
        VideoSize 320x240
        VideoQMin 1
        VideoQMax 31
        VideoGopSize 12
        PreRoll 0
        AVOptionVideo flags +global_header
        Noaudio
</Stream>
 
<Stream stat.html>
        Format status
        # Only allow local people to get the status
        ACL allow localhost
        ACL allow 192.168.0.0 192.168.255.255
</Stream>

Run ffserver and send the video stream:

ffserver -f /etc/ffserver.conf & ffmpeg -re -f video4linux2 -i /dev/video0 -vcodec libtheora http://localhost:9090/feed1.ffm

How to stop ffserver? I got the solution from StackOverflow. Find the port and kill the process:

netstat -tulnap
sudo fuser -k 9090/tcp

Use ffplay or vlc to play the stream:

ffplay http://192.168.8.50:9090/test.ogg

Live Streaming with Nginx RTMP Module

Inspired by the post https://docs.peer5.com/guides/setting-up-hls-live-streaming-server-using-nginx/, I have made Nginx work as a live streaming server on Raspberry Pi.

Get the source code of nginx-rtmp-module:

git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git

Install Nginx dependencies:

sudo apt-get install build-essential libpcre3 libpcre3-dev libssl-dev

Install Nginx:

wget http://nginx.org/download/nginx-1.12.1.tar.gz 
tar -xf nginx-1.12.1.tar.gz 
cd nginx-1.12.1
./configure --with-http_ssl_module --add-module=../nginx-rtmp-module
make -j 2
sudo make install

Create a folder hls under /usr/local/nginx/html:

sudo mkdir /usr/local/nginx/html/hls

Edit /usr/local/nginx/conf/nginx.conf:

rtmp {
    server {
        listen 1935; # Listen on standard RTMP port
        chunk_size 4000;
 
        application show {
            live on;
            # Turn on HLS
            hls on;
            hls_path /usr/local/nginx/html/hls/;
            hls_fragment 3;
            hls_playlist_length 60;
            # disable consuming the stream from nginx as rtmp
            deny play all;
        }
    }
}
 
http {
    server {
        listen 8080;
 
        location /hls {
            # Disable cache
            add_header 'Cache-Control' 'no-cache';
 
            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length';
 
            # allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }
 
            types {
                application/dash+xml mpd;
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
 
            root html;
        }
    }
 
}

Start Nginx:

sudo /usr/local/nginx/sbin/nginx

Reload Nginx:

sudo /usr/local/nginx/sbin/nginx -s reload

Send video stream:

ffmpeg -re -f video4linux2 -i /dev/video0 -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://192.168.8.50/show/stream

Send video stream from Windows:

ffmpeg -re -f dshow -rtbufsize 100M -i video="USB2.0 Camera" -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://192.168.8.50/show/stream

Play the stream:

vlc http://192.168.8.50:8080/hls/stream.m3u8
ffplay http://192.168.8.50:8080/hls/stream.m3u8

Raspberry Pi live streaming