简体   繁体   English

如何在 NodeJS 中暂停特定的 function?

[英]How can I pause a specific function in NodeJS?

Okay, so I've been trying to do this for a long time but I just can't find a solution.好的,所以我一直在尝试这样做很长时间,但我找不到解决方案。 I'm building a personal Voice Assistant that only records when a hotword is detected, and everything until here works fine.我正在构建一个个人语音助手,它只在检测到启动指令时记录,直到这里一切正常。 To record the audio, I'm using the npm package node-record-lcpm16.为了录制音频,我使用的是 npm package node-record-lcpm16。 I can't seem to find a solution to pause or stop(and start again) the recording.我似乎找不到暂停或停止(并重新开始)录制的解决方案。 On the npm website of the audiorecorder there is a function specified that says recording.stop() but it doesn't work for me.在录音机的 npm 网站上,有一个 function 指定,上面写着recording.stop(),但它对我不起作用。 My code right now is:我现在的代码是:


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.`);
  };
};

Any help would be greatly appreciated!任何帮助将不胜感激!

I've played about with your code.. it's definitely a fun project to play with!我玩过你的代码..这绝对是一个有趣的项目!

I would suggest maybe just modifying the code to record to a buffer, then send that to the google speech recognition engine.我建议也许只是修改代码以记录到缓冲区,然后将其发送到谷歌语音识别引擎。

The reason recording.stop() was probably not working for you is that you were calling it on the stream. recording.stop() 可能对您不起作用的原因是您在 stream 上调用它。 If we separate the recording and recordingStream variables we can control the flow better.如果我们将recording 和recordingStream 变量分开,我们可以更好地控制流程。

I've updated the code so when we get the hotword, we stop recording, recognize the speech, then start recording again.我已经更新了代码,所以当我们得到启动指令时,我们会停止录制,识别语音,然后重新开始录制。

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.`);
    };
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM