我正在使用OfflineAudioContext在后台进行波形分析。
一切在Chrome,Firefox和Opera中运行良好,但在Safari中我的行为非常狡猾。 波形应该由许多样本组成(329),但在Safari中样本只有~38。
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.OfflineAudioContext = window.OfflineAudioContext ||
window.webkitOfflineAudioContext;
const sharedAudioContext = new AudioContext();
const audioURL = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/1141585/song.mp3';
const audioDidLoad = ( buffer ) =>
{
console.log("audio decoded");
var samplesCount = 0;
const context = new OfflineAudioContext(1, buffer.length, 44100);
const source = context.createBufferSource();
const processor = context.createScriptProcessor(2048, 1, 1);
const analyser = context.createAnalyser();
analyser.fftSize = 2048;
analyser.smoothingTimeConstant = 0.25;
source.buffer = buffer;
source.connect(analyser);
analyser.connect(processor);
processor.connect(context.destination);
var freqData = new Uint8Array(analyser.frequencyBinCount);
processor.onaudioprocess = () =>
{
analyser.getByteFrequencyData(freqData);
samplesCount++;
};
source.start(0);
context.startRendering();
context.oncomplete = (e) => {
document.getElementById('result').innerHTML = 'Read ' + samplesCount + ' samples';
source.disconnect( analyser );
processor.disconnect( context.destination );
};
};
var request = new XMLHttpRequest();
request.open('GET', audioURL, true);
request.responseType = 'arraybuffer';
request.onload = () => {
var audioData = request.response;
sharedAudioContext.decodeAudioData(
audioData,
audioDidLoad,
e => { console.log("Error with decoding audio data" + e.err); }
);
};
request.send();
请参阅Codepen。
答案 0 :(得分:2)
我想在这里,Safari有正确的行为,而不是其他行为。 onaudioprocess 的工作原理如下:你给出一个缓冲区大小(创建 scriptProcessor 时的第一个参数,这里是2048个样本),每次处理这个缓冲区时,该事件将被触发。因此,您采用采样率(默认为44.1 kHz,意味着每秒44100采样),然后除以缓冲区大小,即每次处理的样本数,并获得每秒的时间数将触发audioprocess事件。见https://webaudio.github.io/web-audio-api/#OfflineAudioContext-methods
此值控制onaudioprocess事件的频率 调度以及每次调用需要处理多少个样本帧。
当你实际播放声音时,这是真的。你需要在适当的时间内取适量,以便正确播放声音。但是,offlineAudioContext处理音频而不关心实际播放时间。
它不会呈现给音频硬件,而是呈现为 尽可能快地完成返回的承诺 结果作为AudioBuffer
因此,使用OfflineAudioContext,无需进行时间计算。 Chrome和其他人似乎每次处理缓冲区时都会触发onaudioprocess,但是对于离线音频上下文,它确实不是必需的。
话虽如此,通常也不需要将 onaudioprocess 与 offlineAudioContext 一起使用,除非要了解性能。所有数据均可从上下文中获得。而且,329个样本并不意味着很多,它基本上只是样本数除以缓冲区大小。在您的示例中,您有673830个样本的来源,每秒44100个样本。所以你的音频是15,279秒。如果您一次处理2048个样本,则处理的音频大约为329次,这是您使用Chrome获得的329。无需使用 onaudioprocess 来获取此号码。
由于您使用离线音频上下文,因此无需实时处理这些样本,甚至无需在每个2048个样本中调用 onaudioprocess 。