audioを自動再生しようとすると発生するエラー
こんな風にaudioタグの音声を自動再生しようとすると・・・。
//html
<audio id="audio" src="..."></audio>
//jsで自動再生
$(function () {
$("#audio")[0].play();
});
chromeだと以下のように怒られます。
play() failed because the user didn't interact with the document first.
safariだとこんな感じ
The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
要するに、「audioの初回再生はユーザのアクションによってしなきゃだめよ」というお話。
自動再生への制約は日に日に厳しくなっている模様です。
というわけで、ユーザの承認を得てaudioを自動再生可能にする方法を紹介します。
対策
概要
clickやtouch等のアクションによってaudioを利用可能にしてあげる必要があります。
流れは以下のような感じになります。
①最初にモーダルで承認ボタンを表示して、ユーザにクリックしてもらう
②以降、任意のタイミングでaudioを再生する。
※以下の端末で音声が再生されることを検証済みです
・mac:chrome・safari
・iphone:chrome・safari
デモ
以下のデモでは、「再生可能にする」ボタンをクリックすると2秒後に音声が流れます。
See the Pen Untitled by masahiro nomura (@masahiroview) on CodePen.
コードのポイント
js
//audioタグを取得
const audio = $("#audio")[0]
$(document).on('click', '#can-play-button', function (e) {
$("#button-wrap").hide();
//audioを読み込み
audio.load()
//3秒後audioを再生
setTimeout(function()
{play(audio)}, 2000
);
});
//audioを再生する関数
function play(audio){
audio.play();
}
一見何の変哲もないコードに見えますが、ポイントは下記。
//audioのロード(すぐに再生するわけではない)
$("#audio")[0].load()
//3秒後に自動再生する(タイマー設定)
setTimeout(function()
{play(audio)}, 2000
);
ボタンクリック時に行なっているのはload()だけで、再生はタイマーによって別途(自動で)行なっています。
つまり「ロードをボタンクリックによって行なってしまえば、後で再生するのは自動でできる(ボタンクリックによらなくてもよい)」のです。
これを使えば、最初にユーザから承認を得ておくことで、以降は任意のタイミングでaudioを再生することが可能です。
上記実装の利用場面
開発時に実際に発生した事例
つい最近実際にあった話なんですが、swiperというプラグインでスライダーを実装し、それとaudioを組み合わせようとしました。
つまり、「ユーザがスライドを切り替えたら、audioを再生」という実装しようとしたのです。
しかし、なぜかスライドを切り替えてもaudioは再生されず・・・。
原因
スマホ実機のブラウザが、swiperのスライド切り替えを「ユーザの動作」と認識しくれなかったのが原因でした・・・。
いや、手動で切り替えるスライドだったので明らかに「ユーザの動作」だと思うんですけど・・・。
スマホのブラウザが「ユーザの動作」の定義をかなり狭くしているのが原因のようです。
解決策
先述のように、「最初にモーダルでユーザに確認して、音声が流れることを承認してもらう。」という方法で乗り切ったのでした。
※swiperについてはこちらの記事をご参照ください。
まとめ
ブラウザの方針として「勝手に自動再生はダメよ」ということなのでそこにはしっかり従う形で対応しましょう。
いろいろ方法は考えられますが、最初にモーダル等でユーザにきちんと確認するのが最適かなと思います。
コメント