iOS15中SFSpeechURLRecognitionRequest仅识别音频首句 如何实现完整转录
问题根因
你当前代码的核心问题是SFSpeechRecognizer实例被声明为函数内的局部变量,函数执行完成后实例会被ARC自动释放,正在运行的识别任务会直接被中断,所以只能拿到前几秒/第一句的识别结果。
另外还有几个容易触发识别不完整的配置问题也需要修正:
- 没有提前申请语音识别权限就直接调用识别接口
- 未对识别过程中的错误、终止状态做完整捕获
- 单次识别默认最大时长限制为1分钟,超过时长的音频需要额外处理
前置配置
首先需要在项目的Info.plist中添加权限声明:
- 键:
NSSpeechRecognitionUsageDescription,值填你自己的权限申请文案,比如「需要语音识别权限完成音频转文字」
修正后完整代码
import Speech // 将识别器和识别任务声明为类的全局属性,避免被提前释放 private var speechRecognizer: SFSpeechRecognizer? private var recognitionTask: SFSpeechRecognitionTask? func transcribeAudio(url: URL) { // 先校验语音识别权限 SFSpeechRecognizer.requestAuthorization { [weak self] authStatus in guard authStatus == .authorized else { print("语音识别权限未授权") return } // 初始化识别器,可根据需要指定语言,比如简体中文对应zh_CN,英文对应en_US self?.speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "zh_CN")) guard let recognizer = self?.speechRecognizer, recognizer.isAvailable else { print("当前设备不支持离线语音识别") return } let request = SFSpeechURLRecognitionRequest(url: url) request.requiresOnDeviceRecognition = true request.taskHint = .dictation // 只需要最终结果保持false即可,需要实时获取部分识别结果可设为true request.shouldReportPartialResults = false // 持有识别任务实例 self?.recognitionTask = recognizer.recognitionTask(with: request) { result, error in // 识别结束后自动释放资源 defer { self?.speechRecognizer = nil self?.recognitionTask = nil } if let error = error { print("识别出错: \(error.localizedDescription)") return } guard let result = result else { print("未获取到有效识别结果") return } if result.isFinal { print("完整识别结果:\(result.bestTranscription.formattedString)") } } } }
长音频适配方案
如果你的音频时长超过系统默认的1分钟识别限制,需要先将音频按30-50秒的长度切片,再依次对每个切片做识别,最后拼接所有切片的识别结果即可。
内容的提问来源于stack exchange,提问作者Olexander Korenyuk
相关产品推荐
相关产品推荐

