Maison  >  Questions et réponses  >  le corps du texte

Comment diffuser http mjpg sur https en utilisant le proxy php

<p>J'ai ce script php qui est censé charger un flux mjpg via HTTP et le sortir via HTTPS. Cependant, tout ce qu'il produit est une image brisée : </p> <pre class="brush:php;toolbar:false;"><?php fonction 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; border=myboundary"); curl_exec($ch); curl_close($ch); } // Récupère l'URL du flux MJPEG vers le proxy if (isset($_GET['url'])) { $mjpegUrl = $_GET['url']; // Valide que l'URL est une source HTTP valide if (filter_var($mjpegUrl, FILTER_VALIDATE_URL) && strpos($mjpegUrl, 'http://') === 0) { proxyMjpegStream($mjpegUrl); sortie; } } // Paramètre URL MJPEG invalide ou manquant en-tête ("HTTP/1.0 400 Requêtes incorrectes"); echo "URL MJPEG invalide"; ?></pre></p>
P粉835428659P粉835428659435 Il y a quelques jours511

répondre à tous(2)je répondrai

  • P粉588152636

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

    Ce n'est pas vraiment la réponse à la question, Anas en a déjà parlé, mais cela mérite quand même la peine d'être mentionné et n'est pas approprié dans les commentaires.

    Vous aurez du mal à écrire des blocs de code comme celui-ci :

     // 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";
    

    Si vous continuez à reporter les conditions d'erreur jusqu'à la fin et à inclure des conditions de non-erreur dans un bloc if(){}, vous rencontrerez deux problèmes.

    1. Les conditions qui déclenchent les erreurs sont de plus en plus déconnectées de l'endroit où les messages d'erreur sont générés.
    2. Votre code « chemin vers le bonheur » est enfoui de plus en plus profondément dans des if(){} blocs imbriqués, connus sous le nom d'« anti-motif de flèche ».
    Vous pouvez reformater :

    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();

    Ce n'est pas une règle absolue, mais la garder à l'esprit peut aider à éviter d'écrire des blocs de code disjoints ou déroutants, ou des blocs de code qui finissent par s'étendre sur le côté droit de la page.

    répondre
    0
  • P粉523625080

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

    Après quelques recherches, vous pouvez utiliser la fonction suivante pour exécuter un stream en curl :

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

    Et créez la fonction de rappel :

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

    Votre code fonctionne bien mais après 30 secondes votre stream se terminera car vous l'avez défini curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    Ma recommandation pour les URL de streaming est d'utiliser fopen() car cURL est principalement conçu pour faire des requêtes HTTP afin d'obtenir du contenu statique. Les flux MJPEG sont dynamiques et de nouvelles trames sont envoyées en continu.

    Par défaut, cURL définit un délai d'attente pour chaque requête. Si le serveur met beaucoup de temps à envoyer des trames, la requête peut expirer, entraînant une interruption du flux ou un message d'erreur.

    Vous pouvez utiliser la fonction fopen() pour obtenir la meilleure expérience. Voici un exemple utilisant streams et 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);
    }
    ?>

    répondre
    0
  • Annulerrépondre