test123321: HTTP-Header für MP4 Stream?

Hallo,

ich verwende einen PHP-Server zum durchleiten von MP4-Datein. Die Videos werden korrekt geladen und abgespielt. Auch die Gesamtlänge wird korrekt abgefragt & übertragen. Springe ich nun manuell in eine bestimmte Position des Streams, wird auch der korrekte partielle Teil angefragt, jedoch wird die Wiedergabe an dieser Stelle nicht mehr weiter fortgeführt.

Beispiel: http://bit.ly/1CoXf1F

Ich verwende den folgenden Code für die Anfrage:

<?php

    $file = $_GET['url'];
    $fp = @fopen($file, 'rb');

    $head = array_change_key_case(get_headers($file, TRUE));
    $size = $head['content-length'];

    $length = $size;           // Content length
    $start  = 0;               // Start byte
    $end    = $size - 1;       // End byte
    
    header('Content-type: video/mp4');
    //header("Accept-Ranges: 0-$length");
    header("Accept-Ranges: bytes");
    if (isset($_SERVER['HTTP_RANGE']))
    {
        $c_start = $start;
        $c_end   = $end;
        list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
        
        if (strpos($range, ',') !== false)
        {
            header('HTTP/1.1 416 Requested Range Not Satisfiable');
            header("Content-Range: bytes $start-$end/$size");
            exit;
        }
        
        if ($range == '-')
        {
            $c_start = $size - substr($range, 1);
        }
        else
        {
            $range  = explode('-', $range);
            $c_start = $range[0];
            $c_end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
        }
        
        $c_end = ($c_end > $end) ? $end : $c_end;
        
        if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size)
        {
            header('HTTP/1.1 416 Requested Range Not Satisfiable');
            header("Content-Range: bytes $start-$end/$size");
            exit;
        }
        
        $start  = $c_start;
        $end    = $c_end;
        $length = $end - $start + 1;
        fseek($fp, $start);
        header('HTTP/1.1 206 Partial Content');
    }
    
    header("Content-Range: bytes $start-$end/$size");
    header("Content-Length: ".$length);
    
    $buffer = 1024 * 8;
    
    while(!feof($fp) && ($p = ftell($fp)) <= $end)
    {
        if ($p + $buffer > $end)
        {
            $buffer = $end - $p + 1;
        }
        
        set_time_limit(0);
        echo fread($fp, $buffer);
        flush();
    }
    
    fclose($fp);
    
?>

Kann mir jemand sagen, wo hier noch der Fehler steckt?

  1. Hat sich erledigt, ich lasse es nun automatisch setzen, funktioniert einwandfrei:

    <?php
    
        $url = $_GET['url'];
        ob_start();
        
        if( isset($_SERVER['HTTP_RANGE']) )
        {
            $opts['http']['header']="Range: ".$_SERVER['HTTP_RANGE'];
        }
        
        $opts['http']['method']= "HEAD";
        $conh=stream_context_create($opts);
        $opts['http']['method']= "GET";
        $cong= stream_context_create($opts);
        $out[]= file_get_contents($url,false,$conh);
        $out[]= $http_response_header;
        
        ob_end_clean();
        array_map("header",$http_response_header);
        readfile($url,false,$cong);
        
    ?>
    

    Edit: Link zur Demo ist nicht mehr gültig.

    1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

      Hat sich erledigt, ich lasse es nun automatisch setzen, funktioniert einwandfrei:

      <?php
      
          $url = $_GET['url'];
          ob_start();
          
          if( isset($_SERVER['HTTP_RANGE']) )
          {
              $opts['http']['header']="Range: ".$_SERVER['HTTP_RANGE'];
          }
          
          $opts['http']['method']= "HEAD";
          $conh=stream_context_create($opts);
          $opts['http']['method']= "GET";
          $cong= stream_context_create($opts);
          $out[]= file_get_contents($url,false,$conh);
          $out[]= $http_response_header;
          
          ob_end_clean();
          array_map("header",$http_response_header);
          readfile($url,false,$cong);
          
      ?>
      

      Edit: Link zur Demo ist nicht mehr gültig.

      Ach, was sehe ich da? *gg*

      Hat sich überschnitten

      Spirituelle Grüße
      Euer Robert
      robert.r@online.de

      --
      Möge der wahre Forumsgeist ewig leben!
  2. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

    Hallo,

    ich verwende einen PHP-Server zum durchleiten von MP4-Datein. Die Videos werden korrekt geladen und abgespielt. Auch die Gesamtlänge wird korrekt abgefragt & übertragen. Springe ich nun manuell in eine bestimmte Position des Streams, wird auch der korrekte partielle Teil angefragt, jedoch wird die Wiedergabe an dieser Stelle nicht mehr weiter fortgeführt.

    Beispiel: http://bit.ly/1CoXf1F

    Ist zwar eine Hangelei, bis man am Video angekommen ist, aber auf dem AndroidTab 4.4.2 kann ich vorwärts und rückwärts jumpen, wie es mir gefällt. Es dauert dann ein bisschen, aber das Video startet dann wieder. Oder meintest Du das anders?

    Eins könnte noch helfen: nach dem flush() auch alle Schichten des OB mit echo ob_get_clean() leeren, also while ob_get_level() > 0

    Kann mir jemand sagen, wo hier noch der Fehler steckt?

    Im Konzept von PHP?

    Spirituelle Grüße
    Euer Robert
    robert.r@online.de

    --
    Möge der wahre Forumsgeist ewig leben!