iOS语音识别

21 篇文章 0 订阅

  • 在 2016 年的 WWDC 上,Apple 终于开放了语音识别 Speech Recognition API,那就是 Speech 框架。事实上,Siri 的语音识别正是由 Speech Kit 提供支持。超过50种语言获得支持、任何运行iOS10的设备都可用、加入用户授权使其更安全、可以转化音频文件和实时语音 。
  • 现在阿里、腾讯、科大讯飞都有相关的语音识别框架、超过时长都会收费的、集成相关框架、调用相关api还是非常简单的,这里主要讲的是iOS自带语音识别框架Speech的使用。

iOS语音识别步骤

  • 录音和语音识别都是用户的隐私权限,所以需要用户授权打开麦克风(实时语音)和音频识别权限,所以要在info.plist文件中添加相关key:(Privacy - Microphone Usage Description、Privacy - Speech Recognition Usage Description)
	<key>NSMicrophoneUsageDescription</key>
	<string>App需要您的同意,才能访问麦克风</string>
	<key>NSSpeechRecognitionUsageDescription</key>
	<string>App需要您的同意,才能使用语音识别技术</string>

设置用户授权

  • 只有用户授权了,才能访问麦克风和音频识别
  override func viewDidLoad() {
        super.viewDidLoad()
    //获取用户权限
        SFSpeechRecognizer.requestAuthorization { (authStatus : SFSpeechRecognizerAuthorizationStatus) in
            DispatchQueue.main.async(execute: {
                switch authStatus {
                case .notDetermined:
                    self.titleL.text = "语音识别未授权"
                    break
                case .denied:
                    self.titleL.text = "用户未授权使用语音识别"
                    break
                case .restricted:
                    self.titleL.text = "语音识别在这台设备上受到限制"
                    break
                case .authorized:
                    self.titleL.text = "可以开始录音了"
                    self.btnClickEnabled = true
                    break
                }
            })
        }
          }
本地音频文件识别
  • 比如像微信支付宝一些搜索框中就是先录音,然后再识别音频文件转为文字进行搜索,这个相对用的比较多。关于录音上篇文章已经写过了,这里不再赘述。这里主要讲录音后的音频文件如何识别。
  • 本地语音文件识别还是很简单的,获取音频文件路径url,通过这个url录音创建识别请求对象,音频识别对象通过该请求去执行识别任务后即可获得识别后的文字。
  • 具体相关代码:
  //本地语音文件识别(录音后,识别录音文件)
    @IBAction func leftBtnClick(_ sender: UIButton) {
        let local = NSLocale(localeIdentifier: "zh_CN")
        //获取本地录音文件路劲
        let url = Bundle.main.url(forResource: "recordAudio.wav", withExtension: nil)
        if url == nil {
            return
        }
        let localRecognizer = SFSpeechRecognizer(locale: local as Locale)!
        let rqs = SFSpeechURLRecognitionRequest(url: url!)
//        recordUrl = [NSURL URLWithString:[NSTemporaryDirectory() stringByAppendingString:@"selfRecord.pcm"]]
        localRecognizer.recognitionTask(with: rqs) { (result, error) in
            if (error != nil) {
                print("语音识别解析失败,%@",error!);
            }else{
               self.titleL.text = result!.bestTranscription.formattedString
            }
        }
    }
实时语音识别
  • 实时语音识别就像Siri一样可以变说话边转文字,类似于语言同步翻译,虽然一遍的开发中用到的很少,但还是有必要了解一下。实时语音需要开启麦克风,所以需要不能用模拟器测试。
  • 实时语音识别需要用到音频引擎这个关键类AVAudioEngine,用于生成和处理音频信号并执行音频输入和输出,功能十分强大。
  • 具体相关代码:
//初始化一些成员变量
class ViewController: UIViewController {
    var btnClickEnabled = false//按钮是否可以点击
    var speechRecognizer : SFSpeechRecognizer?//音频识别器
    var recognitionRequest : SFSpeechAudioBufferRecognitionRequest?//对象用于处理语音识别请求,为语音识别提供音频输入
    var recognitionTask : SFSpeechRecognitionTask? //可以将识别请求的结果返回给你,它带来了极大的便利,必要时,可以取消或停止任务。
    lazy var audioEngine = AVAudioEngine()// 音频引擎 用于进行音频输入

}

//初始化语音识别对象
override func viewDidLoad() {
        super.viewDidLoad()
        //用于apple语言识别的变量
        speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "zh-CN"))
        speechRecognizer?.delegate = (self as SFSpeechRecognizerDelegate);
        }
        
//开始录音
    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{
            
            fatalError("会话创建失败")
        }
        
        //创建音频识别请求对象
        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
        
        guard let inputNode : AVAudioInputNode = audioEngine.inputNode else {
            fatalError("音频引擎 没有输入节点")
        }
        
        guard let recognitionRequest = recognitionRequest else {
            fatalError("创建音频缓存失败")
        }
        //结果报告
        recognitionRequest.shouldReportPartialResults = true
        
        //开启授权任务
        recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
            var isFinal = false
            guard result == nil else {
                self.titleL.text = result?.bestTranscription.formattedString
                //判断语言是否处理完成
                isFinal = (result?.isFinal)!
                return
            }
            
            guard error == nil && isFinal == false else{
                // 停止声音处理器引擎
                self.audioEngine.stop()
                inputNode.removeTap(onBus: 0)
                //停止语音识别请求进程
                self.recognitionRequest?.endAudio()
                self.recognitionRequest = nil
                self.recognitionTask?.cancel()
                self.recognitionTask = nil
                //按钮可以点击
                self.btnClickEnabled = true
                return
            }
        })
        // 初始化语音处理器的输入模式
        let recordingFormat = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
             // 为语音识别请求对象添加一个AudioPCMBuffer,来获取声音数据
            self.recognitionRequest?.append(buffer)
        }
         // 语音处理器准备就绪(会为一些audioEngine启动时所必须的资源开辟内存)
        audioEngine.prepare()
        do {
            //启动识别
            try audioEngine.start()
        } catch {
            print("audioEngine couldn't start because of an error.")
        }
    }

//停止录音
    func endRecording(){
        audioEngine.stop()
        recognitionRequest?.endAudio()
    }


//语音实时识别
extension UIViewController : SFSpeechRecognizerDelegate{
    //当语音识别器的可用性发生更改时通知代理。如果语音识别可用,录音按钮也将被启用。
    public func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {
        if available {
            btnClickEnabled = true
        } else {
            btnClickEnabled = false
    }
    }
}

//按钮点击事件控制
 @IBAction func rightBtnClick(_ sender: UIButton) {
        if btnClickEnabled {
            if audioEngine.isRunning {//结束语言识别
                endRecording()
                sender.setTitle("开始语言识别", for: .normal)
            } else {
                self.titleL.text = ""
                startRecording()
                sender.setTitle("结束语言识别", for: .normal)
            }
        }
    }
  • Apple忠告:
    1. 确保使用语音之别之前,通过UI界面告知用户
    2. 在涉及密码或者敏感信息时,请勿使用
    3. 在你操作识别结果之前,请先把结果展示给用户
    4. Apple 对每台设备的识别有限制。详情未知,不过你可以尝试联系 Apple 获得更多信息
    5. Apple 对每个应用的识别也有限制
    6. 如果你总是遭遇限制,务必联系 Apple,他们或许可以解决这个问题
    7. 语音识别会消耗不少电量和流量
    8. 语音识别每次只能持续大概一分钟

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值