LoginSignup
2
3

More than 5 years have passed since last update.

JavaScriptで音声再生完了タイミングを取得したい。

Last updated at Posted at 2017-07-23

音声を流し終えてから、指定時間後に別の音声を流したいと思ったので
WebAudioAPIで試してみる。

HTML部分

とりあえず、ボタンを用意。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="test.js"></script>
</head>
<body>
    <button id="btn" disabled>Start</button>
</body>
</html>

JavaScript部分

window.AudioContext = window.AudioContext || window.webkitAudioContext; 
context = new AudioContext();

var schedule = [
    {"time":0, "file":"1.wav"},
    {"time":5, "file":"2.wav"}
];
var plans = []
var getAudioBuffer = function(schedule, index){
    if(index >= schedule.length){
        document.getElementById('btn').disabled = false;
        return;
    }
    plans[index] = {
        "time":schedule[index]["time"],
        "buffer":null
    };
    var req = new XMLHttpRequest();
    req.open('GET', schedule[index]["file"], true);
    req.responseType = 'arraybuffer';        
    req.onreadystatechange = function(){
        if(req.readyState === 4){
            if(req.status === 0 || req.status === 200){
                context.decodeAudioData(req.response, function(buffer){
                    plans[index]["buffer"] = buffer;
                });
                getAudioBuffer(schedule, index+1);
            }
        }
    };
    req.send('')
};

var planid = 0;
var playSound = function(){
    var source = context.createBufferSource();
    source.buffer = plans[planid]["buffer"];
    source.onended = function(){
        planid++;
        if(planid < plans.length){
            setTimeout(playSound, plans[planid]["time"]*1000);
        }
    };
    source.connect(context.destination);
    source.start(0);
}

window.onload = function(){
    getAudioBuffer(schedule, 0);
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        planid = 0;
        playSound();
    }
}

とりあえず動かしたかったので
変数がグローバル多い、これはちゃんと作る時は直そう。
エラー制御とか諸々の制御もてきとうになっている。

getAudioBuffer

再生用の音声データをXMLHttpRequestで取ってきてバッファ持っておく。
最初、複数並列に投げようとして最後の1つしか受け取れなかったので
一つずつ、終わったら次の取得をする形にして対応。
全部の読み込みが終わったら再生ボタンを有効にする。

playSound

再生の完了を取得して次の音声流したいので
onendedイベントハンドラに終了を受け取って次の再生を行う処理を追加。
次に再生する音声が再生終了後に何秒後に流すのか持っておいて
setTimeoutで指定秒数後に再生。

参考
Web Audio API で音を再生しよう | phiary

2
3
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
2
3