Swift技术实现:如何将已保存的音频对话文件转换为文本?
如何在iOS中使用Speech框架将本地音频文件转换为文本
既然你已经熟悉iOS的Speech框架做实时的STT和TTS了,那处理本地音频文件其实是类似的思路,只是把实时输入换成本地文件的URL就行,我给你梳理下具体步骤和代码示例:
首先,咱们得确认几个前提:你已经在项目里导入了Speech框架,并且在Info.plist中配置了必要的权限(如果之前做实时STT已经配过,这步可以跳过):
- 添加
NSSpeechRecognitionUsageDescription,说明你的App为什么需要语音识别权限 - 添加
NSMicrophoneUsageDescription(虽然处理本地文件可能用不到,但部分场景下系统可能仍会校验,建议加上)
1. 检查并请求语音识别权限
在处理音频之前,得确保用户已经授权了语音识别权限:
import Speech func checkSpeechRecognitionPermission() { SFSpeechRecognizer.requestAuthorization { authStatus in DispatchQueue.main.async { switch authStatus { case .authorized: // 权限已获取,可以开始处理音频 self.processLocalAudioFile() case .denied, .restricted, .notDetermined: // 权限未授权,提示用户去设置开启 print("语音识别权限未授权,请在设置中开启") @unknown default: break } } } }
2. 处理本地音频文件核心逻辑
使用SFSpeechURLRecognitionRequest可以直接传入本地音频文件的URL,不需要实时录音。这里假设你的音频文件已经保存在沙盒或者可访问的路径下:
func processLocalAudioFile() { // 替换成你的本地音频文件URL,比如从Documents目录获取 guard let audioURL = Bundle.main.url(forResource: "conversation", withExtension: "wav") else { print("找不到目标音频文件") return } // 初始化语音识别请求 let recognitionRequest = SFSpeechURLRecognitionRequest(url: audioURL) // 可选:设置是否返回中间识别结果(适合长音频实时看进度) recognitionRequest.shouldReportPartialResults = true // 初始化语音识别器,设置对应语言(比如中文是"zh-CN",英文是"en-US") guard let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "zh-CN")) else { print("当前设备不支持所选语言的语音识别") return } // 如果识别器暂时忙,等待可用 if !speechRecognizer.isAvailable { print("语音识别器当前不可用,请稍后再试") return } // 发起识别请求 speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in guard let result = result else { print("识别出错:\(error?.localizedDescription ?? "未知错误")") return } // 获取当前识别结果(如果开启了partialResults,这里会实时返回中间内容) let transcribedText = result.bestTranscription.formattedString print("当前识别文本:\(transcribedText)") // 检查是否识别完成 if result.isFinal { print("最终识别文本:\(transcribedText)") // 这里可以把结果保存到本地或者展示给用户 } } }
3. 常见问题与注意事项
- 音频格式兼容性:Speech框架支持WAV、MP4、AAC等常见格式,但推荐使用16kHz采样率、单声道的PCM编码音频,识别准确率更高。如果你的音频格式不被支持,可以用
AVAssetExportSession转成兼容格式:func convertAudioToCompatibleFormat(inputURL: URL, outputURL: URL) { let asset = AVAsset(url: inputURL) guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else { print("创建转码会话失败") return } exportSession.outputURL = outputURL exportSession.outputFileType = .m4a exportSession.exportAsynchronously { switch exportSession.status { case .completed: print("转码完成,新文件路径:\(outputURL)") // 转码完成后调用processLocalAudioFile处理新文件 case .failed, .cancelled: print("转码失败:\(exportSession.error?.localizedDescription ?? "未知错误")") default: break } } } - 语言匹配:确保
SFSpeechRecognizer的locale和音频中的语言完全一致,否则识别准确率会大幅下降。 - 离线识别支持:如果需要无网络场景下使用,需要让用户先在系统设置中下载对应语言的离线识别包,并且初始化识别器时设置
requiresOnDeviceRecognition = true。
内容的提问来源于stack exchange,提问作者Ali Ihsan URAL




