Utilizzo dell'API di riconoscimento vocale in iOS 10

Cosa starai creando

introduzione

Siri è stata una caratteristica fondamentale di iOS da quando è stata introdotta nel 2011. Ora, iOS 10 offre nuove funzionalità che consentono agli sviluppatori di interagire con Siri. In particolare, sono disponibili due nuovi framework: Speech e SiriKit. 

Oggi daremo un'occhiata al framework Speech, che ci consente di tradurre facilmente l'audio in testo. Imparerai come creare un'app di vita reale che utilizza l'API di riconoscimento vocale per verificare lo stato di un volo.

Se vuoi saperne di più su SiriKit, l'ho descritto nel mio tutorial Create SiriKit Extensions in iOS 10. Per ulteriori informazioni sulle altre nuove funzionalità per gli sviluppatori in iOS 10, consulta il corso di Markus Mühlberger, proprio qui su Envato Tuts+.

uso

Il riconoscimento vocale è il processo di traduzione di audio dal vivo o preregistrato al testo trascritto. Poiché Siri è stato introdotto in iOS 5, nella tastiera di sistema è presente un pulsante del microfono che consente agli utenti di dettare facilmente. Questa funzione può essere utilizzata con qualsiasi input di testo UIKit e non richiede di scrivere codice aggiuntivo oltre a quello che si vorrebbe scrivere per supportare un input di testo standard. È veramente veloce e facile da usare, ma presenta alcune limitazioni:

  • La tastiera è sempre presente durante la dettatura.
  • La lingua non può essere personalizzata dall'app stessa.
  • L'app non può essere avvisata quando inizia e termina la dettatura.

Per consentire agli sviluppatori di creare applicazioni più personalizzabili e potenti con la stessa tecnologia di dettatura di Siri, Apple ha creato il framework Speech. Consente a tutti i dispositivi che eseguono iOS 10 di tradurre audio in testo in oltre 50 lingue e dialetti.

Questa nuova API è molto più potente perché non fornisce solo un semplice servizio di trascrizione, ma fornisce anche interpretazioni alternative di ciò che l'utente può aver detto. Puoi controllare quando interrompere un dettato, puoi mostrare i risultati mentre l'utente parla e il motore di riconoscimento vocale si adatterà automaticamente alle preferenze dell'utente (lingua, vocabolario, nomi, ecc.). 

Una caratteristica interessante è il supporto per la trascrizione dell'audio pre-registrato. Ad esempio, se si sta creando un'app di messaggistica istantanea, è possibile utilizzare questa funzionalità per trascrivere il testo dei nuovi messaggi audio.

Impostare

Prima di tutto, dovrai chiedere all'utente l'autorizzazione a trasmettere la loro voce ad Apple per l'analisi. 

A seconda del dispositivo e della lingua che deve essere riconosciuta, iOS può decidere in modo trasparente di trascrivere l'audio sul dispositivo stesso o, se il riconoscimento vocale locale non è disponibile sul dispositivo, iOS utilizzerà i server Apple per svolgere il lavoro.. 

Questo è il motivo per cui per il riconoscimento vocale è solitamente necessaria una connessione Internet attiva. Ti mostrerò come verificare la disponibilità del servizio molto presto.

Esistono tre passaggi per utilizzare il riconoscimento vocale:

  • Spiega: dì al tuo utente perché vuoi accedere alla loro voce.
  • Autorizza: chiedere esplicitamente l'autorizzazione per accedere alla propria voce.
  • Richiesta: carica un audio pre-registrato dal disco usando SFSpeechURLRecognitionRequest, o streaming audio dal vivo utilizzando SFSpeechAudioBufferRecognitionRequest ed elaborare la trascrizione.

Se vuoi saperne di più sulla struttura del discorso, guarda la sessione 509 del WWDC 2016. Puoi anche leggere la documentazione ufficiale.

Esempio

Ora ti mostrerò come costruire un'app di vita reale che sfrutti l'API di riconoscimento vocale. Stiamo costruendo una piccola app per il monitoraggio del volo in cui l'utente può semplicemente dire un numero di volo e l'app mostrerà lo stato attuale del volo. Sì, costruiremo un piccolo assistente come Siri per controllare lo stato di ogni volo!

