【问题标题】:How can I pause a specific function in NodeJS?如何在 NodeJS 中暂停特定功能?
【发布时间】:2023-03-10 23:05:02
【问题描述】:

好的,所以我一直在尝试这样做很长时间,但我找不到解决方案。我正在构建一个个人语音助手,它只在检测到启动指令时记录,直到这里一切正常。为了录制音频,我使用了 npm 包 node-record-lcpm16。我似乎找不到暂停或停止(并重新开始)录制的解决方案。在录音机的 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.`);
  };
};

任何帮助将不胜感激!

【问题讨论】:

    标签: javascript node.js npm audio audio-streaming


    【解决方案1】:

    我玩过你的代码。这绝对是一个有趣的项目!

    我建议也许只是修改代码以记录到缓冲区,然后将其发送到谷歌语音识别引擎。

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

    【讨论】:

    • 嘿,所以我又发现了一件我无法解决的问题。引擎现在只在说热词时才识别,但即使我没有说热词,它也会记录我所说的所有内容,所以如果我启动程序,说现在几点了,然后说热词,它仍然知道现在几点了。是否有任何解决方案,因为导致的一个问题是,如果我不使用它超过一分钟,我将无法再次启动它,因为谷歌语音只允许 1 分钟的识别时间?
    • 这是一个非常好的观点!我已经更新了答案,所以我们在记录时最多只保留最后 10 块数据。您可以调整此数量以获得所需的结果,但主要是它应该在一分钟以内!
    猜你喜欢
    • 2019-01-12
    • 2022-06-15
    • 2017-01-08
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多