PHPファイルによって提供されるMP3またはOGGデータを指すHTML5オーディオ要素を埋め込もうとしています。Safariでページを表示すると、コントロールが表示されますが、UIに「ライブブロードキャスト」と表示されます。 。 "再生をクリックすると、オーディオは期待どおりに開始されます。ただし、終了すると、再生をクリックしても再生を再開できません。オーディオ要素でJS APIを使用し、currentTimeを0に設定しても、インデックスエラーで失敗します。例外。
PHPスクリプトのヘッダーが問題であり、特にコンテンツの長さが欠落しているのではないかと思いました。しかし、そうではありません。応答ヘッダーには、オーディオのサイズが有限であることを示す適切なContent-Lengthが含まれています。さらに、Firefox 3.5以降ではすべてが期待どおりに機能します。オーディオ要素の[再生]を複数回クリックして、サウンドの再生を聞くことができます。
方程式からPHPスクリプトを削除し、MP3ファイルの静的コピーを提供すると、Safariではすべてが正常に機能します。
これは、Safariがクエリパラメータを持つオーディオsrc URLを、クエリパラメータを持たないURLとは異なる方法で処理していることを意味しますか?誰かがこれを機能させる運がありますか?
私の簡単なサンプルページは次のとおりです。
<!DOCTYPE html>
<html>
<head></head>
<body>
<audio controls autobuffer>
<source src="say.php?text=this%20is%20a%20test&format=.ogg" />
<source src="say.php?text=this%20is%20a%20test&format=.mp3" />
</audio>
</body>
</html>
PHPスクリプトからのHTTPヘッダー:
HTTP/1.x 200 OK
Date: Sun, 03 Jan 2010 15:39:34 GMT
Server: Apache
X-Powered-By: PHP/5.2.10
Content-Length: 8993
Keep-Alive: timeout=2, max=98
Connection: Keep-Alive
Content-Type: audio/mpeg
直接ファイルアクセスからのHTTPヘッダー:
HTTP/1.x 200 OK
Date: Sun, 03 Jan 2010 20:06:59 GMT
Server: Apache
Last-Modified: Sun, 03 Jan 2010 03:20:02 GMT
Etag: "a404b-c3f-47c3a14937c80"
Accept-Ranges: bytes
Content-Length: 8993
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: audio/mpeg
Accept-Rangesヘッダーもスクリプトにハードコーディングしようとしましたが、うまくいきませんでした。
PHPスクリプトの有無にかかわらず、サーバーから送信されたヘッダーを投稿できますか?PHPスクリプトは、提供するものとは異なるContent-Type
を送信しているのではないかと思います。通常のファイル。
type
要素にsource
属性を指定することもお勧めします。これにより、ブラウザーは両方のクリップをダウンロードして、再生できるかどうかを判断する必要がなくなります。
私はあなたの問題を再現することはできません。 次のテストページ を使用して、Safari4.0.4と現在のWebKitで毎晩問題を再現しようとしました。私は単にmod_rewriteを使用して、PHPの代わりにパラメーターに基づいてさまざまな形式にディスパッチしていますが、何らかの理由でPHPがファイルを変更していない限り、違いはないと思います。
<!DOCTYPE html>
<title>Auido test</title>
<audio controls autobuffer>
<source src="gnossienne-no-1?foo=bar&format=.mp4">
<source src="gnossienne-no-1?foo=bar&format=.ogg">
</audio>
私の例を試してみて、それがうまくいくかどうか教えていただけますか?
編集ああ。もう少し調べてみると、Safariの<audio>
要素がコンテンツのサイズを決定しようとする奇妙な方法が原因であるように見えます。
これは、Apacheから直接提供されるファイルを指す<audio>
要素に遭遇したときのSafariのパケットキャプチャからの抜粋です。ご覧のとおり、最初にメディアの最初の2バイトをフェッチしようとします。これは、おそらくContent-Lengthと、場合によっては他のヘッダーを取得できるようにするためです。次に、すべてをフェッチしようとします。次に、不可解なことに、最初の2バイトを再度フェッチしようとしますが、適切なキャッシュヘッダーを渡して、「304NotModified」応答を取得します。そして最後に、それでも不可解なことに、ファイルの最後の3440バイトをもう一度フェッチします。これらすべてを別々のTCP接続で実行します。これにより、データを数回フェッチするオーバーヘッドに加えて、かなりのオーバーヘッドが追加されます。
GET /stackoverflow/audio-test/say-noid3?foo=bar&format=.mp3 HTTP/1.1 ホスト:ephemera.continuation.org 範囲:bytes = 0-1 接続:閉じる ユーザーエージェント:Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540 承認:*/* Accept-Encoding:identity Cookie:[編集済み] HTTP/1.1206部分コンテンツ 日付:2010年1月5日火曜日02:12 :48 GMT サーバー:Apache 最終変更日:2010年1月5日火曜日02:02:08 GMT ETag: "b2a80ad-11f6-47c6139aaa800" Accept-Ranges:bytes Content-Length:2 Content-Range:bytes 0-1/4598 Connection:close Content-Type:audio/mpeg #2バイトのデータ GET/stackoverflow/audio-test/say-noid3?foo = bar&format = .mp3 HTTP/1.1 ホスト:ephemera.continuation.org 範囲:bytes = 0-4597 接続:close ユーザーエージェント:Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540 承認:*/* 承認-エンコーディング:identi ty Cookie:[編集済み] HTTP/1.1206部分コンテンツ 日付:2010年1月5日火曜日02:12:48 GMT サーバー:Apache 最終変更日:2010年1月5日火曜日02:02:08 GMT ETag: "b2a80ad-11f6-47c6139aaa800" Accept-Ranges:bytes Content-Length:4598 Content-Range:bytes 0-4597/4598 Connection:close Content-Type:audio/mpeg #4598バイトのデータ GET /stackoverflow/audio-test/say-noid3?foo=bar&format=.mp3 HTTP/1.1 ホスト:ephemera.continuation.org 範囲:bytes = 0-1 接続:close ユーザーエージェント:Apple Mac OS X v10.6.2CoreMediav1.0.0。 10C540 Accept:*/* Accept-Encoding:identity Cookie:[編集済み] If-None-Match: "b2a80ad-11f6-47c6139aaa800" If-Modified-Since:Tue、05 Jan 2010 02:02:08 GMT HTTP/1.1 304 Not Modified Date:Tue、05 Jan 2010 02 :12:49 GMT サーバー:Apache 接続:閉じる ETag: "b2 a80ad-11f6-47c6139aaa800 " #no data GET /stackoverflow/audio-test/say-noid3?foo=bar&format=.mp3 HTTP/1.1 ホスト:ephemera.continuation.org 範囲:bytes = 1158-4597 接続:close ユーザーエージェント:Apple = Mac OS X v10.6.2 CoreMedia v1.0.0.10C540 Accept:*/* Accept-Encoding:identity Cookie:[編集済み] HTTP/1.1 206部分コンテンツ 日付:2010年1月5日火曜日02:12:49 GMT サーバー:Apache 最終変更日:2010年1月5日火曜日02 :02:08 GMT ETag: "b2a80ad-11f6-47c6139aaa800" Accept-Ranges:bytes Content-Length:3440 Content-Range:bytes 1158 -4597/4598 接続:close Content-Type:audio/mpeg #3440バイトのデータ
とにかく、PHPスクリプトの出力をどのように処理するかについてです。ここで、Safariは最初の2バイトを再度ダウンロードしようとしますが、スクリプトはRange
要求を無視して戻りますどうやら、WebKitはそれを好まないので、Range
リクエストなしで再試行します。スクリプトは完全なコンテンツを送信します。Safariはもう一度試行し、Icy-Metadata
ヘッダーを追加します。ストリームをダウンロードしていると考え、ストリーミングメタデータを送信したいことを示します。最終的にその出力を受け入れ、<audio>
要素を再生できます。
GET /say.php?text=this%20is%20a%20test&format=.mp3 HTTP/1.1 ホスト:tts.mindtrove.info 範囲:bytes = 0-1 接続:閉じる ユーザーエージェント:Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540 承認:*/* Accept-Encoding:identity HTTP/1.1 200 OK 日付:2010年1月5日火曜日02:14:28 GMT サーバー:Apache X-Powered-By:PHP/5.2.10 Content-Length:4598 Connection:close Content-Type:audio/mpeg #4598バイトのデータ GET /say.php?text=this%20is%20a%20test&format=.mp3 HTTP/1.1 ホスト:tts .mindtrove.info 接続:閉じる ユーザーエージェント:Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540 承認: */* HTTP/1.1 200 OK 日付:2010年1月5日火曜日02:14:28 GMT サーバー:Apache X -Powered-By:PHP/5.2.10 Content-Length:4598 Connection:close Content-Type:audio/mpeg #4598バイトのデータ GET /say.php?text=this%20is%20a%20test&format=.mp3 HTTP/1.1 ホスト:tts.mindtrove.info 承認:* /* User-Agent:Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540 Icy-Metadata:1 接続: close HTTP/1.1 200 OK 日付:2010年1月5日火曜日02:14:28 GMT サーバー:Apache X-Powered -作成者:PHP/5.2.10 Content-Length:4598 Connection:close Content-Type:audio/mpeg #4598データのバイト
要約すると、Safari(より正確には、Safariがすべてのメディアとメディアのダウンロードを処理するために使用するQuickTime)は、メディアをダウンロードするための完全に頭を悩ませたアプローチを持っているようです。データを送り返す方法の何か、おそらくRange
リクエストに応答しないという事実は、ストリーミングメディアを送信していると思わせ、コンテンツを繰り返しダウンロードさせます(たとえ直面した場合でも) Range
リクエストに応答するサーバーでは、実際に必要な数よりも多くのリクエストを実行します)。
私のアドバイスは、Range
リクエストに適切に応答するようにすることです。メディアを提供するとき、ブラウザは、再生できるようにする必要があるだけバッファリングすることによって、帯域幅を最小化しようとする可能性があります(ただし、バッファリングすることを示すautobuffer
属性があります)全体として、ブラウザはそれを無視するかもしれません)。 X-Sendfile
を使用して、Apacheにファイル、キャッシュ、範囲のリクエストの処理を処理させることをお勧めしますが、mod_xsendfile
がインストールされていないDreamhostを使用しているように見えるため、独自のRange
処理。
ちなみに、PochangとChrisはどちらも、Safariでこの問題を修正するにはContent-Rangeヘッダーが必要であることは正しいですが、Chromeには、currentTimeを正しく機能させるために含める必要のある追加のヘッダーが1つ必要です。 :
header( 'Accept-Ranges: bytes');
実際にリクエストのRangeヘッダーに正しく応答する必要はなく、これを応答に含める必要があることに注意してください。
古いトピックですが、2019年もまだ有効です。最終的に解決策が見つかりました...以下PHPスクリプトサンプルでは、Safariの「範囲」ヘッダーリクエストが考慮されます。
$bytes_total = strlen($data);
if (isset($_SERVER['HTTP_RANGE'])) {
$byte_range = explode('-',trim(str_ireplace('bytes=','',$_SERVER['HTTP_RANGE'])));
$byte_from = $byte_range[0];
$byte_to = ($byte_range[1]+1);
$data = substr($data,$byte_from,$byte_to);
header('HTTP/1.1 206 Partial Content');
}
else {
$byte_from = 0;
$byte_to = $bytes_total;
}
$length = strlen($data);
header('Content-type: '.$content_type);
header('Accept-Ranges: bytes');
header('Content-length: ' . $length);
header('Content-Range: bytes '.$byte_from.'-'.$byte_to.'/'.$bytes_total);
header('Content-Transfer-Encoding: binary');
print($data);
ポチャンは正しいです。 PHP応答にContent-Rangeヘッダーを含めると、Safariが適切に動作します。また、ChromeではなくSafariで恐ろしいINDEX_SIZE_ERRなしで(media.currentTime = 0;)をシークできます。
ヘッダーのPHPコードは次のとおりです。
$len = strlen( $data );
$shortlen = $len - 1;
header( 'Content-Range: bytes 0-'.$shortlen.'/'.$len);
同じ問題が発生しました。重要な点はContent-Rangeヘッダーです。 mp3-output phpに追加すると、すべて正常に動作します。