我在我的应用程序中成功实现了WebRTC,但是我遇到一个问题,即音频将从接收器而不是接收器+扬声器发出。我最终修改了一个发现的解决方案,该解决方案用于在插拔蓝牙耳机或普通耳机时处理音频路由。 通常,当我通过WebRTC库收到音频时,就会触发通知。
NotificationCenter.default.addObserver(forName: AVAudioSession.routeChangeNotification, object: nil, queue: nil, using: routeChange)
func routeChange(_ n: Notification) {
guard let info = n.userInfo,
let value = info[AVAudioSessionRouteChangeReasonKey] as? UInt,
let reason = AVAudioSession.RouteChangeReason(rawValue: value) else { return }
switch reason {
case .categoryChange:
for description in AVAudioSession.sharedInstance().currentRoute.outputs {
if description.portType == AVAudioSession.Port.builtInSpeaker || description.portType == AVAudioSession.Port.builtInReceiver {
try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
}
}
case .oldDeviceUnavailable:
try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
default:
return
}
}
但是,这种解决方案使我无法播放当用户点击我的应用程序中的按钮时用作提示/反馈的音频文件。基本上,以下代码将播放音频文件,但是它将以多种方式破坏我上面的配置。它将主要使音频从接收器而不是扬声器和接收器中发出。我相信它也会与耳机混在一起。
private func playTapSound() {
guard let url = Bundle.main.url(forResource: App.AudioFile.tapFeedback, withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
guard let player = audioPlayer else { return }
player.play()
} catch let error {
print("### Error - playing tap audio -", error.localizedDescription)
}
}
我需要在不影响routeChange方法的情况下播放音频文件。