NGINX / RTMP / HLS live stream on Raspberry pi (Debian 8.4)

7,055

Setup: raspivid -> ffmpeg -> rtmp -> hls[ts/m3u8] -> VideoJS

The NGINX RTMP HLS setup is very straight-forward, so I will not go through that. I use hls_fragment size of 250ms and hls_playlist of 3s. Feel free to use my NGINX RTMP HLS server. Just copy and pasted exactly what's in the rtmp section, but change 'stream_name' to something unique. Similarly, change that in VideoJS so you can play it on your webpage. I'm not guaranteeing the 2a application will exist forever, but I plan on it being my test application for a while.

  1. Video Only, A raspivid -n -t 0 -h 480 -w 854 -fps 24 -b 1536000 -o - | ffmpeg -i - -c:v copy -f flv 'rtmp://streaming.sensored.solutions/2a/stream_name' Pros: Easiest, solid quality, no buffering. Cons: ~10s latency
  2. Video Only, B raspivid -n -t 0 -h 480 -w 854 -fps 15 -b 1080000 -o - | ffmpeg -i - -c:v copy -f flv 'rtmp://streaming.sensored.solutions/2a/stream_name' Pros: Low latency, under 5s. Cons: Buffering, Quality
  3. Video and Audio [USB via Sabrent and cheap 3.5mm mic] raspivid -n -t 0 -h 480 -w 854 -fps 25 -b 2000000 -o - | ffmpeg -thread_queue_size 512 -i - -itsoffset 00:00:05.22 -f alsa -ac 1 -i hw:0,0 -map 0:0 -map 1:0 -c:a aac -c:v copy -f flv 'rtmp://streaming.sensored.solutions/2a/stream_name' Pros: Quality, No Buffering, Synchronized audio/video. Cons: High Bitrate [not good for multiple devices using same bandwidth], Latency ~12s - 15s

VideoJS:

    <!--Note, you should including the following in the HEAD of your HTML file: 
    <link href="http://videojs.github.io/videojs-contrib-hls/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
    -->
    <div class="container" id="videojs_container">
        <section class="starter-template">
            <video id=video-js-player width=854 height=480 class="video-js vjs-default-skin" controls autoplay="true" data-setup="{}" preload="auto">
                <source src = "http://streaming.sensored.solutions/2a/stream_name/index.m3u8" type = "application/x-mpegURL">
            </video>
        </section>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="http://videojs.github.io/videojs-contrib-hls/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
    <script src="http://videojs.github.io/videojs-contrib-hls/js/ie10-viewport-bug-workaround.js"></script>
    <link href="//vjs.zencdn.net/5.4/video-js.css" rel="stylesheet">
    <script src="//vjs.zencdn.net/5.4/video.js"></script>
    <script src="http://videojs.github.io/videojs-contrib-hls/node_modules/videojs-contrib-hls/dist/videojs.hls.min.js"></script>
Share:
7,055

Related videos on Youtube

Emmanuel BRUNET
Author by

Emmanuel BRUNET

Team leader and project manager in the past, now back to the roots in IT development

Updated on September 18, 2022

Comments

  • Emmanuel BRUNET
    Emmanuel BRUNET over 1 year

    Debian 8.4 / Raspbian 8.0

    Nginx 1.9.15

    ffmpeg 2.6.8 (server side) / avconv 11.6-6:11.6-1~deb8u1+rpi1 (camera collect) . Avconv is a FFMPEG fork, it does work fine on raspbian.


    Flow schema

    cam-1 : raspberry pi / model B / raspbian 8.0 (Jessie) / avconv

    mercure : debian server 8.4 (Jessie) / nginx / ffmpeg

    cam-1 [rapivid | avconv (ffmpeg)] -> mercure [nginx rtmp / hls]


    I've read a lot of post on the web since 2 weeks about setting a live video streaming server that received video streams from a raspberry pi camera. don't worry about the raspberry streaming source , the problem is not focused on. The goal is to be able to read RTMP and HLS live streams on the remote NGINX server

    the facts :

    It works, I'am able to read the live stream from the RTMP/NGINX server via

    ffplay rtmp://mercure/live/cam-1 (defaults to 1935 port)
    

    note : it doesn't using VLC and a QT5 app embedding QMediaPlayer / QMediaContent widgets. I've found out that VLC introduces issues with librtmp.so on debian and seems to be the same on window 7 (test also fails). source : debian blog. The QT5 issue is perhaps a side effect as QT5 perhaps uses vlc library ? I'm still investigating. The QT5 components can read any disk video file but freeze on the first image when streaming with rtmp

    Nginx hls module is installed.

    Camera (raspberry pi)

    To connect the video stream from the camera and publish it onto the NGINX rtmp server using raspivid and avconv (The FFMPEG fork) packages the command used is :

    pull from the rasp cam (cam-1) :

    /opt/vc/bin/raspivid -hf -vf -fl -pf main -a 8 -mm matrix -w 640 -h 480 -g 250 -t 0 -b 2048000 -o -
    

    push to the RTMP server (mercure)

    avconv -re -i - -nostats -c copy -copyts -an -r 25 -f flv rtmp://mercure:1935/live/cam-1
    

    the complete command embedded into a debian service is then

    /opt/vc/bin/raspivid -hf -vf -fl -pf main -a 8 -mm matrix -w 640 -h 480 -g 250 -t 0 -b 2048000 -o - | avconv -re -i - -nostats -c copy -copyts -an -r 25 -f flv rtmp://mercure:1935/live/cam-1
    

    RTMP / HTTP server side

    All posts seem to state on this type of configuration ( /etc/nginx.conf excerpt ). That works when reading pure rtmp strems via ffplay as mentioned above

    rtmp {
    
            server {
    
                listen 1935;
                chunk_size 4000;
    
                application live {
    
                        live on;
    
                }
    
                application hls {
                        live on;              
                        hls on;
                        hls_path /tmp/hls;
    
                }
             }
    }
    
    http {
    
        server {
    
                server_name     mercure;
    
                location / {
                    root   /var/www;
                    index  index.html;
                }
    
                location /hls{
    
                        types {
                                video/MP2T ts;
                                application/vnd.apple.mpegurl m3u8;
                        }
    
                        root /tmp;
    
                        add_header Cache-Control no-cache;
                        add_header Access-Control-Allow-Origin *;
    
                }
    
        }
    }
    

    I don't really understand how nginx works with hls ... does the incoming stream from avconv (ffmpeg) is dynamically pushed to the /hls rtmp application ? when the camera stream is received, the /tmp/hls folder is created along with a cam-1-0.ts file .. but nothing else ... no m3u8 index ...

    Trying to access hls resource with http://mercure/hls/cam-1 (.m3u8, .m3u ...) and the response is a 404 HTTP error : standard http behavior.

    I've tryed to feed the /hls rtmp application by changing trought the live rtmp configuration section

    application live {
    
      live on;
      exec ffmpeg -i rtmp://mercure/live/cam-1 -c copy -f flv rtmp://mercure/hls/cam-1;
    
    }
    

    I'am absolutely not confident in the nginx ability to manage HLS streams while documentation states on it.

    My question is : does anybody really succeed publishing incoming flv source to HLS stream using a FFMPEG transport and the NGINX / http - rtmp (/hls/dash) server?