この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: audio要素
SEOタイトル: HTML5 <audio> 要素の使い方と autoplay / 複数 source / Web Audio API

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong><code><audio controls src="..."></audio></code></strong> で音声を再生</li><li><strong><code><source></code></strong> で複数フォーマット指定(mp3 / ogg / wav / aac)→ ブラウザが対応できる最初の 1 つを使用</li><li><strong>autoplay は制限あり</strong>: モバイル / Chrome / Safari は<strong>ユーザ操作なし自動再生不可</strong>。<code>muted</code> 併用なら可</li><li>JavaScript API: <code>.play()</code> / <code>.pause()</code> / <code>.currentTime</code> / <code>.volume</code> / <code>.duration</code></li><li>高度な処理は <strong>Web Audio API</strong>(エフェクト・解析)、<strong>MSE</strong>(ストリーミング)</li></ul></td></tr></table>
<h2>audio 要素の基本</h2>

<p>HTML5 で導入。プラグイン不要で音声を Web ページに埋め込めます。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- 最もシンプル: controls 付きで -->
<audio controls src="music.mp3"></audio>

<!-- 複数フォーマット対応(推奨) -->
<audio controls>
  <source src="music.mp3" type="audio/mpeg">
  <source src="music.ogg" type="audio/ogg">
  <source src="music.wav" type="audio/wav">
  <p>お使いのブラウザは audio タグに対応していません。
    <a href="music.mp3">音声ファイル</a>をダウンロードしてください。
  </p>
</audio>

<!-- 属性盛りだくさん -->
<audio
  controls
  autoplay
  muted
  loop
  preload="metadata"
  src="bgm.mp3"
  id="bgm">
</audio></code></pre>
<h2>属性一覧</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>属性</th><th>意味</th></tr></thead>
<tbody>
<tr><td><code>src</code></td><td>音声ファイル URL(<code><source></code> 無しのとき)</td></tr>
<tr><td><code>controls</code></td><td>ブラウザ標準の再生 UI を表示</td></tr>
<tr><td><code>autoplay</code></td><td>自動再生(多くのブラウザで制限あり)</td></tr>
<tr><td><code>loop</code></td><td>繰り返し再生</td></tr>
<tr><td><code>muted</code></td><td>ミュート初期状態</td></tr>
<tr><td><code>preload</code></td><td><code>none</code> / <code>metadata</code> / <code>auto</code></td></tr>
<tr><td><code>crossorigin</code></td><td>CORS 用 (<code>anonymous</code> / <code>use-credentials</code>)</td></tr>
</tbody>
</table>

<h2>主要フォーマットの対応状況</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>形式</th><th>MIME</th><th>Chrome</th><th>Firefox</th><th>Safari</th><th>Edge</th></tr></thead>
<tbody>
<tr><td>MP3</td><td><code>audio/mpeg</code></td><td>○</td><td>○</td><td>○</td><td>○</td></tr>
<tr><td>AAC</td><td><code>audio/aac</code></td><td>○</td><td>△</td><td>○</td><td>○</td></tr>
<tr><td>Ogg Vorbis</td><td><code>audio/ogg</code></td><td>○</td><td>○</td><td>×</td><td>○</td></tr>
<tr><td>Opus</td><td><code>audio/ogg; codecs=opus</code></td><td>○</td><td>○</td><td>○ (14+)</td><td>○</td></tr>
<tr><td>WAV</td><td><code>audio/wav</code></td><td>○</td><td>○</td><td>○</td><td>○</td></tr>
<tr><td>FLAC</td><td><code>audio/flac</code></td><td>○</td><td>○</td><td>○</td><td>○</td></tr>
<tr><td>WebM (Vorbis/Opus)</td><td><code>audio/webm</code></td><td>○</td><td>○</td><td>△</td><td>○</td></tr>
</tbody>
</table>

<p>最大公約数は <strong>MP3</strong>。容量効率を取るなら <strong>Opus</strong>(Safari 14+ 対応で可用に)。</p>

<h2>autoplay の制限</h2>

<p>ユーザの意図しない音声再生を防ぐため、ブラウザは autoplay を厳しく制限しています:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Chrome / Edge:
  - muted 付き autoplay: OK
  - 音声付き autoplay: ユーザがサイトを「よく訪問する」と判断されたときのみ
    (Media Engagement Index による)
  - iframe 内: allow="autoplay" 属性必要

Safari (macOS / iOS):
  - 音声付き autoplay: 原則 NG
  - muted autoplay: OK
  - ユーザのクリック後なら可

Firefox:
  - サイトごとに許可設定
  - デフォルトは muted のみ許可</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- ✅ どこでも動く: muted で起動、ボタンで unmute -->
<audio id="bgm" autoplay muted loop src="bgm.mp3"></audio>
<button id="unmute">音量オン</button>

<script>
  document.getElementById(&apos;unmute&apos;).addEventListener(&apos;click&apos;, () => {
    const a = document.getElementById(&apos;bgm&apos;);
    a.muted = false;
  });
</script></code></pre>
<h2>JavaScript API</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">const audio = document.querySelector(&apos;#bgm&apos;);

// 再生 / 一時停止
audio.play();          // Promise を返す(autoplay 制限で reject の可能性)
audio.pause();

// シーク
audio.currentTime = 60;     // 60 秒地点へ
console.log(audio.duration); // 総再生時間(秒)

// 音量 / 速度
audio.volume = 0.5;     // 0.0 ~ 1.0
audio.playbackRate = 1.5;  // 1.5 倍速
audio.muted = true;

// 状態
console.log(audio.paused);   // 一時停止中か
console.log(audio.ended);    // 再生終了したか
console.log(audio.readyState); // 0-4

