У меня есть очень похожая ситуация человеку, который спросил: я могу служить файлам 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, кажется, думает, что длина файла только пока блок, который этому удалось загрузить. Когда я перезагружаю - это играет немного больший блок - независимо от того, что этому удалось загрузить до той точки.
Это - проблема в заголовках, которые я отправляю? Как я передал бы такой файл потоком? Действительно ли это - проблема, если swf читает из того файла?
Спасибо!
Спасибо парни для всех ответов. Хотя ни одна из этих вещей не была точно, что решило проблему, многие из них отправили меня в правильном направлении. Очень ценивший. Поскольку полное решение видит мой ответ ниже
Вот что помогло.
$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");
}
Выделяются две вещи:
Content-Length
. Если ваш сервер настроен на автоматический gzip вывод, это может все испортить. Попробуйте отключить Content-Length
и посмотрите, исправит ли это ситуацию. Content-Type
. Поскольку вы используете Mp3, просто используйте audio/mpeg
. Вы можете эффективно избавиться от всей последней команды header()
. Легко увлечься HTTP-заголовками. Попробуйте и дайте нам знать, как все прошло!
Вы можете попробовать HTTP chunking. Установите заголовок "Transfer-Encoding" на "chunked", затем выведите размер каждого чанка перед отправкой. Завершайте каждый размер и чанк символом CRLF.
Для чего-то более сложного я рекомендую использовать потоковый сервер, например Icecast.
если ваш сервер работает на apache или lighty, я бы посоветовал вам обратить внимание на x-sendfile
http://tn123.ath.cx/mod_xsendfile/
это позволяет вам обрабатывать аутентификацию в вашем php-приложении, но позволяет вашему веб-серверу обрабатывать передачу файла. улучшение производительности, которое вы получите, должно быть приятным дополнительным преимуществом
.