web-dev-qa-db-ja.com

PHPストリーミングMP3

私は尋ねた人と非常によく似た状況にあります: PHPでMP3ファイルを提供できますか? 基本的に私は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がそのファイルから読み取っている場合は問題ですか?

ありがとう!


すべての回答をありがとうございます。これらのことのどれも問題を正確に解決したものではありませんでしたが、それらの多くは私を正しい方向に送りました。大変感謝いたします。完全な解決策については、以下の私の答えを参照してください

12
Yuval Karmi

これがトリックをしたものです。

$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");
}
8
Yuval Karmi

HTTPチャンク を試すことができます。 「Transfer-Encoding」ヘッダーを「chunked」に設定し、各チャンクのサイズを出力してから送信します。各チャンクサイズとチャンクをCRLFで終了します。

もっと複雑な場合は、 Icecast などのストリーミングサーバーを使用することをお勧めします。

1
outis

2つの点が際立っています。

  1. _Content-Length_セットがあります。サーバーが出力を自動的にgzipで圧縮するように設定されている場合、これは問題を引き起こす可能性があります。 _Content-Length_をオフにして、問題が解決するかどうかを確認してください。
  2. 約1000個の_Content-Type_ sセットがあります。提供しているのはMp3なので、_audio/mpeg_を使用してください。最後のheader()コマンド全体を効果的に取り除くことができます。 HTTPヘッダーに夢中になるのは簡単です。

試してみて、どうなるか教えてください!

1
mattbasta

サーバーがApacheまたはlightyで実行されている場合は、x-sendfileを調べることをお勧めします

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

これにより、phpアプリケーションで認証を処理できますが、ファイルの送信はWebサーバーで処理できます。あなたが得るパフォーマンスの改善は素晴らしい追加の利点になるはずです

0
roman

header("Content-Transfer-Encoding: binary");を削除すると、設定が完了します。

0
Roozbeh15

これらのソリューションでは、Apache(mod_xsendfile)またはnginx HttpSecureLinkModuleでxsendfileを構成する必要もあります-正確なmp3が得られるため、ブラウザーは正しく再生します

0
nvvetal

元のパスとファイル名を非表示にするために有効なこれらすべてのソリューションを適用しても、残念ながら不正なダウンロードを防ぐことはできません。実際、クライアント(私の場合: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というファイルをダウンロードします。

0
Tormy Van Cool