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

AVSpeechSynthesizer使用听筒而非底部扬声器播放问题如何解决

解决方案

这个问题的核心是未主动配置AVAudioSession的音频路由策略,iOS默认的音频会话配置会将语音类音频优先输出到听筒,需要手动指定输出到底部扬声器。

具体修改逻辑

  1. 确保已经导入AVFoundation框架(你当前使用AVSpeechSynthesizer已经满足该前提)
  2. 在调用AVSpeechSynthesizer播放语音前,先配置音频会话的类别和输出路由
  3. 可以根据业务需要选择是否在播放完成后重置音频会话配置,避免影响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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:15:04