AVAudioSession-如何在扬声器和耳机输出之间切换

时间:2018-09-18 16:09:32

标签: ios avfoundation avaudiosession

我正在尝试在通话过程中模仿“电话”应用程序中的行为。您可以轻松地在扬声器或耳机之间切换输出源。 我知道在通过以下方式连接耳机时,可以强制扬声器作为输出:

try! audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)  
try! audioSession.overrideOutputAudioPort(.speaker)  

但是,当我这样做时,我看不到任何方法来检测耳机是否仍连接到设备上。

我最初认为AVAudioSession上的outputDataSources将返回所有可能的输出,但始终返回nil。

有什么我想念的吗

1 个答案:

答案 0 :(得分:0)

您需要更改outputDataSources,就像您覆盖它时一样

现在它仅包含.Speaker选项

在文档中,您可以找到解决方案,

  

如果您的应用使用playAndRecord类别,则无论其他设置如何,使用AVAudioSession.PortOverride.speaker选项调用此方法都会导致将音频路由到内置扬声器和麦克风。该更改仅在当前路由更改之前有效,或者您使用AVAudioSession.PortOverride.none选项再次调用此方法。

因此,音频被路由到内置扬声器,此更改仅在当前路由更改或您用.noneOption再次调用此方法之前一直有效。

除非将附件插入耳机插孔(这会激活物理开关以将语音引导到耳机),否则无法将声音强制引导到耳机。

因此,当您想切换回耳机时,这应该可以工作。 如果未连接耳机,则会将输出设备切换到设备顶部的小扬声器输出,而不是大扬声器。

let session: AVAudioSession = AVAudioSession.sharedInstance()
        do {
            try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
            try session.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
            try session.setActive(true)
        } catch {
            print("Couldn't override output audio port")
        }

了解有关此AVAdioSession / OverrideOutputAudioPort Here的信息。

您可以检查是否已连接耳机以添加此扩展名,

    extension AVAudioSession {

    static var isHeadphonesConnected: Bool {
        return sharedInstance().isHeadphonesConnected
    }

    var isHeadphonesConnected: Bool {
        return !currentRoute.outputs.filter { $0.isHeadphones }.isEmpty
    }

}

extension AVAudioSessionPortDescription {
    var isHeadphones: Bool {
        return portType == AVAudioSessionPortHeadphones
    }
}

只需使用此行代码

session.isHeadphonesConnected