Safari では、最初のクリックで Secure media audio が再生されません

(おそらく 2.5.0 安定版へのアップデート以降)Safari では、セキュアメディアのオーディオファイルが最初のクリックでは再生されません。再生アイコンを 2〜3 回クリックしないとオーディオが再生されません。最初のクリックでは、Web サーバーにリクエストが送信されず、3 回目にようやくリクエストが送信されます。

これは Safari のみで発生するためブラウザの問題のようですが、2.5.0 へのアップデートのタイミングで発生し始めたことは少し不審に感じられます。

同様の経験をお持ちの方はいらっしゃいますか?

これが関連しているかどうかはわかりませんが、参考までに:Secure media uploads expire

@martin ここに何かアイデアはありますか?

明日確認します。Safari の問題のようですね。2〜3 回クリックしないと動作しないとのことなので、iPhone で試してみます。

iOS の Safari と Firefox の両方で、この問題がバグとして確認できます。オーディオは、再生/一時停止を複数回行うまで再生されません。ウィジェットコンポーネントは両方とも同じように見えます(モバイル版 Firefox は、モバイル版 Safari のレンダリングエンジンのラッパーであると私は考えています)。これは iOS 13.5.1 で試しました。

WebKit バグトラッカーには最近のオーディオ関連のバグがいくつかありますが、どれが関連するかはわかりません https://bugs.webkit.org/buglist.cgi?bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=product&field0-0-1=component&field0-0-2=alias&field0-0-3=short_desc&field0-0-4=status_whiteboard&field0-0-5=content&no_redirect=1&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id%26query_format=advanced&type0-0-0=substring&type0-0-1=substring&type0-0-2=substring&type0-0-3=substring&type0-0-4=substring&type0-0-5=matches&value0-0-0=audio&value0-0-1=audio&value0-0-2=audio&value0-0-3=audio&value0-0-4=audio&value0-0-5="audio".

この w3schools のオーディオクリップは、iOS Safari と Firefox の両方で動作します W3Schools Tryit Editor preload="none" を使用していることかもしれません。それが私が思いつく唯一の違いです…あるいは、セキュアなメディア URL の 302 リダイレクトが実際のオーディオ URL に行われることが何らかの問題を引き起こしているのでしょうか?

リダイレクトが原因だと考えるきっかけとなったいくつかのヒントは以下の通りです:

最初のクリックではサーバーへのリクエストが発生していないようです。したがって、問題は 302 の前にあるはずです…

@martin この件について何か見つけられましたか?

残念ながら、他のプロジェクトに忙殺されており、まだ着手できていません。ただし、これは私のタスクリストに記載されており、近々より詳しく検討したいと考えています。社内でも同様の問題について簡潔に議論したことがあります。

これまでのところ、これは冒険のようでした。Ubuntu マシン上の Chrome と iPhone 上の iOS Safari 間でリモートデバッグを設定することができましたが、多くの困難がありました。しかし、厄介なことに、最も重要な「Network」タブが空白のままです。

preload="metadata" を設定すると、iOS Safari で最初のクリックでオーディオが再生されることがわかりました。一方、preload="none" に設定すると、実際にオーディオが再生されるまで「再生」→「一時停止」→「再生」のシーケンスが必要になります。

これを video タグでも試してみましたが、同様の問題が存在するようです。

