マガジン

音が出る前に必要な「一回の操作」:自動再生制限の裏側

遊びを見つける

執筆にClaudeを使用しています。

大きなボタンに指が触れ、スピーカーへ金色の音の波が広がる立体イラスト
記事のテーマをもとに制作したAI生成イラスト。

ゲームのページを開いたのに、BGMが鳴らない場面を考えてみます。音量は上がっていて、スピーカーも壊れていません。それなのに画面のボタンを一度押した途端、何事もなかったように音が流れ始めます。不具合に見えますが、多くの場合はブラウザが意図して音を止めています。 この記事で確かめるのは、次の三点です。ブラウザはなぜ音を止めるのか。止めた状態は何をきっかけに解けるのか。その「きっかけ」を遊ぶ人と作る人はそれぞれどう扱えばよいのか。最後まで読めば、自分のブラウザで音の状態を観察する小さな実験を手元で行えます。結果は環境によって変わるため、ここには書きません。観察の手順と、結果の読み方だけを示します。

この記事の目次
  1. 音が出ないとき、ページの中で起きていること
  2. ブラウザはなぜ音を止めるのか
  3. 解除の条件:「一回の操作」とは何か
  4. 自分のブラウザで状態を見る実験の設計書
  5. 公式作品の設計から読み取れること
  6. 作る人が押さえたい三つの設計
  7. 次の行動
  8. 参考資料

音が出ないとき、ページの中で起きていること

ブラウザで音を扱う方法は大きく二つあります。ひとつは <audio> や <video> のようなメディア要素で、もうひとつは Web Audio API です。Web Audio API は、音を部品としてつなぎ合わせて鳴らす仕組みで、楽器やゲームの効果音によく使われます。

Web Audio API では、音の処理全体を AudioContext という入れ物が管理します。この入れ物には状態があり、主に次の三つの値を取ります。

  • suspended:一時停止中です。音の処理が止まっており、何を鳴らしても聞こえません。
  • running:動作中です。鳴らした音が出力に流れます。
  • closed:破棄済みです。もう使えません。

ページが読み込まれた直後、ブラウザの方針によっては、入れ物が suspended のまま始まります。コードがエラーを出さずに音の部品を組み立てても、音は出ません。画面上は何も壊れていないので、原因に気づきにくい状況です。

つまり「音が出ない」の正体は、多くの場合、音のデータや再生コードの不具合ではなく、入れ物が止まっていることです。この状態を動かせるのが、題名にある「一回の操作」です。

ブラウザはなぜ音を止めるのか

自動再生を制限する理由は、一般には次のように説明されています。

  • 突然の音を防ぐため:静かな場所や会議中に、ページを開いただけで音が鳴り出すのは困ります。
  • 意図しないページが音を出すのを防ぐため:タブをたくさん開いていると、どのタブから音が出ているのか分からなくなります。
  • 動画広告のような押しつけを抑えるため:見る人が選ぶ前に音と映像が始まる体験は、苦情の多いものでした。
  • 端末の負担を抑えるため:特にモバイルでは、バッテリーや通信量への配慮も理由に挙げられます。

ここで大切なのは、制限の対象が「音」そのものではなく、「利用者が望んだかどうかが分からない音」だという点です。利用者が自分でボタンを押したのなら、その人は音が出ることを予期しています。ブラウザはその操作を、「この音は望まれている」という手がかりとして扱います。

制限の細かい基準はブラウザごとに異なり、更新で変わることもあります。たとえば、そのサイトをよく利用しているかどうかを考慮するブラウザもあります。具体的な基準は、各ブラウザの公式ドキュメントで確認してください。この記事では、どのブラウザにも共通する大きな考え方だけを扱います。

解除の条件:「一回の操作」とは何か

一般に、解除のきっかけになるのは、利用者が能動的に行う操作です。クリック、タップ、キーの押下などが代表例です。マウスを動かす、ページをスクロールするといった動きは、操作として数えない方針のブラウザが多いとされています。ただし、どの操作が数えられるかはブラウザによって異なる可能性があるため、断定は避けます。この点も、次の節の実験で自分の環境について確かめられます。

