我正在尝试使用Web Audio API即时(非实时)从从 URL 加载的声音中提取振幅信息,这可能需要OfflineAudioContext
. 我期望沿着包含声音t
持续时间每秒的声音幅度的数组的线获得一些东西(大小取决于声音的持续时间,除以t
)。不幸的是,此时文档很少,我不确定如何继续。如何加载声音并每秒钟提取一次幅度t
?
问问题
543 次
1 回答
2
这完成得非常快,所以数学可能会搞砸。但希望它能让你开始......
var ac = new webkitAudioContext(),
url = 'path/to/audio.mp3';
function fetchAudio( url, callback ) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
callback(xhr.response);
};
xhr.send();
}
function decode( arrayBuffer, callback ) {
ac.decodeAudioData(arrayBuffer, function( audioBuffer ) {
callback(audioBuffer);
});
}
// return an array of amplitudes for the supplied `audioBuffer`
//
// each item in the array will represent the average amplitude (in dB)
// for a chunk of audio `t` seconds long
function slice( audioBuffer, t ) {
var channels = audioBuffer.numberOfChannels,
sampleRate = ac.sampleRate,
len = audioBuffer.length,
samples = sampleRate * t,
output = [],
amplitude,
values,
i = 0,
j, k;
// loop by chunks of `t` seconds
for ( ; i < len; i += samples ) {
values = [];
// loop through each sample in the chunk
for ( j = 0; j < samples && j + i < len; ++j ) {
amplitude = 0;
// sum the samples across all channels
for ( k = 0; k < channels; ++k ) {
amplitude += audioBuffer.getChannelData(k)[i + j];
}
values.push(amplitude);
}
output.push(dB(values));
}
return output;
}
// calculate the average amplitude (in dB) for an array of samples
function dB( buffer ) {
var len = buffer.length,
total = 0,
i = 0,
rms,
db;
while ( i < len ) {
total += ( buffer[i] * buffer[i++] );
}
rms = Math.sqrt( total / len );
db = 20 * ( Math.log(rms) / Math.LN10 );
return db;
}
// fetch the audio, decode it, and log an array of average
// amplitudes for each 5-second chunk
fetchAudio(url, function( arrayBuffer ) {
decode(arrayBuffer, function( audioBuffer ) {
console.log(slice(audioBuffer, 5));
});
});
基本上,如果你想比实时更快地获取整个缓冲区的数据,你甚至不需要OfflineAudioContext
. 您可以阅读示例,做一些数学运算,然后弄清楚。
不过,这很慢。特别是对于较大的音频文件。所以你可能想把它放在一个 Web Worker 中。
使用 anOfflineAudioContext
可能会更快。我真的不确定。但即使你决定走那条路,你仍然需要做很多手动工作才能获得这些任意t
秒数的幅度。
于 2014-03-27T02:46:58.740 回答