在iOS 10中使用语音识别API

最终产品图片
您将要创造的

介绍

自2011年推出以来,Siri一直是iOS的核心功能。现在,iOS 10带来了新功能,允许开发人员与Siri进行交互。 特别是,现在提供了两个新框架:Speech和SiriKit。

今天,我们将看一下“语音”框架,该框架使我们能够轻松地将音频转换为文本。 您将学习如何构建使用语音识别API来检查航班状态的真实应用。

用法

语音识别是将现场或预先录制的音频转换为转录文本的过程。 自从iOS 5中引入Siri以来,系统键盘中就有一个麦克风按钮,使用户可以轻松地进行命令。 此功能可以与任何UIKit文本输入一起使用,并且不需要编写其他代码即可支持标准文本输入。 它确实快速且易于使用,但有一些限制:

  • 听写时键盘始终存在。
  • 该语言无法由应用本身进行自定义。
  • 听写开始和结束时无法通知应用程序。
iOS键盘上的听写

为了使开发人员能够使用与Siri相同的口述技术来构建更多可自定义和功能强大的应用程序,Apple创建了Speech框架。 它允许运行iOS 10的每台设备将音频转换为50多种语言和方言的文本。

这个新的API更加强大,因为它不仅提供了简单的转录服务,而且还提供了用户可能所说的替代解释。 您可以控制何时停止听写,可以在用户说话时显示结果,语音识别引擎将自动适应用户的首选项(语言,词汇,姓名等)。

一个有趣的功能是支持转录预先录制的音频。 例如,如果您要构建即时消息传递应用程序,则可以使用此功能来转录新音频消息的文本。

建立

首先,您将需要征询用户的许可,以将其声音传送给Apple进行分析。

根据设备和要识别的语言,iOS可以透明地决定在设备本身上转录音频,或者,如果设备上不提供本地语音识别,则iOS将使用Apple的服务器来完成此工作。

这就是为什么语音识别通常需要活动的Internet连接的原因。 我将向您展示如何尽快检查该服务的可用性。

使用语音识别需要三个步骤:

  • 说明:告诉您的用户为什么要访问他们的声音。
  • 授权:明确要求授权以访问他们的声音。
  • 要求:从磁盘加载使用预先录制的音频SFSpeechURLRecognitionRequest ,或使用流式实况音频SFSpeechAudioBufferRecognitionRequest和处理的转录。

如果您想进一步了解Speech框架,请观看WWDC 2016 Session 509 。 您也可以阅读官方文档

现在,我将向您展示如何构建利用语音识别API的真实应用程序。 我们将构建一个小型的航班跟踪应用程序,用户可以在其中简单地说出航班号,该应用程序将显示航班的当前状态。 是的,我们将建立一个像Siri这样的小助手来检查任何航班的状态!

在教程的GitHub存储库中,我提供了一个框架项目 ,该项目包含一个基本的UI,可帮助我们完成本教程。 下载并在Xcode 8.2或更高版本中打开项目。 从现有的UI开始,我们将专注于语音识别API。

看一下项目中的类。 UIViewController+Style.swift包含负责更新UI的大多数代码。 表中显示的航班的示例数据源在FlightsDataSource.swift声明。

如果您运行该项目,则它应如下所示。

初始示例项目

用户按下麦克风按钮后,我们要启动语音识别以记录航班号。 因此,如果用户说“ LX40”,我们想显示有关登机口和航班当前状态的信息。 为此,我们将调用一个函数以自动在数据源中查找航班并显示航班状态。

我们首先将探讨如何从预先录制的音频中进行转录。 稍后,我们将学习如何实现更有趣的实时语音识别。

让我们从设置项目开始。 打开Info.plist文件,并添加新行,其中包含解释,当要求其访问语音的权限时,该解释将显示给用户。 下图以蓝色突出显示了新添加的行。

带有新添加的密钥的Infoplist文件

完成此操作后,打开ViewController.swift 。 不要介意此类中已经存在的代码。 它只是为我们更新UI。

要使用任何新框架的第一步是将其导入文件顶部。

import Speech

要向用户显示权限对话框,请在viewDidLoad(animated:)方法中添加以下代码:

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

status变量负责更改UI,以警告用户在出现问题时语音识别不可用。 每次我们想要更改UI时,都将为同一变量分配新状态。

如果该应用尚未请求用户许可,则授权状态将为notDetermined ,我们将按照askSpeechPermission中的定义调​​用askSpeechPermission方法进行询问。

