Samouczek JavaScript: dodaj rozpoznawanie mowy do swojej aplikacji internetowej

Podczas gdy przeglądarki zmierzają w kierunku obsługi rozpoznawania mowy i bardziej futurystycznych możliwości, programiści aplikacji internetowych są zwykle ograniczeni do klawiatury i myszy. Ale co by było, gdybyśmy mogli rozszerzyć interakcje klawiatury i myszy o inne tryby interakcji, takie jak polecenia głosowe lub pozycje rąk?

W tej serii postów zbudujemy podstawowy eksplorator map z interakcjami multimodalnymi. Najpierw są polecenia głosowe. Jednak najpierw musimy rozplanować strukturę naszej aplikacji, zanim będziemy mogli włączyć jakiekolwiek polecenia.

Nasza aplikacja, uruchomiona za pomocą create-react-app, będzie pełnoekranową mapą opartą na komponentach React dla Leaflet.js. Po uruchomieniu create-react-app, yarn add leafleti yarn add react-leaflet, otworzymy nasz Appkomponent i zdefiniujemy nasz Mapkomponent:

import React, {Component} z 'reaguj';

import {Map, TileLayer} z „broszury reagowania”

import './App.css';

class App extends Component {

  state = {

    Centrum: [41,878099, -87,648116],

    zoom: 12,

  };

  updateViewport = (viewport) => {

    this.setState ({

      środek: viewport.center,

      zoom: viewport.zoom,

    });

  };

  renderowanie() {

    const {

      środek,

      Powiększenie,

    } = this.state;

    powrót (

          style = {{wysokość: '100%', szerokość: '100%'}}

          center = {center}

          zoom = {zoom}

          onViewportChange = {this.updateViewport}>

            url = "// {s} .tile.openstreetmap.org / {z} / {x} / {y} .png"

            atrybucja = "© Współtwórcy OpenStreetMap"

          />

    )

  }

}

eksportuj domyślną aplikację;

AppSkładnikiem jest Stateful komponent, który śledzi właściwości centrum i zoom, przekazując je do Mapkomponentu. Kiedy użytkownik wchodzi w interakcję z mapami za pomocą wbudowanej myszy i klawiatury, otrzymujemy powiadomienie o aktualizacji naszego stanu o nowe poziomy środka i powiększenia.

Po zdefiniowaniu komponentu pełnoekranowego nasza aplikacja wygląda następująco:

Po wyjęciu z pudełka otrzymujemy typowe tryby interakcji, w tym mysz, klawiaturę i dotyk na urządzeniach, które je obsługują. Po zdefiniowaniu naszych podstawowych interakcji i interfejsu użytkownika dodajmy polecenia głosowe, aby powiększać i pomniejszać.

Dostępnych jest wiele bibliotek umożliwiających rozpoznawanie mowy w przeglądarce. Istnieje nawet podstawowy interfejs API SpeechDetection obsługiwany przez Chrome. Użyjemy annyang, popularnej i prostej biblioteki do wykrywania tekstu JavaScript. W annyang definiujesz polecenia i ich funkcje obsługi w obiekcie JavaScript, na przykład:

const commands = {

  'in': () => console.log ('otrzymano komendę'),

  'out': () => console.log ('otrzymano polecenie out'),

};

Następnie wszystko, co musisz zrobić, to przekazać ten obiekt do metody na annyangobiekcie i wywołać start()ten obiekt. Pełny przykład wygląda następująco:

import annyang z „annyang”;

const commands = {

  'in': () => console.log ('otrzymano komendę'),

  'out': () => console.log ('otrzymano polecenie out'),

};

annyang.addCommands (polecenia);

annyang.start ();

To bardzo proste, ale wyrwanie się z kontekstu nie ma większego sensu, więc włączmy to do naszego komponentu React. W componentDidMounthaku dodamy nasze polecenia i zaczniemy nasłuchiwać, ale zamiast logować się do konsoli, wywołamy dwie metody, które aktualizują poziom powiększenia w naszym stanie:

  zoomIn = () => {

    this.setState ({

      zoom: this.state.zoom + 1

    });

  };

  zoomOut = (... args) => {

    this.setState ({

      zoom: this.state.zoom - 1

    });

  };

  componentDidMount () {

    annyang.addCommands ({

      'in': this.zoomIn,

      'out': this.zoomOut,

    });

    annyang.start ();

  }

Gdy nasza strona odświeża się, przeglądarka prosi nas o pozwolenie na używanie mikrofonu. Jeśli powiesz „tak”, będziesz mógł teraz używać poleceń głosowych „in” i „out”, aby powiększać i pomniejszać. Chcieć więcej? Biblioteka annyang obsługuje także symbole zastępcze i wyrażenia regularne. Aby obsługiwać powiększanie bezpośrednio do określonego poziomu, możemy zdefiniować takie polecenie:

    annyang.addCommands ({

      / * istniejące polecenia * /

      'zoom level: level': {regexp: / ^ zoom level (\ d +) /, callback: this.zoomTo},

    });

To, :levelco jest częścią klucza, jest standardowym sposobem definiowania symbolu zastępczego pojedynczego słowa. (Gdybyśmy chcieli mieć symbol zastępczy z wieloma światami, moglibyśmy *levelzamiast tego użyć .) Domyślnie słowo przechwycone przez symbol zastępczy jest przekazywane jako argument ciągu do funkcji obsługi. Ale jeśli zdefiniujemy procedurę obsługi jako obiekt z kluczami regexi callback, możemy dodatkowo ograniczyć to, czym może być symbol zastępczy. W tym przypadku ograniczamy symbol zastępczy tylko do cyfr. Ten symbol zastępczy nadal będzie przekazywany jako ciąg, więc będziemy musieli przekształcić go w liczbę, gdy ustawiamy poziom powiększenia:

  zoomTo = (zoomLevel) => {

    this.setState ({

      zoom: + zoomLevel,

    });

  }

I to wszystko! Możemy teraz powiększać lub pomniejszać o jeden poziom na raz lub możemy przejść bezpośrednio do poziomu, wypowiadając jego numer. Jeśli bawisz się tym w domu, zauważysz, że annyang potrzebuje kilku sekund, aby zarejestrować polecenie, a czasami polecenia nie są rejestrowane. Rozpoznawanie mowy nie jest doskonałe. Jeśli budujesz rozpoznawanie mowy w systemie produkcyjnym, zechcesz uwzględnić mechanizmy informacji zwrotnej w czasie rzeczywistym dotyczące błędów lub określić, kiedy biblioteka aktywnie nasłuchuje.

Jeśli chcesz pobawić się kodem, możesz go znaleźć na GitHub. Zapraszam do kontaktu na Twitterze, aby udostępnić własne interfejsy multimodalne: @freethejazz.