Heim  >  Fragen und Antworten  >  Hauptteil

So streamen Sie http mjpg über https mithilfe eines PHP-Proxys

<p>Ich habe dieses PHP-Skript, das einen MJPG-Stream über HTTP laden und über HTTPS ausgeben soll. Es entsteht jedoch lediglich ein kaputtes Bild: </p> <pre class="brush:php;toolbar:false;"><?php Funktion ProxyMjpegStream($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_BUFFERSIZE, 8192); header("Content-Type: multipart/x-mixed-replace;boundary=myboundary"); curl_exec($ch); curl_close($ch); } // Holen Sie sich die URL des MJPEG-Streams zum Proxy if (isset($_GET['url'])) { $mjpegUrl = $_GET['url']; // Überprüfen Sie, ob die URL eine gültige HTTP-Quelle ist if (filter_var($mjpegUrl, FILTER_VALIDATE_URL) && strpos($mjpegUrl, 'http://') === 0) { ProxyMjpegStream($mjpegUrl); Ausfahrt; } } // Ungültiger oder fehlender MJPEG-URL-Parameter header("HTTP/1.0 400 Bad Request"); echo „Ungültige MJPEG-URL“; ?></pre></p>
P粉835428659P粉835428659435 Tage vor510

Antworte allen(2)Ich werde antworten

  • P粉588152636

    P粉5881526362023-09-04 15:45:35

    这并不是问题的真正答案,Anas 已经涵盖了这一点,但无论如何还是值得一提,并且不适合在评论中。

    编写这样的代码块时会遇到麻烦:

     // 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(){} 块中,则会遇到两个问题。

    1. 触发错误的条件与生成错误消息的位置越来越脱节。
    2. 您的“幸福之路”代码越来越深地埋藏在嵌套 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();

    这不是一个一成不变的规则,但牢记它可以帮助避免编写脱节或混乱的代码块,或最终延伸到页面右侧的代码块。

    Antwort
    0
  • P粉523625080

    P粉5236250802023-09-04 09:43:59

    经过一些研究后,您可以使用以下函数在curl中执行流:

    curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'streamCallback');

    并创建回调函数:

    function streamCallback($curl, $data) {
        // Process the received data
        echo $data;
    
        // Return the length of the data processed
        return strlen($data);
    }

    您的代码可以正常工作,但 30 秒后您的流将结束,因为您设置了 curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    我对流 URL 的建议是使用 fopen() 因为 cURL 主要是为发出​​ HTTP 请求来获取静态内容而设计的。 MJPEG 流是动态的并且不断发送新帧。

    默认情况下,cURL 为每个请求设置了超时。如果服务器发送帧的时间较长,请求可能会超时,从而导致流中断或错误消息。

    您可以使用fopen()函数以获得最佳体验。 这是使用流和 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);
    }
    ?>

    Antwort
    0
  • StornierenAntwort