🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

無音を鳴らして自動再生ポリシーをアンロックする

Safariなどのブラウザには、音の自動再生に制限があって、ロード時にいきなり再生!というのがだいたいできない時代。(この制限にはいろいろ条件があるけども)

そのため、「このサイトでは音が出ます」みたいなモーダルを出して、まずそれをクリックしてもらい、そのタイミングでこの制限を突破するために一手間かけるということが行われてきた。

で、そのひと手間で盛大に音を鳴らすわけにはいかないので、無音を鳴らすという半ばハック的な方法があるのである。

その無音の鳴らし方を毎回思い出すのが大変なので、いい加減メモっておく。

HTMLAudio

const $audio = new Audio();
$audio.src = "/sound-of-silence.mp3";

$audio.play();

ここでアンロックした`audio`要素を使い続けることが重要で、ReactとかでイミュータブルにやるとなぜかiOSでだけ再生されないみたいな事態になる・・。

無音の音源は、`ffmpeg`とかで作る。

ffmpeg -i anullsrc=r=11025:cl=mono -t 1 -f mp3 -acodec libmp3lame sound-of-silence.mp3

WebAudio

const ctx: AudioContext = new (typeof AudioContext !== "undefined"
  ? AudioContext
  : webkitAudioContext)();

const source = ctx.createBufferSource();
source.connect(ctx.destination);

source.buffer = ctx.createBuffer(1, 1, 22050);
source.onended = () => source.disconnect(0);

source.start(0);

そろそろプレフィックスはいらなくなるけど、まあ念のため・・。

WebRTC

MediaStream-backed media will autoplay if the web page is already capturing.
MediaStream-backed media will autoplay if the web page is already playing audio. A user gesture will still be required to initiate audio playback.
https://webkit.org/blog/7763/a-closer-look-into-webrtc/

なので、事前に`getUserMedia()`しておくか、何かしらの方法で音を出しておけばいいらしい。

後者の英語がいまいちしっくりきてないけど、たぶん「何かしらのユーザーアクション経由で、既に音が出てる状態であれば」ってことかね。