如何在 AppRTC iOS 示例中将音频重定向到扬声器?
Posted
技术标签:
【中文标题】如何在 AppRTC iOS 示例中将音频重定向到扬声器?【英文标题】:How to redirect audio to speakers in the AppRTC iOS example? 【发布时间】:2014-07-06 11:58:23 【问题描述】:我正在尝试将音频重定向到 AppRTC ios example 中的扬声器。
我试过了:
AVAudioSession* session = [AVAudioSession sharedInstance];
//error handling
BOOL success;
NSError* error;
//set the audioSession category.
//Needs to be Record or PlayAndRecord to use audioRouteOverride:
success = [session setCategory:AVAudioSessionCategoryPlayAndRecord
error:&error];
if (!success) NSLog(@"AVAudioSession error setting category:%@",error);
//set the audioSession override
success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
error:&error];
if (!success) NSLog(@"AVAudioSession error overrideOutputAudioPort:%@",error);
//activate the audio session
success = [session setActive:YES error:&error];
if (!success) NSLog(@"AVAudioSession error activating: %@",error);
else NSLog(@"audioSession active");
没有错误,但它不起作用。我该如何解决这个问题?
【问题讨论】:
您找到解决问题的方法了吗?我现在和你面临同样的问题。 @JosipB。 github.com/alongubkin/audiotoggle 对我不起作用... 【参考方案1】:我通过解决方案解决了它。 只听AVAudioSessionRouteChangeNotification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didSessionRouteChange:) name:AVAudioSessionRouteChangeNotification object:nil];
并使用 didSessionRouteChange 选择器,如下所示:
- (void)didSessionRouteChange:(NSNotification *)notification
NSDictionary *interuptionDict = notification.userInfo;
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
switch (routeChangeReason)
case AVAudioSessionRouteChangeReasonCategoryChange:
// Set speaker as default route
NSError* error;
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
break;
default:
break;
【讨论】:
终于找到了一个适合我的解决方案。非常感谢。 这个解决方案很危险。每次有人更改路线时都会调用此通知,换句话说,它可能会在以后导致潜在的问题。【参考方案2】:似乎仍然是一个问题,phuongle 答案对我有用。 Swift 4 版本:
NotificationCenter.default.addObserver(forName: .AVAudioSessionRouteChange, object: nil, queue: nil, using: routeChange)
private func routeChange(_ n: Notification)
guard let info = n.userInfo,
let value = info[AVAudioSessionRouteChangeReasonKey] as? UInt,
let reason = AVAudioSessionRouteChangeReason(rawValue: value) else return
switch reason
case .categoryChange: try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
default: break
【讨论】:
【参考方案3】:对于任何来到这里的人,都在 Swift 中寻找解决方案,该解决方案还考虑了从 (BT-) 耳机返回的变化。下面的示例 (Swift 5) 就是这样做的。 部分来自@Teivaz
@objc func handleRouteChange(notification: Notification)
guard let info = notification.userInfo,
let value = info[AVAudioSessionRouteChangeReasonKey] as? UInt,
let reason = AVAudioSession.RouteChangeReason(rawValue: value) else return
switch reason
case .categoryChange:
try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
case .oldDeviceUnavailable:
try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
default:
l.debug("other")
【讨论】:
【参考方案4】:我最终找到了解决办法。
原因是您需要将AVAudioSession
类别设置为AVAudioSessionCategoryPlayback
。但由于某种原因,在建立 webRTC 调用后,它被设置回AVAudioSessionCategoryPlayAndRecord
。
最后,我决定为AVAudioSessionRouteChangeNotification
添加观察者,并在每次检测到不需要的类别更改时切换到AVAudioSessionCategoryPlayback
。
一些黑客解决方案,但最终奏效了。您可以查看here。
【讨论】:
【参考方案5】:phuongle's answer 是正确的。虽然当您启用覆盖时,即使用户插入耳机,这实际上也会覆盖音频输出。当用户使用耳机时,通过扬声器播放音频没有多大意义。为此,请使用以下代码:
- (void)didSessionRouteChange:(NSNotification *)notification
NSDictionary *interuptionDict = notification.userInfo;
const NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
if (routeChangeReason == AVAudioSessionRouteChangeReasonRouteConfigurationChange)
[self enableLoudspeaker];
- (void)enableLoudspeaker
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
AVAudioSessionCategoryOptions options = audioSession.categoryOptions;
if (options & AVAudioSessionCategoryOptionDefaultToSpeaker) return;
options |= AVAudioSessionCategoryOptionDefaultToSpeaker;
[audioSession setActive:YES error:nil];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:options error:nil];
【讨论】:
"AVAudioSessionRouteChangeReasonCategoryChange" 而不是 "AVAudioSessionRouteChangeReasonRouteConfigurationChange" 解决了我的问题。谢谢以上是关于如何在 AppRTC iOS 示例中将音频重定向到扬声器?的主要内容,如果未能解决你的问题,请参考以下文章