WebサイトやWebアプリに動きを付ける際に、音声を流したいと思ったことはありませんか?

JavaScriptでは、audioオブジェクトを制御することで、音声ファイルの再生や停止をすることができます。
audioオブジェクトとは、音声ファイルを扱うオブジェクトのことで、「mp3/mp4ファイル」「WAVEファイル」などが該当します。

そこで今回は、JavaScriptで音声ファイルを再生する方法を解説していきます。

デモ

単に音声を再生するだけではつまらないので、キーボードイベントを取り入れて、キーボードを押すと音声が再生され、キーボードを離すと停止されるように実装してみましょう。
今回は、このような動物の鳴き声を再生/停止できるように作っていきます。

HTMLCSSの準備

まずはHTMLとCSSの準備をしていきます。

HTML

<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
</head>
<body>
  <h1>Animal Sound</h1>
  <div class="keys">
    <div data-key="a" class="key">
      <kbd>A</kbd>
      <span class="sound">CAT</span>
    </div>
    <div data-key="s" class="key">
      <kbd>S</kbd>
      <span class="sound">CHICKEN</span>
    </div>
    <div data-key="d" class="key">
      <kbd>D</kbd>
      <span class="sound">DOG</span>
    </div>
    <div data-key="f" class="key">
      <kbd>F</kbd>
      <span class="sound">HORSE</span>
    </div>
    <div data-key="g" class="key">
      <kbd>G</kbd>
      <span class="sound">SHEEP</span>
    </div>
    <div data-key="h" class="key">
      <kbd>H</kbd>
      <span class="sound">WARBLER</span>
    </div>
    <div data-key="j" class="key">
      <kbd>J</kbd>
      <span class="sound">WOLF</span>
    </div>
  </div>

  <audio data-key="a" src="sounds/cat.mp3"></audio>
  <audio data-key="s" src="sounds/chicken.mp3"></audio>
  <audio data-key="d" src="sounds/dog.mp3"></audio>
  <audio data-key="f" src="sounds/horse.mp3"></audio>
  <audio data-key="g" src="sounds/sheep.mp3"></audio>
  <audio data-key="h" src="sounds/warbler.mp3"></audio>
  <audio data-key="j" src="sounds/wolf.mp3"></audio>

<script type="text/javascript" async="" src="main.js"></script>
</body>
</html>

今回は「A」「S」「D」「F」「G」「H」「J」のキーを作るために、divタグで見た目の用意とaudioタグでそれぞれのキーに割り当てられる音声を用意します。

ここでのポイントは、data-key="a"のように、data属性にそれぞれのキーのアルファベットを記述している点です。JavaScript側でキーを取得するために必要になります。

キーの取得方法はいくつかありますが、e.keyまたはe.codeを使う方法が推奨されています。
今回は、e.keyを使ってキーを取得するため、data属性にはキーと同じ値を付与してください。

詳しくはJavaScriptのコードで解説します。

CSS

html {
  font-size: 1rem;
}

body,html {
  font-family: serif;
}

h1 {
  text-align: center;
  margin-top: 10rem;
}

