Rozpoznawanie głosu to temat trudny, nawet dla największych wyjadaczy. Z pomocą przychodzi jednak Wit.ai, wraz ze swoim Speech API. Dzięki dedykowanej aplikacji oraz wykorzystaniu WebRTC i WebSockets możemy w prosty sposób przekonwertować mowę na tekst oraz skomunikować się z naszym chatbotem.
Trochę teorii
Wit.ai Speech API powstało w lutym 2014 roku jako rozwinięcie projektu Wit.ai. Zasada działania jest prosta, przesyłamy na backend (w tym wypadku na zewnętrzny serwer Wit.ai) plik audio. Dźwięk jest przetwarzany i konwertowany. Dostajemy w zwrotce JSON z intencją oraz wartościami, które zostaną wychwycone.
Wit.ai Speech API łączy w sobie różne techniki przetwarzania języka naturalnego oraz silniki rozpoznawania mowy. Potrafi odseparować szumy z otoczenia, dostosować poziom głośności i wydobyć właściwe dźwięki.
Microphone
W ramach tego wpisu zapoznamy się z nakładką wit-ai/microphone. Biblioteka jest rozwijana przez zespół zajmujący się Wit.ai. Została napisana w CoffeeScript, wykorzystuje WebRTC i WebSockets, dzięki czemu nie musimy zapisywać plików audio lokalnie. Cały kod jest jawny, a jego rdzeń możemy znaleźć tutaj.
Implementacja Speech API
Po wpięciu biblioteki obsługującej mikrofon i komunikującej się z Wit.ai API, pozostało obsłużyć mikrofon na stronie internetowej.
Zaczynamy od stworzenia instancji Microphone
:
const microphone = new Wit.Microphone(document.getElementById('microphone'));
Jak widać, odwołujemy się do elementu posiadającego id
microphone
. W ten sam sposób dodajemy info
oraz error
:
const info = message => {
document.getElementById('info').innerHTML = message;
};
const error = message => {
document.getElementById('error').innerHTML = message;
};
Teraz, korzystając z dokumentacji, stwórzmy kilka metod obsługujących naszą aplikację. Poinformujmy użytkownika, że można rozpocząć nagrywanie:
microphone.onready = () => {
info('Mikrofon gotowy do nagrywania');
};
Po starcie, zmiana statusu z informacją:
microphone.onaudiostart = () => {
info('Nagrywanie rozpoczęte');
};
Oraz po zakończeniu nagrywania:
microphone.onaudioend = () => {
info('Nagrywanie zakończone, trwa konwertowanie');
};
Pamiętajmy, że w razie niepowodzenia, warto o tym poinformować użytkownika. Wykorzystujemy więc metodę onerror
:
microphone.onerror = errorMessage => {
error('Błąd: ' + errorMessage);
};
W momencie nawiązywania oraz zamykania połączenia mamy dwa dodatkowe callbacki: onconnecting
, ondisconnected
. Wykorzystujemy je do stworzenia dodatkowych statusów informujących:
microphone.onconnecting = () => {
info('Trwa weryfikowanie mikrofonu');
};
microphone.ondisconnected = () => {
info('Mikrofon nie jest podłączony');
};
Została nam jeszcze obsługa onresult
. Analogicznie jak w wersji node'owej, tutaj też po zidentyfikowaniu osoby, spróbujemy wyszukać o niej informacje na Wikipedii:
microphone.onresult = (intent, entities) => {
if (entities.fullName === undefined) {
document.getElementById('result').innerHTML =
'Nie zrozumiałem, spróbuj jeszcze raz!';
} else {
let fullName = entities.fullName.value;
document.getElementById('result').innerHTML =
fullName + '? Szukam na wikipedii...';
window.open('https://pl.wikipedia.org/wiki/' + fullName.replace(' ', '_'));
}
};
W metodzie connect przekazujemy token, który możemy wygenerować w ustawieniach aplikacji.
Podsumowanie
Po implementacji i deployu na Heroku, możemy sprawdzić, jak się zachowuje aplikacja. Przykładowy screen z testu zamieszczam poniżej. Cały kod dostępny jest na moim GitHubie, zachęcam też do przetestowania aplikacji samodzielnie.
Źródła
- wit-ai/microphone - dedykowana biblioteka obsługująca mikrofon w przeglądarce. Oparta na WebRTC i WebSockets.
- wit.ai/docs/quickstart - szybki start z Wit.ai
- ~~spy-chatbot.herokuapp.com - aplikacja wykonana w tym wpisie~~
- github.com/dawidrylko/spy-web - kod źródłowy