這并不是問題的真正答案,Anas 已經(jīng)涵蓋了這一點(diǎn),但無論如何還是值得一提,并且不適合在評(píng)論中。
編寫這樣的代碼塊時(shí)會(huì)遇到麻煩:
// 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";
如果您繼續(xù)將錯(cuò)誤條件推遲到最后,并將非錯(cuò)誤條件包含在 if(){}
塊中,則會(huì)遇到兩個(gè)問題。
if(){}
塊中,稱為 箭頭反模式。您可以重新格式化:
if( good ) { if( also good ) { do_thing(); exit(); } else { raise_error('also bad'); } } raise_error('bad');
致:
if( ! good ) { raise_error('bad'); } if( ! also good ) { raise_error('also bad'); } do_thing();
這不是一個(gè)一成不變的規(guī)則,但牢記它可以幫助避免編寫脫節(jié)或混亂的代碼塊,或最終延伸到頁(yè)面右側(cè)的代碼塊。
經(jīng)過一些研究后,您可以使用以下函數(shù)在curl中執(zhí)行流:
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'streamCallback');
并創(chuàng)建回調(diào)函數(shù):
function streamCallback($curl, $data) { // Process the received data echo $data; // Return the length of the data processed return strlen($data); }
您的代碼可以正常工作,但 30 秒后您的流將結(jié)束,因?yàn)槟O(shè)置了 curl_setopt($ch, CURLOPT_TIMEOUT, 30);
我對(duì)流 URL 的建議是使用 fopen()
因?yàn)?cURL 主要是為發(fā)出?? HTTP 請(qǐng)求來獲取靜態(tài)內(nèi)容而設(shè)計(jì)的。 MJPEG 流是動(dòng)態(tài)的并且不斷發(fā)送新幀。
默認(rèn)情況下,cURL 為每個(gè)請(qǐng)求設(shè)置了超時(shí)。如果服務(wù)器發(fā)送幀的時(shí)間較長(zhǎng),請(qǐng)求可能會(huì)超時(shí),從而導(dǎo)致流中斷或錯(cuò)誤消息。
您可以使用fopen()
函數(shù)以獲得最佳體驗(yàn)。
這是使用流和 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); } ?>