我正在尝试使用HTML5 Web Audio API创建均衡器类型的图形,但是由于某些原因,数据从未带入MediaElementSource
中。
$('.table').on('click', 'tr', function() {
if ($(this) != $('.table tr:first-child')) {
var src = $(this).children().first().attr('data-src');
var audio = new Audio();
audio.src = src;
audio.controls = true;
$('.file-playlist').append(audio);
console.log(audio);
audio.load();
audio.play();
context = new webkitAudioContext();
console.log(context);
analyser = context.createAnalyser();
console.log(analyser);
source = context.createMediaElementSource(audio);
console.log(source);
source.connect(analyser);
console.log(source);
analyser.connect(context.destination);
console.log(analyser);
rafCallback();
}
});
在上面的函数中,我创建了一个audio元素并将其用作上下文的
MediaElementSource
的源,但是我找不到一些问题,因为在控制台中,AudioContext的activeSourceCount
属性始终为0,这意味着它从未收到我给它作为参数的音频元素。编辑:
我根据idbehold所说的修改了我的代码;但是,现在我有2个错误,
InvalidStateError: DOM Exception 11
行上的source = context.createMediaElementSource(audio);
和TypeError: Cannot read property 'frequencyBinCount' of undefined
行上的var freqByteData = new Uint8Array(analyser.frequencyBinCount);
。此外,MediaElementSource仍然具有0 activeSourceCounts。$(document).ready(function() {
var context = new webkitAudioContext();
console.log(context);
var audio;
var source;
$('.table').on('click', 'tr', function() {
if ($(this) != $('.table tr:first-child')) {
var src = $(this).children().first().attr('data-src');
if (audio) {
audio.remove();
audio = new Audio();
audio.src = src;
audio.controls = true;
$('.file-playlist').append(audio);
console.log(audio);
audio.addEventListener("canplay", function(e) {
analyser = context.createAnalyser();
console.log(analyser);
source.disconnect();
source = context.createMediaElementSource(audio);
console.log(source);
source.connect(analyser);
console.log(source);
analyser.connect(context.destination);
console.log(analyser);
audio.load();
audio.play();
}, false);
}
else {
audio = new Audio();
audio.src = src;
audio.controls = true;
$('.file-playlist').append(audio);
console.log(audio);
audio.addEventListener("canplay", function(e) {
analyser = (analyser || context.createAnalyser());
console.log(analyser);
source = context.createMediaElementSource(audio);
console.log(source);
source.connect(analyser);
console.log(source);
analyser.connect(context.destination);
console.log(analyser);
audio.load();
audio.play();
}, false);
}
}
rafCallback();
});
});
编辑2:
在我的rafCallback()函数中,我注意到从未处理过Uint8Array的数据,因此我添加了
getByteFrequencyData(analyser.frequencyBinCount);
来修复所有问题。 最佳答案
您只能在每个窗口中创建一个AudioContext
,并且应该等到音频的canplay
事件触发后再设置MediaElementSource
。使用完后,还应该断开MediaElementSource
的连接。
这是我用来回答类似问题的示例:http://jsbin.com/acolet/1/