Bruke API for taleegenkjenning i iOS 10

Hva du skal skape

Introduksjon

Siri har vært en sentral funksjon av iOS siden den ble introdusert tilbake i 2011. Nå bringer iOS 10 nye funksjoner som tillater utviklere å samhandle med Siri. Spesielt er to nye rammer nå tilgjengelig: Tale og SiriKit. 

I dag skal vi ta en titt på talerammen, som gjør at vi enkelt kan oversette lyd til tekst. Du lærer hvordan du bygger en virkelig app som bruker talegjenkjennings-API for å sjekke statusen for et fly.

Hvis du vil lære mer om SiriKit, dekket jeg det i Mine Opprett SiriKit Extensions i IOS 10 opplæringen. For mer om de andre nye funksjonene for utviklere i IOS 10, sjekk Markus Mühlberger kurs, her på Envato Tuts+.

bruk

Talegenkjenning er prosessen med å oversette levende eller forhåndsinnspilt lyd til transkribert tekst. Siden Siri ble introdusert i IOS 5, har det vært en mikrofon-knapp i systemtastaturet som gjør at brukerne enkelt kan diktere. Denne funksjonen kan brukes med hvilken som helst UIKit-tekstinngang, og det krever ikke at du skriver tilleggskode utover det du vil skrive for å støtte en standard tekstinngang. Det er veldig raskt og enkelt å bruke, men det kommer med noen begrensninger:

  • Klaviaturet er alltid tilstede når man dikterer.
  • Språket kan ikke tilpasses av selve appen.
  • Appen kan ikke bli varslet når diktering starter og avsluttes.

For å tillate utviklere å bygge mer tilpassbare og kraftige applikasjoner med samme diktateknologi som Siri, opprettet Apple Speech-rammeverket. Det tillater alle enheter som kjører iOS 10 for å oversette lyd til tekst på over 50 språk og dialekter.

Denne nye API-en er mye kraftigere fordi den ikke bare gir en enkel transkripsjonstjeneste, men gir også alternative tolkninger av hva brukeren har sagt. Du kan kontrollere når du skal stoppe en diktering, du kan vise resultater som brukeren snakker, og talegjenkjenningsmotoren tilpasses automatisk til brukerens preferanser (språk, ordforråd, navn osv.).. 

En interessant funksjon er støtte for transkribering av forhåndsinnspilt lyd. Hvis du bygger en direktemeldingsapp, kan du for eksempel bruke denne funksjonaliteten til å transkribe teksten til nye lydmeldinger.

Setup

Først og fremst må du spørre brukeren om tillatelse til å overføre stemmen til Apple for analyse. 

Avhengig av enheten og språket som skal gjenkjennes, kan iOS automatisk bestemme seg for å transkribere lyden på selve enheten, eller hvis lokal talegjenkjenning ikke er tilgjengelig på enheten, bruker iOS Apples servere til å gjøre jobben. 

Det er derfor en aktiv internettforbindelse vanligvis kreves for talegjenkjenning. Jeg vil vise deg hvordan du sjekker tilgjengeligheten av tjenesten snart.

Det er tre trinn for å bruke talegjenkjenning:

  • Forklar: Fortell brukeren hvorfor du vil få tilgang til stemmen deres.
  • Tillat: Be om autorisasjon for å få tilgang til stemmen sin.
  • Forespørsel: Last inn en forhåndsinnspilt lyd fra disk ved hjelp av SFSpeechURLRecognitionRequest, eller stream live lyd bruk SFSpeechAudioBufferRecognitionRequest og behandle transkripsjonen.

Hvis du vil vite mer om talerammen, se WWDC 2016 sesjon 509. Du kan også lese den offisielle dokumentasjonen.

Eksempel

Jeg vil nå vise deg hvordan du bygger en virkelig app som utnytter talegjenkjennings-API. Vi skal bygge en liten flysporingsapp hvor brukeren bare kan si et flynummer, og appen viser den aktuelle statusen for flyet. Ja, vi skal bygge en liten assistent som Siri for å sjekke statusen for et fly!

I opplæringen er GitHub repo, har jeg gitt et skjelettprosjekt som inneholder et grunnleggende brukergrensesnitt som vil hjelpe oss med denne opplæringen. Last ned og åpne prosjektet i Xcode 8.2 eller høyere. Med utgangspunkt i et eksisterende brukergrensesnitt vil vi fokusere på talegenkjennings-API.

