Usare lo Speech to Text di Siri nelle applicazioni iOS10

Al WWDC 2016, Apple ha introdotto il framework Speech, una API utile per il riconoscimento vocale. Infatti, lo Speech Kit è il framework che Siri utilizza per il riconoscimento vocale. Ci sono una manciata di framework di riconoscimento vocale oggi disponibili, ma sono o molto costosi o semplicemente non adatti.

siri spot text to speech

In questo tutorial, vi mostrerò come creare una applicazione come Siri per trasformare la voce in testo utilizzando Speech Kit.

Prerequisito: devi avere Xcode 8 beta e un dispositivo con la versione beta di iOS 10.

Cominciamo con la creazione di un nuovo progetto iOS Single View Application con il nomeSpeechToTextDemo. Poi, vai al tuo Main.storyboard e aggiungiamo un UILabel, un UITextView , e un UIButton .

speechkit-demo-1-1024x597

Quindi, definiamo le variabili outlet per la UITextView e la UIButton in ViewController.swift . In questa demo, ho impostato il nome di UITextView come “textView”, e il nome del UIButton come “microphoneButton”. Inoltre, creiamo un metodo IBAction che viene attivato quando il pulsante del microfono viene toccato:

[code lang=”swift”]
@IBAction func microphoneTapped(_ sender: AnyObject) {

}
[/code]

Usare il framework

Per usare il framework Speech, è necessario importarlo e adottare il protocollo SFSpeechRecognizerDelegate. Ora il vostro ViewController.swift dovrebbe essere simile a questo:

[code lang=”swift”]
import UIKit
import Speech

class ViewController: UIViewController, SFSpeechRecognizerDelegate {

@IBOutlet weak var textView: UITextView!
@IBOutlet weak var microphoneButton: UIButton!

override func viewDidLoad() {
super.viewDidLoad()

}

@IBAction func microphoneTapped(_ sender: AnyObject) {

}

}
[/code]

Autorizzazione utente

Prima di utilizzare il framework vocale per il riconoscimento, si deve prima chiedere il permesso degli utenti, perché il riconoscimento non avviene solo localmente sul dispositivo iOS, ma sui server di Apple. Tutti i dati voce vengono trasmessi al backend di Apple per l’elaborazione. Pertanto, è obbligatorio per ottenere l’autorizzazione dell’utente.

Cerchiamo di autorizzare il sistema di riconoscimento vocale nel metodo viewDidLoad. L’utente deve consentire all’applicazione di utilizzare l’audio in ingresso e il riconoscimento vocale. In primo luogo, dichiarare speechRecognizer come variabile:

[code lang=”swift”]
private let speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "en-US")) //1
[/code]

Ed aggiorniamo il metodo.

[code lang=”swift”]
override func viewDidLoad() {
super.viewDidLoad()

microphoneButton.isEnabled = false //2

speechRecognizer.delegate = self //3

SFSpeechRecognizer.requestAuthorization { (authStatus) in //4

var isButtonEnabled = false

switch authStatus { //5
case .authorized:
isButtonEnabled = true

case .denied:
isButtonEnabled = false
print("User denied access to speech recognition")

case .restricted:
isButtonEnabled = false
print("Speech recognition restricted on this device")

case .notDetermined:
isButtonEnabled = false
print("Speech recognition not yet authorized")
}

OperationQueue.main.addOperation() {
self.microphoneButton.isEnabled = isButtonEnabled
}
}
}
[/code]

  1. In primo luogo, creiamo un SFSpeechRecognizer ad esempio con un identificatore locale di en-US (oppure per l’italiano it-IT) in modo che il “riconoscitore” vocale sappia che lingua l’utente stia parlando. Questo è l’oggetto che gestisce il riconoscimento vocale.
  2. Per impostazione predefinita, disattivare il pulsante del microfono fino a quando viene attivato il sistema di riconoscimento vocale.
  3. Quindi, impostare il delegato riconoscitore vocale di self che in questo caso è il nostro ViewController .
  4. Dopo, bisogna richiedere l’autorizzazione di riconoscimento vocale chiamando SFSpeechRecognizer.requestAuthorization.
  5. Infine, controllare lo stato della verifica. Se è autorizzato, attivare il pulsante del microfono. In caso contrario, stampare il messaggio di errore e disattivare il pulsante del microfono.

Ora si potrebbe pensare che eseguendo l’applicazione si dovrebbe vedere un avviso di autorizzazione, ma vi sbagliate. Se si esegue, l’applicazione si blocca.

Fornire i messaggi di autorizzazione

