Using Web Audio API to assign two sounds to two Divs and play each independently via a click event with javascript

放肆的年华 提交于 2019-12-08 12:33:24

问题


I have been picking away at the code linked in the url below and I haven't been able to get anywhere. I have only managed to reassign the event handler to a small div instead of the whole page. I can't figure out how to tweak this to load more than one sound.

http://www.f1lt3r.com/w3caudio/web-audio-api/basic-examples/low-latency-playback-user-input.html

With the code example below I haven't been able to trigger a sound via a click of a div at all. However this code seems nicer to look at so I would really like to modify this for learning purposes.

   var context = new webkitAudioContext(),
        buffer;

    var playAudioFile = function (buffer) {
        var source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        source.noteOn(0); // Play sound immediately
    };

    var loadAudioFile = (function (url) {
        var request = new XMLHttpRequest();

        request.open('get', 'A.mp3', true);
        request.responseType = 'arraybuffer';

        request.onload = function () {
                context.decodeAudioData(request.response,
                     function(incomingBuffer) {
                         playAudioFile(incomingBuffer);
                     }
                );
        };

        request.send();
    }());





// I added this & it doesn't work



var divElement = document.getElementById("divElement");

divElement.addEventListener("click", playAudioFile , false);


// END of code I added

I understand how to create oscillators and connect filter/gain and other nodes. Thus far that is my point of reference when using the API. The XMLHttpRequest processess coupled withe the buffer creation is confusing. I understand what a buffer is and I understand what XMLHttprequest is, but for some reason the process around loading an audio file for playback doesn't seem clear to me, let alone loading more than one which is what I ultimately want to do. I've tried to read the HTML-5 rocks tutorials as well but without working C&P code that I can tweak I can never tell if I'm on the right track. BTW I don't want to use abstracted libraries. I want to learn the API from the ground up. Thanks


回答1:


First off, you're executing playAudioFile when you click the div. playAudioFile needs a buffer as an argument, or else it won't be able to do what it's supposed to. However, there is no buffer passed when you click the div, the playAudioFile function is executed without a buffer (and is given an event object as an argument instead, but that's not important), and thus no sound.

What you probably want to do is to assign loadAudioFile instead when you click the div. At the moment loadAudioFile is written to execute as the page loads (which is what happens when you wrap your function in parantheses). So I'd update the loadAudioFile function to look like this:

var loadAudioFile = function () {
    var request = new XMLHttpRequest();

    request.open('get', 'A.mp3', true);
    request.responseType = 'arraybuffer';

    request.onload = function () {
            context.decodeAudioData(request.response,
                 function(incomingBuffer) {
                     //HERE is where the playAudioFile function is called, with a buffer to play
                     playAudioFile(incomingBuffer);
                 }
            );
    };

    request.send();
};

And then

divElement.addEventListener("click", loadAudioFile , false);

Now, this makes the app load the mp3 each time you click the div. It could be optimised a lot by just loading it once and saving the buffer for later.

var context = new webkitAudioContext(),
    savedBuffer;

var playAudioFile = function () {
    var source = context.createBufferSource();
    source.buffer = savedBuffer;
    source.connect(context.destination);
    source.noteOn(0); // Play sound immediately
};

var request = new XMLHttpRequest();

request.open('get', 'A.mp3', true);
request.responseType = 'arraybuffer';

request.onload = function () {
        context.decodeAudioData(request.response,
             function(incomingBuffer) {
                 //save the buffer, we'll reuse it
                 savedBuffer = incomingBuffer;
                 //once the file has been loaded, we can start listening for click on the div, and use playAudioFile since it no longer requires a buffer to be passed to it
                 var divElement = document.getElementById("divElement");
                 divElement.addEventListener("click", playAudioFile , false);
             }
        );
};

request.send();


来源:https://stackoverflow.com/questions/13106769/using-web-audio-api-to-assign-two-sounds-to-two-divs-and-play-each-independently

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!