使用不同的浏览器通过 getUserMedia 获得一致的音频质量

Get consistent audio quality with getUserMedia using different browsers

我在做什么

我在 Mac 上使用 getUserMedia API to record audio in the browser and then send this audio to a websocket server. Furthermore, to test the recordings, I use soundflower 作为输入设备,因此我可以播放波形文件,而不是对着麦克风讲话。

客户端 (JavaScript)

window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

var audioContext = new AudioContext();
var wsClient = new WebSocket("ws://" + WEBSOCKET_URL + ":" + WEBSOCKET_PORT);

navigator.getUserMedia({audio: true}, function (stream) {
    var input = audioContext.createMediaStreamSource(stream);
    var recordNode = audioContext.createScriptProcessor(4096);
    recordNode.onaudioprocess = recorderProcess;
    input.connect(recordNode);
    recordNode.connect(audioContext.destination);
}, function (e) {
    console.error("No live audio input: " + e);
});

function recorderProcess(e) {
    var buffer = e.inputBuffer.getChannelData(0);
    wsClient.send(buffer);
}

服务器端 (python)

在服务器端,我只是将块写入文件中:

def onMessage(self, msg, binary):
    if binary:
        with open("/tmp/test.raw", "ab") as f:
            f.write(msg)

问题

我遇到的问题是,浏览器似乎对音频进行了预处理,因此最终结果与原始音频的质量不同。质量也取决于浏览器。

这是一个例子:

图片显示了原音频的三个波形,在Chrome中录制的结果和在FireFox中录制的结果。如您所见,波形看起来不同。特别是在 Chrome 中,低振幅通常会被转换为零。

查看频谱图时可以看到更大的差异:

所以这两个浏览器似乎都切断了更高的频率,而 FireFox 肯定更极端。

所有这些可能没什么大不了的,因为音频文件听起来都非常相似。但是我在服务器端处理和分析音频,浏览器的预处理给我带来了更糟糕的最终结果。

问题

所以这是怎么回事?这些浏览器是否有额外的音频预处理步骤?他们大概应用了什么样的过滤器?我可以在 getUserMedia API 中以某种方式避免这种情况吗?有没有什么方法可以在 Chrome 和 FireFox 中产生一致的良好音频质量?

免责声明

我不是音频专家,所以我只能以非常业余的方式分析结果,但我希望图形能说明一切。

是的,您正在 Chrome 上进行默认输入处理。这有助于减少噪音、管理自动增益控制并有助于避免回声。尝试在您的 getUserMedia 调用中禁用它,a la:

https://github.com/cwilso/AudioRecorder/blob/master/js/main.js#L169-L183