How to stream http mjpg over https using php proxy
P粉835428659
P粉835428659 2023-09-03 20:54:13
0
2
528
<p>I have this php script which is supposed to load an mjpg stream over HTTP and output over HTTPS. However, all it produces is a broken image: </p> <pre class="brush:php;toolbar:false;"><?php function 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); } // 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"; ?></pre></p>
P粉835428659
P粉835428659

reply all(2)
P粉588152636

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.

  1. The conditions that trigger errors are becoming increasingly disconnected from where error messages are generated.
  2. Your "path to happiness" code is buried deeper and deeper in nested 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粉523625080

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);
}
?>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template