2016-10-25 可可中国翻译组可可中国
▲点击上方“ CocoaChina ”关注即可免费学习iOS开发
译者:王跃
在2016WWDC大会上,苹果公司介绍了一个很好的语音识别的API,那就是语音框架。事实上,这个语音套件就是Siri使用做语音识别的框架。现在已经有一些可用的语音识别框架,但是在今天的教程里面,我会教你如何创建一个使用语音工具包来进行语音转文字的类似Siri的app。
设计App UI
满足:您需要Xcode 8 beta版本和一个运行iOS 10 beta系统版本的iOS设备。
然后,到Main.storyboard中添加一个UILabel,一个UITextView和一个UIButton,你的storyboard应该看起来如下图:

接下来在ViewController.swift文件中为UITextView和UIButton定义出口变量。在这个演示当中,我设置UITextView的名称为“ textView”,UIButton的名称为“ microphoneButton”。的空的按钮执行方法。
@IBAction功能麦克风[_发送者:AnyObject){
}
如果你不想从创造最原始的工程开始,你可以在这里下载原始工程然后继续下面的教学指导。
使用语音框架
为了能使用语音框架,您必须首先引入它然后遵循SFSpeechRecognizerDelegate协议。因此让我们引入这个框架,然后在ViewController文件中加上它的协议。现在你的ViewController.swift文件应该如下所示:
导入UIKit
导入语音
ViewController类:UIViewController,SFSpeechRecognizerDelegate {
@IBOutlet弱var textView:UITextView!
@IBOutlet弱变量麦克风:UIButton!
覆盖func viewDidLoad(){
super.viewDidLoad()
}
@IBAction功能麦克风[_发送者:AnyObject){
}
}
用户授权
在使用语音框架做语音识别之前,您必须首先得到用户的允许,因为不仅仅只有本地的ios设备会进行进行识别,苹果的服务器也会识别。所有的语音数据都会被传递到苹果的后台进行处理。因此,获取用户授权是强制必须的。
让我们在viewDidLoad方法里授权语音识别。用户必须允许应用程序使用麦克风和语音识别。首先,声明一个语音识别变量:
私人let speechRecognizer = SFSpeechRecognizer(locale:Locale.init(identifier:“ en-US”))// 1
然后按如下更新viewDidLoad方法:
覆盖func viewDidLoad(){
super.viewDidLoad()
MikeButton.isEnabled = false // 2
speechRecognizer.delegate =自我// 3
// 4中的SFSpeechRecognizer.requestAuthorization {(authStatus)
var isButtonEnabled = false
切换authStatus {// 5
案例授权:
isButtonEnabled = true
大小写被拒绝:
isButtonEnabled =否
打印(“用户拒绝访问语音识别”)
大小写受限制:
isButtonEnabled =否
打印(“此设备上的语音识别受限”)
大小写。未确定:
isButtonEnabled =否
打印(“语音识别尚未授权”)
}
OperationQueue.main.addOperation(){
self.microphoneButton.isEnabled = isButtonEnabled
}
}
}
首先,我们创建一个带有标识符en-US的SFSpeechRecognizer实例,这样语音识别API就能知道用户说的是哪一种语言。这个实例就是处理语音识别的对象。
我们默认让麦克风按钮至少直到语音识别功能被激活。
接下来,把语音识别的代理设置为self也就是我们的ViewController。
之后,我们必须通过调用SFSpeechRecognizer.requestAuthorization方法来请求语音识别的授权。
最后,检查验证的状态。如果被授权了,让麦克风按钮有效。如果没有,打印错误信息然后让麦克风按钮无效。
现在如果你认为app跑起来之后你会看到一个授权发布窗口,那你就错了。如果运行,app会崩溃。好吧,既然知道结果为什么还要问呢?(别打我),看看下面解决方法。
提供授权消息
苹果要求app里所有的授权都要一个自定义的信息。例如语音授权,我们必须请求2个授权:
麦克风使用权。
语音识别。
为了自定义信息,您必须在info.plist配置文件里提供这些自定义消息。
让我们打开info.plist配置文件的源代码。首先,右键单击info.plist。然后选择另存为>源代码。最后,复制下面的XML代码然后在
标记前插入这段代码。


