現象
Chrome 66で音声が鳴らなくなった。
原因
原因は、GoogleがChromeに導入したMEIという仕組みにあった。
対策
以下のような対策を行い、何らかのユーザーアクションがあった場合に音が鳴るようにする。
using System.Runtime.InteropServices;
[DllImport("__Internal")]
public static extern void resumeAudioByNextUserAction();
resumeAudioByNextUserAction();
mergeInto(LibraryManager.library, {
resumeAudioByNextUserAction: function() {
var wakeupWebAudio = function() {
if (WEBAudio && WEBAudio.audioContext && WEBAudio.audioContext.state === "suspended") {
WEBAudio.audioContext.resume();
}
document.removeEventListener("click", wakeupWebAudio);
document.removeEventListener("touchend", wakeupWebAudio);
document.removeEventListener("keydown", wakeupWebAudio);
};
document.addEventListener("click", wakeupWebAudio);
document.addEventListener("touchend", wakeupWebAudio);
document.addEventListener("keydown", wakeupWebAudio);
}
});
MEIとは何か
Media Engagement Indexと言う。
これは、サイトを閲覧した際に自動的に音声を流し始めるサイトに対して、独自のレーティングに従って音声をブロックするものだ。
音声を再生するためには、クリック等なんらかのユーザーのアクションが必要になる。
対象となるのは、<audio>
や<video>
、そしてWeb Audio API。
現在のレーティングはchrome://media-engagement
から確認できる。
この値がある閾値を上回ると自動再生されなくなる。
MEIの何が問題になったか
一見すると良いことに聞こえるこの仕組みだが、例え自分が意図して開始したゲームであっても、レーディングに基づいて音声がブロックされてしまう。
更に厄介なのは、ユーザーに依存していてユーザー毎にレーティングの状況が異なるという点だ。
Google曰く「最初から止めるのではなく、止まっていたら再生するように」という事なので、ユーザーによって音声の開始位置がズレることを考慮しなければならない。
そして延期、しかし延期
この実装は説明不足のままChrome 66で実装された。
そしてブラウザ上で動くゲームサービスやオーディオサービス提供者の反感を買った。
これに対してGoogleは、多くの当該サービスで利用されているWeb Audio APIに対してはポリシーをはずす事を発表した。
それはChrome 66の次のバージョンですぐに適用された。
なお、<audio>
や<video>
についてはポリシーを適用したままだ。
また、これは当該サービスの提供者に対策する猶予を与えるためのもので、2018年10月にリリース予定のバージョン70で改めて適用される。