Search code examples
javascriptnode.jsexpressraspberry-pimpeg

Access Live Stream with Raspberry Pi Camera Module on Web Browser using NodeJS?


I am building a time-lapse camera web application using Raspberry Pi and the Raspberry Pi Camera Module. So far I have built a web application (using NodeJS, Express, AngularJS, and BootStrap 3) that can interact with the Raspberry Camera Module using an open source NodeJS module (https://www.npmjs.org/package/raspicam). My web app can set time-lapse settings and take photos by pushing the buttons on the web interface. However, it currently does not have a live stream feature on the web browser where users can watch what the Raspberry Pi Camera module is seeing remotely. I would love to figure out a way to display a live stream of the camera module on the web by simply doing something like this in the html file:

<img src="live-stream-raspberry-pi-camera">

Solution

  • Here's something I came up with for live streaming from a camera. It's crude but it works in all browsers.

    I don't know how you access the Raspberry pi camera but the example below shows how to access a built-in web cam in linux:

    Encode your camera to a updateing image file with ffmpeg:

    ffmpeg -analyzeduration 0 -i /dev/video0 -update 1 -q 1 -r 5 -y /video/feed/1.jpg
    

    Read the image file with php and output contents on change:

    <?php
    session_start();
    session_write_close();
    $imgFile = '/video/feed/1.jpg';
    $img = (file_get_contents($imgFile));
    $lastImgSize = $_SESSION['imageSize'];
    while (true) {
        usleep(20000);
        $img = (file_get_contents($imgFile));
        $imgSize = strlen($img);
        if ($lastImgSize != $imgSize) {
            break;
        }
    } 
    session_start();
    header("Content-type: image/jpg");
    $_SESSION['imageSize'] = $imgSize;
    echo $img;
    exit;
    

    Reload the image with javascript, the php will deliver a new image when available:

    <img id="feed" src>
            <script>
                img = new Image
                function f() {
                    img.src = "img.php?rnd=" + Date.now();
                    img.onload = function() {
                        feed.src = img.src;
                        setTimeout(function() {
                            f();
                        }, 50);
                    };
                    img.onerror = function() {
                        setTimeout(function() {
                            f();
                        }, 50);
                    };
                }
                f();
            </script>
    

    If you're looking for something a bit fancier:

    Take a look at flowplayer which supports live streaming from a rtmp / hls source, both can be encoded with ffmpeg.

    Or fancier still Dashcast a linux / windows streaming service which encodes live streams in the html5 mpeg-DASH format currently supported by ie and chrome, firefox support is on the way