P粉5881526362023-09-04 15:45:35
This isn't really the answer to the question, Anas already covered this, but it's worth mentioning anyway and doesn't fit in the comments.
You will have trouble writing code blocks like this:
// Get the URL of the MJPEG stream to proxy
if (isset($_GET['url'])) {
$mjpegUrl = $_GET['url'];
// Validate that the URL is a valid HTTP source
if (filter_var($mjpegUrl, FILTER_VALIDATE_URL) && strpos($mjpegUrl, 'http://') === 0) {
proxyMjpegStream($mjpegUrl);
exit;
}
}
// Invalid or missing MJPEG URL parameter
header("HTTP/1.0 400 Bad Request");
echo "Invalid MJPEG URL";
If you continue to defer error conditions to the end and include non-error conditions in if(){}
blocks, you will run into two problems.
if(){}
blocks, known as the arrow anti-pattern. You can reformat:
if( good ) { if( also good ) { do_thing(); exit(); } else { raise_error('also bad'); } } raise_error('bad');
To:
if( ! good ) { raise_error('bad'); } if( ! also good ) { raise_error('also bad'); } do_thing();
This is not a hard and fast rule, but keeping it in mind can help avoid writing disjointed or confusing blocks of code, or blocks of code that end up extending to the right side of the page.
P粉5236250802023-09-04 09:43:59
After some research, you can use the following function to execute a stream in curl:
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'streamCallback');
And create a callback function:
function streamCallback($curl, $data) { // Process the received data echo $data; // Return the length of the data processed return strlen($data); }
Your code works fine, but after 30 seconds your stream will end because you set curl_setopt($ch, CURLOPT_TIMEOUT, 30);
My recommendation for streaming URLs is to use fopen()
since cURL is primarily designed for making HTTP requests to get static content. MJPEG streams are dynamic and new frames are sent continuously.
By default, cURL sets a timeout for each request. If the server takes a long time to send frames, the request may timeout, resulting in an interruption in the stream or an error message.
You can use the fopen()
function for the best experience.
Here is an example using streams and fopen.
<?php $videoUrl = 'http://74.142.49.38:8000/axis-cgi/mjpg/video.cgi'; // Set the appropriate headers for MJPG header('Content-Type: multipart/x-mixed-replace; boundary=myboundary'); // Continuously fetch and display frames while (true) { // Open a connection to the video stream $stream = fopen($videoUrl, 'rb'); // Check if the stream is valid if (!$stream) { die('Error opening stream'); } // Read and display each frame while ($frame = fread($stream, 4096)) { // Display the frame echo $frame; // Flush the output buffer ob_flush(); flush(); } // Close the stream fclose($stream); } ?>