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」の第1引数にキーボードイベントを記述し、第2引数に実行させる関数を記述します。
「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」の第1引数にキーボードイベントを記述し、第2引数に実行させる関数を記述します。「keyup」はキーが離れた時にイベントを実行させます。

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

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

まとめ

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

キーボードイベントの「keydown」「keyup」や、映像メディアイベントの「play」「pause」によるさまざまなイベントと、特定のキーを認識させるための「e.key」を使用することで、よりプログラムを制御することができました。

また、addEventListnerでのイベント処理は、キーボードイベントだけでなく、マウスイベントなどさまざまなアクションを可能にさせるため、使えるようになると便利です。

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

JavaScriptの基本をおさらい