You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更细致调试SFSpeechRecognizer?集成识别异常求助

SFSpeechRecognizer 识别异常调试方案求助

我正在应用中集成SFSpeechRecognizer,但三个预录制的m4a音频文件返回的结果/错误无法帮我定位问题,相关资料也比较少。所有文件都是清晰大声录制的,但仍出现“未检测到语音”或无文本返回的情况:

SS-X-03.m4a : There was an error: Optional(Error Domain=kAFAssistantErrorDomain Code=1110 "No speech detected" UserInfo={NSLocalizedDescription=No speech detected})
SS-X-20221125000.m4a : There was an error: Optional(Error Domain=kAFAssistantErrorDomain Code=1110 "No speech detected" UserInfo={NSLocalizedDescription=No speech detected})
SS-X-20221125001.m4a : (仅当设置request.requiresOnDeviceRecognition = false时能识别出文本)

我的代码:

func findAudioFiles(){
        let fm = FileManager.default
        var aFiles : URL
        
        print ("\(urlPath)")
        do {
            let items = try fm.contentsOfDirectory(atPath: documentsPath)

            let filteredInterestArray1 = items.filter({$0.hasSuffix(".m4a")})
            let filteredInterestArray2 = filteredInterestArray1.filter({$0.contains("SS-X-")})
            let sortedItems = filteredInterestArray2.sorted()
            
            for item in sortedItems {
                audioFiles.append(item)
            }

            NotificationCenter.default.post(name: Notification.Name("goAndRead"), object: nil, userInfo: myDic)

        } catch {
            print ("\(error)")
        }
}

@objc func goAndRead(){
    audioIndex += 1
    if audioIndex != audioFiles.count {
    let fileURL = NSURL.fileURL(withPath: documentsPath + "/" + audioFiles[audioIndex], isDirectory: false)
    transcribeAudio(url: fileURL, item: audioFiles[audioIndex])
    }
}

func requestTranscribePermissions() {
    SFSpeechRecognizer.requestAuthorization { [unowned self] authStatus in
        DispatchQueue.main.async {
            if authStatus == .authorized {
                print("Good to go!")
            } else {
                print("Transcription permission was declined.")
            }
        }
    }
}

func transcribeAudio(url: URL, item: String) {
    guard let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US")) else {return}
    let request = SFSpeechURLRecognitionRequest(url: url)
    if !recognizer.supportsOnDeviceRecognition { print ("offline not available") ; return   }
     if !recognizer.isAvailable { print ("not available") ; return   }
    request.requiresOnDeviceRecognition = true
    request.shouldReportPartialResults = true

    recognizer.recognitionTask(with: request) {(result, error) in
        guard let result = result else {
            print("\(item) : There was an error: \(error.debugDescription)")
            return
        }

        if result.isFinal {
            print("\(item) : \(result.bestTranscription.formattedString)")
        NotificationCenter.default.post(name: Notification.Name("goAndRead"), object: nil, userInfo: self.myDic)
        }
    }
}

更新信息

  • 之前存在频繁调用SFSpeechURLRecognitionRequest的问题,前一次请求未完成就发起新请求,不确定是否需要创建新的SFSpeechRecognizer实例
  • 调整为前一次请求返回结果后再调用新请求,情况有所改善,但仍有一个音频文件无识别结果(无错误返回,仅无文本)
  • 该文件与能识别的文件格式、音量一致,是同一录音拆分而来
  • 需要更有效的调试方法定位该文件的问题

调试排查方案

一、音频文件本身验证

  1. 检查音频编码与参数
    使用音频工具(如Audacity)打开异常文件,确认:
    • 采样率:SFSpeechRecognizer推荐16kHz(离线识别对采样率更敏感)
    • 声道:必须是单声道(离线识别不支持立体声)
    • 编码格式:m4a需使用AAC-LC编码,避免使用其他特殊编码
    • 音量电平:确保语音部分的音量在-16dB到-6dB之间,无静音开头/结尾过长(超过1-2秒可能被判定为无语音)
  2. 手动播放验证
    直接播放异常文件,确认确实包含清晰可辨的英文语音,无背景噪音、断音情况;同时检查文件是否完整,无损坏。

二、代码逻辑优化与调试

  1. 请求队列管理
    • 不需要每次创建新的SFSpeechRecognizer实例,可全局复用一个实例(确保locale一致)
    • 维护一个请求状态标记,确保同一时间只有一个识别任务在运行,避免并发请求被系统限流或干扰
  2. 增强错误与结果日志
    在recognitionTask的回调中,补充以下日志,获取更多调试信息:
    // 打印部分结果,查看是否有临时识别内容
    if !result.bestTranscription.formattedString.isEmpty {
        print("\(item) 临时识别结果: \(result.bestTranscription.formattedString)")
    }
    // 打印错误的详细信息,包括所有UserInfo字段
    if let error = error {
        print("\(item) 错误详情: \(error),UserInfo: \(error.userInfo)")
    }
    
  3. 离线与在线识别对比测试
    对异常文件分别测试在线(requiresOnDeviceRecognition = false)和离线模式:
    • 若在线能识别,说明离线语言包可能未正确下载,需检查SFSpeechRecognizer.isAvailable状态,或手动在系统设置中确认英文离线语音包已下载
    • 若在线也无法识别,说明音频文件本身存在不符合识别要求的问题

三、系统环境验证

  1. 离线语言包状态
    调用SFSpeechRecognizer.supportedLocales()确认当前设备支持的离线语言,同时检查系统设置中「Siri与搜索」-「离线语音识别」是否已开启并下载对应语言包
  2. 权限与系统版本
    确保应用已配置NSSpeechRecognitionUsageDescription权限,且设备系统版本符合离线识别要求(iOS 13+支持离线英文识别)
  3. 系统限流检查
    SFSpeechRecognizer有请求频率限制,若短时间内发起大量请求,可能被系统静默拒绝,可在每次请求前添加1-2秒延迟,测试是否恢复正常

内容的提问来源于stack exchange,提问作者Bartender1382

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:05:17