JavaScript | Web API:グラフィック・メディア - Audio API

JavaScript JavaScript
スポンサーリンク

Audio API は「ブラウザの中にある音のミキサー&シンセサイザー」

JavaScript で音を扱う方法は大きく分けて 2 つあります。

ひとつは <audio> タグを JavaScript から操作する、シンプルなやり方。
もうひとつは Web Audio API を使って、音を細かく加工・合成・分析するやり方です。

前者は「音楽プレイヤーのリモコン」。
後者は「本格的な音のスタジオ(ミキサー&シンセサイザー)」というイメージです。

ここでは、まずシンプルな <audio> 制御から入り、
そのあと Web Audio API の「核」だけを、初心者向けにかみ砕いて説明します。


まずは一番シンプルな音の再生から始める

HTMLAudioElement を使った「再生・一時停止」

HTML:

<audio id="audio" src="sound.mp3"></audio>

<button id="playPauseBtn">再生</button>
<span id="status"></span>

JavaScript:

const audio = document.querySelector("#audio");
const playPauseBtn = document.querySelector("#playPauseBtn");
const status = document.querySelector("#status");

playPauseBtn.addEventListener("click", async () => {
  try {
    if (audio.paused) {
      await audio.play();
      playPauseBtn.textContent = "一時停止";
      status.textContent = "再生中";
    } else {
      audio.pause();
      playPauseBtn.textContent = "再生";
      status.textContent = "一時停止中";
    }
  } catch (err) {
    status.textContent = "再生できませんでした: " + err;
  }
});
JavaScript

ここで重要なのは、audio.play() が Promise を返すことです。
ブラウザの自動再生制限などで再生がブロックされることがあるので、
awaittry...catch で「失敗するかもしれない前提」で書くのが安全です。

audio.paused で「今止まっているかどうか」が分かるので、
それを見て「再生/一時停止」を切り替えています。

音量・ミュート・再生位置も同じように触れる

音量は audio.volume(0〜1)、ミュートは audio.muted で制御できます。

audio.volume = 0.5;   // 50%
audio.muted = true;   // ミュート
JavaScript

再生位置は audio.currentTime(秒)で読み書きできます。

audio.currentTime = 10;  // 10 秒目から再生
JavaScript

ここまでは「動画制御」とほぼ同じ感覚です。
「音だけの video」として扱えるのが HTMLAudioElement です。


Web Audio API の世界観をざっくりつかむ

AudioContext と「ノードのつながり」がすべての基本

Web Audio API の中心にあるのが AudioContext です。

const audioCtx = new AudioContext();
JavaScript

AudioContext は「音の世界を管理する司令塔」です。
この中に「ノード」と呼ばれる部品をつないでいきます。

音を出すノード(発振器・音声ファイルなど)
音を加工するノード(音量、フィルタ、エコーなど)
最後にスピーカーにつながるノード(destination)

これらを線でつないでいくイメージです。

図にすると、こんな感じの「音のパイプライン」を作ります。

音の発生源 → エフェクト(音量・フィルタなど) → 出力(スピーカー)

この「ノードをつないで音の流れを作る」という感覚が、
Web Audio API の一番大事なポイントです。


一番小さな Web Audio の例:ビープ音を鳴らす

オシレーター(発振器)で「ピー」という音を作る

HTML:

<button id="beepBtn">ビープ音を鳴らす</button>

JavaScript:

const beepBtn = document.querySelector("#beepBtn");
const audioCtx = new AudioContext();

beepBtn.addEventListener("click", () => {
  const osc = audioCtx.createOscillator();   // 音の発生源(発振器)
  const gain = audioCtx.createGain();        // 音量を調整するノード

  osc.type = "sine";                         // 波形(sine: 正弦波)
  osc.frequency.value = 440;                 // 周波数(Hz)A4 = 440Hz

  gain.gain.value = 0.2;                     // 音量(0〜1)

  osc.connect(gain);                         // 発振器 → 音量
  gain.connect(audioCtx.destination);        // 音量 → スピーカー

  osc.start();                               // 再生開始
  osc.stop(audioCtx.currentTime + 0.3);      // 0.3 秒後に停止
});
JavaScript

ここでの流れを日本語で整理すると、

AudioContext を作る
オシレーター(音の発生源)とゲイン(音量)を作る
オシレーターの波形と周波数を設定する
ゲインの音量を設定する
オシレーター → ゲイン → destination(スピーカー)とつなぐ
start / stop で鳴らす時間を決める