Nel repository GitHub del tutorial, ho fornito un progetto skeleton che contiene un'interfaccia utente di base che ci aiuterà per questo tutorial. Scarica e apri il progetto in Xcode 8.2 o versioni successive. A partire da un'interfaccia utente esistente ci concentreremo sull'API di riconoscimento vocale.

Dai un'occhiata alle lezioni del progetto. UIViewController + Style.swift contiene la maggior parte del codice responsabile per l'aggiornamento dell'interfaccia utente. L'origine dati di esempio dei voli visualizzati nella tabella è dichiarata in FlightsDataSource.swift.

Se si esegue il progetto, dovrebbe apparire come il seguente.

Dopo che l'utente preme il pulsante del microfono, vogliamo avviare il riconoscimento vocale per trascrivere il numero del volo. Quindi se l'utente dice "LX40", vorremmo mostrare le informazioni riguardanti il ​​gate e lo stato corrente del volo. Per fare ciò, chiameremo una funzione per cercare automaticamente il volo in un'origine dati e mostrare lo stato del volo. 

Per prima cosa esploreremo come trascrivere dall'audio pre-registrato. Più avanti, impareremo come implementare il riconoscimento vocale dal vivo più interessante.

Iniziamo impostando il progetto. Apri il Info.plist file e aggiungi una nuova riga con la spiegazione che verrà mostrata all'utente quando viene richiesto il permesso di accedere alla propria voce. La riga appena aggiunta è evidenziata in blu nell'immagine seguente.

Una volta fatto, apri ViewController.swift. Non importa il codice che è già in questa classe; si sta solo occupando di aggiornare l'interfaccia utente per noi.

Il primo passo con qualsiasi nuovo framework che si desidera utilizzare è di importarlo nella parte superiore del file.

discorso di importazione

Per mostrare la finestra di dialogo delle autorizzazioni all'utente, aggiungere questo codice nel file viewDidLoad (animato :) metodo:

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

Il stato La variabile si occupa della modifica dell'interfaccia utente per avvisare l'utente che il riconoscimento vocale non è disponibile nel caso in cui qualcosa vada storto. Assegneremo un nuovo stato alla stessa variabile ogni volta che vorremmo cambiare l'interfaccia utente.

Se l'app non ha ancora richiesto l'autorizzazione all'utente, lo stato dell'autorizzazione sarà non determinato, e noi chiamiamo il askSpeechPermission metodo per chiederlo come definito nel passaggio successivo.

Dovresti fallire sempre con garbo se non è disponibile una funzione specifica. È anche molto importante da sempre comunicare all'utente quando si registra la propria voce. Non cercare mai di riconoscere la propria voce senza prima aggiornare l'interfaccia utente e renderla consapevole all'utente.

Ecco l'implementazione della funzione per chiedere l'autorizzazione all'utente.

func askSpeechPermission () SFSpeechRecognizer.requestAuthorization stato in OperationQueue.main.addOperation stato switch caso. autorizzato: self.status = .ready default: self.status = .unavailable

Invochiamo il requestAuthorization metodo per visualizzare la richiesta di privacy di riconoscimento vocale che abbiamo aggiunto al Info.plist. Passiamo quindi al thread principale nel caso in cui la chiusura sia stata invocata su un thread diverso: vogliamo aggiornare l'interfaccia utente solo dal thread principale. Assegniamo il nuovo stato per aggiornare il pulsante del microfono per segnalare all'utente la disponibilità (o meno) del riconoscimento vocale.

Riconoscimento audio pre-registrato

Prima di scrivere il codice per riconoscere l'audio pre-registrato, dobbiamo trovare l'URL del file audio. Nel navigatore del progetto, controlla di avere un file chiamato LX40.m4a. Ho registrato questo file io stesso con l'app Voice Memos sul mio iPhone dicendo "LX40". Possiamo facilmente verificare se otteniamo una corretta trascrizione dell'audio.

Archivia l'URL del file audio in una proprietà:

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

È tempo di vedere finalmente la potenza e la semplicità della struttura del linguaggio. Questo è il codice che fa tutto il riconoscimento vocale per noi:

func recognizeFile (url: URL) guard let recognizer = SFSpeechRecognizer (), recognizer.isAvailable else return let request = SFSpeechURLRecognitionRequest (url: url) recognizer.recognitionTask (con: request) result, error in guard let recognizer = SFSpeechRecognizer (), recognizer.isAvailable else return self.status = .unavailable se let result = result self.flightTextView.text = result.bestTranscription.formattedString if result.isFinal self.searchFlight (number: result.bestTranscription.formattedString)  else if let error = error print (errore)