Ta en titt på klassene i prosjektet. UIViewController + Style.swift inneholder det meste av koden som er ansvarlig for oppdateringen av brukergrensesnittet. Eksempeldatakilden for flyene som vises i tabellen er oppgitt i FlightsDataSource.swift.

Hvis du kjører prosjektet, bør det se ut som følgende.

Etter at brukeren trykker på mikrofonknappen, vil vi starte talegjenkjenningen for å transkribere flynummeret. Så hvis brukeren sier "LX40", vil vi gjerne vise informasjonen om porten og nåværende status for flyet. For å gjøre dette, vil vi ringe en funksjon for automatisk å se opp flyet i en datakilde og vise statusen for flyet. 

Vi skal først undersøke hvordan du kan transkribere fra forhåndsinnspilt lyd. Senere lærer vi hvordan vi implementerer den mer interessante levende talegjenkjenningen.

La oss starte med å sette opp prosjektet. Åpne Info.plist fil og legg til en ny rad med forklaringen som vil bli vist til brukeren når du blir bedt om tillatelse til å få tilgang til stemmen deres. Den nylig tilførte raden er uthevet i blått i det følgende bildet.

Når dette er gjort, åpne ViewController.swift. Ikke bry deg om koden som allerede er i denne klassen; Det tar bare vare på å oppdatere brukergrensesnittet for oss.

Det første trinnet med noe nytt rammeverk du vil bruke, er å importere det øverst på filen.

importere tale

For å vise tillatelsesdialogen til brukeren, legg til denne koden i viewDidLoad (animert :) metode:

bytt SFSpeechRecognizer.authorizationStatus () case .notDetermined: askSpeechPermission () tilfelle .authorized: self.status = .ready case .denied, .restricted: self.status = .unavailable

De status variabel tar seg av å endre brukergrensesnittet for å advare brukeren om at talegjenkjenning ikke er tilgjengelig i tilfelle noe går galt. Vi skal tildele en ny status til samme variabel hver gang vi ønsker å endre brukergrensesnittet.

Hvis appen ikke har bedt brukeren om tillatelse ennå, vil autorisasjonsstatusen være ikke bestemt, og vi kaller askSpeechPermission metode for å spørre det som definert i neste trinn.

Du burde alltid mislykkes grasiøst hvis en bestemt funksjon ikke er tilgjengelig. Det er også veldig viktig å alltid kommuniserer til brukeren når du spiller inn stemmen deres. Prøv aldri å gjenkjenne stemmen uten først å oppdatere brukergrensesnittet og gjøre brukeren oppmerksom på det.

Her er implementeringen av funksjonen for å be brukeren om tillatelse.

func askSpeechPermission () SFSpeechRecognizer.requestAuthorization status i OperationQueue.main.addOperation bytt status tilfelle .authorized: self.status = .ready default: self.status = .unavailable

Vi påberoper requestAuthorization metode for å vise talegjenkjenningspersonverns forespørsel som vi har lagt til i Info.plist. Vi bytter deretter til hovedtråden dersom lukkingen ble påkalt på en annen tråd - vi vil bare oppdatere brukergrensesnittet fra hovedtråden. Vi tildeler den nye status for å oppdatere mikrofonknappen for å signalere til brukeren tilgjengeligheten (eller ikke) for talegjenkjenning.

Pre-Recorded Audio Recognition

Før du skriver koden for å gjenkjenne forhåndsinnspilt lyd, må vi finne nettadressen til lydfilen. I prosjektnavigatoren kontrollerer du at du har en fil som heter LX40.m4a. Jeg registrerte denne filen selv med Voice Memos-appen på min iPhone ved å si "LX40". Vi kan enkelt sjekke om vi får en riktig transkripsjon av lyden.

Lagre lydfiladressen i en eiendom:

var preRecordedAudioURL: URL = retur Bundle.main.url (forResource: "LX40", withExtension: "m4a")!  ()

Det er på tide å endelig se kraften og enkelheten i talerammen. Dette er koden som gjør all talegjenkjenning for oss:

func recognizeFile (url: URL) guard let recognizer = SFSpeechRecognizer (), recognizer.isAvailable else return la request = SFSpeechURLRecognitionRequest (url: url) recognizer.recognitionTask (med: request) resultat, feil i vakt let recognizer = SFSpeechRecognizer (), recognizer.isAvailable else return self.status = .unavailable hvis la resultat = resultat self.flightTextView.text = result.bestTranscription.formattedString hvis result.isFinal self.searchFlight (nummer: result.bestTranscription.formattedString)  annet hvis la feil = feil print (error)

