2014-10-19 62 views
1

我正尝试在JavaScript中使用Web Audio API将声音加载到缓冲区并播放它。遗憾的是它不工作,我得到了以下错误:JavaScript Web音频:无法正确解码音频数据?

Uncaught TypeError: Failed to set the 'buffer' property on 'AudioBufferSourceNode': 
The provided value is not of type 'AudioBuffer'. 

我可以指出哪些线是给我的错误,但我不知道为什么。下面是相关的代码,如果有帮助:

var audioContext; 
var playSoundBuffer; 

function init() { 
    window.AudioContext = window.AudioContext || window.webkitAudioContext; 
    audioContext = new AudioContext(); 

    loadNote(); 
} 

function loadNote() { 
    var request = new XMLHttpRequest(); 
    request.open("GET", "./sounds/topE.wav", true); 
    request.responseType = "arraybuffer"; 
    request.onload = function() { 
     audioContext.decodeAudioData(request.response, function(buffer) { 
      playSoundBuffer = buffer; 
     }, function(error) { 
      console.error("decodeAudioData error", error); 
     }); 
    }; 
    request.send(); 

    playSound(); 
} 

function playSound() { 
    var source = audioContext.createBufferSource(); 
    source.buffer = playSoundBuffer;  // This is the line that generates the error 
    source.connect(audioContext.destination); 
    source.start(0); 
} 

相信decodeAudioData方法返回一个AudioBuffer其第一个回调函数(第二个参数)。我试图将这个AudioBuffer保存到“playSoundBuffer”然后播放它,但是我得到了这个错误,我不知道为什么。任何帮助将不胜感激。

回答

6

您得到该错误的原因是因为您忽略了代码的异步性质,并将它看作是同步的。如果您始终记录所有相关部分的内容作为调试的第一步,则您会意识到在您尝试处理缓冲区时,它是undefined而不是AudioBuffer。提示:总是console.log 所有东西,直到你确切地知道它在任何点的行为如何。

function loadNote() { 
    var request = new XMLHttpRequest(); 
    request.open("GET", "./sounds/topE.wav", true); 
    request.responseType = "arraybuffer"; 
    request.onload = function() { 
     audioContext.decodeAudioData(request.response, function(buffer) { 
      playSoundBuffer = buffer; 
      playSound(); // don't start processing it before the response is there! 
     }, function(error) { 
      console.error("decodeAudioData error", error); 
     }); 
    }; 
    request.send();//start doing something async 


} 
+1

非常感谢您的回复!您建议的编辑使声音播放正常。不幸的是我不太了解异步函数是如何工作的。 playSound()方法是否与decodeAudioData方法同时执行?那是什么造成了错误?再次感谢你的帮助! – hashahid 2014-10-19 07:36:17

+2

这里是一个文章https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests在你的情况下,你实际上在'decodeAudioData'方法之前执行了'playSound()'方法,基本上在您发送请求(即异步)之后,在请求到达之前,以及在您开始对其进行解码之前(这也是异步) – Winchestro 2014-10-19 07:48:52