▲点击上方“
CocoaChina
”关注即可免费学习iOS开发
原文:
Building a Speech-to-Text App Using Speech Framework in iOS 10
作者:
Sahand Edrisian
译者:王跃
在2016WWDC大会上,Apple公司介绍了一个很好的语音识别的API,那就是Speech framework。事实上,这个Speech Kit就是Siri用来做语音识别的框架。如今已经有一些可用的语音识别框架,但是它们要么太贵要么不好。在今天的教程里面,我会教你怎样创建一个使用Speech Kit来进行语音转文字的类似Siri的app。
设计App UI
前提:你需要Xcode 8 beta版本和一个运行iOS 10 beta系统版本的iOS 设备。
先从创建一个新的命名为SpeechToTextDemo的单视图工程开始。接下来,到 Main.storyboard 中添加一个 UILabel,一个 UITextView, 和一个 UIButton,你的storyboard应该看起来如下图:
接下来在 ViewController.swift文件中为UITextView 和UIButton 定义outlet变量。在这个demo当中,我设置UITextView 的名称为“textView”,UIButton的名称为“microphoneButton”。然后创建一个当microphone按钮被点击时会触发的空的按钮执行方法。
@IBAction func microphoneTapped(_ sender: AnyObject) {
}
如果你不想从创建最原始工程开始,你可以在
在这里下载原始工程
然后继续下面的教学指导。
使用Speech Framework
为了能使用Speech framework, 你必须首先导入它然后遵循 SFSpeechRecognizerDelegate 协议。因此让我们导入这个框架,然后在 ViewController 文件中加上它的协议。现在你的 ViewController.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) {
}
}
用户授权
在使用speech framework做语音识别之前,你必须首先得到用户的允许,因为不仅仅只有本地的ios设备会进行识别,苹果的服务器也会识别。所有的语音数据都会被传递到苹果的后台进行处理。因此,获取用户授权是强制必须的。
让我们在 viewDidLoad 方法里授权语音识别。用户必须允许app使用话筒和语音识别。首先,声明一个speechRecognizer变量:
private let speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "en-US")) //1
然后按如下更新 viewDidLoad 方法:
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
}
}
}
-
首先,我们创建一个带有标识符en-US 的 SFSpeechRecognizer实例,这样语音识别API就能知道用户说的是哪一种语言。这个实例就是处理语音识别的对象。
-
我们默认让microphone按钮失效直到语音识别功能被激活。
-
接下来,把语音识别的代理设置为 self 也就是我们的ViewController.
-
之后,我们必须通过调用SFSpeechRecognizer.requestAuthorization方法来请求语音识别的授权。
-
最后,检查验证的状态。如果被授权了,让microphone按钮有效。如果没有,打印错误信息然后让microphone按钮失效。
现在如果你认为app跑起来之后你会看到一个授权弹出窗口,那你就错了。如果运行,app会崩溃。好吧,既然知道结果为什么还要问呢?(别打我),看看下面解决方法。
提供授权消息
苹果要求app里所有的授权都要一个自定义的信息。例如语音授权,我们必须请求2个授权:
-
麦克风使用权。
-
语音识别。
为了自定义信息,你必须在info.plist 配置文件里提供这些自定义消息。
让我们打开 info.plist配置文件的源代码。首先,右键点击 info.plist。然后选择Open As > Source Code。最后,拷贝下面的XML代码然后在
标记前插入这段代码。
现在你已经在info.plist文件里添加了两个键值:
可以自行更改这些消息的内容。现在点击Run按钮,你应该可以编译和成功运行app了,不会报任何错误。
注意:
如果稍后在工程运行完成时还没有看到语音输入授权框,那是因为你是在模拟器上运行的程序。iOS模拟器没有权限进入你Mac电脑的麦克风。
处理语音识别
现在我们已经实现了用户授权,我们现在去实现语音识别功能。先从在 ViewController里定义下面的对象开始:
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var recognitionTask: SFSpeechRecognitionTask?
private let audioEngine = AVAudioEngine()
-
recognitionRequest对象处理了语音识别请求。它给语音识别提供了语音输入。
-
reconition task对象告诉你语音识别对象的结果。拥有这个对象很方便因为你可以用它删除或者中断任务。
-
audioEngine是你的语音引擎。它负责提供你的语音输入。
接下来,创建一个新的方法名叫 startRecording()。
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.")