Uso de la API de reconocimiento de voz en iOS 10

Lo que vas a crear

Introducción

Siri ha sido una característica principal de iOS desde que se introdujo en 2011. Ahora, iOS 10 trae nuevas características para permitir a los desarrolladores interactuar con Siri. En particular, ahora están disponibles dos nuevos marcos: Speech y SiriKit. 

Hoy vamos a echar un vistazo al marco de Speech, que nos permite traducir fácilmente el audio en texto. Aprenderá cómo construir una aplicación de la vida real que utiliza la API de reconocimiento de voz para verificar el estado de un vuelo.

Si desea obtener más información sobre SiriKit, lo describí en mi tutorial Crear extensiones SiriKit en iOS 10. Para más información sobre las otras nuevas funciones para desarrolladores en iOS 10, consulte el curso de Markus Mühlberger, aquí mismo, en Envato Tuts+.

Uso

El reconocimiento de voz es el proceso de traducir audio en vivo o pregrabado a texto transcrito. Desde que se introdujo Siri en iOS 5, ha habido un botón de micrófono en el teclado del sistema que permite a los usuarios dictar fácilmente. Esta función se puede utilizar con cualquier entrada de texto UIKit, y no requiere que escriba un código adicional más allá de lo que escribiría para admitir una entrada de texto estándar. Es realmente rápido y fácil de usar, pero viene con algunas limitaciones:

  • El teclado está siempre presente al dictar..
  • El idioma no puede ser personalizado por la propia aplicación..
  • La aplicación no puede ser notificada cuando el dictado comienza y termina.

Para permitir a los desarrolladores crear aplicaciones más personalizables y potentes con la misma tecnología de dictado que Siri, Apple creó el marco de Speech. Permite que cada dispositivo que ejecute iOS 10 traduzca audio a texto en más de 50 idiomas y dialectos.

Esta nueva API es mucho más poderosa porque no solo proporciona un servicio de transcripción simple, sino que también proporciona interpretaciones alternativas de lo que el usuario pudo haber dicho. Puede controlar cuándo detener un dictado, puede mostrar resultados a medida que su usuario habla, y el motor de reconocimiento de voz se adaptará automáticamente a las preferencias del usuario (idioma, vocabulario, nombres, etc.). 

Una característica interesante es el soporte para transcribir audio pregrabado. Si está creando una aplicación de mensajería instantánea, por ejemplo, podría utilizar esta funcionalidad para transcribir el texto de los nuevos mensajes de audio..

Preparar

En primer lugar, deberá solicitar al usuario permiso para transmitir su voz a Apple para su análisis.. 

Dependiendo del dispositivo y del idioma que se va a reconocer, iOS puede decidir de manera transparente transcribir el audio en el propio dispositivo o, si el reconocimiento de voz local no está disponible en el dispositivo, iOS utilizará los servidores de Apple para hacer el trabajo. 

Por esta razón, generalmente se requiere una conexión activa a Internet para el reconocimiento de voz. Te mostraré cómo comprobar la disponibilidad del servicio muy pronto..

Hay tres pasos para usar el reconocimiento de voz:

  • Explique: diga a su usuario por qué desea acceder a su voz.
  • Autorizar: solicitar explícitamente autorización para acceder a su voz..
  • Solicitud: cargar un audio pregrabado desde el disco usando SFSpeechURLRecognitionRequest, o transmitir audio en vivo usando SFSpeechAudioBufferRecognitionRequest y procesar la transcripción.

Si desea saber más sobre el marco de Speech, vea la Sesión 509. WWDC 2016. También puede leer la documentación oficial.

Ejemplo

Ahora te mostraré cómo construir una aplicación de la vida real que aproveche la API de reconocimiento de voz. Vamos a construir una pequeña aplicación de seguimiento de vuelo en la que el usuario puede simplemente decir un número de vuelo, y la aplicación mostrará el estado actual del vuelo. Sí, vamos a construir un pequeño asistente como Siri para verificar el estado de cualquier vuelo!

En el repositorio de GitHub del tutorial, proporcioné un proyecto de esqueleto que contiene una IU básica que nos ayudará en este tutorial. Descarga y abre el proyecto en Xcode 8.2 o superior. Comenzar con una interfaz de usuario existente nos permitirá centrarnos en la API de reconocimiento de voz.