Her er hva denne metoden gjør:

  • Initialiser en SFSpeechRecognizer forekomst og kontroller at talegjenkjennelsen er tilgjengelig med en vaktuttalelse. Hvis det ikke er tilgjengelig, setter vi bare statusen til utilgjengelig og returnere. (Standardinitialiser bruker standardbrukerlandskapet, men du kan også bruke SFSpeechRecognizer (locale :) initialiserer for å gi en annen lokalitet.)
  • Hvis talegjenkjenning er tilgjengelig, opprett en SFSpeechURLRecognitionRequest eksempel ved å sende den forhåndsinnspilte lydadressen.
  • Start talegjenkjenningen ved å påkalle recognitionTask (med :) metode med den tidligere opprettede forespørselen.

Lukkingen vil bli kalt flere ganger med to parametre: et resultat og et feilobjekt. 

De kjenneren spiller faktisk filen og prøver å gjenkjenne teksten gradvis. Av denne grunn kalles lukkingen flere ganger. Hver gang det gjenkjenner et brev eller et ord, eller det gjør noen korreksjoner, er nedleggelsen påkalt med oppdaterte objekter. 

De resultat objektet har isFinal Egenskapen satt til sann når lydfilen ble analysert helt. I dette tilfellet starter vi et søk i vår flydatakilde for å se om vi kan finne et fly med det anerkjente flynummeret. De searchFlight funksjonen vil passe på å vise resultatet.

Det siste vi mangler er å påberope seg recognizeFile (url :) Fungerer når mikrofonknappen trykkes:

@IBAction func mikrofonPresset (_ sender: Enhver) recognizeFile (url: preRecordedAudioURL)

Kjør appen på enheten din som kjører iOS 10, trykk på mikrofonknappen, og du får se resultatet. Lyden "LX40" gjenkjennes inkrementert, og flystatusen vises!

 

Tips: Flynummeret vises i en UITextView. Som du kanskje har lagt merke til, hvis du aktiverer Flight Number data detektoren i UITextView, kan du trykke på den og den aktuelle statusen for flyet vil faktisk bli vist!

Den komplette eksemplskoden til dette punktet kan ses i forhåndsinnspilt lydavdeling i GitHub.

Live Audio Recognition

La oss nå se hvordan du implementerer live talegjenkjenning. Det kommer til å bli litt mer komplisert enn hva vi nettopp gjorde. Du kan igjen laste ned det samme skjelettprosjektet og følge med.

Vi trenger en ny nøkkel i Info.plist fil for å forklare brukeren hvorfor vi trenger tilgang til mikrofonen. Legg til en ny rad til din Info.plist som vist på bildet.

Vi trenger ikke å manuelt spørre brukeren om tillatelse fordi iOS vil gjøre det for oss så snart vi prøver å få tilgang til hvilken som helst mikrofonelatert API.

Vi kan gjenbruke den samme koden som vi brukte i forrige seksjon (husk å importere tale) å be om autorisasjonen. De viewDidLoad (animert :) Metoden implementeres akkurat som før:

bytt SFSpeechRecognizer.authorizationStatus () case .notDetermined: askSpeechPermission () tilfelle .authorized: self.status = .ready case .denied, .restricted: self.status = .unavailable

Også metoden for å spørre brukeren om tillatelse er det samme.

func askSpeechPermission () SFSpeechRecognizer.requestAuthorization status i OperationQueue.main.addOperation bytt status tilfelle .authorized: self.status = .ready default: self.status = .unavailable

Gjennomføringen av start opptak kommer til å være litt annerledes. La oss først legge til noen nye instansvariabler som vil komme til nytte når du administrerer lydsesjonen og talegjenkjenningsoppgaven.

la lydEngine = AVAudioEngine () la speechRecognizer: SFSpeechRecognizer? = SFSpeechRecognizer () la request = SFSpeechAudioBufferRecognitionRequest () var recognitionTask: SFSpeechRecognitionTask?