如果特定功能不可用,则应始终正常地失败在录制用户的声音时始终与用户交流也很重要。 在未先更新用户界面并使用户意识到之前,切勿尝试识别其声音。

这是请求用户许可的功能的实现。

func askSpeechPermission() {
    SFSpeechRecognizer.requestAuthorization { status in
        OperationQueue.main.addOperation {
            switch status {
            case .authorized:
                self.status = .ready
            default:
                self.status = .unavailable
            }
        }
    }
}

我们调用requestAuthorization方法来显示添加到Info.plist的语音识别隐私请求。 然后,如果在另一个线程上调用了闭包,我们将切换到主线程-我们只希望从主线程更新UI。 我们为新status分配了更新麦克风按钮的功能,以向用户发送语音(或不语音)语音识别的信号。

预先录制的音频识别

在编写代码以识别预先录制的音频之前,我们需要找到音频文件的URL。 在项目浏览器中,检查是否有一个名为LX40.m4a的文件。 我说了“ LX40”,然后用我的iPhone上的Voice Memos应用程序自己录制了此文件。 我们可以轻松检查我们是否获得了正确的音频转录。

将音频文件URL存储在属性中:

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

现在是时候终于了解一下语音框架的功能和简单性了。 这是为我们完成所有语音识别的代码:

func recognizeFile(url: URL) {
    guard let recognizer = SFSpeechRecognizer(), recognizer.isAvailable else {
        return
    }

    let request = SFSpeechURLRecognitionRequest(url: url)
    recognizer.recognitionTask(with: request) { result, error in
        guard let recognizer = SFSpeechRecognizer(), recognizer.isAvailable else {
            return self.status = .unavailable
        }
        if let result = result {
            self.flightTextView.text = result.bestTranscription.formattedString
            if result.isFinal {
                self.searchFlight(number: result.bestTranscription.formattedString)
            }
        } else if let error = error {
            print(error)
        }
    }
}

这是此方法的作用:

  • 初始化SFSpeechRecognizer实例,并使用防护语句检查语音识别是否可用。 如果不可用,我们只需将状态设置为unavailable并返回。 (默认的初始值设定项使用默认的用户区域设置,但您也可以使用SFSpeechRecognizer(locale:)初始值设定项来提供不同的语言环境。)
  • 如果语音识别可用,则通过传递预先录制的音频URL来创建SFSpeechURLRecognitionRequest实例。
  • 通过使用先前创建的请求调用recognitionTask(with:)方法来启动语音识别。

将使用两个参数多次调用该闭包:结果和错误对象。

recognizer器实际上正在播放文件,并尝试逐步识别文本。 因此,多次调用该闭包。 每次识别字母或单词或进行某些更正时,都会使用最新的对象来调用闭包。

当音频文件被完全分析时, result对象的isFinal属性设置为true。 在这种情况下,我们开始在航班数据源中进行搜索,以查看是否可以找到带有识别航班号的航班。 searchFlight函数将负责显示结果。

我们缺少的最后一件事是在按下麦克风按钮时调用recognizeFile(url:)函数:

@IBAction func microphonePressed(_ sender: Any) {
    recognizeFile(url: preRecordedAudioURL)
}

在运行iOS 10的设备上运行应用程序,按麦克风按钮,您将看到结果。 音频“ LX40”被逐渐识别,并显示飞行状态!

提示:航班号显示在UITextView中。 您可能已经注意到,如果在UITextView中启用了航班号数据检测器,则可以按一下它,航班的当前状态将实际显示出来!

到目前为止的完整示例代码可以在GitHub的pre-recorded-audio分支中查看。

实时音频识别

现在让我们看看如何实现实时语音识别。 与我们刚才所做的相比,它将变得更加复杂。 您可以再次下载相同的框架项目,然后继续。

我们需要在Info.plist文件中使用一个新密钥来向用户解释为什么我们需要访问麦克风。 如图所示,将新行添加到Info.plist中。

新行说明了为什么我们需要使用麦克风

我们不需要手动询问用户的许可,因为一旦我们尝试访问任何与麦克风相关的API,iOS就会为我们执行此操作。

我们可以重用上一节中使用的相同代码(记住要import Speech )以请求授权。 viewDidLoad(animated:)方法的实现与之前完全相同:

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

另外,向用户请求许可的方法是相同的。

func askSpeechPermission() {
    SFSpeechRecognizer.requestAuthorization { status in
        OperationQueue.main.addOperation {
            switch status {
            case .authorized:
                self.status = .ready
            default:
                self.status = .unavailable
            }
        }
    }
}