Echa un vistazo a las clases en el proyecto.. UIViewController + Style.swift Contiene la mayoría del código responsable de actualizar la interfaz de usuario. El ejemplo de fuente de datos de los vuelos mostrados en la tabla se declara en VuelosDataSource.swift.

Si ejecuta el proyecto, debería verse como el siguiente.

Después de que el usuario presiona el botón del micrófono, queremos iniciar el reconocimiento de voz para transcribir el número de vuelo. Entonces, si el usuario dice "LX40", nos gustaría mostrar la información sobre la puerta y el estado actual del vuelo. Para hacer esto, llamaremos a una función para buscar automáticamente el vuelo en una fuente de datos y mostrar el estado del vuelo.. 

Primero vamos a explorar cómo transcribir desde audio pregrabado. Más adelante, aprenderemos cómo implementar el reconocimiento de voz en vivo más interesante.

Empecemos por configurar el proyecto. Abre el Info.plist presentar y agregar una nueva fila con la explicación que se mostrará al usuario cuando se le solicite permiso para acceder a su voz. La fila recién agregada se resalta en azul en la siguiente imagen.

Una vez hecho esto, abrir ViewController.swift. No importa el código que ya está en esta clase; Solo nos encargamos de actualizar la interfaz de usuario para nosotros..

El primer paso con cualquier nuevo marco que desee utilizar es importarlo en la parte superior del archivo.

Importar discurso

Para mostrar el diálogo de permiso al usuario, agregue este código en el viewDidLoad (animado :) método:

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

los estado La variable se encarga de cambiar la interfaz de usuario para advertir al usuario de que el reconocimiento de voz no está disponible en caso de que algo salga mal. Vamos a asignar un nuevo estado a la misma variable cada vez que nos gustaría cambiar la interfaz de usuario.

Si la aplicación aún no ha solicitado permiso al usuario, el estado de la autorización será no determinado, y llamamos al askSpeechPermission Método para preguntar como se define en el siguiente paso..

Debieras siempre falla correctamente si una característica específica no está disponible. También es muy importante siempre Comunícate con el usuario cuando estés grabando su voz.. Nunca intente reconocer su voz sin actualizar primero la interfaz de usuario y hacer que su usuario se dé cuenta de ello..

Aquí está la implementación de la función para pedir permiso al usuario..

func askSpeechPermission () SFSpeechRecognizer.requestAuthorization estado en OperationQueue.main.addOperation cambiar estado caso. authorized: self.status = .ready predeterminado: self.status = .unavailable

Invocamos el solicitud de autorización método para mostrar la solicitud de privacidad de reconocimiento de voz que agregamos a la Info.plist. Luego, cambiamos al subproceso principal en caso de que se invoque el cierre en un subproceso diferente; queremos actualizar la interfaz de usuario solo desde el subproceso principal. Le asignamos el nuevo estado para actualizar el botón del micrófono para indicar al usuario la disponibilidad (o no) del reconocimiento de voz.

Reconocimiento de audio pregrabado

Antes de escribir el código para reconocer el audio pregrabado, necesitamos encontrar la URL del archivo de audio. En el navegador del proyecto, compruebe que tiene un archivo llamado LX40.m4a. Grabé este archivo yo mismo con la aplicación Voice Memos en mi iPhone diciendo "LX40". Podemos comprobar fácilmente si obtenemos una correcta transcripción del audio..

Almacena la URL del archivo de audio en una propiedad:

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

Es hora de ver finalmente el poder y la simplicidad del marco de Speech. Este es el código que hace todo el reconocimiento de voz para nosotros:

func RecognitionFile (url: URL) guard let reconocizer = SFSpeechRecognizer (), reconocizer.isAvailable else return let request = SFSpeechURLRecognitionRequest (url: url) reconocizer.recognitionTask (con: request) resultado, error en guardia let Recognizer = SFSpeechechRecognizer (), reconocizer.isAvailable else return self.status = .unavailable if let result = result self.flightTextView.text = result.bestTranscription.formattedString if result.isFinal self.searchFlight (número: result.bestTranscription.formattedString)  de lo contrario, si se deja error = error imprimir (error)