Ecco cosa sta facendo questo metodo:

  • Inizializza a SFSpeechRecognizer istanza e verificare che il riconoscimento vocale sia disponibile con una dichiarazione di guardia. Se non è disponibile, impostiamo semplicemente lo stato su non disponibile e ritorno. (L'inizializzatore predefinito utilizza le impostazioni locali dell'utente predefinito, ma è anche possibile utilizzare il file SFSpeechRecognizer (locale :) inizializzatore per fornire una diversa localizzazione.)
  • Se è disponibile il riconoscimento vocale, creare a SFSpeechURLRecognitionRequest istanza passando l'URL audio pre-registrato.
  • Avviare il riconoscimento vocale richiamando il recognitionTask (con :) metodo con la richiesta creata in precedenza.

La chiusura verrà chiamata più volte con due parametri: un risultato e un oggetto errore. 

Il riconoscitore sta effettivamente riproducendo il file e cercando di riconoscere il testo in modo incrementale. Per questo motivo, la chiusura viene chiamata più volte. Ogni volta che riconosce una lettera o una parola o esegue alcune correzioni, la chiusura viene invocata con oggetti aggiornati. 

Il risultato l'oggetto ha il isfinal proprietà impostata su true quando il file audio è stato completamente analizzato. In questo caso, iniziamo una ricerca nella nostra origine dati di volo per vedere se riusciamo a trovare un volo con il numero di volo riconosciuto. Il searchFlight la funzione si occuperà di visualizzare il risultato.

L'ultima cosa che ci manca è invocare il recognizeFile (URL :) funzione quando viene premuto il pulsante del microfono:

@IBAction func microphonePressed (_ sender: Any) recognitionFile (url: preRecordedAudioURL)

Esegui l'app sul tuo dispositivo con iOS 10, premi il pulsante del microfono e vedrai il risultato. L'audio "LX40" viene riconosciuto in modo incrementale e viene visualizzato lo stato del volo!

 

Suggerimento: il numero di volo viene visualizzato in una UITextView. Come avrai notato, se abiliti il ​​rilevatore di dati del numero di volo in UITextView, puoi premere su di esso e verrà visualizzato lo stato corrente del volo!

Il codice di esempio completo fino a questo punto può essere visualizzato nel ramo audio pre-registrato in GitHub.

Riconoscimento audio dal vivo

Vediamo ora come implementare il riconoscimento vocale dal vivo. Sarà un po 'più complicato rispetto a quello che abbiamo appena fatto. Puoi ancora scaricare lo stesso progetto scheletro e seguirlo.

Abbiamo bisogno di una nuova chiave nel Info.plist file per spiegare all'utente perché abbiamo bisogno di accedere al microfono. Aggiungi una nuova riga al tuo Info.plist come mostrato nell'immagine.

Non è necessario chiedere manualmente all'utente l'autorizzazione perché iOS lo farà per noi non appena tenteremo di accedere a qualsiasi API relativa al microfono.

Possiamo riutilizzare lo stesso codice che abbiamo usato nella sezione precedente (ricordati di discorso di importazione) per chiedere l'autorizzazione. Il viewDidLoad (animato :) il metodo è implementato esattamente come prima:

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

Inoltre, il metodo per chiedere l'autorizzazione all'utente è lo stesso.

func askSpeechPermission () SFSpeechRecognizer.requestAuthorization stato in OperationQueue.main.addOperation stato switch caso. autorizzato: self.status = .ready default: self.status = .unavailable

L'implementazione di inizia a registrare sarà un po 'diverso. Aggiungiamo innanzitutto alcune nuove variabili di istanza che saranno utili durante la gestione della sessione audio e dell'attività di riconoscimento vocale.

let audioEngine = AVAudioEngine () lascia speechRecognizer: SFSpeechRecognizer? = SFSpeechRecognizer () let request = SFSpeechAudioBufferRecognitionRequest () var recognitionTask: SFSpeechRecognitionTask?

