Skip to content

Commit 9fb6b4c

Browse files
authored
Merge pull request #2 from jeroenouw/speech
Speech
2 parents 64f9c5b + f371db0 commit 9fb6b4c

File tree

11 files changed

+184
-40
lines changed

11 files changed

+184
-40
lines changed

README.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,11 @@ A small AI application containing [Angular 5](https://angular.io), [Material](ht
1717
* Dialogflow AI
1818
* Chatbot
1919

20-
## Example sentences
21-
* Can you get smarter?
22-
* You're boring
23-
* Who is your boss?
24-
* You are funny
25-
* Are we friends?
26-
* I'll be back
27-
* You're wrong
28-
* Nice to see you!
29-
* What's up?
30-
* I don't want to talk
31-
* Today is my birthday
32-
* I need an advice
20+
## Sentences
21+
[A couple of example sentences to get you start talking](https://github.com/jeroenouw/AngularAI/blob/master/docs/SENTENCES.md)
22+
23+
## Developing
24+
[Quick starting and development](https://github.com/jeroenouw/AngularAI/blob/master/docs/DEVELOPING.md)
3325

3426
## Contributing
3527
Want to file a bug, contribute some code, or improve documentation? Feel free to place an [issue](https://github.com/jeroenouw/AngularAI/issues).

docs/DEVELOPING.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Quick start
2+
First clone this repo: `git clone https://github.com/jeroenouw/AngularAI.git`.
3+
Change directory to this project
4+
Run `npm install` to install all the dependencies.
5+
Run `npm start` to run this project. This will run with the AoT Compiler.
6+
Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
7+
8+
## Development
9+
For own projects please use different token `src/environment/environment.prod.ts` and `src/environment/environment.ts`:
10+
``` dialogflow: { ```
11+
``` [CHOOSE_A_NAME]': '[YOUR_TOKEN]' ```
12+
``` }```
13+
14+
Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
15+
16+
To build the development environment, run `npm run dist`.
17+
18+
## Production
19+
To build the default production environment, run `npm run prod`. This will run with the AoT Compiler.
20+
To build the production environment with reduced file size, run `npm run prod:opt` (Takes extra time to build with build optimizer).
21+
22+
## Speech Options
23+
Available speech recognition options in `src/app/service/ai.service.ts`
24+
25+
Choose if the API needs to look for further words:
26+
`this.speechRecognition.continuous = false;`
27+
28+
Show interim results or just final results:
29+
`this.speechRecognition.interimResults = false;`
30+
31+
Select your speech language:
32+
`this.speechRecognition.lang = 'en-us';`
33+
34+
Choose the quantity of alternative available matches:
35+
`this.speechRecognition.maxAlternatives = 0;`

docs/SENTENCES.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## Example sentences
2+
* Can you get smarter?
3+
* You're boring
4+
* Who is your boss?
5+
* You are funny
6+
* Are we friends?
7+
* I'll be back
8+
* You're wrong
9+
* Nice to see you!
10+
* What's up?
11+
* I don't want to talk
12+
* Today is my birthday
13+
* I need an advice

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
22
"name": "ngx-ai",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"author": "Jeroen Ouwehand",
55
"description": "Angular 5 AI",
66
"keywords": [
77
"angular",
88
"dialogflow",
9+
"web speech api",
910
"google",
1011
"material",
1112
"chatbot",

src/app/components/ai/ai.component.html

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@ <h1 class="mat-display-1">Angular 5 AI</h1>
99
</div>
1010
</mat-card-content>
1111

12-
<mat-input-container>
13-
<input matInput [(ngModel)]="formInput" min="2" placeholder="Your Message..." (keyup.enter)="sendMessageToBot()" type="text">
14-
</mat-input-container>
12+
<div class="message-container">
13+
<mat-card-actions class="voice-button">
14+
<button mat-icon-button (click)="startTalkingToBot()">
15+
<mat-icon>keyboard_voice</mat-icon>
16+
</button>
17+
</mat-card-actions>
18+
<mat-input-container>
19+
<input matInput [(ngModel)]="formInput" min="2" placeholder="Your Message..." (keyup.enter)="sendMessageToBot()" type="text">
20+
</mat-input-container>
21+
</div>
1522

1623
<mat-card-actions class="button center">
1724
<button mat-raised-button (click)="sendMessageToBot()">Send</button>
1825
</mat-card-actions>
19-
26+
2027
</mat-card>

src/app/components/ai/ai.component.scss

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
word-wrap: break-word;
1212
}
1313

14+
.message-container {
15+
display: flex;
16+
flex-direction: row;
17+
justify-content: center;
18+
}
19+
1420
.message.to {
1521
background-color: $darkblue;
1622
color: $white;
@@ -32,7 +38,19 @@
3238
display: inline;
3339
}
3440

41+
.mat-form-field {
42+
width: 100%;
43+
}
44+
3545
.mat-raised-button {
3646
background-color: $darkblue;
3747
color: $white;
48+
}
49+
50+
.voice-button {
51+
border-radius: 50%;
52+
width: 40px;
53+
height: 40px;
54+
line-height: 24px;
55+
padding: 8px 20px 8px 8px;
3856
}
Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import { Component, OnInit, OnDestroy } from '@angular/core';
22

33
import { Observable } from 'rxjs/Observable';
44
import 'rxjs/add/operator/scan';
@@ -11,21 +11,46 @@ import { Message } from '../../model/message';
1111
templateUrl: './ai.component.html',
1212
styleUrls: ['./ai.component.scss']
1313
})
14-
export class AiComponent implements OnInit {
15-
allMessages: Observable<Message[]>;
16-
formInput: string;
17-
18-
constructor(public ai: AiService) {
19-
}
20-
21-
ngOnInit() {
22-
this.allMessages = this.ai.conversation.asObservable()
23-
.scan((acc, val) => acc.concat(val) );
24-
}
25-
26-
sendMessageToBot() {
27-
this.ai.converse(this.formInput);
28-
this.formInput = '';
29-
}
14+
export class AiComponent implements OnInit, OnDestroy {
15+
allMessages: Observable<Message[]>;
16+
formInput: string;
17+
18+
constructor(public ai: AiService) {
19+
this.formInput = '';
20+
}
21+
22+
ngOnInit() {
23+
this.allMessages = this.ai.conversation.asObservable()
24+
.scan((acc, val) => acc.concat(val) );
25+
}
26+
27+
ngOnDestroy() {
28+
this.ai.destroyVoiceConversation();
29+
}
30+
31+
sendMessageToBot() {
32+
this.ai.textConversation(this.formInput);
33+
this.formInput = '';
34+
}
35+
36+
startTalkingToBot() {
37+
this.ai.voiceConversation()
38+
.subscribe(
39+
(value) => {
40+
this.formInput = value;
41+
console.log(value);
42+
},
43+
(err) => {
44+
console.log(err);
45+
if (err.error) {
46+
// console.log("Talking error");
47+
this.startTalkingToBot();
48+
}
49+
},
50+
() => {
51+
// console.log("Talking complete");
52+
this.startTalkingToBot();
53+
});
54+
}
3055
}
3156

src/app/interface/Iwindow.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface IWindow extends Window {
2+
webkitSpeechRecognition: any;
3+
SpeechRecognition: any;
4+
}

src/app/service/ai.service.ts

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
1-
import { Injectable } from '@angular/core';
1+
import { Injectable, NgZone } from '@angular/core';
22
import { environment } from '../../environments/environment';
3+
import * as lodash from "lodash";
34

45
import { Observable } from 'rxjs/Observable';
56
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
67

78
import { ApiAiClient } from 'api-ai-javascript';
89
import { Message } from '../model/message'
10+
import { IWindow } from '../interface/iwindow'
911

1012
@Injectable()
1113
export class AiService {
1214
readonly token = environment.dialogflow.angularAIBot;
1315
readonly client = new ApiAiClient({ accessToken: this.token });
1416

17+
speechRecognition: any;
1518
conversation = new BehaviorSubject<Message[]>([]);
1619

17-
constructor() {
20+
constructor(private zone: NgZone) {
1821
}
1922

20-
converse(msg: string) {
23+
textConversation(msg: string) {
2124
const userMessage = new Message(msg, 'user');
2225
this.update(userMessage);
2326
return this.client.textRequest(msg)
@@ -31,4 +34,51 @@ export class AiService {
3134
update(msg: Message) {
3235
this.conversation.next([msg]);
3336
}
37+
38+
voiceConversation(): Observable<string> {
39+
return Observable.create(observer => {
40+
const { webkitSpeechRecognition }: IWindow = <IWindow>window;
41+
this.speechRecognition = new webkitSpeechRecognition();
42+
this.speechRecognition.continuous = false;
43+
this.speechRecognition.interimResults = false;
44+
this.speechRecognition.lang = 'en-us';
45+
this.speechRecognition.maxAlternatives = 0;
46+
47+
this.speechRecognition.onresult = speech => {
48+
let sentence: string = "";
49+
if (speech.results) {
50+
var result = speech.results[speech.resultIndex];
51+
var transcript = result[0].transcript;
52+
if (result.isFinal) {
53+
if (result[0].confidence < 0.1) {
54+
console.log("Unrecognized result - Please try again");
55+
}
56+
else {
57+
sentence = lodash.trim(transcript);
58+
console.log("Did you said? -> " + sentence + " , If not then say something else...");
59+
}
60+
}
61+
}
62+
this.zone.run(() => {
63+
observer.next(sentence);
64+
});
65+
};
66+
67+
this.speechRecognition.onerror = error => {
68+
observer.error(error);
69+
};
70+
71+
this.speechRecognition.onend = () => {
72+
observer.complete();
73+
};
74+
75+
this.speechRecognition.start();
76+
// console.log("I'm listening...");
77+
});
78+
}
79+
80+
destroyVoiceConversation() {
81+
if (this.speechRecognition)
82+
this.speechRecognition.stop();
83+
}
3484
}

0 commit comments

Comments
 (0)