Esto es lo que hace este método:

  • Inicializar un SFSpeechRecognizer Instale y verifique que el reconocimiento de voz esté disponible con una declaración de guardia. Si no está disponible, simplemente establecemos el estado en indisponible y volver. (El inicializador predeterminado usa la configuración regional de usuario predeterminada, pero también puede usar el SFSpeechRecognizer (locale :) inicializador para proporcionar una configuración regional diferente.)
  • Si el reconocimiento de voz está disponible, cree un SFSpeechURLRecognitionRequest instancia pasando la URL de audio pregrabada.
  • Inicia el reconocimiento de voz invocando el reconocimiento de tareas (con :) Método con la solicitud creada anteriormente..

El cierre se llamará varias veces con dos parámetros: un resultado y un objeto de error. 

los reconocedor está realmente reproduciendo el archivo e intentando reconocer el texto de forma incremental. Por este motivo, el cierre se llama varias veces. Cada vez que reconoce una letra o una palabra o hace algunas correcciones, se invoca el cierre con objetos actualizados.. 

los resultado objeto tiene el isFinal propiedad establecida en verdadero cuando el archivo de audio se analizó por completo. En este caso, iniciamos una búsqueda en nuestra fuente de datos de vuelo para ver si podemos encontrar un vuelo con el número de vuelo reconocido. los searchFlight La función se encargará de mostrar el resultado..

Lo último que nos falta es invocar el reconocerFile (url :) función cuando se presiona el botón del micrófono:

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

Ejecute la aplicación en su dispositivo con iOS 10, presione el botón del micrófono y verá el resultado. El audio "LX40" se reconoce incrementalmente y se muestra el estado del vuelo!

 

Consejo: El número de vuelo se muestra en un UITextView. Como habrá notado, si habilita el detector de datos del número de vuelo en el UITextView, puede presionarlo y se mostrará el estado actual del vuelo.!

El código de ejemplo completo hasta este punto se puede ver en la rama de audio pregrabado en GitHub.

Reconocimiento de audio en vivo

Veamos ahora cómo implementar el reconocimiento de voz en vivo. Va a ser un poco más complicado en comparación con lo que acabamos de hacer. Puede volver a descargar el mismo proyecto de esqueleto y seguirlo..

Necesitamos una nueva clave en el Info.plist Archivo para explicar al usuario por qué necesitamos acceso al micrófono. Agrega una nueva fila a tu Info.plist como se muestra en la imagen.

No necesitamos pedir permiso manualmente al usuario porque iOS lo hará por nosotros tan pronto como intentemos acceder a cualquier API relacionada con el micrófono.

Podemos reutilizar el mismo código que usamos en la sección anterior (recuerde Importar discurso) Solicitar la autorización. los viewDidLoad (animado :) El método se implementa exactamente como antes:

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

Además, el método para pedir permiso al usuario es el mismo.

func askSpeechPermission () SFSpeechRecognizer.requestAuthorization estado en OperationQueue.main.addOperation cambiar estado caso. authorized: self.status = .ready predeterminado: self.status = .unavailable

La implementación de iniciar la grabación va a ser un poco diferente Primero agreguemos algunas nuevas variables de instancia que serán útiles al administrar la sesión de audio y la tarea de reconocimiento de voz.

let audioEngine = AVAudioEngine () let speechRecognizer: SFSpeechRecognizer? = SFSpeechRecognizer () permite la solicitud = SFSpeechAudioBufferRecognitionRequest () var reconocimientoTask: SFSpeechRecognitionTask?

Echemos un vistazo a cada variable por separado:

  • AVAudioEngine Se utiliza para procesar un flujo de audio. Crearemos un nodo de audio y lo conectaremos a este motor para que podamos actualizarnos cuando el micrófono reciba algunas señales de audio..
  • SFSpeechRecognizer Es la misma clase que hemos visto en la parte anterior del tutorial y se encarga de reconocer el discurso. Dado que el inicializador puede fallar y devolver cero, lo declaramos como opcional para evitar que se bloquee en tiempo de ejecución.
  • SFSpeechAudioBufferRecognitionRequest Es un buffer utilizado para reconocer el habla en vivo. Dado que no tenemos el archivo de audio completo como lo hicimos antes, necesitamos un búfer para asignar la voz cuando el usuario habla..
  • SFSpeechRecognitionTask gestiona la tarea actual de reconocimiento de voz y puede utilizarse para detenerla o cancelarla.

