angularspeech-recognitionwebspeech-api

Web Speech api in angular


I have implemented Web speech api in angular it is detecting the audio content but it throws this error :

core.js:6486 ERROR DOMException: Failed to execute 'start' on 'SpeechRecognition': recognition has already started. Angular Service:

import { Injectable } from '@angular/core';
    declare var webkitSpeechRecognition: any;
    
    @Injectable({
      providedIn: 'root'
    })
    export class VoiceRecognitionService {
    
      recognition =  new webkitSpeechRecognition();
      isStoppedSpeechRecog = false;
      public text = '';
      public tempWords : any;
      public transcript_arr = [];
      public confidence_arr = [];
    
    
      constructor() { }
    
      init() {
        this.recognition.continuous = true;
        this.recognition.interimResults = false;
        this.recognition.maxAlternatives = 1;
        this.recognition.lang = 'en-US';
    
    
        this.recognition.addEventListener('result', (e:any) => {
          let last = e.results.length - 1;
          let temp_trans = e.results[last][0].transcript; 
          this.transcript_arr.push(temp_trans); 
          const transcript = Array.from(e.results)
            .map((result:any) => result[0])
            .map((result) => result.transcript)
            .join(''); 
          this.tempWords = transcript;
        });
      }
    
      start() {
        this.isStoppedSpeechRecog = false;
        this.recognition.start();
        this.recognition.addEventListener('end', (condition:any) => {
          if (this.isStoppedSpeechRecog) {
            this.recognition.stop();
          } else {
            this.wordConcat()
            this.recognition.start();
          }
        });
      }
      stop() {
        this.isStoppedSpeechRecog = true;
        this.wordConcat();
        this.recognition.stop();
      }
      reinit()
      {
        this.transcript_arr = [];
        this.confidence_arr = [];
        this.tempWords='';
        this.text='';
      }
      wordConcat() {
        this.text = this.text + ' ' + this.tempWords + '.';
        this.tempWords = '';
      }
    }

Solution

  • I added two different flags to manage both cases:

    case 1: when the user stops the service.

    case 2: when the service is stopped automatically.

    import { Injectable } from '@angular/core';
    declare var webkitSpeechRecognition: any;
    
    @Injectable({
      providedIn: 'root',
    })
    export class VoiceRecognitionService {
      recognition = new webkitSpeechRecognition();
      isStoppedSpeechRecog = false;
      public text = '';
      tempWords: any;
      transcript_arr = [];
      confidence_arr = [];
      isStarted = false; //<< this Flag to check if the user stop the service
      isStoppedAutomatically = true; //<< this Flag to check if the service stopped automaticically.
      constructor() {}
    
      init() {
        this.recognition.continuous = true;
        this.recognition.interimResults = true;
        this.recognition.lang = 'en-US';
    
        this.recognition.addEventListener('result', (e: any) => {
          const transcript = Array.from(e.results)
            .map((result: any) => result[0])
            .map((result) => result.transcript)
            .join('');
          this.transcript_arr.push(transcript);
          this.tempWords = transcript;
          console.log(this.transcript_arr);
    
          const confidence = Array.from(e.results)
            .map((result: any) => result[0])
            .map((result) => result.confidence)
            .join('');
          this.confidence_arr.push(confidence);
          console.log(this.confidence_arr);
        });
    
        this.recognition.addEventListener('end', (condition: any) => {
          this.wordConcat();
          console.log('automatic!!');
          if (this.isStoppedAutomatically) {
            this.recognition.stop();
            this.recognition.start();
            this.isStoppedAutomatically = true;
          }
        });
      }
    
      start() {
        if (!this.isStarted) {
          this.recognition.start();
          this.isStarted = true;
          console.log('Speech recognition started');
        }
        return true;
      }
      stop() {
        if (this.isStarted) {
          this.isStoppedAutomatically = false;
          this.wordConcat();
          this.recognition.stop();
          this.isStarted = false;
          console.log('End speech recognition2');
        }
        return false;
      }
    
      wordConcat() {
        this.text = this.text + ' ' + this.tempWords + '.';
        this.tempWords = '';
      }
    }
    

    Check it running here