Потоковое воспроизведение через PHP в формате MP3

У меня ситуация очень похожа на человека, который спросил: Могу ли я обслуживать файлы MP3 с PHP? В основном я пытаюсь защитить mp3-файлы от прямой загрузки, поэтому пользователи должны сначала пройти через php, чтобы пройти аутентификацию. Вот мой код:

header('Content-type: audio/mpeg');
header('Content-length: ' . filesize($file));
header('X-Pad: avoid browser bug');
Header('Cache-Control: no-cache');
header("Content-Transfer-Encoding: binary"); 
header("Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3");
readfile($file);

Вот моя проблема: файл воспроизводит только очень небольшой фрагмент в начале (через Quicktime в браузере), а затем останавливается - Quicktime, похоже, думает, что длина файла равна длине фрагмента, который ему удалось загрузить < / em>. Когда я перезагружаюсь - он проигрывает немного больший кусок - все, что ему удалось загрузить до этого момента.

Это проблема с заголовками, которые я отправляю? Как мне передать такой файл в потоковом режиме? Это проблема, если SWF-файл читает из этого файла?

Спасибо!


Спасибо, ребята, за все ответы. Хотя ни одна из этих вещей не решала проблему, многие из них направили меня в правильном направлении. Очень признателен. Полное решение см. В моем ответе ниже


person Yuval Karmi    schedule 01.03.2010    source источник


Ответы (7)


Вот в чем фокус.

$dir = dirname($_SERVER['DOCUMENT_ROOT'])."/protected_content";
$filename = $_GET['file'];
$file = $dir."/".$filename;

$extension = "mp3";
$mime_type = "audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3";

if(file_exists($file)){
    header('Content-type: {$mime_type}');
    header('Content-length: ' . filesize($file));
    header('Content-Disposition: filename="' . $filename);
    header('X-Pad: avoid browser bug');
    header('Cache-Control: no-cache');
    readfile($file);
}else{
    header("HTTP/1.0 404 Not Found");
}
person Yuval Karmi    schedule 02.03.2010
comment
Возможно, вы захотите выполнить некоторую проверку / очистку в $ _GET ['file'] перед его чтением ... - person Simon; 03.03.2010
comment
Проверяю, существует ли файл _1 _... Вы это имели в виду? - person Yuval Karmi; 03.03.2010
comment
Нет, он не это имел в виду. Подумайте сами, что произойдет, если кто-то попробует это yoursite.com/yourscript.php?file = .. / .. / .. / home / - person Jonny; 17.08.2010
comment
Это здорово, но не ищите !! - person Moh Arjmandi; 14.05.2015
comment
Чтобы сделать его доступным для поиска, просто добавьте следующую строку заголовка, но без поддержки возобновления в этом коде. header('Accept-Ranges: bytes'); Если вам нужна Content-Transfer-Encoding, лучше попробуйте использовать header("Content-Transfer-Encoding: chunked"); - person Ajmal Praveen; 02.07.2018

Вы можете попробовать фрагменты HTTP. Установите заголовок «Transfer-Encoding» на «chunked», затем выведите размер каждого фрагмента перед его отправкой. Завершите каждый размер и каждый фрагмент CRLF.

Для чего-то более сложного я рекомендую использовать сервер потоковой передачи, например Icecast.

person outis    schedule 01.03.2010

Выделяются две вещи:

  1. У вас есть Content-Length набор. Если ваш сервер настроен на автоматическое сжатие ваших выходных данных, это может испортить ситуацию. Попробуйте выключить Content-Length и посмотрите, решит ли это проблему.
  2. У вас есть около тысячи Content-Types набора. Поскольку вы обслуживаете Mp3, просто используйте audio/mpeg. Вы можете полностью избавиться от последней header() команды. Заголовками HTTP легко увлечься.

Попробуйте и дайте нам знать, как это происходит!

person mattbasta    schedule 01.03.2010

если ваш сервер работает на apache или lighty, я бы посоветовал вам заглянуть в x-sendfile

http://tn123.ath.cx/mod_xsendfile/

это позволяет вам обрабатывать аутентификацию в вашем приложении php, но пусть ваш веб-сервер обрабатывает передачу файла. улучшение производительности, которое вы получаете, должно быть приятным дополнительным преимуществом

person roman    schedule 01.03.2010

Удалите header("Content-Transfer-Encoding: binary"); И все будет готово!

person Roozbeh15    schedule 09.03.2012

Для этого решения вам также необходимо настроить xsendfile в apache (mod_xsendfile) или nginx HttpSecureLinkModule - они предоставят вам точный mp3, поэтому браузер будет воспроизводить его правильно

person nvvetal    schedule 06.06.2013

Применение всех этих решений, которые позволяют скрыть исходный путь и имя файла, к сожалению, не предотвращает несанкционированную загрузку. Действительно, клиент (в моем случае: Chrome) загружает файл.

Вот строки, которые я поместил на свой сервер:

<?php
$dir = dirname($_SERVER['DOCUMENT_ROOT'])."/mp3";
$filename = $_GET['file'];
$file = $dir."/".$filename;

$extension = "mp3";
$mime_type = "audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3";

if(file_exists($file)){
    header('Content-type: {$mime_type}');
    header('Content-length: ' . filesize($file));
    header("Content-Transfer-Encoding: binary"); 
    header('Content-Disposition: filename="' . $filename);
    header('X-Pad: avoid browser bug');
    header('Cache-Control: no-cache');
    readfile($file);
}else{
    header("HTTP/1.0 404 Not Found");
}
?>

с линией или без нее

    header("Content-Transfer-Encoding: binary"); 

окончательный результат не меняется. Каталог / mp3 находится в

/home/myuser/

(таким образом, / home / myuser / mp3), а общедоступный каталог HTML -

/home/myuser/public_html

таким образом называя мой домен и давая

/player.php?file=music.mp3

он загружает файл под названием music.mp3 со всем исходным содержимым.

person Tormy Van Cool    schedule 31.03.2015