Una vez que hayamos declarado todas las variables requeridas, implementemos iniciar la grabación.

func startRecording () // Configurar el motor de audio y la protección del reconocedor de voz let node = audioEngine.inputNode else return letordingFormat = node.outputFormat (forBus: 0) node.installTap (onBus: 0, bufferSize: 1024, format :ordingFormat ) búfer, _ en self.request.append (búfer) // Preparar y comenzar a grabar audioEngine.prepare () do try audioEngine.start () self.status = .recognizing catch return print (error) / / Analizar el reconocimiento de vozTask = speechRecognizer? .RecognitionTask (con: request, resultHandler: result, error en si let result = result self.flightTextView.text = result.bestTranscription.formattedString self.searchFlight ) else si es error = error imprimir (error))

Este es el código básico de nuestra función. Lo explicaré paso a paso:

  • Primero obtenemos el inputNode del audioEngine. Un dispositivo posiblemente puede tener múltiples entradas de audio, y aquí seleccionamos la primera.
  • Le decimos al nodo de entrada que queremos monitorear la transmisión de audio. El bloque que proporcionamos se invocará en cada flujo de audio recibido de 1024 bytes. Inmediatamente agregamos el búfer de audio a la solicitud Para que pueda comenzar el proceso de reconocimiento..
  • Preparamos el motor de audio para empezar a grabar. Si la grabación comienza con éxito, establezca el estado en .reconociendo para que podamos actualizar el icono del botón para que el usuario sepa que su voz se está grabando.
  • Vamos a asignar el objeto devuelto de speechRecognizer.recognitionTask (con: resultHandler :) al reconocimiento de tareas variable. Si el reconocimiento es exitoso, buscamos el vuelo en nuestra fuente de datos y actualizamos la interfaz de usuario. 

La función para cancelar la grabación es tan simple como detener el motor de audio, quitar el toque del nodo de entrada y cancelar la tarea de reconocimiento.

func cancelRecording () audioEngine.stop () si se deja node = audioEngine.inputNode node.removeTap (onBus: 0) reconocimientoTask? .cancel ()

Ahora solo necesitamos iniciar y detener la grabación. Modificar el micrófono presionado método de la siguiente manera:

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

Dependiendo de la corriente estado, Empezamos o paramos el reconocimiento de voz..

Crea y ejecuta la aplicación para ver el resultado. Intente deletrear cualquiera de los números de vuelo que aparecen en la lista y debería ver su estado aparecer.

 

Una vez más, el código de ejemplo se puede ver en la rama de audio en vivo en GitHub.

Mejores prácticas

El reconocimiento de voz es una API muy poderosa que Apple proporcionó a los desarrolladores de iOS dirigidos a iOS 10. Es de uso completamente gratuito, pero tenga en cuenta que no tiene un uso ilimitado. Se limita a aproximadamente un minuto para cada tarea de reconocimiento de voz, y los servidores de Apple también pueden limitar su aplicación si requiere demasiados cálculos. Por estas razones, tiene un alto impacto en el tráfico de red y el uso de energía. 

Asegúrese de que sus usuarios reciban instrucciones adecuadas sobre cómo usar el reconocimiento de voz y sea lo más transparente posible cuando grabe su voz.. 

Resumen

En este tutorial, ha visto cómo usar el reconocimiento de voz rápido, preciso y flexible en iOS 10. Utilícelo para su propio beneficio para brindar a sus usuarios una nueva forma de interactuar con su aplicación y mejorar su accesibilidad al mismo tiempo.. 

Si desea obtener más información sobre la integración de Siri en su aplicación, o si desea conocer algunas de las otras funciones de desarrollador de iOS 10, consulte el curso de Markus Mühlberger.

Además, echa un vistazo a algunos de nuestros otros tutoriales gratuitos sobre las características de iOS 10.