iOS • iPadOSにおける音の出力条件がカオスすぎる
iOS • iPadOSではミュートスイッチがあり、iPhoneには端末に物理的なスイッチがついており、iPadではコントロールセンターからアクセスできます。
先日制作した自分の会社のウェブサイトで、「ボタンをクリックすると音が鳴る」というありふれた仕掛けをしたのですが、音の再生条件で実はかなり苦労しています。
というのもiOSとiPadOSにおいて
ミュートスイッチの状態
出力先(スピーカーorイヤフォン)
音の再生処理の仕方
で実際に音が出力されるかどうかの挙動が異なるためです。
実装していてあまりにカオスなので、色々な再生条件のもと音の出力の有無について調べてみました。
HTML Audio要素による再生
ミュートスイッチが「オン」のとき、つまり消音をしているときに、ボタンを押した時にスピーカーから音が再生されたらどう思われますか?
ミュートしているのだから音がなっては困る。が自然の考え方だと思うのですが、結論から言うとHTMLのAudio要素を使った再生処理の場合、iOS • iPadOSではミュートをしていても問答無用に音が出力されます。
アップルとしては「ユーザーが音を再生するために明示的に再生の操作(クリック)をしているのであれば、ミュートのありなしに関わりなく音を出そう」という考え方なのかもしれませんですが、ミュートしているんだから出力するなよ…
一方、macOS • Windows 11 • Androidではミュート時は音が出力されず、素直な実装のように思えます。
Web Audio APIによる再生
一方、JavaScriptで音を再生する手段には、HTML Audio要素意外にも「Web Audio API」を使う方法があります。
Web Audio APIを利用すると、音のミックスや動的な生成、リバーブ・ディレイ効果などHTML Audio要素では到底不可能な高度なリアルタイム音声処理が可能なのですが、実はこのWeb Audio APIには音の出力の部分で特異な性質があります。
「Web Audio APIではiOS • iPadOSでミュートスイッチがオンならば、スピーカーからは音が出力されない。」
ただし、同一ページでHTML Audio要素での再生を行った場合、上記の条件はキャンセルされミュート時にも出力される挙動に変化してしまう。
音の出力の面では、上記の点がHTML Audioとの大きな違いで、他のOSと同等の挙動となりますが、2番目の挙動がまったくもって意味不明です。ゴールド・エクスペリエンスかな?ジョジョなのかな?
また、イヤフォンを使っている場合にはミュートしていてもHTML Audio要素同様に音が出ます。イヤフォンはパーソナルな空間なので出力されたとしても(公共交通機関などで)困ることはなさそうですが、スピーカーに対する結果とどうして異なるのか謎でしかありません。
※以下のCodePenを試す場合にはこのページを一度リロードしてからお試しください。
おそらくiOS • iPadOSの仕様によると思われますが、何故そうなっているのかまで調査はできておらず、その意味で「性質」と言いました。
音を扱うにはWeb Audio APIを利用した方がよさそう??
以上を踏まえると。ウェブサイトで音を扱いたい場合には、
ユーザーがいつもパーソナルな空間でウェブサイトを利用しているとは限らないため、状況・状態に関わらず音が出力されてしまうHTML Audio要素の利用は控えWeb Audio APIを利用する。
のが良いのかもしれません。
以下はaguijeサイトで使用している、Web Audio APIで音を出力するためのJavaScript classです。
指定した音源を非同期で読み込み、再生時に音量の指定ができる程度の簡素な機能しかありませんので、もうすこし複雑なことをされたいのであれば優れたWeb Audio APIライブラリである「howler.js」の利用を検討してみてください。
読んでいただきありがとうございます。丁寧な記事作りをこころがけていますので、記事が気に入ったなどでカンパをよせていただけるのなら励みになります。