问题
I've searched related questions but wasn't able to find any relevant info.
I'm trying to get the Web Audio API to play an mp3 file which is encoded in another file container, so what I'm doing so far is parsing said container, and feeding the result binary data (arraybuffer) to the audioContext.decodeAudioData method, which supposedly accepts any kind of arraybuffer containing audio data. However, it always throws the error callback.
I only have a faint grasp of what I'm doing so probably the whole approach is wrong. Or maybe it's just not possible.
Has any of you tried something like this before? Any help is appreciated!
Here's some of the code to try to illustrate this better. The following just stores the arraybuffer:
newFile: function(filename){
var that=this;
var oReq = new XMLHttpRequest();
oReq.open("GET", filename, true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; //
if (arrayBuffer) {
that.arrayBuffer=arrayBuffer;
that.parsed=true;
}
};
oReq.send(null);
And this is what I'm doing in the decoding part:
newTrack: function(tracknumber){
var that=this;
var arraybuffer=Parser.arrayBuffer;
that.audioContext.decodeAudioData(arraybuffer,function(buffer){
var track={};
track.trackBuffer=buffer;
track.isLoaded=true;
track.trackSource=null;
track.gainNode=that.audioContext.createGainNode();
that.tracklist.push(track);
},alert('error'));
Where Parser is an object literal that I've used to parse and store the arraybuffer (which has the newFile function)
So, to sum up, I don't know if I'm doing something wrong or it simply cannot be done.
回答1:
Without the container, I'm not sure how decodeAudioData
would know that it's an MP3. Or what the bitrate is. Or how many channels it has. Or a lot of other pretty important information. Basically, you need to tell decodeAudioData
how to interpret that ArrayBuffer.
The only thing I could think of on the client side is trying to use a Blob. You'd basically have to write the header yourself, and then readAsArrayBuffer
before passing it in to decodeAudioData
.
If you're interested in trying that out, here's a spec: http://www.mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm
And here's RecorderJS, which would show you how to create the Blob (although it writes RIFF/WAV headers instead of MP3):
https://github.com/mattdiamond/Recorderjs/blob/master/recorderWorker.js
You'd want to look at the encodeWAV
method.
Anyway, I would strongly recommend getting this sorted out on the server instead, if you can.
来源:https://stackoverflow.com/questions/17953259/using-web-audio-api-decodeaudiodata-with-external-binary-data