9

Chcę sprawdzić subskrypcję użytkowników przed zezwoleniem im na obejrzenie wideo, z tego powodu używam PHP do interakcji z Stripe, aby sprawdzić subskrypcja autora, a nie wykorzystywane PHP script służyć MP4 do przeglądarkiPHP serve MP4 - Chrome "Tymczasowe nagłówki są wyświetlane/żądanie jeszcze się nie zakończyło" bug

działa on prawidłowo po raz pierwszy film jest odtwarzany w Google Chrome (używając odtwarzacza HTML5) ... Ale kiedy zamknąć wideo i odtwarzać je znowu, wideo nie jest już odtwarzane ... NIE mogę też ponownie załadować bieżącej strony. To tak, jakby serwer przestał działać.

Po sprawdzeniu pierwszego żądania wideo (tego, który został odtworzony), w zakładce Timing widzę: "UWAGA: żądanie nie zostało jeszcze zakończone!" (Zrzut ekranu poniżej)

CAUTION: request is not finished yet!

Kiedy sprawdzać 2nd żądanie wideo (jeden nie grał), w zakładce Nagłówki mówi „[znak ostrzegawczy] nagłówki tymczasowe są pokazane” (zrzut ekranu poniżej)

enter image description here

wszystko działało zgodnie z oczekiwaniami w Safari lub Firefox

Ktoś ma jakiś pomysł co się dzieje? Jedynym sposobem, aby ponownie odtworzyć film, jest zamknięcie bieżącej karty i ponowne wejście do witryny. Ponowne ładowanie nie działa!

+0

Czy pliki są lokalne? Jeśli tak, w jaki sposób udostępniasz swoje pliki? – divaka

+2

To, co wydaje mi się dziwne, to nagłówek 'Range'. W twoim przypadku jest to 'bytes = 0-'. Typowy format nagłówka "Content-Range" to "bajty 0-499/1234", co oznacza pierwsze 500 bajtów pliku o rozmiarze 1234 bajtów. Właśnie dlatego pytam, w jaki sposób udostępniasz swoje pliki, ponieważ musisz wspierać wznawianie pobierania/przesyłania strumieniowego plików. Sprawdź to, aby uzyskać więcej informacji: http://stackoverflow.com/a/4451376/1412896 – divaka

+0

Dokumenty dotyczące zakresu treści: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html – divaka

Odpowiedz

1

Proponuję użyć poniższej funkcji zamiast aktualnego "skryptu strumieniowego". Jeśli podasz parametr $ filename_output, wyświetli on plik jako plik do pobrania, który będzie przesyłany strumieniowo w inny sposób!

Powinien działać w każdej przeglądarce.

serveFile ('/ where/my/vid.mp4');

public function serveFile($filename, $filename_output = false, $mime = 'application/octet-stream') 
{ 
    $buffer_size = 8192; 
    $expiry = 90; //days 
    if(!file_exists($filename)) 
    { 
     throw new Exception('File not found: ' . $filename); 
    } 
    if(!is_readable($filename)) 
    { 
     throw new Exception('File not readable: ' . $filename); 
    } 

    header_remove('Cache-Control'); 
    header_remove('Pragma'); 

    $byte_offset = 0; 
    $filesize_bytes = $filesize_original = filesize($filename); 

    header('Accept-Ranges: bytes', true); 
    header('Content-Type: ' . $mime, true); 

    if($filename_output) 
    { 
     header('Content-Disposition: attachment; filename="' . $filename_output . '"'); 
    } 

    // Content-Range header for byte offsets 
    if (isset($_SERVER['HTTP_RANGE']) && preg_match('%bytes=(\d+)-(\d+)?%i', $_SERVER['HTTP_RANGE'], $match)) 
    { 
     $byte_offset = (int) $match[1];//Offset signifies where we should begin to read the file    
     if (isset($match[2]))//Length is for how long we should read the file according to the browser, and can never go beyond the file size 
     { 
      $filesize_bytes = min((int) $match[2], $filesize_bytes - $byte_offset); 
     } 
     header("HTTP/1.1 206 Partial content"); 
     header(sprintf('Content-Range: bytes %d-%d/%d', $byte_offset, $filesize_bytes - 1, $filesize_original)); ### Decrease by 1 on byte-length since this definition is zero-based index of bytes being sent 
    } 

    $byte_range = $filesize_bytes - $byte_offset; 

    header('Content-Length: ' . $byte_range); 
    header('Expires: ' . date('D, d M Y H:i:s', time() + 60 * 60 * 24 * $expiry) . ' GMT'); 

    $buffer = ''; 
    $bytes_remaining = $byte_range; 

    $handle = fopen($filename, 'r'); 
    if(!$handle) 
    { 
     throw new Exception("Could not get handle for file: " . $filename); 
    } 
    if (fseek($handle, $byte_offset, SEEK_SET) == -1) 
    { 
     throw new Exception("Could not seek to byte offset %d", $byte_offset); 
    } 

    while ($bytes_remaining > 0) 
    { 
     $chunksize_requested = min($buffer_size, $bytes_remaining); 
     $buffer = fread($handle, $chunksize_requested); 
     $chunksize_real = strlen($buffer); 
     if ($chunksize_real == 0) 
     { 
      break; 
     } 
     $bytes_remaining -= $chunksize_real; 
     echo $buffer; 
     flush(); 
    } 
} 
1

Cóż, z pewnością jest to intrygujący problem. I naprawdę trudno jest ustalić przyczynę źródłową tutaj. Ale gdybym był w twoim przypadku, sprawdziłbym dwie rzeczy.

  1. Najpierw chciałbym się upewnić, że keep-alive jest wyłączony KeepAlive Off na httpd.conf

  2. Następnie przetestować go z tej konfiguracji.

  3. Wtedy mogę wyłączyć wszystkie buforowanie przeglądarki:

    nagłówek ('Cache-Control: no-cache, no-store, must-revalidate'); nagłówek ("Pragma: no-cache"); nagłówek ("Wygasa: 0");

  4. Ostateczny test po tym.

Problem wydaje się być albo z podtrzymywaniem pamięci lub buforowaniem przeglądarki, albo nawet z obydwoma, ale nie rozumiem, dlaczego pojawia się tylko w chrome. W ostateczności upewnij się, że nie używasz żadnych rozszerzeń, które mogą powodować problemy, takie jak Adblock.

nadzieję, że Ci chodzi z tymi informacjami :)

0

miałem ten sam problem, gdy próbuje strumieniowo pliki audio. Skończyło się na tym, że rozwiązałem swój problem przez zwykły zbieg okoliczności.

W pewnym momencie utworzyłem skrypt, który zmniejszyłby bitrate plików do 128 kb/s przy użyciu FFMPEG (działa również w przypadku klipów wideo, o ile wiem). Po tym, gdy sprawdzałem w chromie, zacząłem zauważać, że wszystkie moje prośby kończyły się po kilku sekundach, w przeciwieństwie do pozostawania niekompletnymi w nieskończoność, jak poprzednio. Nie jestem pewien, czy to opłacalne, ale skompresowane pliki rozwiązały ten problem, a także zwiększały prędkość przesyłania strumieniowego, więc bardzo polecam.