解码音频数据 HTML5 音频 API

23

我希望能够从ArrayBuffer中播放音频数据......因此我生成了我的数组并用麦克风输入填充它。 如果我在画布上绘制这些数据,它看起来像 --> enter image description here

所以这个方法可行!

但是如果我想要收听这些数据,则:

context.decodeAudioData(tmp, function(bufferN) { //tmp is a arrayBuffer
    var out = context.createBufferSource();
    out.buffer = bufferN;
    out.connect(context.destination);
    out.noteOn(0);
}, errorFunction);

我什么都听不到...因为调用了errorFunction。但是错误为空!

我也尝试这样获取缓冲区:

var soundBuffer = context.createBuffer(myArrayBuffer, true/*make mono*/);
But i get the error: Uncaught SyntaxError: An invalid or illegal string was specified.
anybody who can give me a hint ?
EDIT 1 (More code and how I get the mic input):
 navigator.webkitGetUserMedia({audio: true}, function(stream) {

                liveSource = context.createMediaStreamSource(stream);

                // create a ScriptProcessorNode
                if(!context.createScriptProcessor){
                   node = context.createJavaScriptNode(2048, 1, 1);
                } else {
                   node = context.createScriptProcessor(2048, 1, 1);
                }


                node.onaudioprocess = function(e){

               var tmp = new Uint8Array(e.inputBuffer.byteLength);
               tmp.set(new      Uint8Array(e.inputBuffer.byteLength), 0);

   //Here comes the code from above.

谢谢你的帮助!


2
使用Web Audio API和外部二进制数据的DecodeAudioData? (注:该内容已被翻译成中文) - Tasos Bitsios
3
我认为这个链接很有帮助 - https://dev59.com/FWkv5IYBdhLWcg3wwjkI - Neha
当我访问您的链接时,我可以听到自己的声音,并且它会产生一个不错的反馈环。也许这是特定于您的设置?(我使用的是Chrome浏览器) - Pinpickle
是的,链接中的示例可以工作,因为我使用了直接媒体对象而不是我的生成缓冲区。 "不工作" 的代码也在 index.html 中,但作为注释存在。该链接展示了它应该看起来/听起来的样子。(我也使用 Chrome) - Cracker0dks
2
回调函数返回的错误是null,因为在当前的WebAudio API规范中,该函数不返回错误对象。请查看http://www.w3.org/TR/webaudio/#AudioContext-section中的“callback DecodeErrorCallback = void();”。 - vzamanillo
显示剩余6条评论
3个回答

6

回调函数返回的错误是null,因为在当前的webaudio api spec中,该函数不返回错误对象

callback DecodeSuccessCallback = void (AudioBuffer decodedData);
callback DecodeErrorCallback = void ();

    void decodeAudioData(ArrayBuffer audioData,
                         DecodeSuccessCallback successCallback,
                         optional DecodeErrorCallback errorCallback);

当完整的输入ArrayBuffer被解码并存储为AudioBuffer时,如果decodeAudioData无法解码实时流,则会引发DecodeSuccessCallback。

在处理音频时,您可以尝试设置输出缓冲区数据以播放捕获的缓冲区。

function connectAudioInToSpeakers(){

  //var context = new webkitAudioContext();  
  navigator.webkitGetUserMedia({audio: true}, function(stream) {

    var context = new webkitAudioContext();  
    liveSource = context.createMediaStreamSource(stream);

    // create a ScriptProcessorNode
    if(!context.createScriptProcessor){
       node = context.createJavaScriptNode(2048, 1, 1);
    } else {
       node = context.createScriptProcessor(2048, 1, 1);
    }


    node.onaudioprocess = function(e){

        try{
            ctx.clearRect(0, 0, document.getElementById("myCanvas").width, document.getElementById("myCanvas").height);
            document.getElementById("myCanvas").width = document.getElementById("myCanvas").width;
            ctx.fillStyle="#FF0000";

            var input = e.inputBuffer.getChannelData(0);
            var output = e.outputBuffer.getChannelData(0);
            for(var i in input) {
                output[i] = input[i];
                ctx.fillRect(i/4,input[i]*500+200,1,1);
            }


        }catch (e){
            console.log('node.onaudioprocess',e.message);
        }

    }

     // connect the ScriptProcessorNode with the input audio
    liveSource.connect(node);
    // if the ScriptProcessorNode is not connected to an output the "onaudioprocess" event is not triggered in chrome
    node.connect(context.destination);

    //Geb mic eingang auf boxen
    //liveSource.connect(context.destination);
  });
}

1

过了一会儿,我又尝试解决这个问题,并找到了一个解决方案:

https://developer.mozilla.org/en-US/docs/Web/API/ScriptProcessorNode

这并不复杂,所以我创建了一个可工作的fiddle:

https://jsfiddle.net/WEM3y/

请激活您的麦克风(已在Chrome v35上测试),然后进行检查。

我更改的部分:

node.onaudioprocess = function(e){

    var outData = e.outputBuffer.getChannelData(0);
    var inData = e.inputBuffer.getChannelData(0);

    // Loop through the 4096 samples, copy them to output buffer
    for (var sample = 0; sample < e.outputBuffer.length; sample++) {
      // Set the data in the output buffer for each sample
      outData[sample] = inData[sample]; //Modify your buffer here if you want
    }
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接