audio.duration возвращает бесконечность в Safari, когда mp3 подается из PHP

Итак, у меня есть php-скрипт, который отправляет мой mp3-файл на аудио-тег html5. Проблема в том, что в Safari тег audio.duration не работает и возвращает бесконечность. Если я устанавливаю src аудио прямо в файл, все работает нормально. Но я не хочу, чтобы мои пользователи видели путь к файлу.

В любом случае, так я отправляю свои заголовки из PHP.

Я уже пробовал иметь контент-диапазоны. Это не помогло.

if (file_exists($filename)) {
  $fp = fopen($filename, 'r');
  $etag = md5(serialize(fstat($fp)));
  fclose($fp);
  header("Content-Transfer-Encoding: binary"); 
  header("Content-Type: audio/mpeg");
  header('Content-Length: ' . (string)(filesize($filename)));
  header('Content-Disposition: inline; filename="' . $filename . '"');
  header('X-Pad: avoid browser bug');
  header('Cache-Control: no-cache');
  header('Etag: ' . $etag);

  //GetContentRange($filelength);

  readfile($filename);
  exit;
}
else {
  header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
  echo "no file";
}

3 ответа

Решение

У меня была та же проблема и я добавил пару заголовков. Кажется, работает на меня -

 header("Pragma: public");
 header("Expires: 0"); 
 header("Content-Type: audio/mpeg");
 header('Content-Length: ' . $fsize);
 header('Content-Disposition: inline; filename="' . $track2play . '"');
 header( 'Content-Range: bytes 0-'.$shortlen.'/'.$fsize); 
 header( 'Accept-Ranges: bytes');
 header('X-Pad: avoid browser bug');
 header('Cache-Control: no-cache');
 header('Etag: ' . $etag);

$ fsize - это размер файла, а $shortlen =$filesize-1... протестировано в Safari 5.1.4 и на новом iPad...

Ваш сервер должен разрешить запросы Range. Это легко проверить, посмотрев, включает ли ответ вашего сервера Accept-Ranges в его заголовок. Большинство браузеров HTML5 позволяют искать новые позиции файлов во время загрузки, поэтому сервер должен разрешать запрашивать новый диапазон.

Непринятие байтовых запросов Range вызовет проблемы в некоторых браузерах HTML5. Часто продолжительность не может быть прочитана из файла, поскольку некоторые форматы требуют, чтобы начало и конец файла читались, чтобы узнать его продолжительность. Chrome, как правило, является браузером, который имеет большинство проблем, если запрос Range не включен на сервере, но все браузеры будут иметь некоторую проблему, даже если это только то, что вам придется ждать загрузки всех мультимедийных данных, прежде чем прыгнуть близко к концу,

В этом посте приведен пример PHP для обработки мультимедиа с включенными запросами диапазона.

Кроме того, я заметил, что вы используете No-Cache..

Использование ответа сервера для отключения локального кэша мультимедиа может вызвать проблемы с некоторыми браузерами HTML5. Это может привести к тому, что продолжительность носителя будет неизвестна.

  • Сегодня я потратил большую часть своего времени на изучение этой проблемы и, наконец, нашел решение. Причина, по которой Safari возвращает длительность как бесконечность, довольно интересна: похоже, что Safari дважды запрашивает сервер для воспроизведения файлов. Сначала он отправляет запрос диапазона на сервер с заголовком диапазона, например:(байты:0-1).
  • Если сервер не возвращает ответ в виде частичного содержимого и если он возвращает весь поток, то браузер Safari не установит тег audio.duration, что приведет к воспроизведению файла только один раз, и его невозможно воспроизвести снова.
  • Я быстро это исправил, на стороне сервера просто проверьте заголовок, и если он содержит rangeHeader, верните его.

    String rangeHeader = request.getHeader("Range"); if(rangeHeader != null) { //just return it }

Другие вопросы по тегам