La oss ta en titt på hver variabel separat:

  • AVAudioEngine brukes til å behandle en lydstrøm. Vi vil opprette en lydknude og legge den til denne motoren slik at vi kan få oppdatert når mikrofonen mottar noen lydsignaler.
  • SFSpeechRecognizer er den samme klassen vi har sett i forrige del av opplæringen, og det tar seg av å gjenkjenne talen. Gitt at initieringsprogrammet kan mislykkes og returnere null, erklærer vi det som valgfritt for å unngå å krasje ved brukstid.
  • SFSpeechAudioBufferRecognitionRequest er en buffer som brukes til å gjenkjenne levende tale. Gitt at vi ikke har den komplette lydfilen som vi gjorde før, trenger vi en buffer for å tildele talen som brukeren snakker.
  • SFSpeechRecognitionTask administrerer gjeldende talegjenkjenningsoppgave og kan brukes til å stoppe eller avbryte den.

Når vi har erklært alle nødvendige variabler, la oss implementere start opptak.

func startRecording () // Oppsett lydmotor og talegjenkjenning vakt la node = audioEngine.inputNode annet return la recordingFormat = node.outputFormat (forBus: 0) node.installTap (onBus: 0, bufferSize: 1024, format: recordingFormat ) buffer, _ i self.request.append (buffer) // Forbered og start opptaket audioEngine.prepare () gjør prøv audioEngine.start () self.status = .recognizing fange returutskrift (feil) / / Analysér talegjenkjenningTask = Talekjenkjenning ?.Kjenkjenningstabell (med: Forespørsel, ResultatHandler: Resultat, Feil i hvis La Resultat = Resultat self.flightTextView.text = result.bestTranscription.formattedString self.searchFlight (nummer: result.bestTranscription.formattedString ) ellers hvis la feil = feil skriv ut (feil))

Dette er kjernekoden til vår funksjon. Jeg vil forklare det trinnvis:

  • Først får vi inputNode av Audioengine. En enhet kan muligens ha flere lydinnganger, og her velger vi den første.
  • Vi forteller inngangsnoden som vi vil overvåke lydstrømmen. Blokken som vi gir, vil bli påkalt på hver mottatt lydstrøm på 1024 byte. Vi legger umiddelbart lydbufferen til be om slik at den kan starte anerkjennelsesprosessen.
  • Vi forbereder lydmotor for å starte opptaket. Hvis opptaket starter, må du stille inn statusen til .gjenkjenne slik at vi oppdaterer knappikonet for å la brukeren vite at stemmen deres blir tatt opp.
  • La oss tildele den returnerte gjenstanden fra speechRecognizer.recognitionTask (med: resultHandler :) til recognitionTask variabel. Hvis godkjenningen er vellykket, søker vi flyet i datakilden vår og oppdaterer brukergrensesnittet. 

Funksjonen for å avbryte opptaket er like enkelt som å stoppe lydmotoren, fjerne trykknappen fra inngangskoden og kansellere gjenkjenningsoppgaven.

func cancelRecording () audioEngine.stop () hvis la node = audioEngine.inputNode node.removeTap (onBus: 0) recognitionTask? .cancel ()

Vi trenger nå bare å starte og stoppe opptaket. Endre microphonePressed metode som følger:

@IBAction func mikrofonPressed () switch status case.ready: startRecording () status = .recognizing case .recognizing: cancelRecording () status = .ready default: break

Avhengig av gjeldende status, vi starter eller stopper talegjenkjenningen.

Bygg og kjør appen for å se resultatet. Prøv å stave noen av de angitte flynummerene, og du bør se at statusen vises.

 

Igjen kan eksempelkoden bli vist i live-lydgrenen på GitHub.

Beste praksis

Taleegenkjenning er en veldig kraftig API som Apple ga til iOS-utviklere som målrettet mot iOS 10. Det er helt gratis å bruke, men husk at det ikke er ubegrenset i bruk. Det er begrenset til omtrent ett minutt for hver talegjenkjennelsesoppgave, og appen din kan også bli smurt av Apples servere hvis den krever for mye beregning. Av disse grunner har det stor innvirkning på nettverkstrafikk og strømforbruk. 

Pass på at brukerne dine er riktig instruert om hvordan du bruker talegjenkjenning, og vær så gjennomsiktig som mulig når du spiller inn stemmen deres. 

oppsummering

I denne veiledningen har du sett hvordan du bruker rask, nøyaktig og fleksibel talegjenkjenning i iOS 10. Bruk det til din fordel å gi brukerne en ny måte å samhandle med din app og forbedre tilgjengeligheten samtidig. 

Hvis du vil lære mer om å integrere Siri i appen din, eller hvis du vil finne ut om noen av de andre kule utviklerfunksjonene i IOS 10, sjekk Markus Mühlberger kurs.

Se også noen av våre andre gratis opplæringsprogrammer på iOS 10-funksjoner.