// 再生 Promise を扱う
try {
    await audio.play();
} catch (err) {
    console.warn(&apos;再生失敗:&apos;, err);
    // → 多くは autoplay policy 違反
}</code></pre>
<h2>イベント</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">const a = document.querySelector(&apos;audio&apos;);

a.addEventListener(&apos;loadedmetadata&apos;, () => console.log(&apos;長さ:&apos;, a.duration));
a.addEventListener(&apos;canplay&apos;, () => console.log(&apos;再生可能&apos;));
a.addEventListener(&apos;play&apos;, () => console.log(&apos;再生開始&apos;));
a.addEventListener(&apos;pause&apos;, () => console.log(&apos;一時停止&apos;));
a.addEventListener(&apos;ended&apos;, () => console.log(&apos;再生終了&apos;));
a.addEventListener(&apos;timeupdate&apos;, () => {
    document.querySelector(&apos;#current&apos;).textContent = a.currentTime.toFixed(1);
});
a.addEventListener(&apos;error&apos;, () => console.error(&apos;エラー:&apos;, a.error));
a.addEventListener(&apos;waiting&apos;, () => console.log(&apos;バッファリング中&apos;));
a.addEventListener(&apos;volumechange&apos;, () => console.log(&apos;音量:&apos;, a.volume));</code></pre>
<h2>カスタム UI を作る</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><audio id="track" src="song.mp3"></audio>
<button id="playPause">▶</button>
<input type="range" id="seek" min="0" max="100" value="0">
<span id="time">0:00 / 0:00</span>

<script>
const track = document.getElementById(&apos;track&apos;);
const btn = document.getElementById(&apos;playPause&apos;);
const seek = document.getElementById(&apos;seek&apos;);
const time = document.getElementById(&apos;time&apos;);

btn.onclick = () => {
    if (track.paused) {
        track.play();
        btn.textContent = &apos;⏸&apos;;
    } else {
        track.pause();
        btn.textContent = &apos;▶&apos;;
    }
};

track.ontimeupdate = () => {
    seek.value = (track.currentTime / track.duration) * 100;
    time.textContent = formatTime(track.currentTime) + &apos; / &apos; + formatTime(track.duration);
};

seek.oninput = () => {
    track.currentTime = (seek.value / 100) * track.duration;
};

function formatTime(sec) {
    const m = Math.floor(sec / 60);
    const s = Math.floor(sec % 60).toString().padStart(2, &apos;0&apos;);
    return `${m}:${s}`;
}
</script></code></pre>
<h2>Web Audio API でエフェクト</h2>

<p>音量調整・イコライザ・解析など高度な処理は <strong>Web Audio API</strong> を使います:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">const audioCtx = new AudioContext();
const audio = document.querySelector(&apos;audio&apos;);
const source = audioCtx.createMediaElementSource(audio);

// 音量を上げる
const gain = audioCtx.createGain();
gain.gain.value = 1.5;

// FFT 解析(ビジュアライザ用)
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048;

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

// 周波数データ取得
const buf = new Uint8Array(analyser.frequencyBinCount);
function draw() {
    analyser.getByteFrequencyData(buf);
    // buf を canvas に描画 → ビジュアライザ完成
    requestAnimationFrame(draw);
}
draw();

// 再生開始(ユーザ操作後に呼ぶ)
audio.play();
audioCtx.resume();   // Safari 等で必要</code></pre>
<h2>ストリーミング(MSE)</h2>

<p><strong>Media Source Extensions</strong> を使うと、JS から音声チャンクを供給できます。HLS / DASH 配信に必須:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">const mediaSource = new MediaSource();
const audio = document.querySelector(&apos;audio&apos;);
audio.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener(&apos;sourceopen&apos;, async () => {
    const sb = mediaSource.addSourceBuffer(&apos;audio/mpeg&apos;);
    const chunks = await fetchChunks();   // 自前で取得
    for (const chunk of chunks) {
        sb.appendBuffer(chunk);
        await new Promise(r => sb.addEventListener(&apos;updateend&apos;, r, {once:true}));
    }
    mediaSource.endOfStream();
});

// HLS は hls.js ライブラリ利用が一般的
// import Hls from &apos;hls.js&apos;;
// const hls = new Hls();
// hls.loadSource(&apos;stream.m3u8&apos;);
// hls.attachMedia(audio);</code></pre>
<h2>アクセシビリティ</h2>

<ul>
<li><strong>controls</strong> を出して、キーボード操作可能に</li>
<li>字幕付き音声なら <strong><code><track></code></strong>(ただし audio 要素では公式サポート外、video のみ)→ 代替テキストを近くに置く</li>
<li>背景音楽の自動再生は避ける(音響過敏症の方への配慮)</li>
<li>テキスト書き起こしを併設すると検索性も a11y も向上</li>
</ul>

<h2>FAQ</h2>

<p><strong>Q: <code>play()</code> が rejected されるのはなぜ?</strong><br />
A: autoplay policy 違反です。ユーザのクリック等のジェスチャ後に呼ぶか、<code>muted</code> 状態で開始してください。</p>

<p><strong>Q: ファイルが大きくて遅い</strong><br />
A: <code>preload="metadata"</code> でメタデータだけ先読み、Opus / AAC でサイズ削減、CDN を使う、Range リクエストで部分配信を有効化。</p>

<p><strong>Q: iOS Safari で動かない</strong><br />
A: ① ユーザ操作後に <code>play()</code> ② muted 初期化 ③ <code>preload="auto"</code> 試行。それでもダメなら HLS でのストリーミング検討。</p>