Apple richiede a tutte le autorizzazioni di avere un messaggio personalizzato dall’applicazione. In caso di autorizzazione speech, dobbiamo autorizzare due cose:

  1. l’uso del microfono.
  2. Riconoscimento vocale.

Per personalizzare i messaggi, è necessario fornire questi messaggi personalizzati attraverso il file info.plist.

Apriamo il nostro info.plist come codice sorgente: in primo luogo, fare clic destro sul info.plist . Poi Apri come > codice sorgente. Infine, copiare il seguente codice XML e inserirli prima del </dict> tag.

[code lang=”xml”]
&amp;amp;lt;key&amp;amp;gt;NSMicrophoneUsageDescription&amp;amp;lt;/key&amp;amp;gt; &amp;amp;lt;string&amp;amp;gt;Your microphone will be used to record your speech when you press the &amp;amp;amp;quot;Start Recording&amp;amp;amp;quot; button.&amp;amp;lt;/string&amp;amp;gt;
&amp;amp;lt;key&amp;amp;gt;NSSpeechRecognitionUsageDescription&amp;amp;lt;/key&amp;amp;gt; &amp;amp;lt;string&amp;amp;gt;Speech recognition will be used to determine which words you speak into this device&amp;amp;amp;apos;s microphone.&amp;amp;lt;/string&amp;amp;gt;
[/code]

Ora che hai aggiunto le due chiavi a info.plist :

  • NSMicrophoneUsageDescription – il messaggio personalizzato per l’autorizzazione del vostro ingresso audio. Si noti che l’autorizzazione avverrà solo quando l’utente fa clic sul pulsante del microfono.
  • NSSpeechRecognitionUsageDescription – il messaggio personalizzato per il riconoscimento vocale
    Sentitevi liberi di modificare i valori di questi record. Ora premere il pulsante Run, si dovrebbe essere in grado di compilare ed eseguire l’applicazione senza errori.

Nota: Se non vedi l’autorizzazione audio, quando il progetto sarà completo, è perché si esegue l’applicazione su un simulatore. Il simulatore iOS non ha accesso al microfono del tuo Mac.

speech-kit-2

Gestione riconoscimento vocale

Ora che abbiamo implementato l’autorizzazione dell’utente, passiamo sulla realizzazione del riconoscimento vocale.Iniziamo definendo i seguenti oggetti nel ViewController:

[code lang=”swift”]
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var recognitionTask: SFSpeechRecognitionTask?
private let audioEngine = AVAudioEngine()
[/code]

Questo oggetto gestisce le richieste di riconoscimento vocale. Esso fornisce un ingresso audio per il sistema di riconoscimento vocale. Successivamente, creiamo una nuova funzione chiamata startRecording()

 

[code lang=”swift”]
func startRecording() {

if recognitionTask != nil {
recognitionTask?.cancel()
recognitionTask = nil
}

let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryRecord)
try audioSession.setMode(AVAudioSessionModeMeasurement)
try audioSession.setActive(true, with: .notifyOthersOnDeactivation)
} catch {
print("audioSession properties weren’t set because of an error.")
}

recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

guard let inputNode = audioEngine.inputNode else {
fatalError("Audio engine has no input node")
}

guard let recognitionRequest = recognitionRequest else {
fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")
}

recognitionRequest.shouldReportPartialResults = true

recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in

var isFinal = false

if result != nil {

self.textView.text = result?.bestTranscription.formattedString
isFinal = (result?.isFinal)!
}

if error != nil || isFinal {
self.audioEngine.stop()
inputNode.removeTap(onBus: 0)

self.recognitionRequest = nil
self.recognitionTask = nil

self.microphoneButton.isEnabled = true
}
})

let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
self.recognitionRequest?.append(buffer)
}

audioEngine.prepare()

do {
try audioEngine.start()
} catch {
print("audioEngine couldn’t start because of an error.")
}

textView.text = "Say something, I’m listening!"

}
[/code]

 

