我正在尝试在通话过程中模仿“电话”应用程序中的行为。您可以轻松地在扬声器或耳机之间切换输出源。 我知道在通过以下方式连接耳机时,可以强制扬声器作为输出:
try! audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
try! audioSession.overrideOutputAudioPort(.speaker)
但是,当我这样做时,我看不到任何方法来检测耳机是否仍连接到设备上。
我最初认为AVAudioSession上的outputDataSources
将返回所有可能的输出,但始终返回nil。
有什么我想念的吗
答案 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