preload="none" への変更は、こちらのバグレポート Secure media uploads expire に基づいて行われました。現在、私たちは少し厄介な「トワイライトゾーン」にいます。preloadmetadata に戻すと、上記の問題が再発してしまうからです。最近、プレサイン済み URL の有効期限を 5 分に延長しました(https://github.com/discourse/discourse/pull/10160)。そのため、元のバグは 以前より 少なくなりましたが、まだ問題です。

私はまだこの件について考え、あれこれ試しています。両方の利点を兼ね備えられるかどうかはわかりません。セキュリティ保護されたメディアの表示に複数のクリックを要求するのは、理想的な体験ではありません。

編集:デバッガーの Network タブが機能するようになりました。内部 Discourse インスタンスにおける preload="none"audio タグの例を示します:

  1. 再生ボタンを押す:GET /secure-media-uploads/dev/original/4X/6/1/8/618a6b19a07de18205cc9889cb604e414b30372b.mp3 → ステータスは Finished

  2. 一時停止ボタンを押す。

  3. 再生ボタンを押す:GET presigned_url_here → ステータスは 206 Partial Content、オーディオが正常に読み込まれる。

奇妙なことに、preload="metadata" の場合でも、再生を 1 回クリックするだけで、全く同じリクエストのシーケンスが発生します。Safari は最初の再生クリックでメタデータを取得し、その後にオーディオを再生するには一時停止と再再生が必要のようです。

これが他のデバイス(例:Android)でも発生するかどうかはわかりません。テストできるデバイスを持っていないためです。

素晴らしいデバッグセッションですね!

一つ質問です:

このレスポンスはどのような形式でしょうか?Finished は HTTP レスポンスコードではないですよね?

ありがとうございます!

いい質問ですね!おっしゃる通り、Finished はステータスコードではありません。ここではネットワークタブから追加の情報は得られません:

サイズは 0B、時間は 0ms です。

この発見をきっかけに、mitmproxy をセットアップして、ここで何が起きているのかを改めて確認することにしました。どうやら、最初の「Finished」リクエストは iOS デバイスや Safari ブラウザから送信されていないようです。mitm プロキシは、PLAY が 2 回目にクリックされるまで、何も検出しないのです。

Safari(iOS とデスクトップの両方。デスクトップでも再現確認済み)では preload="metadata" を、それ以外の環境では preload="none" を使用するのが妥当でしょうか?

(なお、Android ではこの現象は発生していないようです。PWA でテストしました。)

はい、その方向で進める必要があると思います。Android とデスクトップ版 Safari でのテストもありがとうございました。preload 属性は現在機能していないため、ブラウザが Safari であることを検知して preload 属性を切り替えるクライアントサイドのコードが必要になるでしょう。今日はこれについていくつか実験を行います。

私の理解が正しいか確認させてください。このバグは、Safari がオーディオのダウンロードチャンキングポイントを 5 分を超えた位置に設定した際に再発するのでしょうか?

はい、しかしこの新しい修正により、メディアを含む投稿が画面内に表示されたとき(例えばスクロールによって)にのみ preload 属性を変更することで回避できると思います。問題は、セキュアなメディア URL からメタデータを取得すると、プレサインされた URL が生成されプレイヤーで使用されるのですが、その有効期限が5分間しかないことです。そのため、その5分以内に再生ボタンを押さないと、URL が期限切れになってしまいます。

JavaScript を使ってメディアを再生してから一時停止することで、その後に送信される 206 パーシャルコンテンツ要求に影響が出るかどうかを試してみたいと考えています。これらの要求はプレサインされた URL の有効期限に縛られていないように見えるからです。ただし、私の認識が間違っている可能性もありますので、もう少し試してみます。

追記:Android デバイスで Chrome を使用して確認したところ、この問題は存在しないことが分かりました。

@martinwoodward 氏の許可を得て、本日いくつかのコミットを行いました。これにより、すべてのコンテキスト(セキュアなメディアを含む)にあるオーディオ/ビデオ要素で preload="metadata" を使用するよう切り替えられました。これにより、ここで説明されている問題が解決されるはずです。

なお、ユーザーがページに 5 分間以上滞在した場合、セキュアな URL は現在 5 分間のみ有効であるため、オーディオ/ビデオを再生できなくなる可能性が非常に高い点にご注意ください。

お待たせして申し訳ありません。この問題は現在、修正済みです :tada:

@pmusaraj さん、@martin さん、ありがとうございます!