仕組みを順に並べると、次のようになります。

  1. ページが開き、AudioContext が作られる。状態は suspended の場合がある。
  2. 利用者がボタンを押す、またはキーを打つ。
  3. その操作に対する処理の中で resume() を呼ぶ。
  4. 状態が running に変わり、以降は音が出る。

3番目が重要です。音を鳴らすコードが、操作とは無関係なタイミング(たとえば読み込み完了の直後)で動いても、制限は解けません。操作に対応する処理の中で、入れ物を動かし始める必要があります。

また、一度解除されれば、そのページを開いている間は基本的に音を出し続けられます。必要なのは「毎回の操作」ではなく、「最初の一回」です。題名が「一回の操作」としているのはそのためです。

自分のブラウザで状態を見る実験の設計書

ここからは、読者が自分の環境で確かめるための手順です。問いは次のとおりです。

自分のブラウザでは、ページを開いた直後の AudioContext はどの状態か。そして、どの操作で状態が変わるか。

準備するもの

  • テキストエディタと、普段使いのブラウザ
  • 可能なら、別のブラウザも一つ(PCとスマートフォンの両方で試せると差が見えます)
  • 下のコードを、audio-state.html という名前で保存したファイル
html
<!doctype html>
<meta charset="utf-8">
<title>音の状態を見る</title>
<p id="log">読み込み中…</p>
<button id="go">音を鳴らす</button>
<script>
const log = document.getElementById("log");
const ctx = new AudioContext();
const lines = [];
function note(text) {
  lines.push(text);
  log.textContent = lines.join(" / ");
}
note("作成直後: " + ctx.state);
ctx.onstatechange = () => note("変化: " + ctx.state);
function beep() {
  const osc = ctx.createOscillator();
  const gain = ctx.createGain();
  gain.gain.value = 0.1;
  osc.connect(gain).connect(ctx.destination);
  osc.start();
  osc.stop(ctx.currentTime + 0.3);
}
document.getElementById("go").addEventListener("click", async () => {
  note("クリック時: " + ctx.state);
  await ctx.resume();
  note("resume後: " + ctx.state);
  beep();
});
</script>

外部ライブラリは使いません。ファイルをブラウザで開くだけで動きます。音量は小さめ(0.1)にしていますが、実験前に端末の音量も下げておくと安心です。

手順と記録の取り方

次の四つの条件を、それぞれ3回ずつ行います。記録するのは「画面に出た文字列」と「実際に音が聞こえたか」の二つです。耳で確かめた結果と、画面の状態を必ず別々に書いてください。

  • A、操作:ファイルを開き、何も押さずに画面を見る、記録すること:「作成直後」の状態
  • B、操作:ボタンを1回押す、記録すること:「クリック時」「resume後」の状態、音の有無
  • C、操作:ページを再読み込みし、何も押さない、記録すること:状態がAと同じか
  • D、操作:キーボードのキー(Tabなど)だけを押し、続けてボタンを押す、記録すること:キー押下だけで状態が変わるか

あわせて、ブラウザ名とバージョン、端末の種類(PC/スマートフォン)、イヤホンの有無をメモしておきます。別のブラウザでも同じ表を作ると、比較できます。

結果の読み方

  • Aで suspended と表示されたなら、そのブラウザでは、このページに対して自動再生の制限が働いています。
  • Aで最初から running と表示されたなら、そのブラウザでは、この条件で制限が緩んでいるか、基準が異なります。どの基準で緩んだのかは、この実験だけでは分かりません。ブラウザの公式ドキュメントで確認してください。
  • Bで resume後 が running になり音も聞こえたなら、「操作の中で resume を呼ぶと解ける」という流れが自分の環境で確認できたことになります。
  • Bで running と表示されたのに音が聞こえないなら、制限以外の原因を疑います。端末のサイレントスイッチ、タブのミュート、OSの音量、出力先(接続中のイヤホンなど)の順に見てください。
  • Dの結果は、キー押下が操作として数えられるかどうかを示します。ブラウザによって差が出るかもしれない部分です。

