如何暂停 NodeJS 中的特定功能?
How can I pause a specific function in NodeJS?
好吧,我已经尝试这样做很长时间了,但就是找不到解决方案。我正在构建一个个人语音助手,它只在检测到热词时才记录,直到这里一切正常。为了录制音频,我使用了 npm 包 node-record-lcpm16。我似乎找不到暂停或停止(并重新开始)录音的解决方案。在 audiorecorder 的 npm 网站上有一个指定的函数,上面写着 recording.stop()
但它对我不起作用。我现在的代码是:
const recorder = require('node-record-lpcm16');
const fs = require('file-system');
const speech = require('@google-cloud/speech');
const say = require('say');
const notifier = require('node-notifier');
const Bumblebee = require('bumblebee-hotword-node');
const { setTimeout } = require('timers');
const { record } = require('node-record-lpcm16');
const bumblebee = new Bumblebee;
const voice = 'Microsoft Zira Desktop';
bumblebee.addHotword('computer');
const config = {
encoding: 'LINEAR16',
sampleRateHertz: 16000,
languageCode: 'en-US',
};
const request = {
config,
interimResults: false,
};
const client = new speech.SpeechClient();
const recognizeStream = client
.streamingRecognize(request)
.on('error', console.error)
.on('data', data => findfunction(data.results[0].alternatives[0].transcript)
);
const recording = recorder.record({
sampleRateHertz: 16000,
threshold: 0,
recorder: 'sox',
silence: '5.0',
})
.stream().on('error', console.error); //Here is the Recorder, and I can't actually stop it and that's my problem.
recording.pipe(recognizeStream);
bumblebee.on('hotword', function(hotword){
console.log('Hotword detected:', hotword); // It does these actions as soon as the hotword is detected
recording.pipe(recognizeStream);
setTimeout(function stop(){
recording.pipe(fs.createWriteStream("\\.\NUL")),
console.log('Stopped Recording.')
}, 5000);
});
console.log('Computer initiated.');
bumblebee.start();
//Everything down from here is just what do to with the translated speech, it doesn't play a role in my problem.
function findfunction(Data){
let findFunction = Data;
console.log(Data);
if(findFunction.includes('time')){
whattimeisit(findFunction);
};
if(findFunction.includes('day')){
whatdateisit(findFunction);
};
if(findFunction.includes('thank you')){
thankyou();
};
if(findFunction.includes('remind')){
setatimer(findFunction);
};
};
function whattimeisit(timeString){
const date = new Date();
const time = date.toLocaleTimeString();
say.speak(`It's currently ${time}.`, voice);
console.log(`It's currently ${time}.`);
};
function whatdateisit(dateString){
const date = new Date();
const currentDate = date.toLocaleDateString();
say.speak(`It's currently ${currentDate}.`, voice);
console.log(`It's currently ${currentDate}.`);
};
function thankyou(){
say.speak("You're welcome!", voice);
console.log("You're welcome!");
};
function setatimer(timerString){
const timer = timerString.replace(/\D/g, '');
setTimeout(function stop() {notifier.notify({title: 'Computer', message: 'Your timer ran out!', icon: './computericon1.png'})} , timer * 60000);
if(timer == 1){
say.speak(`Set a timer for ${timer} minute.`, voice);
console.log(`Set a timer for ${timer} minute.`);
}else{
say.speak(`Set a timer for ${timer} minutes.`, voice);
console.log(`Set a timer for ${timer} minutes.`);
};
};
如有任何帮助,我们将不胜感激!
我玩过你的代码。这绝对是一个有趣的项目!
我建议也许只是修改代码以记录到缓冲区,然后将其发送到 google 语音识别引擎。
recording.stop() 对您不起作用的原因可能是您在流中调用它。如果我们将 recording 和 recordingStream 变量分开,我们可以更好地控制流量。
我已经更新了代码,所以当我们得到热词时,我们会停止录音,识别语音,然后重新开始录音。
const recorder = require('node-record-lpcm16');
const Bumblebee = require('bumblebee-hotword-node');
const say = require('say');
const voice = 'Microsoft Zira Desktop';
const speech = require('@google-cloud/speech');
let chunks = null;
let recording = null;
function startRecording() {
console.log("listening...");
chunks = [];
recording = recorder.record({
sampleRateHertz: 16000,
threshold: 0,
recorder: 'sox',
silence: '5.0',
})
const recordingStream = recording.stream();
recordingStream.on('error', () => {});
// Tune this to ensure we only send the last few seconds of audio to google..
const maxChunks = 10;
recordingStream.on('data', (chunk) => {
chunks.push(chunk);
// keep the number of chunks below a reasonable limit...
if (chunks.length > maxChunks) {
chunks = chunks.slice(-maxChunks);
}
});
recordingStream.on('end', async () => {
// Create a buffer from our recording, it should only be a few seconds long.
const audioBuffer = Buffer.concat(chunks);
console.log("Chunk count:", chunks.length);
await recognizeSpeech(audioBuffer);
startRecording();
});
}
async function recognizeSpeech(audioBuffer) {
console.log(`recognizeSpeech: Converting audio buffer to text (${audioBuffer.length} bytes)...`)
const client = new speech.SpeechClient();
const request = {
config: { encoding: 'LINEAR16', sampleRateHertz: 16000, languageCode: 'en-US'},
audio: { content: audioBuffer.toString("base64") }
};
// Convert our audio to text.
const response = await client.recognize(request)
findfunction(response[0].results[0].alternatives[0].transcript);
}
startRecording();
startBumblebee();
function startBumblebee() {
const bumblebee = new Bumblebee();
bumblebee.addHotword('computer');
bumblebee.on('hotword', function(hotword){
console.log('Hotword detected:', hotword);
setTimeout(() => {
console.log('Stopping recording...');
recording.stop()
}, 2000);
});
bumblebee.start( );
}
// Nothing changed from here...
function findfunction(Data){
let findFunction = Data;
console.log(Data);
if(findFunction.includes('time')){
whattimeisit(findFunction);
};
if(findFunction.includes('day')){
whatdateisit(findFunction);
};
if(findFunction.includes('thank you')){
thankyou();
};
if(findFunction.includes('remind')){
setatimer(findFunction);
};
};
function whattimeisit(timeString){
const date = new Date();
const time = date.toLocaleTimeString();
say.speak(`It's currently ${time}.`, voice);
console.log(`It's currently ${time}.`);
};
function whatdateisit(dateString){
const date = new Date();
const currentDate = date.toLocaleDateString();
say.speak(`It's currently ${currentDate}.`, voice);
console.log(`It's currently ${currentDate}.`);
};
function thankyou(){
say.speak("You're welcome!", voice);
console.log("You're welcome!");
};
function setatimer(timerString){
const timer = timerString.replace(/\D/g, '');
setTimeout(function stop() {notifier.notify({title: 'Computer', message: 'Your timer ran out!', icon: './computericon1.png'})} , timer * 60000);
if(timer == 1){
say.speak(`Set a timer for ${timer} minute.`, voice);
console.log(`Set a timer for ${timer} minute.`);
}else{
say.speak(`Set a timer for ${timer} minutes.`, voice);
console.log(`Set a timer for ${timer} minutes.`);
};
};
好吧,我已经尝试这样做很长时间了,但就是找不到解决方案。我正在构建一个个人语音助手,它只在检测到热词时才记录,直到这里一切正常。为了录制音频,我使用了 npm 包 node-record-lcpm16。我似乎找不到暂停或停止(并重新开始)录音的解决方案。在 audiorecorder 的 npm 网站上有一个指定的函数,上面写着 recording.stop() 但它对我不起作用。我现在的代码是:
const recorder = require('node-record-lpcm16');
const fs = require('file-system');
const speech = require('@google-cloud/speech');
const say = require('say');
const notifier = require('node-notifier');
const Bumblebee = require('bumblebee-hotword-node');
const { setTimeout } = require('timers');
const { record } = require('node-record-lpcm16');
const bumblebee = new Bumblebee;
const voice = 'Microsoft Zira Desktop';
bumblebee.addHotword('computer');
const config = {
encoding: 'LINEAR16',
sampleRateHertz: 16000,
languageCode: 'en-US',
};
const request = {
config,
interimResults: false,
};
const client = new speech.SpeechClient();
const recognizeStream = client
.streamingRecognize(request)
.on('error', console.error)
.on('data', data => findfunction(data.results[0].alternatives[0].transcript)
);
const recording = recorder.record({
sampleRateHertz: 16000,
threshold: 0,
recorder: 'sox',
silence: '5.0',
})
.stream().on('error', console.error); //Here is the Recorder, and I can't actually stop it and that's my problem.
recording.pipe(recognizeStream);
bumblebee.on('hotword', function(hotword){
console.log('Hotword detected:', hotword); // It does these actions as soon as the hotword is detected
recording.pipe(recognizeStream);
setTimeout(function stop(){
recording.pipe(fs.createWriteStream("\\.\NUL")),
console.log('Stopped Recording.')
}, 5000);
});
console.log('Computer initiated.');
bumblebee.start();
//Everything down from here is just what do to with the translated speech, it doesn't play a role in my problem.
function findfunction(Data){
let findFunction = Data;
console.log(Data);
if(findFunction.includes('time')){
whattimeisit(findFunction);
};
if(findFunction.includes('day')){
whatdateisit(findFunction);
};
if(findFunction.includes('thank you')){
thankyou();
};
if(findFunction.includes('remind')){
setatimer(findFunction);
};
};
function whattimeisit(timeString){
const date = new Date();
const time = date.toLocaleTimeString();
say.speak(`It's currently ${time}.`, voice);
console.log(`It's currently ${time}.`);
};
function whatdateisit(dateString){
const date = new Date();
const currentDate = date.toLocaleDateString();
say.speak(`It's currently ${currentDate}.`, voice);
console.log(`It's currently ${currentDate}.`);
};
function thankyou(){
say.speak("You're welcome!", voice);
console.log("You're welcome!");
};
function setatimer(timerString){
const timer = timerString.replace(/\D/g, '');
setTimeout(function stop() {notifier.notify({title: 'Computer', message: 'Your timer ran out!', icon: './computericon1.png'})} , timer * 60000);
if(timer == 1){
say.speak(`Set a timer for ${timer} minute.`, voice);
console.log(`Set a timer for ${timer} minute.`);
}else{
say.speak(`Set a timer for ${timer} minutes.`, voice);
console.log(`Set a timer for ${timer} minutes.`);
};
};
如有任何帮助,我们将不胜感激!
我玩过你的代码。这绝对是一个有趣的项目!
我建议也许只是修改代码以记录到缓冲区,然后将其发送到 google 语音识别引擎。
recording.stop() 对您不起作用的原因可能是您在流中调用它。如果我们将 recording 和 recordingStream 变量分开,我们可以更好地控制流量。
我已经更新了代码,所以当我们得到热词时,我们会停止录音,识别语音,然后重新开始录音。
const recorder = require('node-record-lpcm16');
const Bumblebee = require('bumblebee-hotword-node');
const say = require('say');
const voice = 'Microsoft Zira Desktop';
const speech = require('@google-cloud/speech');
let chunks = null;
let recording = null;
function startRecording() {
console.log("listening...");
chunks = [];
recording = recorder.record({
sampleRateHertz: 16000,
threshold: 0,
recorder: 'sox',
silence: '5.0',
})
const recordingStream = recording.stream();
recordingStream.on('error', () => {});
// Tune this to ensure we only send the last few seconds of audio to google..
const maxChunks = 10;
recordingStream.on('data', (chunk) => {
chunks.push(chunk);
// keep the number of chunks below a reasonable limit...
if (chunks.length > maxChunks) {
chunks = chunks.slice(-maxChunks);
}
});
recordingStream.on('end', async () => {
// Create a buffer from our recording, it should only be a few seconds long.
const audioBuffer = Buffer.concat(chunks);
console.log("Chunk count:", chunks.length);
await recognizeSpeech(audioBuffer);
startRecording();
});
}
async function recognizeSpeech(audioBuffer) {
console.log(`recognizeSpeech: Converting audio buffer to text (${audioBuffer.length} bytes)...`)
const client = new speech.SpeechClient();
const request = {
config: { encoding: 'LINEAR16', sampleRateHertz: 16000, languageCode: 'en-US'},
audio: { content: audioBuffer.toString("base64") }
};
// Convert our audio to text.
const response = await client.recognize(request)
findfunction(response[0].results[0].alternatives[0].transcript);
}
startRecording();
startBumblebee();
function startBumblebee() {
const bumblebee = new Bumblebee();
bumblebee.addHotword('computer');
bumblebee.on('hotword', function(hotword){
console.log('Hotword detected:', hotword);
setTimeout(() => {
console.log('Stopping recording...');
recording.stop()
}, 2000);
});
bumblebee.start( );
}
// Nothing changed from here...
function findfunction(Data){
let findFunction = Data;
console.log(Data);
if(findFunction.includes('time')){
whattimeisit(findFunction);
};
if(findFunction.includes('day')){
whatdateisit(findFunction);
};
if(findFunction.includes('thank you')){
thankyou();
};
if(findFunction.includes('remind')){
setatimer(findFunction);
};
};
function whattimeisit(timeString){
const date = new Date();
const time = date.toLocaleTimeString();
say.speak(`It's currently ${time}.`, voice);
console.log(`It's currently ${time}.`);
};
function whatdateisit(dateString){
const date = new Date();
const currentDate = date.toLocaleDateString();
say.speak(`It's currently ${currentDate}.`, voice);
console.log(`It's currently ${currentDate}.`);
};
function thankyou(){
say.speak("You're welcome!", voice);
console.log("You're welcome!");
};
function setatimer(timerString){
const timer = timerString.replace(/\D/g, '');
setTimeout(function stop() {notifier.notify({title: 'Computer', message: 'Your timer ran out!', icon: './computericon1.png'})} , timer * 60000);
if(timer == 1){
say.speak(`Set a timer for ${timer} minute.`, voice);
console.log(`Set a timer for ${timer} minute.`);
}else{
say.speak(`Set a timer for ${timer} minutes.`, voice);
console.log(`Set a timer for ${timer} minutes.`);
};
};