var buffer = (new Response(data)).arrayBuffer();//二进制缓存区内容
buffer.then(function(buf){
var audioContext = new ( window.AudioContext || window.webkitAudioContext )();
var fileResult =addWavHeader(buf, '8000', '16', '1');//解析数据转码wav
audioContext.decodeAudioData(fileResult, function(buffer) {
_visualize(audioContext,buffer);//播放
});
//处理音频流,转码wav
var addWavHeader = function(samples,sampleRateTmp,sampleBits,channelCount){
var dataLength = samples.byteLength;
var buffer = new ArrayBuffer(44 + dataLength);
var view = new DataView(buffer);
function writeString(view, offset, string){
for (var i = 0; i < string.length; i++){
view.setUint8(offset + i, string.charCodeAt(i));
}
}
var offset = 0;
/* 资源交换文件标识符 */
writeString(view, offset, 'RIFF'); offset += 4;
/* 下个地址开始到文件尾总字节数,即文件大小-8 */
view.setUint32(offset, /*32*/ 36 + dataLength, true); offset += 4;
/* WAV文件标志 */
writeString(view, offset, 'WAVE'); offset += 4;
/* 波形格式标志 */
writeString(view, offset, 'fmt '); offset += 4;
/* 过滤字节,一般为 0x10 = 16 */
view.setUint32(offset, 16, true); offset += 4;
/* 格式类别 (PCM形式采样数据) */
view.setUint16(offset, 1, true); offset += 2;
/* 通道数 */
view.setUint16(offset, channelCount, true); offset += 2;
/* 采样率,每秒样本数,表示每个通道的播放速度 */
view.setUint32(offset, sampleRateTmp, true); offset += 4;
/* 波形数据传输率 (每秒平均字节数) 通道数×每秒数据位数×每样本数据位/8 */
view.setUint32(offset, sampleRateTmp * channelCount * (sampleBits / 8), true); offset +=4;
/* 快数据调整数 采样一次占用字节数 通道数×每样本的数据位数/8 */
view.setUint16(offset, channelCount * (sampleBits / 8), true); offset += 2;
/* 每样本数据位数 */
view.setUint16(offset, sampleBits, true); offset += 2;
/* 数据标识符 */
writeString(view, offset, 'data'); offset += 4;
/* 采样数据总数,即数据总大小-44 */
view.setUint32(offset, dataLength, true); offset += 4;
function floatTo32BitPCM(output, offset, input){
input = new Int32Array(input);
for (var i = 0; i < input.length; i++, offset+=4){
output.setInt32(offset,input[i],true);
}
}
function floatTo16BitPCM(output, offset, input){
input = new Int16Array(input);
for (var i = 0; i < input.length; i++, offset+=2){
output.setInt16(offset,input[i],true);
}
}
function floatTo8BitPCM(output, offset, input){
input = new Int8Array(input);
for (var i = 0; i < input.length; i++, offset++){
output.setInt8(offset,input[i],true);
}
}
if(sampleBits == 16){
floatTo16BitPCM(view, 44, samples);
}else if(sampleBits == 8){
floatTo8BitPCM(view, 44, samples);
}else{
floatTo32BitPCM(view, 44, samples);
}
return view.buffer;
}
//播放音频
var _visualize = function(audioContext, buffer) {
var audioBufferSouceNode = audioContext.createBufferSource(),
analyser = audioContext.createAnalyser(),
that = this;
//将信号源连接到分析仪
audioBufferSouceNode.connect(analyser);
//将分析仪连接到目的地(扬声器),否则我们将听不到声音
analyser.connect(audioContext.destination);
//然后将缓冲区分配给缓冲区源节点
audioBufferSouceNode.buffer = buffer;
//发挥作用
if (!audioBufferSouceNode.start) {
audioBufferSouceNode.start = audioBufferSouceNode.noteOn //在旧浏览器中使用noteOn方法
audioBufferSouceNode.stop = audioBufferSouceNode.noteOff //在旧浏览器中使用noteOff方法
};
//如果有的话,停止前一个声音
if (this.animationId !== null) {
cancelAnimationFrame(this.animationId);
}
audioBufferSouceNode.start(0);
audo.source = audioBufferSouceNode;
audo.audioContext = audioContext;
}
网友回复