Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. iOS 10

A Beszédfelismerő API alkalmazása iOS 10-en

by
Difficulty:IntermediateLength:LongLanguages:

Hungarian (Magyar) translation by Andras Czegledi (you can also view the original English article)

Final product image
What You'll Be Creating

Bevezetés

A Siri az iOS egyik fő funkciójává vált mióta 2011-ben bemutatták. Az iOS 10-zel az Apple új funkciókat vezet be, amivel a fejlesztők hozzáférhetnek Sirihez. Két új framework vált elérhetővé: a Speech és a SiriKit.

Ebben a cikkben a Speech framework-kel fogunk foglalkozni, amivel könnyed fordíthatunk hangfájlokat szöveggé. Meg fogjuk tanulni, hogyan építsünk egy működő appot ami a beszédfelismerő API használatával ellenőrzi egy repülőjárat helyzetét.

Hogyha többet szeretnél tudni a SiriKit-ről, olvasd át a Create SiriKit Extensions in iOS 10 bejegyzésemet. Ha pedig az iOS 10  fejlesztők számára elérhető új funkciói érdekelnek, olvasd el Markus Mühlberger kurzusát, itt az Envato Tuts+-on.

Kezelés

A beszédfelismerés alatt az élőbeszéd vagy az előre felvett hangfájl szöveggé alakítását értjük. Mióta Siri bemutatkozott az iOS 5-ben, a billentyűzeten megjelent egy mikrofon gomb, amivel a felhasználók diktálhatnak a telefonnak. Ez a funkció bármelyik UIKit szöveges beviteli mezőben alkalmazható, és nem szükséges extra kódot írni egy standard szövegmező kódján kívül. Nagyon gyorsan és könnyen használható, de van néhány limitációja:

  • A billentyűzet folyamatosan a képernyőn van diktálás közben.
  • A nyelvet nem változtathatja meg az app.
  • Az app nem értesülhet róla, hogy a diktálás mikor kezdődik és mikor ér véget.
Dictation in the iOS keyboard

Annak érdekében hogy a fejlesztők még jobban testreszabbható és jobban használható applikációkat fejleszthessenek a Siri technológiáját felhasználva, az Apple megalkotta a Speech framework-öt. Ezzel minden eszköz ami iOS 10-et futtat képes az audio szöveggé konvertálására, több mint 50 nyelven és dialektusban.

Ez az új API sokkal több dologra képes, mert így nem csak szövegleiratot készít, hanem alternatívákat is felajánl, ha nem érti pontosan hogy a felhasználó mit mondott. A fejlesztő kontrollálhatja hogy mikor legyen a diktálásnak vége, a keresési találatokat beszéd közben is meg lehet mutatni, illetve a beszédfelismerő rendszer automatikusan adaptálódik a felhasználó preferenciáihoz (nyelv, szókincs, nevek, stb.).

Egy érdekes funkció az előre felvett szöveg feldolgozása. Ha például egy üzenetküldő alkalmazást készítesz, akkor ezzel leiratot készíthetsz az audioüzenetekről.

Beállítás

Először is meg kell kérdezned a felhasználót, hogy hozzájárul-e ahhoz, hogy a hangüzeneteit továbbítsuk az Apple-nek analízisre.

Az eszköztől és a felismerendő nyelvtől függően az iOS eldöntheti, hogy magán az eszközön fordítja a hangot szövegre, illetve - ha a lokális beszédfelismerés nem elérhető - továbbítja azt az Apple szervereire.

Ezért szükséges általában aktív internetkapcsolat a beszédelismeréshez. Mindjárt megmutatom, hogy hogyan ellenőrizheted a szolgáltatás elérhetőségét.

A beszédfelismerés három lépésből áll:

  • Magyarázás: írd le a felhasználónak hogy miért akarsz hozzáférni a hangfájljaihoz.
  • Engedélyezés: expliciten kérj engedélyt a hangfájlokhoz való hozzáférésre.
  • Kérelem: tölts be egy előre felvett audiofájlt a lemezről a SFSpeechURLRecognitionRequest paranccsal, vagy streamelj audiót a SFSpeechAudioBufferRecognitionRequest paranccsal, majd dolgozd fel a szöveget.

