AVSpeechSynthesizer使用听筒而非底部扬声器播放问题如何解决
解决方案
这个问题的核心是未主动配置AVAudioSession的音频路由策略,iOS默认的音频会话配置会将语音类音频优先输出到听筒,需要手动指定输出到底部扬声器。
具体修改逻辑
- 确保已经导入
AVFoundation框架(你当前使用AVSpeechSynthesizer已经满足该前提) - 在调用
AVSpeechSynthesizer播放语音前,先配置音频会话的类别和输出路由 - 可以根据业务需要选择是否在播放完成后重置音频会话配置,避免影响App其他音频功能
修正后的完整代码
import AVFoundation @discardableResult func speechSentence(_ text: String) -> Bool { // 先配置音频会话 let audioSession = AVAudioSession.sharedInstance() do { // 若不需要同时录音,可以把类别换成.playback,默认就会走扬声器 try audioSession.setCategory(.playAndRecord, options: [.defaultToSpeaker, .allowBluetoothA2DP]) try audioSession.setActive(true) } catch { print("音频会话配置失败: \(error.localizedDescription)") return false } let synthesizer = AVSpeechSynthesizer() let utterance = AVSpeechUtterance(string: text) utterance.voice = AVSpeechSynthesisVoice(language: "en-US") utterance.rate = AVSpeechUtteranceDefaultSpeechRate synthesizer.speak(utterance) return true }
可选优化点
- 如果你的App只有语音播放需求、没有录音需求,直接将音频类别改为
.playback即可,不需要额外加.defaultToSpeaker选项,该类别下默认走底部扬声器,且不受静音开关影响 - 如果播放完成后不需要保持音频会话激活,可以在
AVSpeechSynthesizer的播放完成回调中调用try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation),把音频会话控制权还给系统和其他App
内容的提问来源于stack exchange,提问作者mohsen
相关产品推荐
相关产品推荐

