Почему PHP мешает моему видео HTML5 MP4? - PullRequest
4 голосов
/ 11 июля 2010

Я пишу веб-приложение, которое обслуживает видео MP4 в кодировке H.264.В Chrome и Safari он делает это с помощью видео-тега HTML5.

Чтобы контролировать доступ к этим видео, их содержимое обслуживается через PHP с использованием действительно простого механизма:

header('Content-type: video/mp4');
readfile($filename);
exit;

Независимо от того, что я делаю, видео не будет транслироваться.Дополнительно:

  • Если я изменю исходный код для непосредственного обслуживания файлов, используя тот же тег видео, но со ссылкой на копию видео, обслуживаемую Apache, без передачи PHP, потоковая передача работает нормально.
  • Даже когда потоковая передача не работает, я всегда могу щелкнуть правой кнопкой мыши на неактивном проигрывателе HTML5 и загрузить файл через PHP-код - и он отлично воспроизводится в автономном режиме.

Есть идеи?Я выдергиваю волосы!

Ответы [ 3 ]

7 голосов
/ 11 июля 2010

Может быть. Попробуйте добавить также заголовок длины содержимого:

header('Content-length: '.filesize($filename));

Если это по-прежнему не работает, проверьте наличие выходных данных до readfile (echo или пробел до <?php). Проверьте также, что после ?> у вас нет пробелов или просто пропустите ?> (это не обязательно, если у вас ничего нет после).

Как уже упоминал Бруно, для поддержки потоковой передачи вам также необходимо подчиняться заголовку Range. Вот упрощенный пример, который учитывает только левую границу:

if (empty($_SERVER["HTTP_RANGE"])) {
    //do your current stuff...
}
else { //violes rfc2616, which requires ignoring  the header if it's invalid
    preg_match("/^bytes=(\d+)-/i",$_SERVER["HTTP_RANGE"], $matches);
         $offset = (int) $matches[1];
    if ($offset < $filesize && $offset >= 0) {
        if (@fseek($fp, $offset, SEEK_SET) != 0)
            die("err");
        header("HTTP/1.1 206 Partial Content");
        header("Content-Range: bytes $offset-".($filesize - 1)."/$filesize");
    }
    else {
        header("HTTP/1.1 416 Requested Range Not Satisfiable");
        die();
    }
        //fread in loop here
}
0 голосов
/ 11 июля 2010

При потоковой передаче файлов на встроенный видеопроигрыватель HTML5 вам все равно необходимо добавить заголовки, которые информируют проигрывателя с информацией о видео.

Вы не можете просто ожидать выполнения команды чтения readfile(), и все будет работать волшебным образом, извините, приятель, но программирование не так просто. (Хотелось бы, чтобы это было).

Вот небольшое приложение, которое вы можете использовать для правильной трансляции или просто учиться.

http://stream.xmoov.com/download/xmoov-php/

0 голосов
/ 11 июля 2010

См. Комментарии!

Использование потокового файла не рекомендуется для потоковой передачи видеофайлов, поскольку он загружает весь файл в память перед выводом.Это приводит к серьезным проблемам с нехваткой памяти.

Попробуйте прочитать и вывести фрагмент файла по фрагменту.

...