50
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

jsのオーディオライブラリ、howler.jsを試してみた

Last updated at Posted at 2019-03-21

注意

私はaudioのファイル形式など詳しくありません、個人的に興味があり公式に書いてあることを試してみたという内容です。
詳しく知りたい方は以下の公式などを参照し、本記事は読まなくて良いです。間違いなどありましたらご指摘お願いします:bow:

howler.jsとは

jsで扱えるオーディオライブラリ

Screen Shot 2019-03-21 at 23.09.46.png

2019/03/19現在

install

npmを使って試してみました

bash
npm init -y
npm i -D howler

すぐ試せるサンプル

こちらに用意しました

この記事のサンプルコードは全てこちらにあります。

確認バージョン

  • howler.js 2.1.1
  • node v10.14.1

Quick Start

quickStart.html
<button>play</button>
quickStart.js
import { Howl, Howler } from 'howler';

var sound = new Howl({
    src: [
        'audio/piano.ogg',
        'audio/piano.mp3',
    ]
});

document.querySelector("button").addEventListener("click", e => sound.play() );

piano.oggを再生してくれました

v0FLDNsn22.gif

Safariではogg形式のファイルに対応していないため、mp3で再生されたことを確認

Screen Shot 2019-03-21 at 16.png

なので、この書き方ですと、

const sound = new Howl({
    src: [
        'audio/piano.ogg',
        'audio/piano.mp3',
    ]
});

このようにタグで書いたのと同じように扱ってくれるようです

    <audio controls>
        <source src="audio/piano.ogg">
        <source src="audio/piano.mp3">
    </audio>

Typescript

bash
npm i -D typescript howler @types/howler
import { Howl, Howler } from 'howler';

const sound: Howl = new Howl({
    src: ['audio/piano.mp3'],
});

Examples

optionの指定

このように引数を渡すと色々なオプションを渡すことができます

option.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ['audio/piano.mp3'],
    autoplay: true,
    loop: true,
    volume: 0.5,
    onend: () => { // 再生完了時のendイベント
        console.log('Finished!');
    }
});

ループ再生だと再生が終端までくるたびにendイベントが呼ばれるようです

Screen Shot 2019-03-21 at 17.15.22.png

sound sprite

sound.play("hogesprite") とすることで再生開始位置と再生秒数を設定できるようです

soundSprite.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ['audio/piano.mp3'],
    sprite: {
        play1: [0, 3000], // 開始から3秒間を再生
        play2: [3000, 1000], // 開始3秒から1秒間再生
        play3: [60000, 5000], // 開始1分から5秒間再生
    }
});
  
document.body.insertAdjacentHTML("afterbegin", `
    <button id="play1">play1</button>
    <button id="play2">play2</button>
    <button id="play3">play3</button>
`);

play1.addEventListener("click", e => sound.play("play1") );
play2.addEventListener("click", e => sound.play("play2") );
play3.addEventListener("click", e => sound.play("play3") );

Listen for events

イベントを設定することができます

listenEvents.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ['audio/piano.mp3'],
});

// 最初の呼び出し後にリスナーをクリアします (このイベントは一回しか実行されない)
sound.once('load',() => {
    console.log('Load!');
});

// サウンドの再生が終了したときに発生します。
sound.on('end',() => {
    console.log('Finished!');
});

Control multiple sounds:

複数音楽を再生してそれぞれ制御できます

multipleSounds.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ['audio/piano.mp3'],
});

button.addEventListener("click", e => {
    // 同じサウンドを2回再生する
    const id1 = sound.play();
    const id2 = sound.play();

    // 1つ目の再生は10秒かけて音量を 1 -> 0 に変化させる
    sound.fade(1, 0, 10000, id1);
    // 2つ目の再生は再生速度を速くする
    sound.rate(1.5, id2);
});

Methods

pause

再生を一時停止する。
一時停止した後に play() を実行すると途中から再生できる

pause.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ['audio/piano.mp3'],
});

document.body.insertAdjacentHTML("afterbegin", `
    <button id="play">再生</button>
    <button id="pause">一時停止</button>
`);

play.addEventListener("click", e => {
    sound.play() // 一時停止したところから再生
});
pause.addEventListener("click", e => {
    sound.pause(); // 一時停止
});

stop

再生をストップする。
もう一度 play() を実行すると途中から最初から再生される

stop.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ['audio/piano.mp3'],
});

document.body.insertAdjacentHTML("afterbegin", `
    <button id="play">再生</button>
    <button id="stoped">再生終了</button>
`);

play.addEventListener("click", e => {
    sound.play() // 最初から再生される
});
stoped.addEventListener("click", e => {
    sound.stop(); // 再生を終了
});

mute

mute.js
sound.mute(true); // ミュート
sound.mute(false); // ミュート解除

volume

volume.js
sound.play();
sound.volume(0.2); // ボリュームは 0.0 〜 1.0 の間で設定できる

fade

fade.js
sound.play();
sound.fade(1, 0, 5000); // 5秒かけて音量を 1 -> 0 にする

rate

rate.js
sound.play();
sound.rate(2); // 速度を変更する 0.5 〜 4.0 の間で指定する(1だとデフォルトの速度)

seek

seek.js
sound.play();
sound.seek(30); // 再生位置を30秒の部分に移動

state

音声ファイルの読み込み状態を確認できる

state.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ['audio/piano.mp3'],
});
console.log(sound.state()); // loading

sound.once('load', () => {
    console.log(sound.state()); // loaded
    sound.unload();
    console.log(sound.state()); // unloaded
});

duration

duration.js
console.log(sound.duration()); // 0 (まだ読み込んでいないため)
sound.once('load', () => {
    console.log(sound.duration()); // オーディオソースの長さを取得
});

off