现在你已经在info.plist文件里添加了两个键值:
NSMicrophoneUsageDescription-为获取麦克风语音输入授权的自定义消息。注意此语音输入授权仅只会在用户点击麦克风按钮时发生。
NSSpeechRecognitionUsageDescription –语音识别授权的自定义信息
可以自行更改这些消息的内容。现在点击Run按钮,你应该可以编译和成功运行app了,不会报任何错误。

注意:如果稍后在工程运行完成时还没有看到语音输入授权框,那是因为你是在模拟器上运行的程序。iOS模拟器没有权限进入你Mac电脑的麦克风。
处理语音识别
现在我们已经实现了用户授权,我们现在去实现语音识别功能。先从在ViewController里定义下面的对象开始:
专用var识别请求:SFSpeechAudioBufferRecognitionRequest?
私有var识别任务:SFSpeechRecognitionTask?
私人让audioEngine = AVAudioEngine()
RecognitionRequest对象处理了语音识别请求。它给语音识别提供了语音输入。
拥有这个对象很方便,因为你可以用它删除或中断任务。
audioEngine是你的语音引擎。它负责提供你的语音输入。
接下来,创建一个新的方法名叫startRecording()。
func startRecording(){
如果ognitionTask!= nil {
ognitionTask?.cancel()
RecognitionTask =无
}
让audioSession = AVAudioSession.sharedInstance()
做{
尝试audioSession.setCategory(AVAudioSessionCategoryRecord)
尝试audioSession.setMode(AVAudioSessionModeMeasurement)
尝试audioSession.setActive(true,带有:.notifyOthersOnDeactivation)
} {
print(“由于错误而未设置audioSession属性。”)
}
IdentificationRequest = SFSpeechAudioBufferRecognitionRequest()
警卫让inputNode = audioEngine.inputNode其他{
fatalError(“音频引擎没有输入节点”)
}
警卫队让RecognitionRequest = IdentificationRequest else {
fatalError(“无法创建SFSpeechAudioBufferRecognitionRequest对象”)
}
IdentificationRequest.shouldReportPartialResults = true
RecognitionTask = speechRecognizer.recognitionTask(with:IdentificationRequest,resultHandler:{(result,error)in
var isFinal = false
如果结果!=无{
self.textView.text =结果?.bestTranscription.formattedString
isFinal =(结果?.isFinal)!
}
如果错误!= nil || isFinal {
self.audioEngine.stop()
inputNode.removeTap(onBus:0)
self.recognitionRequest =无
self.recognitionTask =无
self.microphoneButton.isEnabled = true
}
})
让recordingFormat = inputNode.outputFormat(forBus:0)
inputNode.installTap(onBus:0,bufferSize:1024,format:recordingFormat){(buffer when when)在
self.recognitionRequest?.append(buffer)
}
audioEngine.prepare()
做{
尝试audioEngine.start()
} {
print(“由于错误,audioEngine无法启动。”)
}
textView.text =“说点什么,我在听!”
}
这个方法会在开始录音按钮被点击时调用。它的主要功能是开启语音识别然后聆听你的麦克风。
3-6行–检查识别任务是否在运行。如果在就取消任务和识别。
8-15行–创建一个AVAudioSession来为记录语音做准备。在这里我们设置会话的类别为录音,模式为测量,然后激活它。注意设置这些属性有可能会引发异常,因此你必须把他们放入try catch语句里面。
17行–实例化recognitionRequest。在这里我们创建了SFSpeechAudioBufferRecognitionRequest对象。稍后我们利用它把语音数据传到苹果后台。
19-21行–检查audioEngine(你的设备)是否有做录音功能作为语音输入。如果没有,我们就报告一个错误。
23-25行–检查recognitionRequest对象是否被实例化和不是nil。
27行–当用户说话的时候让recognitionRequest报告语音识别的部分结果。
29行–调用SpeechRecognizer'srecognitionTask方法来开启语音识别。这个方法有一个完整的处理程序。此替换每次都会在识别引擎收到输入的时候,完善了当前识别的信息时候,或者被删除或停止的时候被调用,最后会返回一个最终的文本。
31行–定义一个布尔值决定识别是否已经结束。
35行–如果结果结果不是nil,则将textView.text的值设置为我们的最优文本。如果结果是最终结果,设置isFinal为true。
39-47行–如果没有错误或结果是最终结果,则停止audioEngine(语音输入)并停止识别请求和识别Task。同时,使Start Recording按钮有效。
50-53行–向识别请求增加一个语音输入。注意在开始了recognitionTask之后增加语音输入是OK的。语音框架会在语音输入被加入的同时就开始进行解析识别。
55行–准备并开始audioEngine。
触发语音识别
我们需要保证当创建一个语音识别任务的时候语音识别功能是可用的,因此我们必须给ViewController添加一个代理方法。如果语音输入不可用或改变了它的状态,那么话筒按钮。启用属性就要被设置。针对这种情况,我们实现了SFSpeechRecognizerDelegate协议的AvailabilityDidChange方法。实现内容看下面:
func speechRecognizer(_ SpeechRecognizer:SFSpeechRecognizer,availableDidChange可用:Bool){
如果可供使用的话 {
MikeButton.isEnabled = true
}其他{
MikeButton.isEnabled =否
}
}
如果语音识别可用,那么记录按钮记录会被设为可用状态。
最后一件事就是我们必须更新响应方法
@IBAction功能麦克风[_发送者:AnyObject){
如果audioEngine.isRunning {
audioEngine.stop()
IdentificationRequest?.endAudio()
MikeButton.isEnabled =否
MicrophoneButton.setTitle(“开始录制”,用于:.normal)
}其他{
startRecording()
MikeButton.setTitle(“ Stop Recording”,for:.normal)
}
}
在这个方法中,我们必须检查audioEngine是否正在工作。如果是,app应该停止audioEngine,中止向recognitionRequest输入音频,让microphoneButton按钮不可用,并且设置按钮的标题为“ Start Recording”
如果audioEngine正在工作,app应该调用startRecording()并且设置按钮的标题为“ Stop Recording”。
非常好!现在可以准备测试app了。把app部署到一个iOS10的设备,然后点击“开始录制”按钮。去说些什么吧!

注意:
苹果公司对每个设备的识别功能都有限制。具体的限制并不知道,但是你可以联系苹果公司了解更多信息。
苹果公司对每个app也有识别功能限制。
如果你经常遇到限制,请一定联系苹果公司,他们应该可以解决问题。
语音识别会很耗电以及会使用很多数据。
语音识别一次只持续大概一分钟时间。
总结
在这个教程中,你学习到了怎样好的好利用苹果公司开放给开发者的惊人的新语言API,用于语音识别和转换到文本。语音框架使用了跟Siri相同的语音识别框架。这是一个相对小的API。但是,它非常强大可以让开发者们开发非凡的应用程序转换一个语音文件到文本文字。
我推荐你看WWDC 2016 session 509去获取更多有用的信息。希望你喜欢这篇文章并且在探索这个全新的API中获得乐趣。
作为参考,你可以在这里查看Github完整工程
微信号:CocoaChinabbs

▲长按二维码“识别”关注即可免费学习iOS开发
月薪十万,出任首席执行官,赢娶白富美,走上人生巅峰不是梦
-------- ----------------- -------------
商务合作QQ:2408167315
投稿邮箱:support@cocoachina.com