DEV Community

Cover image for Adding Speech Recognition with Grammar Support to Your Angular Application
Ali Ahsan
Ali Ahsan

Posted on • Updated on

Adding Speech Recognition with Grammar Support to Your Angular Application

Speech recognition can greatly enhance user interactions in web applications by allowing users to input text or commands using their voice. In this tutorial, I'll show you how to integrate speech recognition into an Angular application and enhance it with grammar support.
(only chrome supported)
Prerequisites

  • Basic knowledge of Angular.
  • Angular CLI installed.
  • An existing Angular project or create a new one using ng new speech-recognition-app.

Step 1: Set Up the Speech Recognition Service

First, we need to create a service to handle speech recognition. This service will use the Web Speech API's webkitSpeechRecognition and SpeechGrammarList.

Create a new service:
ng generate service speech-recognition
Now, update the generated speech-recognition.service.ts:

import { Injectable, NgZone } from '@angular/core';
@Injectable({
  providedIn: 'root',
})
export class SpeechRecognitionService {
  recognition: any;
  isListening: boolean = false;

  constructor(private zone: NgZone) {
    const { webkitSpeechRecognition, webkitSpeechGrammarList }: IWindow = window as any;
    this.recognition = new webkitSpeechRecognition();
    this.recognition.continuous = false;
    this.recognition.interimResults = false;
    this.recognition.lang = 'en-US';

    const grammar = '#JSGF V1.0; grammar colors; public <color> = red | green | blue | yellow ;';
    const speechRecognitionList = new webkitSpeechGrammarList();
    speechRecognitionList.addFromString(grammar, 1);
    this.recognition.grammars = speechRecognitionList;
  }

  startListening(): Promise<string> {
    return new Promise((resolve, reject) => {
      if (this.isListening) {
        reject('Already listening');
      }

      this.isListening = true;

      this.recognition.onresult = (event: any) => {
        this.zone.run(() => {
          const result = event.results[0][0].transcript;
          this.stopListening();
          resolve(result);
        });
      };

      this.recognition.onerror = (event: any) => {
        this.zone.run(() => {
          this.isListening = false;
          reject(event.error);
        });
      };

      this.recognition.onend = () => {
        this.zone.run(() => {
          this.isListening = false;
        });
      };

      this.recognition.start();
    });
  }

  stopListening(): void {
    if (this.isListening) {
      this.recognition.stop();
      this.isListening = false;
    }
  }
}

interface IWindow extends Window {
  webkitSpeechRecognition: any;
  webkitSpeechGrammarList: any;
}

Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Component

Next, we'll create a component to utilize our speech recognition service. This component will have a textarea and a microphone icon. When the user clicks the icon, speech recognition will start, and the recognized text will be added to the textarea.
Update app.component.ts:

import { Component } from '@angular/core';
import { SpeechRecognitionService } from './speech-recognition.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  note: string = '';
  isListening: boolean = false;

  constructor(private speechRecognitionService: SpeechRecognitionService) {}

  toggleListening() {
    if (this.isListening) {
      this.speechRecognitionService.stopListening();
      this.isListening = false;
    } else {
      this.isListening = true;
      this.speechRecognitionService.startListening().then(
        (result: string) => {
          this.note = result;
          this.isListening = false;
        },
        (error: any) => {
          console.error('Speech recognition error', error);
          this.isListening = false;
        }
      );
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Update the Template

In the template, we'll bind the click event to our toggle method and use Angular's ngClass directive to add a glow effect when the microphone is listening.

Update app.component.html:

<div class="textarea-container">
  <textarea
    maxlength="150"
    class="form-control"
    id="message-text"
    rows="3"
    [(ngModel)]="note"
  ></textarea>
  <i
    (click)="toggleListening()"
    class="mdi mdi-microphone mic-icon"
    [ngClass]="{ 'glow': isListening }"
  ></i>
</div>
Enter fullscreen mode Exit fullscreen mode

Step 4: Add Styling

Add some styles to position the microphone icon and add a glow effect when it is listening.

Update app.component.css:

.textarea-container {
  position: relative;
  display: inline-block;
}

.textarea-container textarea {
  width: 100%;
  box-sizing: border-box;
}

.mic-icon {
  position: absolute;
  top: 10px;
  right: 10px;
  cursor: pointer;
  font-size: 24px;
  color: #333;
  transition: box-shadow 0.3s ease;
}

.mic-icon.glow {
  box-shadow: 0 0 10px 2px rgba(255, 0, 0, 0.8);
}

Enter fullscreen mode Exit fullscreen mode

Step 5: Test Your Application

Run your Angular application using:
ng serve

Navigate to http://localhost:4200/ in your browser. You should see the textarea with a microphone icon. When you click the icon, it will start listening, and the icon will glow. Speak a color from the grammar list (red, green, blue, yellow), and the recognized color will be added to the textarea.

Conclusion

You've successfully added speech recognition with grammar support to your Angular application. This feature can be expanded to recognize more complex commands and integrate seamlessly with various functionalities in your application. Experiment with different grammars and speech recognition settings to see what works best for your use case.
Follow me on linkedin
Happy coding!

Top comments (0)