Hogyha többet szeretnél tudni a Speech framework-ről, nézd meg a 2016-os WWDC 509-es előadását, illetve olvasd el a hivatalos dokumentációt.

Példa

Most pedig megmutatom hogyan készíts egy igazi applikációt ami a beszédfelismerő API-t használja. Egy egyszerű repülőjárat-követő appot fogunk készíteni, amiben a felhasználó csak kimondja a járat számát, az app pedig megmutatja a repülő állapotát. Így igaz, egy apró asszisztenst fogunk készíteni, mint a Siri, ami bármelyik repülőjárat adatait le tudja kérdezni!

Ennek a bejegyzétsnek a GitHub repo-jába feltöltöttem a projekt vázát, amiben egy egy egyszerű UI lesz a segítségünkre a tutorial során. Töltsd le és nyisd meg a projektet Xcode 8.2-ben vagy annak újabb verziójában. Mivel az UI már megvan, nekünk már csak a beszédfelismerő API-ra fókuszálnunk.

Nézzük meg a projektben található class-okat. Az UIViewController+Style.swift tartalmazza az UI frissítéséért felelős kódot. A járatok adatbázisa a FlightsDataSource.swift-ban egy táblázatban van tárolva.

Ha lefuttatod a projektet, így kell kinéznie.

The initial example project

Miután a felhasználó megnyomja a mikrofon gombot, elindítjuk a beszédfelismerést hogy lementsük a járatszámot. Tehát ha a felhasználó kimondja hogy "LX40", megmutatjuk neki hogy melyik kapuhoz kell mennie és mi a járat státusza. Ehhez meghívunk egy függvényt ami kikeresi a járatot az adatbázisból és megmutatja a státuszt.

Először azt vizsgáljuk meg, hogyan tudunk előre felvett audiófájlt feldolgozni. Később megtanuljuk az előbeszéd felismerését is, ami sokkal érdekesebb lesz.

Először is álltsuk be a projektet. Nyisd meg az Info.plist fájlt és adj hozzá egy új sort, aminek a szövegét a felhasználó akkor fogja látni, amikor hozzáférést kérünk a hangfájlokhoz. Az újonnan hozzáadott sor kék kiemeléssel látható az alábbi képen.

The Infoplist file with the newly added key

Ha ez megvan, nyisd meg a ViewController.swift fájlt. Ne foglalkozz a kóddal ami már alapból benne van a class-ban; ez csak az UI frissítését végzi el nekünk.

Minden új framework esetén az első lépés hogy beimportáljuk azt a fájl elején:

Az engedélykérő ablak feldobásához add hozzá az alábbi kódot a viewDidLoad(animated:) metódushoz:

A status változó végzi el azt az UI változtatást ami a felhasználót figyelmezteti, hogy a beszédfelismerés nem lesz elérhető ha valami hiba történik. Minden alkalommal amikor meg akarjuk változtatni az UI-t, új értéket adunk a változónak.

Ha az app még nem kért engedélyt a felhasználótól, az engedélyezés státusza notDetermined lesz, és meghívjuk az askSpeechPermission metódust hogy engedélyt kérjünk, ahogy az a következő lépésben látható majd.

Ha egy bizonyos funkció nem elérhető, mindig graceful fail-t kell alkalmazni. Ezen kívül nagyon fontos, hogy mindig kommunikáld a felhasználó felé ha rögzíted a hangját. Soha ne próbáld meg felismertetni a hangját anélkül, hogy ezt kijeleznéd az UI-t, vagy anélkül hogy a felhasználó nem tud róla.

Íme az engedélykérő függvény implementációja.

A requestAuthorization metódus meghívásával megjelenítjük a beszédfelismeréshez szükséges engedélykérő ablakot, amit az Info.plist-ben definiáltunk. Ezután átváltunk a fő thread-re ha a lezárás egy másik thread-ről hívódott meg - mivel csak a fő thread-ről akarjuk frissíteni az UI-t. A status-hoz új értéket rendelünk, ami frissíti a mikrofon gombot, ezzel is jelezve a felhasználó felé hogy a beszédfelismerés elérhető-e.

Beszédfelismerés előre felvett audiofájlból

