-
Notifications
You must be signed in to change notification settings - Fork 1
Videostream
This page shows all the possible streaming solutions that were tested, as well as issues and statistics concerning these solutions.
name | multiple observer possible | problem |
---|---|---|
vlc | probably | needs extern software -> not in browser and not mobile |
flash | yes | requires flash plugin -> not in mobile and depricated |
jpeg | no | high bandwidth required |
hlc | yes | not working with desktop browsers |
uv4l | yes and no | There is the possibility to add more observers but the problem is the video delay is getting greater with every new observer |
After all research we found out that the uv4l solution fitts best for our purposes. To set it up please find at our wiki the installing and running video stream site.
To start the streaming 'openstream.sh' need to be executed.
Resolution: 640 x 480
Frames per Second: 24
Codec: Mpeg1
Accessible via Port: 8082
Creating a peer-to-peer stream from the pi's camera to a target pc.
The delay of the camera stream was less than 1 second.
But the problem with this solution is that it's only possible to stream at exactly one pc.
sudo apt-get install netcat
raspivid -t 0 -o - | nc 192.168.178.20 5001
sudo apt-get install mplayer netcat
nc -l -p 5001 | mplayer -fps 90 -cache 1024 -
Another idea was to stream the video with vlc using RTSP.
This way didn't work either because there was a minimum delay of about 3 while playing around with different parameters.
raspivid -o - -t 0 -n | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264
We also tried to create an flv or mp4 stream using the ffmpeg library as mplayer does.
But we didn't get it to work properly.
We still trying to figure out how mplayer does the encoding in time.
A video can be captured from the camera to the harddrive with the following command (after having installed ffmpeg successfully)
raspivid -t 0 -w 960 -h 540 -fps 25 -b 500000 -o - | ffmpeg -i - -vcodec copy myVideo.mp4
http://elinux.org/RPi-Cam-Web-Interface#RaspiMJPEG
This project also uses MJPEG, so it transfers pictures insteas of a video stream. It works quite well on the desktop-pc, but on the mobile phone the stream isn't too fluid. Another problem with this one is, that there is no license included in the project folder.
https://www.tmplab.org/wiki/index.php/Streaming_Video_With_RaspberryPi
Needs a server, so no solution for our purpose (Raspberry itself is too slow), also not Html5 compatible
http://videos.cctvcamerapros.com/raspberry-pi/how-to-setup-video-streaming-server.html
http://blog.miguelgrinberg.com/post/video-streaming-with-flask
Gives an image-stream, delay is okay. But as always, no multi-client scenario possible. Very lightweight solution, however might cause problems on mobile devices due to huge amount of data.
https://github.com/mpromonet/h264_v4l2_rtspserver
Streams over RTSP, I can open it in VLC-Player, until now I only tried unicast.
Commands to install (you need to grab cmake first):
sudo modprobe -v bcm2835-v4l2
sudo apt-get install liblivemedia-dev liblog4cpp5-dev
git clone https://github.com/mpromonet/h264_v4l2_rtspserver.git
cd h264_v4l2_rtspserver
cmake .
make install
h264_v4l2_rtspserver -H <height> -W <width> -F <fps>
I chose the following parameters, the 15 frames per second still delivered a smooth image: h264_v4l2_rtspserver -H 480 -W 640 -F 15
After restarting the Pi, you need to execute sudo modprobe -v bcm2835-v4l2
again before starting the server.
Access the stream from VLC-media-player: Open VLC, press Ctrl + N.
Now enter the adress the server printed out on start, should be something like: rtsp://192.168.0.8:8554/unicast
Important: Tick the little checkbox on the bottom to get the advanced options. There put the caching value to 0 ms. This way your delay will be smaller.
To setup the streaming with ffmpeg and crtmpserver you have to follow this manual to step 10. This manual explains how to setup and install ffmpeg and crtmpserver. To view the stream later you have also to install nginx and use the video.js player to show the stream in a html page.
If the setup is done as described in the manual you could start the stream with the shell script which was created at the manual or with the following command:
raspivid -t 0 -w 960 -h 540 -fps 25 -b 500000 -o - | ffmpeg -i - -vcodec copy -an -f flv -metadata streamName=myStream tcp://0.0.0.0:6666
This command starts the video stream and crtmpserver will grap the flash stream which is created by ffmpeg and send it to port 6666 as configured before in crtmpserver config.
It is possible to access the live stream in multiple ways. For instance you could use the vlc player or you could use ffplay from ffmpeg:
ffplay -an "rtmp://<IP-ADDRESS/HOSTNAME OF PI>/flvplayback/myStream live=1"
In the last step you could create a new html page on your running webserver, for example in nginx. Here are the content of the file I created to view the stream:
<!DOCTYPE html>
<head>
<link href="http://vjs.zencdn.net/5.9.2/video-js.css" rel="stylesheet">
</head>
<body>
<video id="my-video" class="video-js" controls preload="auto" width="640" height="264" data-setup="{}">
<source src="rtmp://<IP-ADDRESS/HOSTNAME OF PI>/flvplayback/myStream" type='rtmp/flv'>
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that
<a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
</p>
</video>
<script src="http://vjs.zencdn.net/5.9.2/video.js"></script>
</body>
</html>
If you now open the webpage in your browser you should be able to see the pi's video stream with a delay of about 1.5 seconds.
The big problem with this solution is that we are using an flv flash stream. This method is working for almost all webbrowsers which are supporting flash video. But as you might know flash videos are not playable on mobile devices.
We've tried ffmpeg, vlc, raspivid, nc, uv4l, crtmpserver ... might as well try gstreamer too! Gstreamer provides hardware accelerated video encoding on the Pi (via OpenMAX).
First, install gstreamer-1.0 from the Raspbian repositories. Be sure to install gstreamer 1.0, not 0.10 as the latter version does not provide hardware acceleration.
If you have nginx already installed, you have to remove it before installing it from source code:
sudo apt-get remove nginx nginx-common
sudo apt-get purge nginx nginx-common
sudo apt-get autoremove
Next, we need to install nginx with the rtmp-server add-on. Unfortunately, the packaged version of nginx in the Raspbian repositories does not come with the add-on. So we need to compile it manually. For this step, please refer to the official manuals for nginx-rmtp.
To access the camera as /dev/video0 you also have to run this command:
sudo modprobe bcm2835-v4l2
After make && sudo make install
ing nginx, I used this config file /etc/nginx/nginx.conf
.
Start nginx. It should now be listening for a video transmission from localhost on port 1935. It is possible that port 1935 is already in use for another service at your device. So you have to choose another available port. Be aware that you have to replace the port in the nginx.conf and in the command below. To provide the video stream we can use the following video pipeline:
gst-launch-1.0 v4l2src device=/dev/video0 ! "video/x-raw,format=I420,width=640,height=480,framerate=30/1" ! decodebin ! queue ! videoconvert ! omxh264enc ! "video/x-h264,stream-format=byte-stream,profile=baseline,low-latency=true,control-rate=variable,target-bitrate=5000000" ! h264parse ! flvmux streamable=true name=mux ! rtmpsink location="rtmp://localhost:1935/example/live live=1"
Note the use of the encoder omxh264enc
for hardware acceleration.
I manage to view the stream in VLC by opening rtmp://<raspberrypi-hostname>/example/live
. Unfortunately I experienced a delay of approximately 6 seconds.
If you read the nginx configuration above, you should notice that nginx is set up to provide DASH video. DASH allows live streaming to HTML5 enabled browsers that run a Javascript application.
I set up an example HTML file that utilizes the Dash.js project:
<!DOCTYPE html5>
<script src="http://cdn.dashjs.org/latest/dash.all.min.js"></script>
<style>
video {
width: 640px;
height: 360px;
}
</style>
<body>
<div>
<video data-dashjs-player autoplay src="http://raspberrypi2.local/dash/live.mpd" controls></video>
</div>
</body>
This is where our luck is over. The file /dash/live.mpd
exists and contains stream information (you can investigate it using curl
). However, Dash.js cannot play any video 😢
The gstreamer solution is also working within the video.js player. You could use the html webside from the ffmpeg and crtmpserver solution. The only change you have to make is the video type (rtmp/mp4) and the source url.
This approach has the same problems as streaming via ffmpeg and crtmpserver. It doesn't work on the mobile devices.
After only getting desktop pc's streaming solutions to work we tried another solution which supports mobile devices web browsers.
First you have to build and install ffmpeg from source code like the ffmpeg and crtmpserver solution. If you already installed ffmpeg over the raspbian repository you have to remove it.
cd /usr/src
git clone git://source.ffmpeg.org/ffmpeg.git
cd ffmpeg
./configure
make && make install
The next step is to install the webserver of your choice. We for instance used nginx.
Whit the following command the video stream is started:
raspivid -n -w 720 -h 405 -fps 25 -vf -t 86400000 -b 1800000 -ih -o - | ffmpeg -y -i - -c:v copy -map 0:0 -f ssegment -segment_time 4 -segment_format mpegts -segment_list ./stream.m3u8 -segment_list_size 720 -segment_list_flags live -segment_list_type m3u8 "%08d.ts"
This approach is creating segments of the live stream with a specific time set by the -segment_time tag and a .m3u8 stream file where the segments are listed. Be aware that you have to remove the segments *.ts and the *.m3u8 files after your video stream session.
To view the stream we created a simple html page:
<html>
<head>
<title>PiVid</title>
</head>
<body>
<video controls width="1280" height="720" >
<source src="stream.m3u8" type="application/x-mpegURL" />
</video>
</body>
</html>
This solution was tested with an iPhone and an iPad and was showing the live stream in the browser. The disavantages of this solution are that the video stream has a minimum delay of 6 seconds and doesn't work with Firefox and Google Chrome on Ubuntu.
This approach is streaming with the MJPEG library and is using the raspberry pi's camera driver to access the image information.
First you have to install the camera driver and some other additional packages:
curl http://www.linux-projects.org/listing/uv4l_repo/lrkey.asc | sudo apt-key add -
Add the following line to the file /etc/apt/sources.list
// deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/ wheezy main
sudo apt-get update
sudo apt-get install uv4l uv4l-raspicam
sudo apt-get install uv4l-raspicam-extras
sudo apt-get install uv41-webrtc
After installing the packages you have to configure the uv4l-raspicam settings at /etc/uv4l/uv4l-raspicam.conf
. Please search the following keys and edit them in the file:
server-option = --max-streams=15
encoding = mjpeg
width = 800
height = 600
framerate = 25
If you like to you could also use your customized encoding, width, height and framerate but you have to edit the server-option max streams because the default value is limited to 3 clients.
After you applied your settings you have to restart the uv4l-raspicam service:
sudo service uv4l_raspicam restart
If the setup is done you can access the stream by visiting <IP-Address of your Pi>:8080/stream
. Now youl should see the MJPEG stream in your browser.
For embdding the "video stream" we used the follwing html webpage:
<!DOCTYPE HTML>
<head>
<title>Pi Live Stream</title>
</head>
<body>
<img src="<IP-Address of your Pi>:8080/stream/video.jpeg" style="width: 800px; height: 600px;" />
</body>
This solution is working on desktop pc's as well as on mobile devices. The problem with this solution is that the delay increases with more connected clients.
We tried to make a hybrid solution with the purpose to spilt the desktop browser and the mobile browser traffic. The idea was to use the above described uv4l solution as a poster in the html video tag and show it if the browser couldn't open the rtmp/mp4 stream. To get this solution to work we tried to install v4l2loopback so we could access the camera output multiple times. The problem with the solution was that we were not able to build the v4l2loopback because there were no linux headers for the current raspian jessie available. Therefore we tried to build the current linux headers from source and we also tried to downgrade the kernel version but this also didn't solve our problem.