我正在构建一个简单的应用程序,我试图获取缓冲区,但似乎以下代码中的onaudio进程不会触发:(PasteBin)
<script>
var audio_context;
var recorder;
window.onload = function init() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
window.URL = window.URL || window.webkitURL;
audio_context = new AudioContext;
} catch (e) {
console.log(e);
}
navigator.getUserMedia({audio: true}, startUserMedia);
function startUserMedia(stream) {
console.log('Initializing');
var input = audio_context.createMediaStreamSource(stream);
input.connect(audio_context.destination);
var node = input.context.createGain(4096, 2, 2);
node.onaudioprocess = function(e){
console.log('done');
}
node.connect(audio_context.destination);
}
};
</script>
如果代码能够正常运行,我应该Initiliazing \n done
,问题是我只能获得启动功能并且不会启动onaudioprocess。我使用最新的Chrome:
答案 0 :(得分:8)
onaudioprocess
不是GainNode
的属性,而是ScriptProcessorNode
的属性。请参阅API reference here。
我对Web Audio API并不熟悉,但如果我理解正确,您需要在获取节点和目的地之间插入它以便能够处理这些事件:
var node = input.context.createGain(4096, 2, 2);
var processor = input.context.createScriptProcessor(4096,1,1);
processor.onaudioprocess = function(e){
console.log('done');
}
node.connect(processor);
processor.connect(audio_context.destination);
Example at jsFiddle。正如您所看到的,它正在处理流时将done
打印到控制台,但我可以说这个设置的正确性(因为,正如我所说,经验不多)所以请仔细检查节点之间的连接 - 如有必要,调整第一个参数(缓冲区大小)。
注意:我假设你想要做一些改变流的事情(在你的问题中不清楚)。如果你想要其他东西(例如,只是分析它)但不会改变输入,你可以像以前那样连接节点(node
和destination
)并创建ScriptProcessorNode
有一个输入,但无输出:
var node = input.context.createGain(4096, 2, 2);
node.connect(audio_context.destination);
var processor = input.context.createScriptProcessor(4096,1,0);
processor.onaudioprocess = function(e){
console.log('done');
}
node.connect(processor);
答案 1 :(得分:3)
您还可以绕过WebAudio事件并使用Audio自己的timeupdate
事件。如果您不需要高分辨率事件(例如audioprocess
),它可能适合您的目的。
与audioprocess
相反,timeupdate
仅在音频位置发生变化时触发:当它实际正在播放或您寻找其他位置时。据说它在大约250毫秒内发射一次(因此频率较低,性能更高)。
function startUserMedia(stream) {
stream.ontimeupdate = function () {
console.log(stream.currentTime);
};
/* … */
}
P.S。
在您的示例中,您希望在console.log('done')
处理程序中onaudioprocess
。这让我觉得你误解了事件的目的。它会被连续触发,而不是一旦流完成。