Siri is een belangrijk kenmerk van iOS sinds het in 2011 werd geïntroduceerd. Nu biedt iOS 10 nieuwe functies waarmee ontwikkelaars met Siri kunnen communiceren. In het bijzonder zijn nu twee nieuwe frameworks beschikbaar: Speech en SiriKit.
Vandaag gaan we het Speech-framework bekijken, waarmee we audio eenvoudig in tekst kunnen vertalen. U leert hoe u een real-life app bouwt die de API voor spraakherkenning gebruikt om de status van een vlucht te controleren.
Als je meer wilt weten over SiriKit, heb ik dit behandeld in mijn Create SiriKit Extensions in iOS 10-zelfstudie. Kijk voor meer informatie over de andere nieuwe functies voor ontwikkelaars in iOS 10 op de cursus van Markus Mühlberger, hier op Envato Tuts+.
Spraakherkenning is het proces waarbij live of vooraf opgenomen audio naar getranscribeerde tekst wordt vertaald. Sinds Siri werd geïntroduceerd in iOS 5, is er een microfoonknop op het systeemtoetsenbord geplaatst waarmee gebruikers eenvoudig kunnen dicteren. Deze functie kan worden gebruikt met elke UIKit-tekstinvoer en u hoeft geen extra code te schrijven die verder gaat dan wat u zou schrijven om een standaard tekstinvoer te ondersteunen. Het is echt snel en gemakkelijk te gebruiken, maar het heeft enkele beperkingen:
Om ontwikkelaars in staat te stellen meer aanpasbare en krachtige applicaties met dezelfde dicteertechnologie als Siri te bouwen, creëerde Apple het Speech-framework. Hiermee kan elk apparaat met iOS 10 audio vertalen naar tekst in meer dan 50 talen en dialecten.
Deze nieuwe API is veel krachtiger omdat deze niet alleen een eenvoudige transcriptieservice biedt, maar ook alternatieve interpretaties biedt van wat de gebruiker mogelijk heeft gezegd. U kunt bepalen wanneer een dictaat moet worden gestopt, u kunt resultaten weergeven terwijl uw gebruiker spreekt en het spraakherkenningsprogramma past zich automatisch aan aan de gebruikersvoorkeuren (taal, woordenschat, namen, etc.).
Een interessante functie is ondersteuning voor het overschrijven van vooraf opgenomen audio. Als u bijvoorbeeld een Instant Messaging-app aan het bouwen bent, kunt u deze functie gebruiken om de tekst van nieuwe audioberichten te transcriberen.
Allereerst moet u de gebruiker om toestemming vragen om zijn stem naar Apple te verzenden voor analyse.
Afhankelijk van het apparaat en de taal die moet worden herkend, kan iOS op transparante wijze besluiten om de audio op het apparaat zelf te transcriberen of, als lokale spraakherkenning niet beschikbaar is op het apparaat, zal iOS de servers van Apple gebruiken om het werk te doen.
Daarom is meestal een actieve internetverbinding vereist voor spraakherkenning. Ik zal u laten zien hoe u de beschikbaarheid van de service zeer snel kunt controleren.
Er zijn drie stappen om spraakherkenning te gebruiken:
SFSpeechURLRecognitionRequest
, of stream live audio met SFSpeechAudioBufferRecognitionRequest
en verwerk de transcriptie.Als je meer wilt weten over het Speech-framework, bekijk dan WWDC 2016 Session 509. Je kunt ook de officiële documentatie lezen.
Ik laat je nu zien hoe je een real-life app bouwt die gebruik maakt van de spraakherkennings-API. We gaan een kleine app voor het volgen van vluchten bouwen waarin de gebruiker eenvoudigweg een vluchtnummer kan zeggen en de app zal de huidige status van de vlucht weergeven. Ja, we gaan een kleine assistent zoals Siri bouwen om de status van een vlucht te controleren!
In de GitHub-repo van de zelfstudie heb ik een skeletproject geleverd met een eenvoudige gebruikersinterface die ons zal helpen bij deze zelfstudie. Download en open het project in Xcode 8.2 of hoger. Beginnend met een bestaande gebruikersinterface kunnen we ons richten op de API voor spraakherkenning.
Bekijk de lessen in het project. UIViewController + Style.swift
bevat de meeste code die verantwoordelijk is voor het updaten van de gebruikersinterface. De voorbeeldgegevensbron van de vluchten die in de tabel worden weergegeven, wordt aangegeven in FlightsDataSource.swift
.
Als u het project uitvoert, ziet het er als volgt uit.
Nadat de gebruiker op de microfoonknop heeft gedrukt, willen we de spraakherkenning starten om het vluchtnummer te transcriberen. Dus als de gebruiker 'LX40' zegt, willen we graag de informatie over de gate en de huidige status van de vlucht weergeven. Om dit te doen, zullen we een functie bellen om automatisch de vlucht op te zoeken in een gegevensbron en de status van de vlucht te tonen.
We gaan eerst onderzoeken hoe je kunt transcriberen van vooraf opgenomen audio. Later leren we hoe we de interessantere live spraakherkenning kunnen implementeren.
Laten we beginnen met het opzetten van het project. Open de Info.plist
bestand en voeg een nieuwe rij toe met de uitleg die aan de gebruiker wordt getoond wanneer hem toestemming wordt gevraagd om toegang te krijgen tot zijn stem. De nieuw toegevoegde rij is blauw gemarkeerd in de volgende afbeelding.
Zodra dit is gebeurd, open ViewController.swift
. Let niet op de code die al in deze klasse staat; het zorgt alleen voor het updaten van de gebruikersinterface voor ons.
De eerste stap met elk nieuw framework dat u wilt gebruiken, is om het bovenaan het bestand te importeren.
Spraak importeren
Om het toestemmingsvenster voor de gebruiker weer te geven, voegt u deze code toe in de viewDidLoad (geanimeerde :)
methode:
schakel SFSpeechRecognizer.authorizationStatus () case .notDetermined: askSpeechPermission () case. geautorized: self.status = .ready case .denied, .restricted: self.status = .unavailable
De staat
variabele zorgt ervoor dat de gebruikersinterface wordt gewijzigd om de gebruiker te waarschuwen dat spraakherkenning niet beschikbaar is voor het geval er iets misgaat. We gaan een nieuwe status toewijzen aan dezelfde variabele elke keer dat we de gebruikersinterface zouden willen wijzigen.
Als de app de gebruiker nog geen toestemming heeft gevraagd, is de autorisatiestatus niet bepaald
, en we noemen het askSpeechPermission
methode om het te vragen zoals gedefinieerd in de volgende stap.
Je zou moeten faal altijd elegant als een specifieke functie niet beschikbaar is. Het is ook heel belangrijk om altijd te doen communiceren met de gebruiker wanneer u hun stem opneemt. Probeer nooit hun stem te herkennen zonder eerst de gebruikersinterface bij te werken en uw gebruiker hiervan op de hoogte te stellen.
Hier is de implementatie van de functie om de gebruiker om toestemming te vragen.
func askSpeechPermission () SFSpeechRecognizer.requestAuthorization status in OperationQueue.main.addOperation switch-status case. authorized: self.status = .ready default: self.status = .unavailable
We roepen het requestAuthorization
methode om het privacy-verzoek voor spraakherkenning weer te geven dat we hebben toegevoegd aan de Info.plist
. We schakelen vervolgens over naar de hoofdthread in het geval dat de sluiting werd aangeroepen op een andere thread. We willen de gebruikersinterface alleen via de hoofdthread bijwerken. We wijzen het nieuwe toe staat
om de microfoonknop bij te werken om de gebruiker de beschikbaarheid (of niet) van spraakherkenning te signaleren.
Voordat we de code schrijven om vooraf opgenomen audio te herkennen, moeten we de URL van het audiobestand vinden. Controleer in de projectnavigator of u een bestand met de naam hebt LX40.m4a
. Ik heb dit bestand zelf opgenomen met de Voice Memo-app op mijn iPhone door "LX40" te zeggen. We kunnen eenvoudig controleren of we een correcte transcriptie van de audio krijgen.
Bewaar de audiobestands-URL in een eigenschap:
var preRecordedAudioURL: URL = return Bundle.main.url (for Resource: "LX40", withExtension: "m4a")! ()
Het is tijd om eindelijk de kracht en eenvoud van het Speech-framework te zien. Dit is de code die alle spraakherkenning voor ons doet:
func recognitionFile (url: URL) guard let recognizer = SFSpeechRecognizer (), recognizer.isAvailable else return let request = SFSpeechURLRecognitionRequest (url: url) recognizer.recognitionTask (with: request) result, fout in bewaker laat herkenner = SFSpeechRecognizer (), recognizer.isBeschikbaar anders return self.status = .unavailable als resultaat laten zien = resultaat self.flightTextView.text = result.bestTranscription.formattedString if result.isFinal self.searchFlight (number: result.bestTranscription.formattedString) else if let error = error print (error)
Dit is wat deze methode doet:
SFSpeechRecognizer
bijvoorbeeld en controleer of de spraakherkenning beschikbaar is met een bewakingsinstructie. Als het niet beschikbaar is, stellen we gewoon de status in niet beschikbaar
En terugkomen. (De standaardinitialisatie gebruikt de standaardgebruikerslandinstelling, maar u kunt ook de SFSpeechRecognizer (locale :)
initializer om een andere locale te bieden.)SFSpeechURLRecognitionRequest
bijvoorbeeld door de vooraf opgenomen audio-URL door te geven.recognitionTask (met :)
methode met het eerder gemaakte verzoek.De sluiting wordt meerdere keren aangeroepen met twee parameters: een resultaat en een foutobject.
De herkenner
speelt in feite het bestand en probeert de tekst stapsgewijs te herkennen. Om deze reden wordt de sluiting meerdere keren genoemd. Telkens wanneer een letter of een woord wordt herkend of er enkele correcties worden aangebracht, wordt de sluiting aangeroepen met actuele objecten.
De resultaat
object heeft de isFinal
eigenschap ingesteld op true wanneer het audiobestand volledig is geanalyseerd. In dit geval starten we een zoekopdracht in onze vluchtgegevensbron om te zien of we een vlucht met het erkende vluchtnummer kunnen vinden. De searchFlight
functie zorgt voor weergave van het resultaat.
Het laatste wat we missen is het aanroepen van de recognizeFile (url :)
functie wanneer de microfoonknop wordt ingedrukt:
@IBAction func microphonePressed (_ sender: Any) recognisefile (url: preRecordedAudioURL)
Voer de app uit op uw apparaat met iOS 10, druk op de microfoonknop en u ziet het resultaat. De audio "LX40" wordt stapsgewijs herkend en de vluchtstatus wordt weergegeven!
Tip: het vluchtnummer wordt weergegeven in een UITextView. Zoals je misschien hebt gemerkt, als je de datanaald van het vluchtnummer in de UITextView inschakelt, kun je erop drukken en de huidige status van de vlucht wordt daadwerkelijk weergegeven!
De volledige voorbeeldcode tot aan dit punt kan worden bekeken in de pre-recorded-audio-vertakking in GitHub.
Laten we nu kijken hoe we live spraakherkenning kunnen implementeren. Het zal een beetje ingewikkelder worden in vergelijking met wat we net deden. U kunt hetzelfde skeletproject opnieuw downloaden en volgen.
We hebben een nieuwe sleutel nodig in de Info.plist
bestand om aan de gebruiker uit te leggen waarom we toegang tot de microfoon nodig hebben. Voeg een nieuwe rij toe aan uw Info.plist
zoals getoond in de afbeelding.
We hoeven de gebruiker niet handmatig toestemming te vragen omdat iOS dit voor ons zal doen zodra we toegang proberen te krijgen tot een microfoon-gerelateerde API.
We kunnen dezelfde code hergebruiken die we in de vorige sectie hebben gebruikt (vergeet niet Spraak importeren
) om toestemming te vragen. De viewDidLoad (geanimeerde :)
methode is precies zoals voorheen geïmplementeerd:
schakel SFSpeechRecognizer.authorizationStatus () case .notDetermined: askSpeechPermission () case. geautorized: self.status = .ready case .denied, .restricted: self.status = .unavailable
Ook is de methode om de gebruiker toestemming te vragen hetzelfde.
func askSpeechPermission () SFSpeechRecognizer.requestAuthorization status in OperationQueue.main.addOperation switch-status case. authorized: self.status = .ready default: self.status = .unavailable
De implementatie van start met opnemen
zal een beetje anders zijn. Laten we eerst een paar nieuwe instantievariabelen toevoegen die van pas zullen komen bij het beheren van de audiosessie en de spraakherkenningstaak.
laat audioEngine = AVAudioEngine () laat speechRecognizer: SFSpeechRecognizer? = SFSpeechRecognizer () laatverzoek = SFSpeechAudioBufferRecognitionRequest () var recognitionTask: SFSpeechRecognitionTask?
Laten we elke variabele afzonderlijk bekijken:
AVAudioEngine
wordt gebruikt om een audiostream te verwerken. We zullen een audioknooppunt maken en dit koppelen aan deze engine, zodat we kunnen worden bijgewerkt wanneer de microfoon een aantal audiosignalen ontvangt.SFSpeechRecognizer
is dezelfde klas die we hebben gezien in het vorige deel van de tutorial, en het zorgt voor de herkenning van de speech. Aangezien de initializer kan mislukken en niets teruggeven, geven we aan dat deze de optionele is om crashen tijdens runtime te voorkomen.SFSpeechAudioBufferRecognitionRequest
is een buffer die wordt gebruikt om de live speech te herkennen. Aangezien we niet het volledige audiobestand hebben zoals we eerder deden, hebben we een buffer nodig om de spraak toe te wijzen als de gebruiker spreekt.SFSpeechRecognitionTask
beheert de huidige spraakherkenningstaak en kan worden gebruikt om deze te stoppen of te annuleren.Zodra we alle vereiste variabelen hebben verklaard, laten we het implementeren start met opnemen
.
func startRecording () // Setup audio engine en spraakherkenner bewaar knooppunt = audioEngine.inputNode else return laat recordingFormat = node.outputFormat (forBus: 0) node.installTap (onBus: 0, bufferSize: 1024, format: recordingFormat ) buffer, _ in self.request.append (buffer) // Bereid u voor en begin met het opnemen van audioEngine.prepare () do try audioEngine.start () self.status = .recognizing catch return print (error) / / Analyseer de spraakherkenningTask = speechRecognizer? .RecognitionTask (met: request, resultHandler: result, error in if let result = resultaat self.flightTextView.text = result.bestTranscription.formattedString self.searchFlight (number: result.bestTranscription.formattedString ) else if let error = error print (error))
Dit is de kerncode van onze functie. Ik zal het stap voor stap uitleggen:
inputNode
van de Audioengine
. Een apparaat kan mogelijk meerdere audio-ingangen hebben en hier selecteren we de eerste.verzoek
zodat het herkenningsproces kan starten..herkennen
zodat we het knoppictogram bijwerken om de gebruiker te laten weten dat zijn stem wordt opgenomen.speechRecognizer.recognitionTask (met: resultHandler :)
naar de recognitionTask
variabel. Als de herkenning succesvol is, zoeken we de vlucht in onze gegevensbron en werken we de gebruikersinterface bij. De functie om de opname te annuleren is net zo eenvoudig als het stoppen van de audiomachine, het verwijderen van de tik van het ingangsknooppunt en het annuleren van de herkenningstaak.
func cancelRecording () audioEngine.stop () if let node = audioEngine.inputNode node.removeTap (onBus: 0) recognitionTask? .cancel ()
We hoeven nu alleen maar de opname te starten en te stoppen. Wijzig de microphonePressed
methode als volgt:
@IBAction func microphonePressed () switchstatus case .ready: startRecording () status =. Herkenning van case .herkenning: cancelRecording () status = .ready default: break
Afhankelijk van de stroom staat
, we starten of stoppen de spraakherkenning.
Bouw en voer de app uit om het resultaat te bekijken. Probeer een van de vermelde vluchtnummers te spellen en u zou de status ervan moeten zien verschijnen.
Nogmaals, de voorbeeldcode kan worden bekeken in de live-audiotak op GitHub.
Spraakherkenning is een zeer krachtige API die Apple heeft verstrekt aan iOS-ontwikkelaars die gericht zijn op iOS 10. Het is volledig gratis te gebruiken, maar onthoud dat het niet onbeperkt is in gebruik. Het is gelimiteerd tot ongeveer één minuut voor elke spraakherkenningstaak en uw app kan ook worden ingeklemd door de servers van Apple als het te veel berekeningen vereist. Om deze redenen heeft dit een grote invloed op het netwerkverkeer en het stroomverbruik.
Zorg ervoor dat uw gebruikers correct zijn geïnstrueerd over het gebruik van spraakherkenning en wees zo transparant mogelijk wanneer u hun stem opneemt.
In deze zelfstudie hebt u gezien hoe u snelle, nauwkeurige en flexibele spraakherkenning in iOS 10 kunt gebruiken. Gebruik het in uw eigen voordeel om uw gebruikers een nieuwe manier van interactie met uw app te bieden en tegelijkertijd de toegankelijkheid te verbeteren.
Als je meer wilt weten over de integratie van Siri in je app, of als je meer wilt weten over de andere coole ontwikkelaarstoepassingen van iOS 10, ga dan naar de cursus van Markus Mühlberger.
Bekijk ook enkele van onze andere gratis tutorials over iOS 10-functies.