起こりやすい誤り

  • 画面の状態だけを見て、耳で確認しない。running でも、出力先の問題で音は聞こえないことがあります。
  • 一度ボタンを押した後のページで、再度「作成直後」の状態を調べようとする。状態を調べ直すには、再読み込みが必要です。
  • 開発者ツールや拡張機能の影響を考えない。設定によって挙動が変わることがあります。気になる場合は、拡張機能を無効にしたウィンドウでも試してください。
  • 1回の結果で結論を出す。3回繰り返して、毎回同じかどうかを見ます。

公式作品の設計から読み取れること

アソバースの公式作品のうち、音に関わる確認済みの事項から、設計として読み取れることを整理します。作品内部の実装は確認できないため、ここでは「確認済みの仕様から言えること」と「作品を開いて確かめること」を分けて書きます。

こだまの森:音がなくても成立する

「こだまの森」は、光る葉の順番を覚え、4つの音色で返す記憶ゲームです。確認済みの事項として、音なしでも遊べます。

自動再生の制限という観点では、これは大きな意味を持ちます。音が出ない状態でも、遊びが成立する形になっているからです。音が出ない原因が、制限であれ、端末のミュートであれ、遊べなくなる事態を避けられます。ゲームの中心に音を置きつつ、音に頼り切らない設計は、制限下でも壊れにくい作り方の一例として読み取れます。

最初に音がどの操作で始まるかは、作品を開いて確かめる部分です。開始ボタンを押す前後で音の出方がどう変わるか、実験の考え方を使って観察できます。

雨音のピアノ:演奏の操作そのものが手がかりになる

「雨音のピアノ」は、フェルトとガラスの2音色を持ち、キーボードではA W S E D F T G Y H U Jの鍵で弾けます。雨音つきの自由演奏もあります。

キー押下が操作として数えられるブラウザが多いとすれば、演奏のための入力が、そのまま「音を出してよい」という合図にもなりえます。ただし、これは一般論から考えた可能性です。この作品が実際にどの操作で音を始めるのか、雨音がどの時点から鳴るのかは、作品を開いて、何も押さない状態と最初の1音を弾いた後を聞き比べて確かめてください。

WAVE / WAVE:ループ再生は「始めるきっかけ」が要る

「WAVE / WAVE」は、4つの音を16ステップに並べてループ再生するリズムスタジオです。ループは自動で鳴り続ける性質の音なので、制限と相性が悪い種類です。再生がどの操作で始まるか、パッド演奏の音と再生ボタンの音で違いがあるかは、作品で確かめられます。

三つの作品に共通する読み取りは、「音を出す側が、利用者の操作を起点に設計されている」と考えられることです。ただし、個々の実装の細部は確認できていないので、上の観察で補ってください。

作る人が押さえたい三つの設計

自分のゲームに音を入れるとき、制限と付き合う基本方針は次のとおりです。

  1. 音の開始を、操作の中に置く。 「はじめる」ボタンのクリック処理の中で resume() を呼びます。入れ物を作る処理も、操作の中で行うと扱いやすくなります。
  2. 音が出ていない状態を、画面で見えるようにする。 「タップで音を有効にします」のような案内を置くと、利用者が原因に気づけます。
  3. 音なしでも遊べる形を考える。 先ほどの「こだまの森」のように、音以外の手がかりを残す設計は、音の制限以外の事情(静かな場所での利用など)にも強くなります。

アソバースに作品を投稿する場合、ゲームはsandbox付きのiframeで実行されます。埋め込まれたページでの音の扱いは、ブラウザや埋め込みの設定によって差が出る可能性があります。そのため、投稿の「入力→表示の確認→公開」の流れのうち、表示の確認の段階で、実際に音が出るかを確かめておくと安心です。確認するときは、何も押さない状態と、ボタンを押した後の両方を試してください。

次の行動

まず、上の audio-state.html を保存し、条件A〜Dを3回ずつ試して、自分のブラウザの「作成直後」の状態を表に残してください。その後、「こだまの森」と「雨音のピアノ」を開き、何も押さない状態と最初の操作の後で音の出方がどう違うかを聞き比べてみてください。作る人は、自分のゲームの「はじめる」ボタンの中で resume() を呼べているかを見直す、と手順が明確になります。

参考資料

  • MDN Web Docs「Autoplay guide for media and Web Audio APIs」
  • Chrome for Developers「Autoplay policy in Chrome」
  • W3C「Web Audio API」仕様