翻译:刘通
又有两个新的麦克风约束得到了标准化,现在可以在adapter.js或者Firefox Nightly上使用:
如果你是音乐家或者医生的话会觉得很有用,因为WebRTC中的音频最初就是为了传递语音来设计的,而不是为了听一段吉他即兴演奏或者远程监听心跳而设计的。
基本上Firefox和Chrome一开始就通过浏览器引擎前缀实现了这个功能,但是并没有得到足够的重视。也许听听别人的一件会有帮助。
下面也展示了媒体捕捉细则中的其他部分。注意,这个demo只能在Firefox浏览器上运行,因为它使用了applyConstraints,而Chrome浏览器还不支持它。
提示:在点击“Result”键之前请戴上耳机。运行结果和HTML代码请点击此处跳转原文查看。
var track, gUM = c => navigator.mediaDevices.getUserMedia(c);
(async () => {
spectrum(audio.srcObject = await gUM({audio: true}));
track = audio.srcObject.getAudioTracks()[0];
update();
})().catch(e => log(e));
function update() {
let set = track.getSettings();
echo.checked = set.echoCancellation;
noise.checked = set.noiseSuppression;
gain.checked = set.autoGainControl;
muted.checked = !track.enabled;
}
echo.onclick = e => apply({echoCancellation: echo.checked});
noise.onclick = e => apply({noiseSuppression: noise.checked});
gain.onclick = e => apply({autoGainControl: gain.checked});
muted.onclick = e => { track.enabled = !muted.checked };
async function apply(c) {
await track.applyConstraints(Object.assign(track.getSettings(), c));
update();
}
function spectrum(stream) {
var audioCtx = new AudioContext();
var analyser = audioCtx.createAnalyser();
var source = audioCtx.createMediaStreamSource(stream);
source.connect(analyser);
var canvas = document.createElement("canvas");
var canvasCtx = canvas.getContext("2d");
canvas.width = window.innerWidth/2 – 20;
canvas.height = window.innerHeight/2 – 20;
container.appendChild(canvas);
var data = new Uint8Array(canvas.width);
canvasCtx.strokeStyle = 'rgb(0, 125, 0)';
setInterval(() => {
canvasCtx.fillStyle = "#a0a0a0";
canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
analyser.getByteFrequencyData(data);
canvasCtx.lineWidth = 2;
data.forEach((y, x) => {
y = canvas.height – (y / 128) * canvas.height / 4;
var c = Math.floor((x*255)/canvas.width);
canvasCtx.fillStyle = "rgb("+c+",0,"+(255-x)+")";
canvasCtx.fillRect(x, y, 2, canvas.height – y)
});
analyser.getByteTimeDomainData(data);
canvasCtx.lineWidth = 5;
canvasCtx.beginPath();
data.forEach((y, x) => {
y = canvas.height – (y / 128) * canvas.height / 2;
x ? canvasCtx.lineTo(x, y) : canvasCtx.moveTo(x, y);
});
canvasCtx.stroke();
var bogus = source; // avoid GC or the whole thing stops
}, 1000 * canvas.width / audioCtx.sampleRate);
};
function log(msg) { div.innerHTML += "<br>" + msg; }
当允许使用麦克风之后,我们使用track.getSettings()来做一个选择框来显示当前的设置:
前两个是Firefox默认的选择。但是想所有设备的设置一样,“默认情况”每个浏览器都可能不一样,每个设备之前可能存在差别,甚至两个不同的场景之间都有可能不同,所以永远不要依赖“默认选择”。如果你关心设置问题,就可以对其进行约束。
测试demo是否工作的最好方法是戴上耳机,然后仔细的听背景噪声:
#当noiseSuppression没有被选中的时候,你应该可以听出存在明显的背景噪声。
#当选中autoGainControl时,你应该听见背景噪声被增强了一点。
#又选中noiseSuppression时,你会发现对音频的增益依然存在,但是背景噪声被抑制了。
感谢Adam Roach写的频谱观测器,即便没有音频的时候你也能看出区别。
将他们设置成什么呢
通常做法是关掉所有的过滤效果,因为这些滤波器会损伤保真度。尤其是在用立体声进行听音的时候,有些实现在使用特定滤波器的时候会将立体声道改成单声道。
但是还是要根据你的录音情况进行具体选择:是人声还是音乐表演,是自然声(心跳),还是周围噪声,亦或是在录音室环境。如果是要通过Web Audio的话,你可能想要获得的是原始信号,然后使用自己的滤波处理。