Search code examples
phphttpmjpeg

How can I render 6 or more mjpeg streams on the same page?


I have a php page that acts as a proxy for a mjpeg stream for some IP cameras

....
header('Content-Type: multipart/x-mixed-replace; boundary=myboundary');
readfile('http://<local_server_ip>:<port>/'.$camId."/mjpg";
ob_end_flush();
....

and a html/javascript page where I display the mjpeg in an img tag, along with camera functions (move left, right, up, down).

Everything works great with less than 6 cameras on the same page; once I add the 6th camera everything else stops working: I can see the 6 camera streams, but I can no longer do anything else on the page - pressing the logout button or pressing the camera move buttons doesn't do anything, Dev Tools shows the actions as pending.

I've read that there is a limit of maximum persistent http connections to a domain (https://stackoverflow.com/a/985704/3668883), and in Chrome (which I am using), the limit is 6.

I cannot remove the php proxy from the equation - this page has to be accessible from the exterior as well, so I cannot put the local ip in the img tag.

Does anyone know a way to do this?


Solution

  • Create subdomains for the camera proxies. These subdomains can all point to the same server.

    Basically, this would be the setup:

        NAME                TYPE   VALUE
    --------------------------------------------------
    camproxy.example.com.   A      127.0.0.1
    cam1.example.com.       CNAME  camproxy.example.com.
    cam2.example.com.       CNAME  camproxy.example.com.
    cam3.example.com.       CNAME  camproxy.example.com.
    cam4.example.com.       CNAME  camproxy.example.com.
    ...
    

    Then, in your control page, either use every subdomain only once or keep a track of how many times you've used one. For example:

    function getCamUrl($file) {
        static $subdomain = 1;
        static $uses = 0;
    
        $uses++;
        if($uses > 6) {
            $uses = 0;
            $subdomain++;
        }
    
        return "cam" . $subdomain . ".example.com/" . $file;
    }
    
    echo '<img src="'. getCamUrl('video1.mjpeg') .'">';
    echo '<img src="'. getCamUrl('video2.mjpeg') .'">';
    echo '<img src="'. getCamUrl('video3.mjpeg') .'">';
    echo '<img src="'. getCamUrl('video4.mjpeg') .'">';
    

    According to the spec, browsers should only use 2 connections. You can get away with setting it to 6, this works in most modern browsers.