如何停止声音与web音频api

How to stop sound with web audio api?

本文关键字:音频 api web 何停止 声音      更新时间:2023-09-26

我想让下面的代码工作。我用左箭头触发声音,我希望它一直播放,直到我松开键。我在找出每个声音的范围时遇到了一点问题,所以我可以向它发送一个stop或。pause命令。

window.AudioContext = window.AudioContext || window.webkitAudioContext;
function BufferLoader(context, urlList, callback) {
    this.context = context;
    this.urlList = urlList;
    this.onload = callback;
    this.bufferList = new Array();
    this.loadCount = 0;
}
BufferLoader.prototype.loadBuffer = function (url, index) {
    // Load buffer asynchronously
    var request = new XMLHttpRequest();
    request.open("GET", url, true);
    request.responseType = "arraybuffer";
    var loader = this;
    request.onload = function () {
        // Asynchronously decode the audio file data in request.response
        loader.context.decodeAudioData(
        request.response,
        function (buffer) {
            if (!buffer) {
                alert('error decoding file data: ' + url);
                return;
            }
            loader.bufferList[index] = buffer;
            if (++loader.loadCount == loader.urlList.length) loader.onload(loader.bufferList);
        },
        function (error) {
            console.error('decodeAudioData error', error);
        });
    }
    request.onerror = function (e) {
        alert('BufferLoader: XHR error');
        console.log(e);
    }
    request.send();
}
BufferLoader.prototype.load = function () {
    for (var i = 0; i < this.urlList.length; ++i)
    this.loadBuffer(this.urlList[i], i);
}
/// setup audio context and start loading samples
var actx = new AudioContext(),
    blst,
    bLoader = new BufferLoader(
    actx, [
        'http://pappmaskin.no/opensource/drivorgel/sonar1.wav',
        'http://pappmaskin.no/opensource/drivorgel/ping1.wav',
        'http://pappmaskin.no/opensource/drivorgel/sonarloop1.wav'],
    done),
    isReady = false;
/// start loading the samples
bLoader.load();
/// when samples are loaded update status
function done(bl) {
    blst = bl;
    isReady = true;
    $('#status').html('Ready!');
}
/// this sets up chain so we can play audio
function play(i) {
    var src = actx.createBufferSource();
    src.buffer = blst[i];
    src.connect(actx.destination);
    //src.loop = true;
    src.start(0);
    playing = i;
   var output = '';
    for (var property in actx) {
       output += property + ': ' + actx[property]+'; ';
    }
    console.log(output);
}
function stop(i) {
    //src.stop(context.currentTime);
    //src.stop(i);
    console.log("stop " + i);
}
/// check keys
var arrowKeyDown = false;
$('body').keydown(function(e) {
    if (e.which == 37 && !arrowKeyDown) {
        arrowKeyDown = true;
    play(0);
        // ...
    }
});
$('body').keyup(function(e) {
    if (e.which == 37) {
        arrowKeyDown = false;
        stop(0);
    }
});


$(window).bind("keydown", function (key) {
    if (!isReady) return;
    var output = '';
    for (var property in key) {
       output += property + ': ' + key[property]+'; ';
    }
    //console.log(output);
    switch (parseInt(key.which, 10)) {
        case 65:
            play(0);
            break;
        case 83:
            play(1);
            break;
        case 68:
            play(2);
            break;
    }
})
$(window).bind("keyup", function (key) {
    if (!isReady) return;
    switch (parseInt(key.which, 10)) {
        case 65:
            stop(0);
            break;
        case 83:
            stop(1);
            break;
        case 68:
            stop(2);
            break;
    }
})

我从一位同事那里得到了以下解决方案的帮助。恐怕不是很优雅,但很管用。我想要一些关于如何使代码更可重用的输入,它有点乱:

