Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading an Audio buffer and play it using the audio tag

I am trying to load an audio buffer from an URL, and then to play it. I got most of the code form this HTML5 Rocks Tutorial.

var request = new XMLHttpRequest();
request.open('GET', $(this).attr('data-url'), true);
request.responseType = 'arraybuffer';

request.onload = function() {
    console.log(request);
    context.decodeAudioData(request.response, function(buffer) {
        console.log(buffer);
        $('#play').click(function() {
              var source = context.createBufferSource();
              source.connect(context.destination);
              source.noteOn(0);
        }).removeAttr('disabled');
    }, function(err) { console.log(err); });
};
request.send();

However, then I press the #play button, nothing happens. source.noteOn(0) is called, I checked it using the debugger. And all of the objects are properly loaded and created, but I hear no sound.

Also, as it seems, I would need to rebuild a complete player with all controls when I am using this approach. What I'd like to do, to save work and to ensure this works better, is to put the buffer into an <audio/>, so it can be played there.

I know there is audio.src for putting the file name in there, but I need to use the audio buffer. I've tried

audio.src = buffer;
audio.load()

But that did not work.

Any info there?

like image 488
Lanbo Avatar asked Feb 16 '13 09:02

Lanbo


1 Answers

To answer the real question not with a "just don't use the audio element", I'd like to provide another solution. I've wanted to show the user the audio controls, thus I needed a solution for the question asked.

Actually you just need to convert the ArrayBuffer to a Blob, get an URL for it and map this to the <audio> element's src attribute:

const blob = new Blob([arrayBuffer], { type: "audio/wav" });
const url = window.URL.createObjectURL(blob);
audioElement.src = url;

Please don't forget to change the mime type accordingly and don't forget to call

window.URL.revokeObjectURL(url);

when unloading your page/component for garbage collection.

like image 197
sibbl Avatar answered Nov 15 '22 16:11

sibbl