Reconocimiento de voz iOS SFSpeechRecognizer

SFSpeechRecognizer pertenece al marco Speech, que apareció por primera vez en iOS 10, se sometió a una actualización importante en iOS 13 y admite reconocimiento y análisis de voz sin conexión en iOS 13. WWDC2019 demostró sus avances en el campo de la IA, entre los cuales el reconocimiento de voz integrado de los dispositivos iOS 13 es una característica relativamente buena.
Por favor agregue una descripción de la imagen.

1. ¿Qué mejoras se han realizado?

El modelo de reconocimiento de voz fuera de línea en el terminal móvil reduce el riesgo de fuga de usuarios y aumenta la privacidad del usuario. La nueva API admite muchas funciones nuevas, como el seguimiento de la calidad y los patrones de voz mediante métricas de análisis del habla.

Al mismo tiempo, el modelo fuera de línea del dispositivo puede admitir el reconocimiento de voz de forma indefinida. Esta es una gran mejora en comparación con versiones anteriores de iOS 10, que sólo lo reconocían durante un minuto. Por supuesto, existen algunas desventajas: no se puede aprender en línea como el modelo en la nube. Esto dará como resultado cierta reducción en la precisión del dispositivo.

iOS 13 SFSpeechRecognizer también es mucho más inteligente y puede reconocer signos de puntuación en el habla. Por ejemplo, reconocerá un punto, y también se podrán reconocer otros símbolos como comas, guiones, etc. Sin embargo, todavía existe el inconveniente de que no puede agregar signos de puntuación al texto que reconoce por sí solo, pero esto se resolvió en iOS 16 y la tasa de precisión también se mejoró en consecuencia. Ya puede reemplazar muchos marcos de reconocimiento de voz pagos. .

2. Lograr resultados

Primero puede echar un vistazo al efecto y tenga en cuenta que las capturas de pantalla se tomaron en modo avión, completamente fuera de línea.
Esta vez, el reconocimiento de voz se realiza a través del micrófono. SFSpeechRecognizer también puede admitir el reconocimiento de archivos de voz. Si está interesado, puede descubrirlo usted mismo.
Por favor agregue una descripción de la imagen.

3. Principio de funcionamiento

Flujo de reconocimiento de voz
La imagen de arriba es la implementación interna del reconocimiento de voz en tiempo real, que se basa en los cuatro siguientes:

  • AVAudioEngine
  • SFSpeechRecognizer
  • Tarea de reconocimiento SF
  • SFSpeechAudioBufferRecognitionSolicitud

A continuación, veamos cómo funcionan.

Para los principiantes, permítanme presentarles primero el contenido relacionado con los permisos de privacidad del usuario:

Agregar instrucciones de privacidad
Aquí debe agregar instrucciones de privacidad para el micrófono y el reconocimiento de voz, como se muestra a continuación.
Por favor agregue una descripción de la imagen.

请求权限
SFSpeechRecognizer.requestAuthorization { authStatus en
el interruptor authStatus { caso .autorizado: caso .restringido: caso .notDetermined: caso .denegado: } }





Inicializar
var SpeechRecognizer = SFSpeechRecognizer(locale: Locale(identificador: “zh-CN”))

4. Implementación

4.1 Configurar AVAudioEngine

AVAudioEngine es responsable de recopilar señales de audio del micrófono y luego pasarlas a SFSpeechAudioBufferRecognitionRequest.

let audioEngine = AVAudioEngine()
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)

let inputNode = audioEngine.inputNode

// 在安装 tap 之前先移除上一个 否则可能报
// "*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: nullptr == Tap()"之类的错误
inputNode.removeTap(onBus: 0)
let recordingFormat = inputNode.outputFormat(forBus: 0)

// bufferSize:传入缓冲区的请求大小
// 创建一个“tap”来记录/监视/观察节点的输出
// bus:连接tap的节点输出总线
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) {
    
     (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
    self.recognitionRequest?.append(buffer)
}

audioEngine.prepare()
try audioEngine.start()

El código anterior instala un tap y establece el tamaño del búfer de salida, que se utiliza para almacenar en búfer la señal de audio al hablar o grabar.
Una vez que se llena el tamaño del búfer, se envía a SFSpeechAudioBufferRecognitionRequest.

Ahora veamos cómo SFSpeechAudioBufferRecognitionRequest usa SFSpeechRecognizer y SFSpeechRecognitionTask para transcribir voz en texto.

4.2 Habilitar el reconocimiento de voz del dispositivo

recognitionRequest.requiresOnDeviceRecognition = true

Configúrelo en falso para usar Apple Cloud para el reconocimiento de voz. Tenga en cuenta que requireOnDeviceRecognition solo está disponible para iOS 13, macOS Catalina y dispositivos posteriores. Requiere el procesador A9 de Apple o más nuevo, compatible con iPhone6s y superiores en iOS.

4.3 Crear tarea SFSpeechRecognition

SFSpeechRecognitionTask se usa para ejecutar SFSpeechAudioBufferRecognitionRequest y SFSpeechRecognizer. Hay dos métodos de bloquear y delegar. El siguiente ejemplo usa el método de bloqueo, que devuelve un resultado y accedemos a diferentes atributos de voz a través del resultado. bestTranscription identifica la opción con mayor confianza

recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest) {
    
     result, error in
    // 处理识别结果
    if let result = result {
    
    
        DispatchQueue.main.async {
    
    
            let transcribedString = result.bestTranscription.formattedString
            self.transcribedText.text = (transcribedString)
        }
    }
    // 异常处理
    if error != nil {
    
    
        self.audioEngine.stop()
        inputNode.removeTap(onBus: 0)
        self.recognitionRequest = nil
        self.recognitionTask = nil
    }
}