startRecording的实现将有所不同。 首先,我们添加一些新的实例变量,这些变量在管理音频会话和语音识别任务时会派上用场。

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

让我们分别看一下每个变量:

  • AVAudioEngine用于处理音频流。 我们将创建一个音频节点并将其附加到此引擎,以便在麦克风收到一些音频信号时可以进行更新。
  • SFSpeechRecognizer与我们在本教程的上半部分中看到的类相同,它负责识别语音。 鉴于初始化程序可能失败并返回nil,我们将其声明为可选操作,以避免在运行时崩溃。
  • SFSpeechAudioBufferRecognitionRequest是用于识别实时语音的缓冲区。 鉴于我们没有像以前那样完整的音频文件,我们需要一个缓冲区来在用户讲话时分配语音。
  • SFSpeechRecognitionTask管理当前的语音识别任务,可用于停止或取消它。

声明所有必需的变量后,让我们实现startRecording

func startRecording() {
    // Setup audio engine and speech recognizer
    guard let node = audioEngine.inputNode else { return }
    let recordingFormat = node.outputFormat(forBus: 0)
    node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
        self.request.append(buffer)
    }

    // Prepare and start recording
    audioEngine.prepare()
    do {
        try audioEngine.start()
        self.status = .recognizing
    } catch {
        return print(error)
    }

    // Analyze the speech
    recognitionTask = speechRecognizer?.recognitionTask(with: 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(error)
        }
    })
}

这是我们功能的核心代码。 我将逐步解释它:

  • 首先,我们获得inputNodeaudioEngine 。 一个设备可能有多个音频输入,在这里我们选择第一个。
  • 我们告诉输入节点我们要监视音频流。 我们提供的块将在收到的每个1024字节音频流上调用。 我们立即将音频缓冲区附加到request以便它可以开始识别过程。
  • 我们准备音频引擎以开始录制。 如果录制成功开始,请将状态设置为.recognizing以便我们更新按钮图标以使用户知道他们的声音正在录制。
  • 让我们从返回的对象分配speechRecognizer.recognitionTask(with:resultHandler:)recognitionTask变量。 如果识别成功,我们将在数据源中搜索航班并更新UI。

取消录音的功能很简单,例如停止音频引擎,从输入节点上删除抽头并取消识别任务。

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

现在,我们只需要开始和停止记录。 修改microphonePressed方法,如下所示:

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

根据当前status ,我们开始或停止语音识别。

生成并运行该应用程序以查看结果。 尝试拼写任何列出的航班号,您应该会看到其状态。

同样,可以在GitHub的live-audio分支中查看示例代码。

最佳实践

语音识别是Apple提供给面向iOS 10的iOS开发人员的一种非常强大的API。它是完全免费的,但请记住,它的使用范围不是无限的。 每个语音识别任务的时间限制为一分钟左右,如果您的应用程序需要太多的计算,那么它可能还会受到Apple服务器的限制。 由于这些原因,它对网络流量和电源使用有很大影响。

确保正确指导用户如何使用语音识别,并在录制他们的声音时使其尽可能透明。

回顾

在本教程中,您已经了解了如何在iOS 10中使用快速,准确和灵活的语音识别。利用它的优势,可以为用户提供与您的应用进行交互的新方法,并同时提高其可访问性。


翻译自: https://code.tutsplus.com/tutorials/using-the-speech-recognition-api-in-ios-10--cms-28032

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Google语音识别API是一种强大的语音识别工具,可以将语音转换为文本。在Python,可以使用Python语音识别程序库来调用Google语音识别API。首先,需要导入speech_recognition库,并创建一个Recognizer对象。然后,使用Microphone对象作为音频源,通过listen()方法来捕获音频输入。接下来,使用recognize_google()方法将音频转换为文本。如果识别失败,可能是由于无法理解音频或无法连接到Google语音识别服务。在这种情况下,可以通过捕获UnknownValueError和RequestError来处理错误信息。\[1\] 需要注意的是,Google语音识别API的URL是"http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN"。\[2\] 总之,通过使用Python语音识别程序库和Google语音识别API,可以实现语音识别功能,并将语音转换为文本。\[3\] #### 引用[.reference_title] - *1* *3* [python speech_使用Google Speech API进行Python语音识别](https://blog.csdn.net/culing2941/article/details/108617530)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [IOS实现语音识别](https://blog.csdn.net/oChunCui1/article/details/17324673)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值