という感じです。

特に大事なのは「ノードを connect でつなぐ」部分です。
これが Web Audio API の「音の配線」です。


音声ファイルを Web Audio API で再生する

fetch + decodeAudioData で AudioBuffer を作る

Web Audio API では、音声ファイルを「バッファ」として読み込んで再生します。

const audioCtx = new AudioContext();

async function loadSound(url) {
  const res = await fetch(url);
  const arrayBuffer = await res.arrayBuffer();
  const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
  return audioBuffer;
}
JavaScript

decodeAudioData は、
「生のバイト列 → 再生可能な AudioBuffer」に変換する処理です。

ここでも「読み込みは非同期」という感覚が重要です。
音声ファイルはすぐには使えないので、
await でちゃんと待つ必要があります。

AudioBufferSourceNode で再生する

読み込んだ AudioBuffer を再生するには、
createBufferSource を使います。

async function playSound(url) {
  const buffer = await loadSound(url);

  const source = audioCtx.createBufferSource();
  source.buffer = buffer;

  source.connect(audioCtx.destination);
  source.start();
}
JavaScript

これで、playSound("sound.mp3") のように呼べば、
Web Audio API 経由で音声ファイルを再生できます。

ここでも「ノードをつないでから start する」という流れは同じです。


Web Audio API の「強み」が出るところを少しだけ

音量やエフェクトを自由に挟める

Web Audio API の真価は、「途中に好きな処理を挟める」ことです。

例えば、音量を調整したいなら GainNode を挟みます。

const gain = audioCtx.createGain();
gain.gain.value = 0.3;

source.connect(gain);
gain.connect(audioCtx.destination);
JavaScript

左右の位置を変えたいなら PannerNode
音をこもらせたりシャリシャリさせたいなら BiquadFilterNode
エコーをかけたいなら DelayNode などがあります。

全部「ノード」として用意されていて、
connect でつなぐだけで音の流れに組み込めます。

この「音の配線を自分で設計できる」という感覚が、
Web Audio API の一番おもしろいところです。

HTMLAudioElement と組み合わせることもできる

既存の <audio> を Web Audio API の世界に引き込むこともできます。

const audio = document.querySelector("#audio");
const audioCtx = new AudioContext();
const source = audioCtx.createMediaElementSource(audio);
const gain = audioCtx.createGain();

gain.gain.value = 0.5;

source.connect(gain);
gain.connect(audioCtx.destination);
JavaScript

こうすると、

再生・一時停止は HTMLAudioElement のまま
音量やエフェクトは Web Audio API で制御

というハイブリッドな使い方ができます。


自動再生制限と「ユーザー操作」の重要性

AudioContext は「ユーザー操作で resume する」のが基本

最近のブラウザは、自動再生にかなり厳しいです。
ユーザーが何もしていないのに音を鳴らすと、
ほぼ確実にブロックされます。

そのため、AudioContext は
「ユーザー操作のタイミングで動かし始める」のが基本です。

const audioCtx = new AudioContext();

document.addEventListener("click", () => {
  if (audioCtx.state === "suspended") {
    audioCtx.resume();
  }
});
JavaScript

「ユーザーがクリックしたら AudioContext を resume する」
という形にしておくと、
自動再生制限に引っかかりにくくなります。

この「音はユーザーの意思で鳴らす」という考え方は、
UX 的にもセキュリティ的にもとても大事です。


初心者として「Audio API」で本当に掴んでほしいこと

Audio API(特に Web Audio API)は、
機能が多くて一気に全部覚える必要はありません。

まずは次の 4 つの感覚だけ、しっかり押さえてください。

シンプルな再生は <audio>audio.play() / audio.pause() で十分できる。
Web Audio API は AudioContext と「ノードをつなぐ配線」が核になっている。
オシレーター(発振器)とゲイン(音量)をつないでビープ音を鳴らすところから始める。
音声ファイルは fetch → decodeAudioData → BufferSource → connect → start という流れで再生する。

おすすめの練習は、次の順番です。

HTMLAudioElement で「再生/一時停止ボタン付きのシンプルなプレイヤー」を作る。
Web Audio API で「ボタンを押したら 0.3 秒だけビープ音が鳴る」コードを書く。
音声ファイルを Web Audio API で読み込んで再生してみる。

ここまでできると、
Audio API はもう「難しそうな黒魔術」ではなく、
「自分のアプリに“音の体験”を足すための、かなり素直な道具」
として感じられるようになっていきます。

タイトルとURLをコピーしました