1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Web Audio APIにおけるユーザーインタラクションと音声再生の実装

Posted at

ブラウザでは、ユーザーが明示的に操作しない限り、音声の自動再生が制限 されています。
これは、ユーザーエクスペリエンスを考慮したブラウザのポリシーによるもの。
この制限を回避するには、適切な AudioContext の管理とイベント処理が必要。

本記事では、ReactアプリケーションでWeb Audio APIを用いて音声を適切に再生する方法を解説します。

公式ドキュメント
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
https://developer.chrome.com/blog/autoplay/

ブラウザの自動再生ポリシー

ポリシーの概要

  • ユーザーが操作しない限り、音声の自動再生は不可
  • 無音の音声 (muted) であれば自動再生可能(そりゃそう)
  • クリック、タップ等のユーザーインタラクション後にAudioContextを起動すれば良い

実装のポイント

1. AudioContext の状態管理

AudioContext には以下の3つの状態があります。

状態 説明
suspended 音声の再生が一時停止された状態(初期状態)
running 音声を再生できる状態
closed 完全に閉じられた状態

2. ユーザーインタラクションの検知

ユーザーがクリックやタップなどの操作をした際に AudioContextrunning 状態に変更する。

document.addEventListener("click", () => {
  // AudioContextがsuspended(停止状態)の場合はresume()を呼び出して再生を許可
  if (audioContext.state === "suspended") {
    audioContext.resume().then(() => {
      console.log("AudioContext is now running");
    });
  }
});

3. 音声再生の制御

AudioBufferSourceNode を用いて音声をロードし、再生する。
ユーザー操作後に AudioContext.resume() を実行して再生を許可する。

Reactでの実装例

1. AudioContextの初期化

import { useEffect, useState } from "react";

const useAudio = (url) => {
  const [audioContext, setAudioContext] = useState(null);
  const [audioBuffer, setAudioBuffer] = useState(null);

  useEffect(() => {
    const context = new (window.AudioContext || window.webkitAudioContext)();
    setAudioContext(context);

    // 音声をロード
    fetch(url)
      .then((res) => res.arrayBuffer())
      .then((data) => context.decodeAudioData(data))
      .then((buffer) => setAudioBuffer(buffer));

    return () => context.close();
  }, [url]);

  const playSound = () => {
    if (audioContext.state === "suspended") {
      audioContext.resume();
    }

    if (audioBuffer) {
      const source = audioContext.createBufferSource();
      source.buffer = audioBuffer;
      source.connect(audioContext.destination);
      source.start(0);
    }
  };

  return playSound;
};

2. Reactコンポーネントでの使用例

const AudioPlayer = () => {
  const playSound = useAudio("/audio/sample.mp3");

  return (
    <button onClick={playSound}>
      音声を再生
    </button>
  );
};

export default AudioPlayer;

実装の流れ

  • ページ読み込み時
    AudioContextsuspended(一時停止) 状態

  • ユーザーがクリックやタップを行う
    AudioContext.resume() を実行し、running 状態にする

  • 音声の再生
    AudioBufferSourceNode を作成し、音声を再生

注意点

  1. ブラウザの自動再生ポリシーへの対応
    初回のクリック・タップで AudioContext.resume() を呼び出す
    音声ファイルはプリロードせず、ユーザー操作後にロード

  2. モバイルデバイスでの挙動の違い
    Safariは AudioContext をページ遷移時に自動で閉じるため、適切な管理が必要
    Chrome は、バックグラウンドに回ると suspended 状態に戻る

  3. 音声ファイルの非同期ロード
    音声データは fetch() でロードし、decodeAudioData() でデコードする
    ネットワーク遅延が発生するため、ローディング状態を管理

まとめ

Web Audio API を使った音声再生には、以下の3つのポイントが重要。

  1. ユーザーインタラクションを適切に検知
    初回クリックやタップ時に AudioContext.resume() を呼び出す
  2. AudioContextの状態を適切に管理
    suspendedrunning の遷移を考慮する
  3. 音声データのロードと再生
    AudioBufferSourceNode を用いた正しい再生処理を実装する
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?