0

HTML5オーディオタグを使用してブラウザからオーディオファイルを提供しようとしています:

<audio preload="auto">
    <source src="<?php echo $song->getUrl('mp3'); ?>" type="audio/mpeg">
    <source src="<?php echo $song->getUrl('ogg'); ?>" type="audio/ogg">
    Please update your browser.
</audio>

トラフィックを節約する必要があるため、部分的なコンテンツを次のように送信することを考えました。

$contentType = ($format == 'mp3') ? 'audio/mpeg' : 'audio/ogg';
$filePath = $song->getPath($format);
$fileLength = filesize($filePath);

$start = 0;
if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])) {
    $http_range = explode('-', substr($_SERVER['HTTP_RANGE'], strlen('bytes=')));
    $start = $http_range[0];
}

$remainingBytes = $fileLength - $start;

$length = min((512*1024), $remainingBytes);
$final = $start + $length;

header('HTTP/1.1 206 Partial Content');
header('Status: 206 Partial Content');
header('Content-Type: ' . $contentType);
header('Content-Disposition: inline;filename="listen.' . $format . '"');
header('Content-length: ' . $length);
header('Content-Transfer-Encoding: bytes');
header('Accept-Ranges: bytes');
header('Cache-Control: no-cache');
header('Content-Range: bytes ' . $start . '-' . $final . '/' . $fileLength);
echo file_get_contents($filePath, false, null, $start, $length);

この結果、Chrome では曲はほぼ完全に再生されます (9.1 MB のファイルの 3.47 秒のうち 3.41 秒)。Firefox では、最初の 39 秒が再生されました (512KB だと思います)。オペラでは、終わることのない「読み込み中」の状態。

4

2 に答える 2

1

RFC2616 に従って206 Partial Content応答は HTTP 範囲要求への応答でのみ有効です。

10.2.7 206 部分的なコンテンツ

サーバーは、リソースに対する部分的な GET 要求を実行しました。要求には、目的の範囲を示す Range ヘッダー フィールド (セクション 14.35) が含まれている必要があり、要求を条件付きにするために If-Range ヘッダー フィールド (セクション 14.27) が含まれている場合があります。

あなたのスクリプトは、部分的なコンテンツに対するものではない可能性が非常に高いリクエストに対して 206 応答を生成しています (または、返されたものとは異なる範囲に対するものである可能性があります)。これは Web ブラウザーを混乱させます。おそらく、ほとんどのブラウザには、残りのコンテンツを取得するために追加のリクエストを行うロジックはありません。このような状況が発生することは決してないからです。

あなたのスクリプトもRangeリクエストを正しく処理していません! 範囲には長さが含まれ、複数の範囲が要求に存在する場合があります。繰り返しますが、詳細については RFC2616 を参照してください

于 2013-05-13T15:35:37.373 に答える