我正在使用带有NodeJS后端的Google Cloud API for Speech-to-text。 应用程序需要能够侦听语音命令,并将它们作为缓冲区传输到后端。为此,我需要在检测到静音时发送前一个音频的缓冲区。
任何帮助将不胜感激。包括下面的js代码
if (!navigator.getUserMedia)
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({audio: true}, success, function (e) {
alert('Error capturing audio.');
});
} else alert('getUserMedia not supported in this browser.');
var recording = false;
window.startRecording = function () {
recording = true;
};
window.stopRecording = function () {
recording = false;
// window.Stream.end();
};
function success(e) {
audioContext = window.AudioContext || window.webkitAudioContext;
context = new audioContext();
// the sample rate is in context.sampleRate
audioInput = context.createMediaStreamSource(e);
var bufferSize = 4096;
recorder = context.createScriptProcessor(bufferSize, 1, 1);
recorder.onaudioprocess = function (e) {
if (!recording) return;
console.log('recording');
var left = e.inputBuffer.getChannelData(0);
console.log(convertoFloat32ToInt16(left));
};
audioInput.connect(recorder);
recorder.connect(context.destination);
}
答案 0 :(得分:16)
我不太确定问题的确切内容,所以这个答案只是为了找到一种方法来检测AudioStream中的静音。
要检测AudioStream中的静音,您可以使用AudioAnalyser节点,在该节点上定期调用getByteFrequencyData
方法,并检查是否有高于预期水平的声音给定的时间。
您可以直接使用AnalyserNode的minDecibels
属性设置阈值级别。
function detectSilence(
stream,
onSoundEnd = _=>{},
onSoundStart = _=>{},
silence_delay = 500,
min_decibels = -80
) {
const ctx = new AudioContext();
const analyser = ctx.createAnalyser();
const streamNode = ctx.createMediaStreamSource(stream);
streamNode.connect(analyser);
analyser.minDecibels = min_decibels;
const data = new Uint8Array(analyser.frequencyBinCount); // will hold our data
let silence_start = performance.now();
let triggered = false; // trigger only once per silence event
function loop(time) {
requestAnimationFrame(loop); // we'll loop every 60th of a second to check
analyser.getByteFrequencyData(data); // get current data
if (data.some(v => v)) { // if there is data above the given db limit
if(triggered){
triggered = false;
onSoundStart();
}
silence_start = time; // set it to now
}
if (!triggered && time - silence_start > silence_delay) {
onSoundEnd();
triggered = true;
}
}
loop();
}
function onSilence() {
console.log('silence');
}
function onSpeak() {
console.log('speaking');
}
navigator.mediaDevices.getUserMedia({
audio: true
})
.then(stream => {
detectSilence(stream, onSilence, onSpeak);
// do something else with the stream
})
.catch(console.error);

而as a fiddle因为stackSnippets可能会阻止gUM。
答案 1 :(得分:2)
您可以使用SpeechRecognition
result
事件来确定何时识别出某个字词或词组,例如ls
,cd
,pwd
或其他命令,将.transcript
的{{1}}传递给SpeechRecognitionAlternative
speechSynthesis.speak()
和start
end
来自SpeechSynthesisUtterance
的{{1}}或{.start()
对.resume()
传递MediaRecorder
的对象{1}};使用MediaStream
或Blob
将dataavailable
事件ArrayBuffer
转换为FileReader
。
我们也可以Response.arrayBuffer()
或audiostart
使用soundstart
或audioend
soundend
事件来记录用户的实际语音,但结果可能不会与仅由标准系统麦克风捕获的音频的实际开始和结束相关地持续发射。
SpeechRecognition
答案 2 :(得分:2)
最简单的方法是使用.pause()
的{{1}}和.resume()
,.stop()
方法,以允许用户使用{{开始,暂停和停止录制音频1}}并将生成的MediaRecorder()
转换为navigator.mediaDevices.getUserMedia()
,如果这是api期望Blob
编辑到服务器
ArrayBuffer