html5 record 修改采样率导致声音无法播放解决方案

最近项目中用到web录音,但是录音的采样率需要设置为8000,而不是默认的44100.但是修改samplerate后,发现录音不能正常播放,播放出来的是噪音。在stackOverFlow上搜到解决方案如下:

function downsampleBuffer(buffer, rate) {
    if (rate == sampleRate) {
        return buffer;
    }
    if (rate > sampleRate) {
        throw "downsampling rate show be smaller than original sample rate";
    }
    var sampleRateRatio = sampleRate / rate;
    var newLength = Math.round(buffer.length / sampleRateRatio);
    var result = new Float32Array(newLength);
    var offsetResult = 0;
    var offsetBuffer = 0;
    while (offsetResult < result.length) {
        var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
        var accum = 0, count = 0;
        for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
            accum += buffer[i];
            count++;
        }
        result[offsetResult] = accum / count;
        offsetResult++;
        offsetBuffer = nextOffsetBuffer;
    }
    return result;
}
function exportWAV(rate, type) {
    var bufferL = mergeBuffers(recBuffersL, recLength);
    var bufferR = mergeBuffers(recBuffersR, recLength);
    var interleaved = interleave(bufferL, bufferR);
    var downsampledBuffer = downsampleBuffer(interleaved, rate);
    var dataview = encodeWAV(rate, downsampledBuffer, false);
    var audioBlob = new Blob([ dataview ], {
        type : type
    });

    this.postMessage(audioBlob);
}

原文链接:stackoverflow

发现集成到项目里面并不能完美的解决问题,找了很多资料发现一篇好的博文:html5 录音

读懂里面的细节后发现,downsampleBuffer(buffer, rate)函数中的
var sampleRateRatio = sampleRate / rate;并不是一个整数,所以修改为:var sampleRateRatio = Math.round(sampleRate / rate);

修改后的代码:

function downsampleBuffer(buffer, rate) {
    if (rate == sampleRate) {
        return buffer;
    }
    if (rate > sampleRate) {
        throw "downsampling rate show be smaller than original sample rate";
    }
    var sampleRateRatio = Math.round(sampleRate / rate); //计算压缩率,注意这里要取整数
    var newLength = Math.round(buffer.length / sampleRateRatio);
    var result = new Float32Array(newLength);
    var offsetResult = 0;
    var offsetBuffer = 0;
    while (offsetResult < result.length) {
        var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
        var accum = 0,
            count = 0;
        for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
            accum += buffer[i];
            count++;
        }
        result[offsetResult] = accum / count;
        offsetResult++;
        offsetBuffer = nextOffsetBuffer;
    }
    return result;
}
function exportWAV(type) {
    var buffers = [];
    for (var channel = 0; channel < numChannels; channel++) {
        buffers.push(mergeBuffers(recBuffers[channel], recLength));
    }
    if (numChannels === 2) {
        var interleaved = interleave(buffers[0], buffers[1]);
        var downsampledBuffer = downsampleBuffer(interleaved, 8000);
        var dataview = encodeWAV(8000, downsampledBuffer);
    } else {
        var interleaved = buffers[0];
        var downsampledBuffer = downsampleBuffer(interleaved, 8000);
    }
    var dataview = encodeWAV(8000,downsampledBuffer);
    var audioBlob = new Blob([dataview], {
        type: type
    });

    this.postMessage(audioBlob);
}

这里wav导出也需要做适当的修改。

这样将原来系统中默认采样率为44100修改成8000后,声音失真的问题得到完美的解决。

你可能感兴趣的:(web)