世にも奇妙な Safari の audio 要素の挙動
audio 要素というか HTMLAudioElement
ってありますけど、あれの play 関数の挙動が Safari だとえらい奇妙だったって話です。ちなみに macOS, iOS どちらの Safari も同じでした。
2回目以降の play の再生開始が遅延する
Safari で次の codepen の Play を押して再生すると「さん、に、いち、はい」と聞こえます。再生が終わってもう一度 Play を押すと「ぁん、に、いち、はい」と、最初の s が聞こえません。new AudioContext() ボタンを押すと、この問題が起こらなくなります。
See the Pen Safari HTMLAudioElement.play delay bug by rch850 (@rch850) on CodePen.
codepen にも書いてますが、StackOverflow の HTML5 Audio tag on Safari has a delay のコメントにこのソリューションが書いてありました。なぜ直るかはわからないそうですが、とにかく直ります。
ちなみに、AudioContext をいくつも new してるとエラーになった記憶があるし、そういったことを言っている2015年の記事もあって、無尽蔵に new するのはいけないと思っていたのですが、今は100個作ってもエラーにならないようです。とはいえ不必要に何個も作るのは避けたほうがいいでしょう。
多分 python -m http.server で立てたサーバが返した mp3 だと2回目以降再生されない
遅延どころか再生できないのかよって話なんですが、できないんです。じゃぁ最初の遅延に気づいたのはなぜかっていうと、そっちは npm run serve
的なもので見てたからです。
最初は localhost 限定の現象かと思ったのですが、ngrok を通してちゃんとしたドメインかつ https にしても変わらなかったので、これは python の http.server のせいだな、と勘付きました。
audio 要素の src に指定する URL を外部の URL にすれば鳴るので、src に指定するファイルの供給のされ方に原因があると推測しました。
python -m http.server
する代わりに npx http-server
したら直りました。
まとめ
- Safari で HTMLAudioElement (audio タグ) の動作に奇妙なところがある。
- 2回目以降の play の再生開始が遅延する → new AudioContext() すればよい。
- 2回目以降の play で再生されない →
python -m http.server
を使っているならnpx http-server
など他の手段にするといい。