4.4 SFVoiceAnalytics

SFVoiceAnalytics es una clase recientemente introducida que contiene un conjunto de métricas de voz para rastrear características como tono, parpadeo y fluctuación en los resultados de voz. Se puede acceder a ellos desde la propiedad segments de la transcripción:

for segment in result.bestTranscription.segments {
    
    
    guard let voiceAnalytics = segment.voiceAnalytics else {
    
     continue }
    
    let pitch = voiceAnalytics.pitch
    let voicing = voiceAnalytics.voicing.acousticFeatureValuePerFrame
    let jitter = voiceAnalytics.jitter.acousticFeatureValuePerFrame
    let shimmer = voiceAnalytics.shimmer.acousticFeatureValuePerFrame
}

4.5 Reconocimiento de voz

Mencionamos cuatro componentes arriba, el siguiente código para ver cómo funciona en su conjunto

private let audioEngine = AVAudioEngine()
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "zh-CN"))
private var recognitionTask: SFSpeechRecognitionTask?

func startRecording() throws {
    
    

        recognitionTask?.cancel()
        self.recognitionTask = nil

        let audioSession = AVAudioSession.sharedInstance()
        try audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)
        try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
        
        let inputNode = audioEngine.inputNode
        inputNode.removeTap(onBus: 0)
        let recordingFormat = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) {
    
     (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
            self.recognitionRequest?.append(buffer)
        }
        
        audioEngine.prepare()
        try audioEngine.start()
        
        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
        guard let recognitionRequest = recognitionRequest else {
    
     fatalError("Unable to create a SFSpeechAudioBufferRecognitionRequest object") }
        // 分部返回结果,每次识别完成就会回调部分结果
        recognitionRequest.shouldReportPartialResults = true
        if #available(iOS 16, *) {
    
    
            // iOS 16 已经支持自动添加标点符号,不需要再喊标点符号了
            recognitionRequest.addsPunctuation = true
        }
        if #available(iOS 13, *) {
    
    
            if speechRecognizer?.supportsOnDeviceRecognition ?? false{
    
    
                recognitionRequest.requiresOnDeviceRecognition = true
            }
        }

        recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest) {
    
     result, error in
            if let result = result {
    
    
                DispatchQueue.main.async {
    
    
                    // 获取置信度最高的 transcription,并格式化为字符串
                    let transcribedString = result.bestTranscription.formattedString
                    self.transcribedText.text = (transcribedString)
                }
            }
            if error != nil {
    
    
                self.audioEngine.stop()
                inputNode.removeTap(onBus: 0)
                self.recognitionRequest = nil
                self.recognitionTask = nil
            }
        }
    }

El código anterior es relativamente largo, expliquemos el código anterior:

  • Al presionar Iniciar grabación de reconocimiento, cualquier tarea de reconocimiento anterior se cancela primero.

  • Utilice SFSpeechRecognizer y SFSpeechAudioBufferRecognitionRequest para crear una tarea de reconocimiento SFSpeechRecognitionTask.

  • Establecer mustReportPartialResults en verdadero permite el acceso a resultados intermedios durante el reconocimiento.

  • result.bestTranscription devuelve la transcripción reconocida con la mayor confianza y la propiedad formattedString proporciona el texto de la transcripción.

  • También puedes acceder a otras propiedades como SpeakingRate, AveragePauseDuration o segmentos, etc.

5. Resumen

Este es básicamente todo el proceso de reconocimiento de voz en texto a través de un micrófono. El SFSpeechAudioBufferRecognitionRequest utilizado es una subclase de SFSpeechRecognitionRequest. También tiene otra subclase, SFSpeechURLRecognitionRequest, que se puede reconocer a través de la ruta del archivo de grabación local. Si está interesado, puede Echa otro vistazo.

En escenarios de aplicaciones reales, es posible utilizar un SDK de terceros para proporcionar información de audio de AudioBuffer, y nuestro ejemplo es utilizar AVAudioEngine para proporcionar AudioBuffer. De hecho, también puede agregar un búfer usted mismo a través de la solicitud de reconocimiento. Si lo encuentra, puede puedo intentarlo.

Supongo que te gusta

Origin blog.csdn.net/ID314846818/article/details/130343061
Recomendado
Clasificación