off.js
const sound = new Howl({
    src: ['audio/piano.mp3'],
});
sound.on("volume", () => {
    console.log("volume!")
})

button.addEventListener("click", e => {
    sound.play();
    setTimeout(() => sound.volume(0.2), 1000); // イベント実行される
    setTimeout(() => sound.off(), 2000); // 引数なしでoff()と実行すると全てのイベントを削除
    setTimeout(() => sound.volume(0.5), 3000); // イベント実行されない
});

load

デフォルトでload()は読み込み時に行われるが、preload:false とした場合は、自分で呼ぶ必要がある

load.js
const sound = new Howl({
    src: ['audio/piano.mp3'],
    preload: false,
});
sound.on("load", () => {
    console.log("load!") // ↓のクリックの後にこのイベントが実行されることになる
})

button.addEventListener("click", e => {
    sound.load();
    sound.play();
});

unload

unload.js
const sound = new Howl({
    src: ['audio/piano.mp3'],
});

button.addEventListener("click", e => {
    sound.play();
    setTimeout(() => { 
        sound.unload()  // 再生終了される
        console.log(sound.state()) // unloaded
    }, 2000);
});

Options

options.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ["audio/piano.mp3"],
    volume: 0.5, // デフォルト:1 音量 0.0〜1.0
    html5: false, // デフォルト:fasle trueだとHTML5オーディオを強制
    loop: false, // デフォルト:false ループをするかしないか
    preload: true, // デフォルト:true Howlの定義時に自動でファイルを読み込むか
    autoplay: false, // デフォルト:false 自動再生するか
    mute: false, // デフォルト:false ミュートするか
    sprite: {
        hoge: [30000, 5000, true], // sound.play("hoge") とすると開始30秒の位置から5秒間再生する、第3引数はloopするかしないか
    },
    rate: 1.5, // デフォルト:1.0 再生速度 0.5〜4.0
    pool: 5, // デフォルト:5 非アクティブサウンドのプールのサイズ。公式によると、通常これを変更する必要はないとのこと
    format: ['mp3'], // 通常は拡張子からファイル形式を自動的にするが、抽出がうまくいかない状況でも指定することができる
});

Events

オプションで指定する方法

const sound = new Howl({
    src: ["audio/piano.mp3"],
    onload: () => {
        console.log("load!");
    }
});

またはonを使用し、onloadイベントを設定したい場合は"load"を第一引数に渡すと同じように設定できる

const sound = new Howl({
    src: ["audio/piano.mp3"],
});
sound.on("load", () => {
    console.log("load!");
})

イベントが想定通り発生されるか確認してみました

events.js
import { Howl, Howler } from 'howler';

const sound = new Howl({
    src: ["audio/piano.mp3"],
});
sound.on("load", () => console.log("load!"));
sound.on("unlock", () => console.log("unlock!")); // タッチ/クリックイベントによってオーディオが自動的にロック解除されたときに発生
sound.on("play", () => console.log("play!"));
sound.on("end", () => console.log("end!"));
sound.on("pause", () => console.log("pause!"));
sound.on("stop", () => console.log("stop!"));
sound.on("mute", () => console.log("mute!"));
sound.on("volume", () => console.log("volume!"));
sound.on("rate", () => console.log("rate!"));
sound.on("seek", () => console.log("seek!"));
sound.on("fade", () => console.log("fade!"));

button.addEventListener("click", e => {
    sound.play();
    setTimeout(() => sound.pause(), 2000); // pauseイベント発生
    setTimeout(() => sound.play(), 4000); // pauseからの再生後もplayイベント発生
    setTimeout(() => sound.stop(), 6000); // stopイベント発生
    setTimeout(() => sound.play(), 8000);
    setTimeout(() => sound.mute(true), 10000); // muteイベント発生
    setTimeout(() => sound.mute(false), 12000); // muteイベント発生
    setTimeout(() => sound.volume(0.5), 14000); // volumeイベント発生
    setTimeout(() => sound.rate(1.2), 16000); // rateイベント発生
    setTimeout(() => sound.seek(5), 16000); // seekイベント発生
    setTimeout(() => sound.fade(0.5, 1, 1000), 18000); // フェードイン/フェードアウトを終了したときに発生
});

Screen Shot 2019-03-21 at 20.48.34.png

公式によるとエラーイベントも設定できるようです

const sound = new Howl({
    src: ["audio/piano.mp3"],
});
sound.on("loaderror", () => {
    console.log("loaderror!"); // サウンドが読み込めないときに発生
})
sound.on("playerror", () => {
    console.log("playerror!"); // サウンドが再生できないときに発生
})

Global Options

グローバルオプションの一部です、 コメントは全て公式のgoogle翻訳です:bow:

globalOptions.js
import { Howl, Howler } from 'howler';

// Web Audio APIが利用可能な場合はtrue
console.log(Howler.usingWebAudio);

// 利用可能なオーディオがない場合はtrue
console.log(Howler.noAudio);

// モバイル(iOS、Androidなど)デバイスおよびデスクトップのChrome / Safariでオーディオを自動的に有効にしようとします。
console.log(Howler.autoUnlock);

Global Methods

グローバルメソッドの一部で、volumeunloadを試してみました

globalMehtods.js
import { Howl, Howler } from 'howler';

// 全てのボリュームを0.5にする
Howler.volume(0.5);

const sound1 = new Howl({
    src: ['audio/piano.mp3'],
});
const sound2 = new Howl({
    src: ['audio/piano.ogg'],
});

button.addEventListener("click", e => {
    sound1.play();
    sound2.play();
    setTimeout(() => Howler.unload(), 3000); // 全て再生中止する
});

最後まで読んでいただいてありがとうございましたm(_ _)m

50
44
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
50
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?