Mielőtt megírjuk az előre felvett audió beszédfelismerés kódját, meg kell találnunk az audiófájl URL-jét. A project navigatorban keresd meg az LX40.m4a fájlt. Az iPhone-omon lévő Voice Memos app-al felvettem, ahogy kimondom azt hogy "LX40". Ezzel könnyedén ellenőrizhetjük hogy jó leiratot kapunk-e az audiófájlból.

Tároljuk el az audiófájl URL-jét egy property-ben:

Most végre megismerkedhetünk a Speech framework egyszerűségével és hatékonyságával. Íme a kód ami az egész beszédfelismerést végzi:

Nézzük mit is csinál ez a metódus:

  • Inicializálja az SFSpeechRecognizer instance-et és a guard utasítással leellenőrzi, hogy működik-e a beszédfelismerés. Ha nem működik, akkor a status visszatérési értékét unavailable-re állítjuk. (Az alapértelmezett inicializátor az alapértelmezett felhasználói nyelvet (locale) használja, de ha eltérő nyelvet szeretnél beállítani, használhatod az SFSpeechRecognizer(locale:) inicializátort is).
  • Ha a beszédfelismerés elérhető, létrehozza az SFSpeechURLRecognitionRequest instance-t az előre felvett audiófájl URL-jének átadásával.
  • Elindítja a beszédfelismerést a recognitionTask(with:) metódus meghívásával az előbb létrehozott request-ből.

A lezárás (closure) többször is meg fog hívódni két paraméterrel: egy eredmény- és egy hibaobjektummal.

A recognizer lejátssza a fájlt és megpróbálja inkrementálisan felismerni a szöveget. Ezért hívódik meg a lezárás többször. Minden alkalommal amikor felismer egy betűt, vagy szót, vagy amikor javításokat végez, a lezárás meghívódik frissített objektumokkal.

A result objektum isFinal tulajdonsága true-ra állítódik amikor az audiófájl analizálása befejeződött. Ebben az esetben elindítunk egy keresést az adatbázisunkban, hogy megtaláljuk a járatot a felismert járatszám alapján. A searchFlight függvény fogja megjeleníteni az eredményt.

Az utolsó dolog amit el kell végeznünk a recognizeFile(url:) függvény meghívása a mikrofon gomb megnyomásakor:

Futtasd le az appot egy iOS 10-es eszközön, nyomd meg a mikrofon gombot, és látni fogod az eredményt. Az "LX40" hangfájlt inkrementálisan felismeri az eszköz, és megjeleníti a járat állapotát!

Tipp: A járatszám egy UITextView-ban jelenik meg. Ahogyan azt bizonyára észrevetted, ha bekapcsolod a járatszám detektort az UITextView-ban, akkor rá is nyomhatsz, és a járat jelenlegi állapota fog megjelenni!

A teljes példakód eddig a pontig megtekinthető a GitHub-on a pre-recorded-audio branch-ben.

Élőbeszéd felismerés

Lássuk hogyan implementálhatjuk az élőbeszéd felismerését. Ez egy kicsit bonyolultabb lesz annál mint amit eddig csináltunk. Töltsd le ismét a projekt vázát és kövesd a tutorialt.

Szükségünk van egy új kulcsra az Info.plist fájlban, hogy elmagyarázzuk a felhasználónak miért kell hozzáférnünk a mikrofonhoz. adj hozzá egy új sort az Info.plist-hez ahogy a képen látható.

New row explaining why we need to access the microphone

Nem szükséges manuálisan engedélyt kérnünk a felhasználótól, mert az iOS megteszi azt helyettünk amint megpróbálunk hozzáférni bármilyen mikrofonhoz kötődő API-hoz.

Újra felhasználhatjuk ugyanazt a kódot amit az előző fejezetben használtunk az engedélykéréshez (ne felejtsd el az import Speech parancsot). A viewDidLoad(animated:) metódust ugyanúgy implementáljuk, mint korábban:

A felhasználótól való hozzáférés kérése is megegyezik.

A startRecording implementációja egy kicsit eltérő lesz. Először is adjunk hozzá néhány instance változót, amik később az audio session-öknél és a beszédfelismerésnél hasznosak lesznek.