window.AudioContext = window.AudioContext || window.webkitAudioContext;
function BufferLoader(context, urlList, callback) {
    this.context = context;
    this.urlList = urlList;
    this.onload = callback;
    this.bufferList = new Array();
    this.loadCount = 0;
}
BufferLoader.prototype.loadBuffer = function (url, index) {
    // Load buffer asynchronously
    var request = new XMLHttpRequest();
    request.open("GET", url, true);
    request.responseType = "arraybuffer";
    var loader = this;
    request.onload = function () {
        // Asynchronously decode the audio file data in request.response
        loader.context.decodeAudioData(
        request.response,
        function (buffer) {
            if (!buffer) {
                alert('error decoding file data: ' + url);
                return;
            }
            loader.bufferList[index] = buffer;
            if (++loader.loadCount == loader.urlList.length) loader.onload(loader.bufferList);
        },
        function (error) {
            console.error('decodeAudioData error', error);
        });
    }
    request.onerror = function (e) {
        alert('BufferLoader: XHR error');
        console.log(e);
    }
    request.send();
}
BufferLoader.prototype.load = function () {
    for (var i = 0; i < this.urlList.length; ++i)
    this.loadBuffer(this.urlList[i], i);
}
var sources = {
    sonar: [],
    ping: [],
    sonarloop: [],
    wave: []
};
/// setup audio context and start loading samples
var actx = new AudioContext(),
    blst,
    bLoader = new BufferLoader(
    actx, [
        'http://pappmaskin.no/opensource/drivorgel/audio/266653_eelke_waves-beach-nighttime.mp3',
        'http://pappmaskin.no/opensource/drivorgel/ping1.wav',
        'http://pappmaskin.no/opensource/drivorgel/sonarloop1.wav',
        'http://pappmaskin.no/opensource/drivorgel/audio/154881_pawsound_wave.wav'],
    done),
    isReady = false;
/// start loading the samples
bLoader.load();
/// when samples are loaded update status
function done(bl) {
    blst = bl;
    isReady = true;
    $('#status').html('Ready!');
}
/// this sets up chain so we can play audio
function play(i) {
    var src = actx.createBufferSource();
    src.buffer = blst[i];
    src.connect(actx.destination);
    src.loop = true;
    src.start(0);
    playing = i;

   var output = '';
    for (var property in actx) {
       output += property + ': ' + actx[property]+'; ';
    }
    console.log(output);
    return src;
}
function stop(src) {
    //src.stop(context.currentTime);
    //src.stop(i);
    src.stop();
    console.log("stop " + src);
}
/// check keys
var leftarrowKeyDown = false; //37
var rightarrowKeyDown = false; //39
var uparrowKeyDown = false; //38
var downarrowKeyDown = false; //40

$('body').keydown(function(e) {
    if (e.which == 37 && !leftarrowKeyDown) {
        leftarrowKeyDown = true;
    var src = play(0);
    sources.sonar.push(src);
        // ...
    }
});
$('body').keyup(function(e) {
    if (e.which == 37) {
        leftarrowKeyDown = false;
        for (var i = 0; i < sources.sonar.length; i++) {
            var source = sources.sonar[i];
            stop(source);
        }
    }
});
$('body').keydown(function(e) {
    if (e.which == 39 && !rightarrowKeyDown) {
        rightarrowKeyDown = true;
    var src = play(1);
    sources.ping.push(src);
        // ...
    }
});
$('body').keyup(function(e) {
    if (e.which == 39) {
        rightarrowKeyDown = false;
        for (var i = 0; i < sources.ping.length; i++) {
            var source = sources.ping[i];
            stop(source);
        }
    }
});

$('body').keydown(function(e) {
    if (e.which == 38 && !uparrowKeyDown) {
        uparrowKeyDown = true;
    var src = play(2);
    sources.sonarloop.push(src);
        // ...
    }
});
$('body').keyup(function(e) {
    if (e.which == 38) {
        uparrowKeyDown = false;
        for (var i = 0; i < sources.sonarloop.length; i++) {
            var source = sources.sonarloop[i];
            stop(source);
        }
    }
});
$('body').keydown(function(e) {
    if (e.which == 40 && !downarrowKeyDown) {
        downarrowKeyDown = true;
    var src = play(3);
    sources.wave.push(src);
        // ...
    }
});
$('body').keyup(function(e) {
    if (e.which == 40) {
        downarrowKeyDown = false;
        for (var i = 0; i < sources.wave.length; i++) {
            var source = sources.wave[i];
            stop(source);
        }
    }
});

