Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP + cURL for live video streaming (can cURL work with infinite data?)

Good day!
I have video server with different streams and server which clients are communicating with. My goal is to make a script going to specific stream on request, taking a chunk of data and returnig this chunk to client.
My idea is similar with this: to use cURL for authorization, capture some raw data and create callback function echoing data every chunk.

Problem is I've failed to find any mentions of using cURL with "endless data"; when I try it with my script it just goes to forever loading then crash with 504 error from nginx.
I don't understand what the difference for cURL between my data and "30 million characters long", if I use buffersize and flush() as well.
With no more introductions, here is my code:

public function callback($curl, $data)
{
    ob_get_clean();
    if (($data === false) || ($data == null))
    {
        throw new Exception (curl_error($curl) . " " . curl_errno($curl));
    }
    $length = strlen($data);
    header("Content-type: video/mp4");
    header("Transfer-encoding: chunked");
    header("Connection: keep-alive");
    header("Cache-Control: max-age=2592000, public");
    header("Expires: ".gmdate('D, d M Y H:i:s', time()+2592000) . ' GMT');
    header("Last-Modified: ".gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT' );
    echo $data;
    ob_flush();
    flush();
    return $length;
}

public function getStreamChunk($camera_id)
{
    $url = "http://example.com/$camera_id:0:0?format=mp4"; //url of noted video server
    $curl = curl_init();
    curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_HEADER => 0,
            CURLOPT_USERPWD => "$this->login:$this->pass",
            CURLOPT_BUFFERSIZE => (1024*1024),
            CURLOPT_WRITEFUNCTION => array($this, "callback")
        )
    );
    curl_exec($curl);
    curl_close($curl);
}

It workes for pictures (from the same server), there's no echo for cURL errors, so problem in infinite source and, I suspect, in headers. I've checked headers for responce from video server via browser, but can't find any overlooked mistake in my solution. Here's headers from video server:

Response Headers

Connection: keep-alive
Content-Type: video/mp4
Date: Wed, 30 May 2018 07:31:34 GMT
Server: nginx/1.12.2
Transfer-Encoding: chunked

Request Headers

Accept: */*
Accept-Encoding: identity;q=1, *;q=0
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: Basic <...>
Connection: keep-alive
Cookie: <...>
Host: <...>
Range: bytes=0-
Referer: http://example.com/$camera_id:0:0?format=mp4
User-Agent: <...>

Solutions from here I also tried, but
1) I've already explained my problem with "30 million characters" answer C:
2) Solution with HTTP_RANGE isn't working for me as well (I tried) because of same error: long loading and crash.

UPD. I think I missed "Content-Range:" header; in the end you can use it without knowing size, like this: "bytes 1024-2047/*", but can't figure out how to use it properly in my case yet.

like image 625
Alex.Default Avatar asked May 30 '18 07:05

Alex.Default


1 Answers

I've figured out what's the problem. My code is working, there's no need for any other headers, except for cURL option:

CURLOPT_FOLLOWLOCATION => 1 

So yeah, cURL CAN work with infinite data. Here's working solution for video proxing via cURL, if anyone else is interested.

like image 123
Alex.Default Avatar answered Oct 25 '22 20:10

Alex.Default