.keys {
  height: 400px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.key {
  border: .1rem solid black;
  border-radius: .3rem;
  margin: 0 0.5rem;
  padding: 1rem .5rem;
  transition: all .07s ease;
  width: 4rem;
  text-align: center;
  background: rgba(0,0,0,0.1);
}

kbd {
  display: block;
  font-size: 1.5rem;
}

.sound {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: .1rem;
}

.playing {
  transform: scale(1.1);
  border-color: red;
  box-shadow: 0 0 1rem red;
}

キーを押した際に枠が赤く光るように.playingを用意しています。
playingクラスはHTMLではまだ使われていませんが、JavaScriptでクラスを追加付与させます。

JavaScriptで音声ファイルの再生/停止を実装

HTMLとCSSの準備ができたら、JavaScriptに移っていきましょう。

全体のコード

function keycodeOutput(e) {
  const keyAction = document.querySelector(`.key[data-key="${e.key}"]`);
  const audioAction = document.querySelector(`audio[data-key="${e.key}"]`);

  keyAction.classList.add('playing');
  audioAction.play();
}
window.addEventListener('keydown', keycodeOutput);

function keycodeRemove(e) {
  const keyAction = document.querySelector(`.key[data-key="${e.key}"]`);
  const audioAction = document.querySelector(`audio[data-key="${e.key}"]`);

  keyAction.classList.remove('playing');
  audioAction.pause();
}
window.addEventListener('keyup', keycodeRemove);

機能としては、以下の2つの関数に分かれています。

  • keycodeOutput関数:キーを押した時に音声を再生する
  • keycodeRemove関数:キーを離した時に音声を停止する

それでは上から順番にコードを解説していきます。

キーを押した時に音声を再生する

keycodeOutput関数から見ていきましょう。

function keycodeOutput(e) {
  const keyAction = document.querySelector(`.key[data-key="${e.key}"]`);
  const audioAction = document.querySelector(`audio[data-key="${e.key}"]`);

  keyAction.classList.add('playing');
  audioAction.play();
}
window.addEventListener('keydown', keycodeOutput);

まずは、キーそのものと、キーの音声が格納されている要素を取得します。

const keyAction = document.querySelector(`.key[data-key="${e.key}"]`);
const audioAction = document.querySelector(`audio[data-key="${e.key}"]`);

[data-key="${e.key}"]は、キーを取得するための役割があります。

e.keyの部分は、すなわち入力された文字を取得します。
つまり、e.keyをaまたはAと設定することで、キーボート上のAだと認識されるようになります。
このことから、HTMLのdata属性で記述したキーが取得できるようになるというわけです。

さらに、querySelectorによってキーを表す要素(.keyを持っている要素)と、音声ファイルが用意されている要素(audio要素)が取得できます。

次に、キーの要素にクラスの追加と、音声ファイルを再生します。

keyAction.classList.add('playing');
audioAction.play();

classList.add('playing')により、キーの要素にクラスが追加され、playingクラスのスタイルが付与されるようになります。

play()は、映像や音声を再生することができるイベントです。
audioAction.play()によって、各キーに割り当てられた音声ファイルが再生されるようになります。

それでは、関数を実行してみましょう。

window.addEventListener('keydown', keycodeOutput);

addEventListnerの第一引数にキーボードイベントを記述し、第二引数に実行させる関数を記述します。
'keydown'は名前の通り、キーボードが押された時にイベントを実行させる役割があります。

これで、A〜Jのキーが押された時に関数が実行されるようになりました。

試しに入力したキーが取得できるか確認してみます。

console.log(e.key);  // a, s, d, f, g, h, j

関数の中で上記を入力すると、キーが取得できていることが確認できるはずです。

キーを離した時に音声を停止する

今度は、キーを離した時に音声が停止されるように、keycodeRemove関数を実装していきましょう。

function keycodeRemove(e) {
  const keyAction = document.querySelector(`.key[data-key="${e.key}"]`);
  const audioAction = document.querySelector(`audio[data-key="${e.key}"]`);

  keyAction.classList.remove('playing');
  audioAction.pause();
}
window.addEventListener('keyup', keycodeRemove);

keyCodeOutput関数で実装した時と同じ方法で、キーと音声の要素を取得してください。

そして、キーの要素からクラスを取り外し、音声ファイルを停止します。

keyAction.classList.remove('playing');
audioAction.pause();

classList.remove('playing')により、先ほど追加したplayingクラスを取り外します。

pause()は、映像や音声を停止することができるイベントです。
audioAction.pause()によって、各キーに割り当てられた音声ファイルを停止できるようになります。

では、関数を実行してみましょう。

window.addEventListener('keyup', keycodeRemove);

addEventListnerの第一引数にキーボードイベントを記述し、第二引数に実行させる関数を記述します。
'keyup‘はキーが離れた時にイベントを実行させます。

これで、A〜Jのキーを離すと関数が停止されるようになりました。

以上で全ての実装が完了です。

まとめ

今回は、イベントを使って音声ファイルの再生/停止を実装しました。

キーボードイベントのkeydown/keyupや、映像メディアイベントのplay/pauseによるさまざまなイベントと、特定のキーを認識させるためのe.keyを使用することで、よりプログラムを制御することができました。
また、addEventListnerでのイベント処理は、キーボードイベントだけでなく、マウスイベントなどさまざまなアクションを可能にさせるため、使えるようになると便利です。

今後もイベントを駆使してJavaScriptを楽しんでいきましょう。

音声ファイルの関連記事

DOMの仕組みと構造
イベントハンドラとイベントリスナー