Javascript 如何使用navigator.mediaDevices.getUserMedia降低麦克风输入音量?

Javascript 如何使用navigator.mediaDevices.getUserMedia降低麦克风输入音量?,javascript,audio-recording,Javascript,Audio Recording,我正在使用navigator.mediaDevices.getUserMedia()创建一个音频录制应用程序,它可以录制我周围的每一个声音,甚至非常安静,距离我10米远。我不播放这个声音,我只是根据音量想象它,所以我只需要非常大的声音或接近麦克风的声音,因为干扰太大了 另外,如果我启用播放功能来听到我的麦克风输入,并开始发出安静的噪音,比如敲击桌子,我不能在播放中看到这个声音,但我在visualizer中看到它,这正是我不想要的 这是我的密码: const stream = await navi

我正在使用navigator.mediaDevices.getUserMedia()创建一个音频录制应用程序,它可以录制我周围的每一个声音,甚至非常安静,距离我10米远。我不播放这个声音,我只是根据音量想象它,所以我只需要非常大的声音或接近麦克风的声音,因为干扰太大了

另外,如果我启用播放功能来听到我的麦克风输入,并开始发出安静的噪音,比如敲击桌子,我不能在播放中看到这个声音,但我在visualizer中看到它,这正是我不想要的

这是我的密码:

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this.audioContext = new AudioContext();
this.sourceNode = this.audioContext.createMediaStreamSource(stream);
this.analyserNode = this.audioContext.createAnalyser();

this.sourceNode.connect(this.analyserNode);

const data = new Float32Array(this.analyserNode.fftSize);
this.analyserNode.getFloatTimeDomainData(data);
那个么,我怎样才能使用网络音频API降低话筒灵敏度,或者降低话筒输入音量,或者转换分析仪的数据呢?我读过关于
AudioContext.createGain()
gain.volume
,但它用于输出音频音量,而不是输入音频音量

我读过关于
AudioContext.createGain()
gain.volume
,但它用于输出音频音量,而不是输入音频音量

不,它用于控制通过它的音频的音量

您必须将音频上下文节点视为一个链,然后您可能会理解,您确实可以使用一个GainNode来控制它所连接的下一个节点的输入音量

例如,如果我们申报

gainNode.gain.volume = 0.5;
input.connect(gainNode);
gainNode.connect(analyserNode);
input.connect(audioContext.destination);
可以说是

Input [mic] ===>  GainNode  ===>  AnalyserNode
    100%   ||       50%                50%
           ||
            ===> AudioContext Output
                       100%
因此,这里的gainNode确实降低了AnalyzerNode的容量,但没有降低上下文输出的容量


但这并不是你真正想要的

事实上,AnalyzerNode API具有和属性,它们将完全满足您的要求(过滤掉db范围之外的声音)

但这些属性仅适用于频率数据(
getXXXFrequencyData
),因为波形不考虑体积

然而,在决定是否绘制波形之前,仍然可以检查该频率数据是否在我们要求的范围内

polyfill();
(异步()=>{
const ctx=新的AudioContext();
const input=wait loadFileAsBufferNode(ctx);
常量分析器=ctx.createAnalyzer();
分析仪。minDecibels=-90;
分析仪最大分贝=-10;
Analyzer.fftSize=512;
输入。连接(分析仪);
const gainNode=ctx.createGain();
输入连接(gainNode);
const bufferLength=分析仪频率B计数;
const freqArray=新的Uint8Array(bufferLength);
const waveArray=新的Uint8Array(缓冲长度);
const canvasCtx=canvas.getContext('2d');
const WIDTH=canvas.WIDTH;
const HEIGHT=canvas.HEIGHT;
canvasCtx.lineWidth=2;
draw();
//取自https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/maxDecibels#Example
函数绘图(){
请求动画帧(绘制);
canvasCtx.clearRect(0,0,宽度,高度);
分析仪。GetByTefFrequencyData(频率阵列);
gainNode.gain.value=1;
Analyzer.getByteTimeDomainData(waveArray);
变量barWidth=(宽度/缓冲长度)*2.5;
高度;
var x=0;
对于(变量i=0;i{
const max=+maxDB.value;
如果(+minDB.value>=max)minDB.value=analyzer.minDecibels=max-1;
分析仪。最大分贝=最大值;
}
minDB.oninput=e=>{
const min=+minDB.value;
如果(+maxDB.value{
如果(已签出)
连接(ctx目的地);
其他的
gainNode.断开连接(ctx.目的地);
};
})();
函数loadFileAsBufferNode(ctx,url=)https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3') {
返回获取(url)
.then(r=>r.arrayBuffer())
.然后(buf=>ctx.decodeAudioData(buf))
.then(bufferNode=>{
const source=ctx.createBufferSource();
source.buffer=bufferNode;
source.repeat=true;
source.start(0);
返回源;
});
};
/*狩猎旅行*/
函数polyfill(){
window.AudioContext=window.AudioContext | | window.webkitadiocontext;
试一试{
const prom=new AudioContext().decodeAudioData(new ArrayBuffer()).catch(e=>{});
}捕获(e){
const prev=AudioContext.prototype.decodeAudioData;
Object.defineProperty(AudioContext.prototype,“decodeAudioData”{
获取:()=>asPromise
});
函数asPromise(音频缓冲区,完成,失败){
返回新承诺((res,rej)=>{
上一个应用(此[audioBuffer,onsuccess,onerror]);
成功时的函数(buf){
if(typeof done==“function”)done(buf);
res(buf);
}
函数ONERR(错误){
如果(typeof failed==“function”)失败(err);
rej(err);
}
});
}
}
}
min
最大值
输出音频

谢谢你的回答,但这并没有多大帮助,也许我需要使用噪声抑制,因为这种方法不是很准确,我要么像以前一样听到所有声音,要么几乎没有有用的声音(当然还有噪声),只是沉默