Live Video Streaming with Raspberry Pi camera module
Installing required software
Raspberry Pi side
Gstreamer is a great way to pass video stream over the network to a streaming media server.
Prerequisites
Raspbian packages
- gstreamer1.0-tools
- gstreamer1.0-plugins-bad?
- gstreamer1.0-plugins-base
- gstreamer1.0-plugins-good?
- libgstreamer1.0-dev
- libgstreamer-plugins-base1.0-dev
- python3-pip
Python packages
- meson
- ninja
Install the necessary packages
root@localhost
~ #
apt install gstreamer1.0-tools gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-good python3-pip
root@localhost
~ #
pip3 install ninja
GStreamer element for the Raspberry Pi camera module
To be able to use the Raspberry PI camera module, download and compile the GStreamer element for the Raspberry Pi camera module (optional).
user@localhost
~ $
mkdir -p /usr/local/src
user@localhost
~ $
cd /usr/local/src
user@localhost
/usr/local/src $
git clone https://github.com/thaytan/gst-rpicamsrc.git
user@localhost
/usr/local/src $
cd gst-rpicamsrc
user@localhost
/usr/local/src/gst-rpicamsrc $
make
Install the GStreamer element for the Raspberry Pi camera module
root@localhost
/usr/local/src/gst-rpicamsrc #
make install
OpenMAX IL GStreamer wrapper
For hardware accelerated video encoding, download and compile the OpenMAX IL GStreamer wrapper (optional)
user@localhost
~ $
mkdir -p /usr/local/src
user@localhost
~ $
cd /usr/local/src
user@localhost
/usr/local/src $
git clone https://gitlab.freedesktop.org/gstreamer/gst-omx.git
user@localhost
/usr/local/src $
cd gst-omx
user@localhost
/usr/local/src $
git checkout 1.14.4
user@localhost
/usr/local/src/gst-omx $
meson builddir -Dwith-omx-target=rpi
user@localhost
/usr/local/src/gst-omx $
make
user@localhost
/usr/local/src/gst-omx $
./autogen.sh --prefix=/usr --sysconfdir=/etc --with-omx-header-path=/opt/vc/include/IL --with-omx-target=rpi
user@localhost
/usr/local/src/gst-omx $
make
Install the OpenMAX IL GStreamer wrapper
root@localhost
~ #
make install
NGINX (optional)
To install NGINX the rtmp
use flag needs to be unmasked
root@localhost
~ #
mkdir -p /etc/portage/profile
root@localhost
~ #
echo -rtmp >> /etc/portage/profile
root@localhost
~ #
echo www-servers/nginx rtmp >> /etc/portage/package.use
root@localhost
~ #
emerge -av nginx
Set up rtmp live streaming with NGINX
rtmp {
server {
listen 1935;
application live {
live on;
}
}
}
Streaming server side (optional)
A more serious streaming media server can be used for streaming the video. The following is the most simple example of using Red5 Media Server, which is a free and open source media server, but Wowza, or the Adobe Media Server can be used as well, possibly others.
- Download the latest stable (or whatever) version (direct link to Red5 1.0.6 Release for Linux and Windows)
- extract the archive
- start the server with default settings using the red5.sh (on Linux) or red5.bat (on Windows) startup script.
Web server side
A flash video player needs to be installed on the web server. Here's a simple example for Adobe's Flash Builder. Replace red5.yourdomain.com with the actual address of the media server.
<?xml version="1.0" encoding="utf-8"?>
<s:Application width="960" height="540" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:VideoDisplay width="100%" height="100%">
<s:source>
<s:DynamicStreamingVideoSource host="rtmp://red5.yourdomain.com/live/livestream"streamType="live">
<s:DynamicStreamingVideoItem streamName="livestream"/>
</s:DynamicStreamingVideoSource>
</s:source>
</s:VideoDisplay>
</s:Application>
Build and export the application, and copy it somewhere on the web server.
Setting up the Raspberry Pi camera module
Boot settings
To be able to use the Raspberry Pi camera module the updated GPU firmware needs to be used and the GPU memory needs to be set to a minimum of 128MB by adding the following lines to the /boot/config.txt
start_file=start_x.elf
fixup_file=fixup_x.dat
gpu_mem=128
User access
To make sure, non-root users can access the camera, create a file named /etc/udev/rules.d/10-vchiq-permissions.rules with the following content
root@localhost
~ #
mkdir -p /etc/udev/rules.d
root@localhost
~ #
echo "SUBSYSTEM==\"vchiq\",GROUP=\"video\",MODE=\"0660\"" > /etc/udev/rules.d/10-vchiq-permissions.rules
This will grant rw access to the video group on the camera device.
The desired user needs to be added to the video group (user is the name of the user, and group1,group2 can be a comma separated list of any additional groups)
root@localhost
~ #
usermod -G group1,group2,video user
These changes require a reboot to take effect.
Test the camera
Enter the following command to check if the camera works. It should display a live feed for 5 seconds.
user@localhost
~ $
/opt/vc/bin/raspivid -d
Start the camera
Start feeding the stream to the media server with issuing the following command on the Raspberry PI
Raspberry Pi camera module
user@localhost
~ $
gst-launch-1.0 rpicamsrc bitrate=2097152 preview=false rotation=180 sensor-mode=5 ! video/x-h264,width=1280,height=720,framerate=25/1,profile=high ! h264parse ! flvmux ! rtmpsink location=rtmp://red5.yourdomain.com/live/livestream
Raspberry Pi camera module with PiP and stats
Similar to the previous but the preview is displayed Picture-in-Picture style. Also the date, time and frame number is displayed.
user@localhost
~ $
gst-launch-1.0 rpicamsrc bitrate=2097152 preview-opacity=127 preview-x=0 preview-y=0 preview-w=480 preview-h=270 fullscreen=false rotation=180 sensor-mode=5 annotation-mode=0x020c ! video/x-h264,width=1280,height=720,framerate=25/1,profile=high ! h264parse ! flvmux ! rtmpsink location=rtmp://red5.yourdomain.com/live/livestream
Raspivid with pipe
In case you don't have gst-rpicamsrc
user@localhost
~ $
raspivid -t 0 -b 2097152 -rot 180 -n -o - | gst-launch-1.0 fdsrc ! video/x-h264,width=1280,height=720,framerate=25/1,profile=high ! h264parse ! flvmux ! rtmpsink location=rtmp://red5.yourdomain.com/live/livestream
Raspivid with pipe with PiP
user@localhost
~ $
raspivid -t 0 -b 2097152 -rot 180 -w 1280 -h 720 -p '0,0,480,270' -op 127 -o - | gst-launch-1.0 fdsrc ! video/x-h264,width=1280,height=720,framerate=25/1,profile=high ! h264parse ! flvmux ! rtmpsink location=rtmp://red5.yourdomain.com/live/livestream
V4L Camera
In case you're using an USB camera
user@localhost
~ $
gst-launch-1.0 v4l2src ! video/x-raw,width=1280,height=720,framerate=25/1 ! omxh264enc target-bitrate=2097152 control-rate=variable ! video/x-h264,width=1280,height=720,framerate=25/1,profile=high ! h264parse ! flvmux ! rtmpsink location=rtmp://red5.yourdomain.com/live/livestream
Explanation
- Raspivid
-t 0
arguments tells raspivid not to stop the video after 5 seconds-b 2097152
sets the bitrate of the video to 2Mbps-rot 180
rotates the image 180 degree (my camera is upside down...don't ask) clockwise (or counter-clockwise, it doesn't matter)-w
sets the video width-h
sets the video height-n
turns off the preview-p
turns on the preview, optionally <'x,y,w,h'> sets the the preview position and size-op
opacity (0-255)-o -
sends the encoded output to STDOUT (or in this case directly to Gstreamer through a pipe)
- Gstreamer
rpicamsrc
reads from the Raspberry Pi camera module (requires gst-rpicamsrc)bitrate=2097152
sets the birtate to 2Mbpspreview=false
disables the preview (obviously you either need this one or the following four - using all five doesn't make sense)preview-opacity=127
sets the preview 50% opaquepreview-x=0 preview-y=0
sets the preview position to the top left cornerpreview-w=480 preview-h=270
sets the preview size 480*270fullscreen=false
disables full screen previewrotation=180
rotates the image 180 degree (my camera is upside down...don't ask) clockwise (or counter-clockwise, it doesn't matter)sensor-mode=5
sets the sensor to the following mode: 1296x730 16:9 1-49fpsannotation-mode=0x020c
adds date, time, and frame counter
fdsrc
reads from STDIN (or in this case from raspivid through the pipe)v4l2src
reads from the a v4l2src sourcevideo/x-raw,width=1280,height=720,framerate=25/1
sets the dimensions and the frame rate of the raw video (1280*720@25)omxh264enc target-bitrate=2097152 control-rate=variable
encodes the video with a target bitrate of 2Mbps using the hardware encoder (requires gst-omx)video/x-h264,width=1280,height=720,framerate=25/1,profile=high
sets the dimensions, the frame rate and the profile of the H.264 video (1280*720@25 - high)h264parse
parses the H.264 streamflvmux
muxes the video stream into an FLV streamrtmpsink
sends FLV content to a server defined by thelocation
via RTMP. Remember to replace red5.yourdomain.com with the actual address of the media server. The/live
path tells the server that it's a live stream, and/livestream
is the name of the stream. These can change when using different media servers and usually broadcasting more than one stream is allowed.