Nézzük egyesével aváltozókat:

  • Az AVAudioEngine dolgozza fel az audio stream-et. Létrehozunk egy audio node-ot és hozzáadjuk ehhez az engine-hez, így értesülni fogunk róla ha a mikrofon audiojeleket vesz.
  • Az SFSpeechRecognizer ugyanaz az osztály amivel a tutorial előző részében is találkozhattunk, ez végzi a beszéd felismerését. Mivel az inicializátor elbukhat és nil értékkel is visszatérhet, opcionálisnak deklaráljuk, hogy elkerüljük a futás közbeni összeomlást.
  • Az SFSpeechAudioBufferRecognitionRequest egy buffer ami az előbeszédet ismeri fel. Mivel most nincs egy teljes audiofájlunk mint az előbb volt, szükségünk van egy bufferra, amibe a beszédet tölthetjük, miközben a felhasznál beszél.
  • Az SFSpeechRecognitionTask menedzseli a beszédfelismerési task-okat, ezzel állítható meg illetve törölhető a folyamat.

Miuttán minden szükséges változót deklaráltunk, implementáljuk a startRecording-ot.

Ez az általunk létrehozott funkció kódja. Elmagyarázom lépésenként:

  • Először megkapjuk az audioEngine inputNode-ját. Egy eszköznek több audióinputja lehet, itt az elsőt választjuk ki.
  • Beállítjuk az input node-ban hogy az audio stream-et akarjuk monitorozni. Az általunk megadott blokk minden 1024 bájtnyi audio stream után meghívódik. Rögtön hozzáadjuk az audio buffert a request-hez, hogy azonnal megkezdhesse a beszédfelismerést.
  • Felkészítjük az audio engine-t a felvétel elkezdéséhez. Ha a felvétel elkezdődik, akkor a status-t .recognizing-ra állítjuk a gomb ikonját pedig megváltoztatjuk hogy a felhasználót értesítsük arról, hogy felvesszük a hangját.
  • Rendeljük hozzá a speechRecognizer.recognitionTask(with:resultHandler:)-ből visszakapott onbjektumot a recognitionTask változóhoz. Ha a beszédfelismerés sikeres volt, akkor kikeressük a járatot az adatbázisból és frissítjük az UI-t.

A felvétel megállításához csak le kell állítanunk az audio engine-t, kitöröljük az input node-ot és megállítjuk a beszédfelismerés task-ot.

Mostmár csak a felvétel elindítása és megállítása van hátra. Módosítsuk a microphonePressed metódust az alábbiak szerint:

A status változó értéke alapján elindítjuk vagy megállítjuk a beszédfelismerést.

Build-eld és futtasd az app-ot a végeredmény megtekintéséhez. Próbáld lebetűzni bármelyik járatot angol kiejtés szerint és meg fog jelenni annak állapota a kijelzőn.

A példakód elérhető GitHub-on a live-audio branch-ben.

Legjobb gyakorlatok

A beszédfelismerés egy nagyon hasznos API amit az Apple az iOS 10-et célzó fejlesztők számára készített. A használata ingyenes, de jó ha tudod hogy nem használható végtelen alkalommal. Minden egyes beszédfelismerés task körülbelül egy percre van limitálva, ezen kívül az app-odat az Apple szerverei is lelassíthatja, ha túl sok számítási erőforrást használ fel. Mindezek miatt nagy hálózati forgalmat generál és az akkumulátort is nagy mértékben meríti.

Győződj meg róla hogy a felhasználók tisztában vannak a beszédfelismerés működésével, és mindig tájékoztasd a felhasználót arról ha a hangját rögzíted.

Összegzés

Ebben a tutorial-ban megtanultuk hogyan használjuk az iOS 10 gyors, pontos és rugalmasbeszédfelismerését. Ezzel a felhasználók többféle módon kezelhetik az app-odat, így azok számára is jól használható lesz, akik számára az érintőkijelző kezelése problémát okoz.

Ha többet szeretnél tudni arról hogy hogyan integrálhatod Siri-t az applikációdban, vagy hogyha az iOS 10 fejlesztői újításaira vagy kiváncsi, tekitsd meg Markus Mühlberger kurzusát.

Tekintsd meg a többi ingyenes bejegyzésünket is az iOS 10 funkcióiról.


Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.