好的,所以我试图确定用户浏览器记录的音频文件样本的强度(以dB为单位)。
我已经能够记录下来并通过HTML元素播放它。 但是,当我尝试将此元素用作源并将其连接到AnalyserNode时,AnalyserNode.getFloatFrequencyData总是返回一个充满-Infinity的数组,getByteFrequencyData总是返回零,getByteTimeDomainData则充满128。
这是我的代码:
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var source;
var analyser = audioCtx.createAnalyser();
var bufferLength = analyser.frequencyBinCount;
var data = new Float32Array(bufferLength);
mediaRecorder.onstop = function(e) {
var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
chunks = [];
var audioURL = window.URL.createObjectURL(blob);
// audio is an HTML audio element
audio.src = audioURL;
audio.addEventListener("canplaythrough", function() {
source = audioCtx.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioCtx.destination);
analyser.getFloatFrequencyData(data);
console.log(data);
});
}
有人知道为什么AnalyserNode表现得像源是空/静音吗?我还尝试在录制时将流作为源,结果相同。
答案 0 :(得分:0)
源文件是否来自其他域?那将在createMediaElementSource中失败。
答案 1 :(得分:0)
您需要获取音频文件并解码音频缓冲区。 音频源的URL也必须位于相同的域上,或者也具有正确的CORS标头(如Anthony所述)。
注意:在下面的示例中,将<FILE-URI>
替换为文件的路径。
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var source;
var analyser = audioCtx.createAnalyser();
var button = document.querySelector('button');
var freqs;
var times;
button.addEventListener('click', (e) => {
fetch("<FILE-URI>", {
headers: new Headers({
"Content-Type" : "audio/mpeg"
})
}).then(function(response){
return response.arrayBuffer()
}).then((ab) => {
audioCtx.decodeAudioData(ab, (buffer) => {
source = audioCtx.createBufferSource();
source.connect(audioCtx.destination)
source.connect(analyser);
source.buffer = buffer;
source.start(0);
viewBufferData();
});
});
});
// Watch the changes in the audio buffer
function viewBufferData() {
setInterval(function(){
freqs = new Uint8Array(analyser.frequencyBinCount);
times = new Uint8Array(analyser.frequencyBinCount);
analyser.smoothingTimeConstant = 0.8;
analyser.fftSize = 2048;
analyser.getByteFrequencyData(freqs);
analyser.getByteTimeDomainData(times);
console.log(freqs)
console.log(times)
}, 1000)
}
答案 2 :(得分:0)
由于您的一些代码片段,我遇到了同样的问题,使它可以正常工作(下面的代码是打字稿,撰写本文时在浏览器中不起作用):
audioCtx.decodeAudioData(this.result as ArrayBuffer).then(function (buffer: AudioBuffer) {
soundSource = audioCtx.createBufferSource();
soundSource.buffer = buffer;
//soundSource.connect(audioCtx.destination); //I do not need to play the sound
soundSource.connect(analyser);
soundSource.start(0);
setInterval(() => {
calc(); //In here, I will get the analyzed data with analyser.getFloatFrequencyData
}, 300); //This can be changed to 0.
// The interval helps with making sure the buffer has the data
一些解释(关于Web Audio API,我仍然是一个初学者,所以我的解释可能是错误的或不完整的):
分析人员需要能够分析声音文件的特定部分。在这种情况下,我创建一个AudioBufferSoundNode
,其中包含从解码音频数据中获得的缓冲区。我将缓冲区提供给源,最终可以将其复制到分析器中。但是,如果没有时间间隔回调,缓冲区似乎永远不会准备好,并且分析的数据在数组的每个索引处都包含-Inifinity
(我认为是没有任何声音,因为没有声音可读取)。这就是为什么存在间隔的原因。每300毫秒分析一次数据。
希望这对某人有帮助!