Diamo un'occhiata a ciascuna variabile separatamente:

  • AVAudioEngine è usato per elaborare un flusso audio. Creeremo un nodo audio e lo collegheremo a questo motore in modo che possiamo essere aggiornati quando il microfono riceve alcuni segnali audio.
  • SFSpeechRecognizer è la stessa classe che abbiamo visto nella parte precedente del tutorial e si occupa di riconoscere il discorso. Dato che l'inizializzatore può fallire e restituire nil, lo dichiariamo opzionale per evitare arresti anomali in fase di runtime.
  • SFSpeechAudioBufferRecognitionRequest è un buffer utilizzato per riconoscere il parlato dal vivo. Dato che non abbiamo il file audio completo come facevamo prima, abbiamo bisogno di un buffer per allocare il discorso mentre l'utente parla.
  • SFSpeechRecognitionTask gestisce l'attuale compito di riconoscimento vocale e può essere utilizzato per fermarlo o annullarlo.

Una volta dichiarate tutte le variabili richieste, implementiamo inizia a registrare.

func startRecording () // Setup audio engine e speech recognizer guardia let node = audioEngine.inputNode else return let recordingFormat = node.outputFormat (forBus: 0) node.installTap (onBus: 0, bufferSize: 1024, formato: recordingFormat ) buffer, _ in self.request.append (buffer) // Prepara e avvia la registrazione audioEngine.prepare () do try audioEngine.start () self.status = .recognizing catch return print (error) / / Analizza il riconoscimento vocaleTask = speechRecognizer? .RecognitionTask (con: request, resultHandler: result, error in if let result = result self.flightTextView.text = result.bestTranscription.formattedString self.searchFlight (number: result.bestTranscription.formattedString ) else if let error = error print (errore))

Questo è il codice principale della nostra funzionalità. Lo spiegherò passo dopo passo:

  • Prima otteniamo il inputNode del Audioengine. Un dispositivo può avere più ingressi audio, e qui selezioniamo il primo.
  • Diciamo al nodo di input che vogliamo monitorare il flusso audio. Il blocco che forniamo verrà invocato su ogni stream audio ricevuto di 1024 byte. Alleghiamo immediatamente il buffer audio al richiesta in modo che possa avviare il processo di riconoscimento.
  • Prepariamo il motore audio per iniziare la registrazione. Se la registrazione inizia correttamente, imposta lo stato su .riconoscendo in modo che aggiorniamo l'icona del pulsante per far sapere all'utente che la loro voce viene registrata.
  • Assegniamo l'oggetto restituito da speechRecognizer.recognitionTask (con: resultHandler :) al recognitionTask variabile. Se il riconoscimento ha esito positivo, cerchiamo il volo nella nostra origine dati e aggiorniamo l'interfaccia utente. 

La funzione per annullare la registrazione è semplice come arrestare il motore audio, rimuovere il tocco dal nodo di input e annullare l'operazione di riconoscimento.

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

Ora abbiamo solo bisogno di avviare e interrompere la registrazione. Modifica il microphonePressed metodo come segue:

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

A seconda della corrente stato, iniziamo o fermiamo il riconoscimento vocale.

Costruisci ed esegui l'app per vedere il risultato. Cerca di scrivere uno qualsiasi dei numeri di volo elencati e dovresti vedere il suo stato apparire.

 

Ancora una volta, il codice di esempio può essere visualizzato nel ramo audio live su GitHub.

Migliori pratiche

Il riconoscimento vocale è un'API molto potente che Apple ha fornito agli sviluppatori iOS che hanno come target iOS 10. È completamente gratuito da utilizzare, ma tieni presente che non è illimitato nell'utilizzo. È limitato a circa un minuto per ogni attività di riconoscimento vocale e la tua app potrebbe essere limitata dai server Apple se richiede un numero eccessivo di calcoli. Per questi motivi, ha un forte impatto sul traffico di rete e sull'uso di energia. 

Assicurati che gli utenti siano adeguatamente istruiti su come utilizzare il riconoscimento vocale e sii il più trasparente possibile quando si registra la propria voce. 

Ricapitolare

In questo tutorial, hai visto come utilizzare il riconoscimento vocale veloce, preciso e flessibile in iOS 10. Usalo a tuo vantaggio per dare ai tuoi utenti un nuovo modo di interagire con la tua app e migliorarne l'accessibilità allo stesso tempo. 

Se vuoi saperne di più sull'integrazione di Siri nella tua app, o se vuoi scoprire alcune delle altre interessanti funzioni sviluppate da iOS 10, consulta il corso di Markus Mühlberger.

Inoltre, dai un'occhiata ad alcuni dei nostri tutorial gratuiti su iOS 10.