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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With