Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Odtwarzanie pliku .flv & parsowanie nagłówka HTTP_RANGE
Forum PHP.pl > Forum > PHP
Michael2318
Pobieram z zewnętrznej strony plik .flv - pobieram go poprzez fopen, fread, potem w pętli while go echuję i używam ob_flusha żeby nie dostać potem fatal_error: Allowed memory size of XXX bytes exhausted (...).
Taki skrypt zapisuję jako video.php i w HTMLu przy użyciu videoJS (http://videojs.com) lub przy użyciu flowplayer'a odtwarzam taki film. Problem jest jednak taki, że nie mogę zmienić czasu odtwarzania filmu, czyli jesli odtwarza się taki film i jest na 2 minucie to nie mogę przesunąć ssuwaka na 1:12:04 przykładowo bo film nie pobrał się jeszcze do takiego czasu. I tutaj potrzebne jest poprawne parsowanie nagłówka HTTP_RANGE.

U mnie skrypt wygląda tak:

  1. $url = 'http://page.com/file.flv';
  2. $length = get_headers($url);
  3. preg_match('!\d+!', $length[8], $matches);
  4. $file_size = $matches[0];
  5.  
  6. $info = pathinfo($url);
  7. $ext = $info['extension'];
  8. $mime_type = generateUpToDateMimeArray($ext);
  9.  
  10. if ( !$mime_type )
  11. {
  12. die('error');
  13. }
  14.  
  15. header("Pragma: public");
  16. header("Expires: -1");
  17. header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
  18. header ("Content-Disposition: attachment; filename=file.".$ext);
  19. header('Content-Type: '.$mime_type);
  20.  
  21. if(isset($_SERVER['HTTP_RANGE']))
  22. {
  23. list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2);
  24.  
  25. if ($size_unit == 'bytes')
  26. {
  27. list($range, $extra_ranges) = explode(',', $range_orig, 2);
  28. }
  29. else
  30. {
  31. $range = '';
  32. header('HTTP/1.1 416 Requested Range Not Satisfiable');
  33. }
  34. }
  35. else
  36. {
  37. $range = '';
  38. }
  39.  
  40. list($seek_start, $seek_end) = explode('-', $range, 2);
  41. $seek_end = (empty($seek_end)) ? ($file_size - 1) : min(abs(intval($seek_end)),($file_size - 1));
  42. $seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);
  43.  
  44. if ($seek_start > 0 || $seek_end < ($file_size - 1))
  45. {
  46. header('HTTP/1.1 206 Partial Content');
  47. header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$file_size);
  48. header('Content-Length: '.($seek_end - $seek_start + 1));
  49. }
  50. else
  51. {
  52. header("Content-Length: $file_size");
  53. }
  54. header('Accept-Ranges: bytes');
  55.  
  56. $fd = fopen($url, "r");
  57. fseek($fd, $seek_start);
  58. while(!feof($fd))
  59. {
  60. echo fread($fd, 4096);
  61.  
  62. if (connection_status()!=0)
  63. {
  64. fclose($fd);
  65. }
  66. }
  67.  
  68. fclose($fd);


Jednak ani flowplayer ani VideoJS nie potrafią sobie poradzić z tym kodem i tak, videoJS zwraca FLASH: srcnotfound, a flowplayer w ogóle nie rusza z miejsca, tak jakby w ogóle nie miał co odtwarzać.
Jeśli jednak wyrzucę te dane dot. nagłówka RANGE:

  1. $url = 'http://page.com/file.flv';
  2. $length = get_headers($url);
  3. preg_match('!\d+!', $length[8], $matches);
  4. $length = $matches[0];
  5.  
  6. $info = pathinfo($url);
  7. $ext = $info['extension'];
  8. $mime_type = generateUpToDateMimeArray($ext);
  9.  
  10. if ( !$mime_type )
  11. {
  12. die('error');
  13. }
  14.  
  15. header('Accept-Ranges: bytes');
  16. header('Content-Type: '.$mime_type);
  17. header('Connection: keep-alive');
  18. header('Content-Transfer-Encoding: binary');
  19. header ("Content-Disposition: attachment; filename=file.".$ext);
  20.  
  21. $fd = fopen($url, "r");
  22. while(!feof($fd))
  23. {
  24. echo fread($fd, 4096);
  25. }


wszystko działa poza tym, że nie mogę ruszyć z tym ssuwakiem...

Kod HTML wygląda tak:

  1. <video id="video1" class="video-js vjs-default-skin" poster="http://video-js.zencoder.com/oceans-clip.png" width="640" height="480"
  2. data-setup='{"loadingSpinner": false, "controls" : true, "autoplay" : false, "preload" : "auto"}'>
  3. <source src="http://mypage.pl/videos/video.php" type="video/x-flv">
  4. </video>


Ma ktoś jakiś pomysł?
Pisałem już na stackoverflow.com, na jakichś ogólnoeuropejskich forach programistycznych, na wielu polskich i nikt mi nigdzie nie udzielił żadnej odpowiedzi, więc nie zdziwię się jak tutaj będzie podobnie, ale... może jednak.

Dzięki.
Pyton_000
Podstawowe pytanie, dlaczego nie zapiszesz tego normalnie jako flv i odpalisz z HTML?
Michael2318
Pliki pochodzą z zewnątrz i ważą po kilka GB. Gdybym chciał to zapisać u siebie na dysku to zapisałbym max. dwa takie pliki i już nie ma miejsca na dysku. Po drugie to który plik miałby zostać zapisany zależy od odwiedzającego stronę, więc jeśli wybrałby już któryś z plików na zewnętrznym serwerze, musiałby sobie poczekać dosyć sporo czasu aż skrypt pobrałby plik na mój serwer i dopiero wtedy byłaby możliwość odpalenia go.
Taka opcja w ogóle nie wchodzi w grę.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.