我不确定我理解你错过了什么,但如果我做了,那么我添加的代码应该修复它。

window.AudioContext = window.AudioContext || window.webkitAudioContext;
function BufferLoader(context, urlList, callback) {
    this.context = context;
    this.urlList = urlList;
    this.onload = callback;
    this.bufferList = new Array();
    this.loadCount = 0;
}
BufferLoader.prototype.loadBuffer = function (url, index) {
    // Load buffer asynchronously
    var request = new XMLHttpRequest();
    request.open("GET", url, true);
    request.responseType = "arraybuffer";
    var loader = this;
    request.onload = function () {
        // Asynchronously decode the audio file data in request.response
        loader.context.decodeAudioData(
        request.response,
        function (buffer) {
            if (!buffer) {
                alert('error decoding file data: ' + url);
                return;
            }
            loader.bufferList[index] = buffer;
            if (++loader.loadCount == loader.urlList.length) loader.onload(loader.bufferList);
        },
        function (error) {
            console.error('decodeAudioData error', error);
        });
    }
    request.onerror = function (e) {
        alert('BufferLoader: XHR error');
        console.log(e);
    }
    request.send();
}
BufferLoader.prototype.load = function () {
    for (var i = 0; i < this.urlList.length; ++i)
    this.loadBuffer(this.urlList[i], i);
}
/// setup audio context and start loading samples
var actx = new AudioContext(),
    blst,
    bLoader = new BufferLoader(
    actx, [
        'http://pappmaskin.no/opensource/drivorgel/sonar1.wav',
        'http://pappmaskin.no/opensource/drivorgel/ping1.wav',
        'http://pappmaskin.no/opensource/drivorgel/sonarloop1.wav'],
    done),
    isReady = false;
/// start loading the samples
bLoader.load();
/// when samples are loaded update status
function done(bl) {
    blst = bl;
    isReady = true;
    $('#status').html('Ready!');
}
/// this sets up chain so we can play audio
function play(i) {
    var src = actx.createBufferSource();
    src.buffer = blst[i];
    src.connect(actx.destination);
    //src.loop = true;
    src.start(0);
    playing = i;
   var output = '';
    for (var property in actx) {
       output += property + ': ' + actx[property]+'; ';
    }
    console.log(output);
    return src;
}
function stop(src) {
    if (!src.stop){
        src.stop = src.noteOff;
    }
    src.stop(0);
    console.log("stop " + i);
}
/// check keys
var arrowKeyDown = false;
(function(){
    var bodySource;
    $('body').keydown(function(e) {
    if (e.which == 37 && !arrowKeyDown) {
        arrowKeyDown = true;
        bodySource = play(0);
    }
});
$('body').keyup(function(e) {
    if (e.which == 37) {
        arrowKeyDown = false;
        if(bodySource){
            bodySource = null;
            stop(0);
        }
    }
});
}());

(function(){
    var arrayOfPlayingSounds = [];
    $(window).bind("keydown", function (key) {
        if (!isReady) return;
        var output = '';
        for (var property in key) {
        output += property + ': ' + key[property]+'; ';
        }
        //console.log(output);
        switch (parseInt(key.which, 10)) {
            case 65:
                arrayOfPlayingSounds[0] = play(0);
                break;
            case 83:
                arrayOfPlayingSounds[1] = play(1);
                break;
            case 68:
                arrayOfPlayingSounds[2] = play(2);
                break;
        }
    })
    $(window).bind("keyup", function (key) {
        if (!isReady) return;
        var soundToCheck;
        switch (parseInt(key.which, 10)) {
            case 65:
                soundToCheck = 0;
                break;
            case 83:
                soundToCheck = 1;
                break;
            case 68:
                soundToCheck = 2;
                break;
        }
        if(soundToCheck && arrayOfPlayingSounds[soundToCheck]){
            arrayOfPlayingSounds.splice(soundToCheck,1);
            stop(arrayOfPlayingSounds[soundToCheck]);   
        }
    })
}());