Questa funzione viene chiamata quando il pulsante Start Recording è toccato. La sua funzione principale è quella di avviare il riconoscimento vocale e iniziare ad ascoltare il microfono.

  1. Linea 3-6 – Controllare se recognitionTask è in esecuzione. Se è così, annullare l’attività e il riconoscimento.
  2. Linea 8-15Crea un AVAudioSession per preparare la registrazione audio. Qui abbiamo impostato la categoria della sessione di registrazione. Si noti che l’impostazione di queste proprietà può generare un’eccezione, quindi è necessario metterlo in una clausola try catch.
  3. Linea 17un’istanza della recognitionRequest. Qui creiamo l’oggetto SFSpeechAudioBufferRecognitionRequest. Più tardi, lo useremo per passare i nostri dati audio al server di Apple.
  4. Linea 19-21Controllare se audioEngine (il dispositivo) ha un ingresso audio per la registrazione. In caso contrario, si segnala un errore fatale.
  5. Linea 23-25Controllare se il recognitionRequest è istanziato e non è nil.
  6. Linea 27 – Dì al recognitionRequest di riportare i risultati parziali di riconoscimento vocale mentre l’utente parla.
  7. Linea 29 – Avviare il riconoscimento chiamando il metodo recognitionTask . Questa funzione ha un gestore di completamento. Questo gestore di completamento verrà chiamato ogni volta che il motore di riconoscimento ha ricevuto un risultato, abbia affinato il riconoscimento corrente, o è stato cancellato o fermato, e tornerà una trascrizione finale.
  8. Linea 31 – Definire un valore booleano per determinare se il riconoscimento è definitivo.
  9. Linea 35Se il result non è nil, impostare la proprietà textView.text come il nostro resultato migliore. Poi, se il risultato è il risultato finale, impostare isFinal su true.
  10. Linea 39-47 – Se non ci sono errori o il risultato è definitivo, fermare l’audioEngine (ingresso audio) e fermare il recognitionRequest e recognitionTask . Allo stesso tempo, dobbiamo attivare il pulsante Start Recording.
  11. Linea 50-53Aggiunge un ingresso audio per il recognitionRequest . Si noti che è OK aggiungere l’ingresso audio dopo l’avvio del recognitionTask . Il framework Speech inizierà il riconoscimento, non appena sia stato aggiunto un ingresso audio.
  12. Linea 55 – Preparare e avviare audioEngine .

Attivazione di riconoscimento vocale

Dobbiamo fare in modo che il riconoscimento vocale sia disponibile quando viene creata un’attività di riconoscimento vocale, quindi dobbiamo aggiungere un metodo delegato per ViewController . Se il riconoscimento vocale non è disponibile o cambia il suo stato, il microphoneButton.enable deve essere impostato. Per questo scenario, implementiamo il availabilityDidChange, metodo di protocollo SFSpeechRecognizerDelegate.

[code lang=”swift”]

func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {
if available {
microphoneButton.isEnabled = true
} else {
microphoneButton.isEnabled = false
}
}
[/code]

Questo metodo verrà chiamato quando cambia disponibilità. Se il riconoscimento vocale è disponibile, il pulsante di registrazione sarà anche attivato.

L’ultima cosa che dobbiamo aggiornare il metodo di azione microphoneTapped(sender:):

[code lang=”swift”]
@IBAction func microphoneTapped(_ sender: AnyObject) {
if audioEngine.isRunning {
audioEngine.stop()
recognitionRequest?.endAudio()
microphoneButton.isEnabled = false
microphoneButton.setTitle("Start Recording", for: .normal)
} else {
startRecording()
microphoneButton.setTitle("Stop Recording", for: .normal)
}
}
[/code]

In questa funzione, dobbiamo controllare se il nostro audioEngine è in esecuzione. Se è in esecuzione, l’applicazione dovrebbe fermare l’audioEngine, terminare l’audio in ingresso al nostro recognitionRequest, disabilitare microphoneButton, e impostare il titolo del pulsante a “Start Recording”.

Se il audioEngine funziona, l’applicazione dovrebbe chiamare startRecording() e impostare il titolo del titolo del pulsante a “Stop Recording”.

Grande! Sei pronto per testare l’applicazione. Distribuire l’applicazione su un dispositivo iOS 10, e premere il pulsante “Start Recording”. Premi run e prova a dire qualcosa!

speech-kit-3-1024x608

 

Note:
  1. Di Apple limita il riconoscimento per dispositivo. Il limite non è nota, ma si può contattare Apple per ulteriori informazioni.
  2. Di Apple limita il riconoscimento per app.
  3. Se abitualmente colpisce limiti, assicurarsi di contattare Apple, possono probabilmente risolverlo.
  4. Il riconoscimento vocale utilizza un sacco di energia e dati.
  5. Il riconoscimento vocale dura solo circa un minuto alla volta.

Riassumendo

In questo tutorial, si è appreso come sfruttare le incredibili nuove API speech di Apple aperte agli sviluppatori per riconoscere il discorso e trascrivere in testo. Il framework Speech utilizza lo stesso framework di riconoscimento vocale come fa Siri. È potente e consente agli sviluppatori di creare cose incredibili come ottenere la trascrizione di un file audio.