连接蓝牙耳机时无法切换到扬声器输出

Posted

技术标签:

【中文标题】连接蓝牙耳机时无法切换到扬声器输出【英文标题】:Unable to switch to speaker output when bluetooth headsets are connected 【发布时间】:2018-12-25 12:25:53 【问题描述】:

我正在尝试使用AVAudiosession 在蓝牙耳机(在我的情况下为airpods)和电话扬声器之间进行切换。我这样初始化我的会话:

AVAudioSessionCategoryOptions options = (AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionDefaultToSpeaker);
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:options error:&error];

然后我尝试在输出模式之间交替:

-(void)setIncomingSoundMode:(IncomingSoundMode)incomingSoundMode
    [self removeAudioRouteChangedObserver];


    [NNLogger logFromInstance: self message: @"Audio stream setting use speaker" data: @(incomingSoundMode)];
    _incomingSoundMode = incomingSoundMode;


    AVAudioSession *session = [AVAudioSession sharedInstance];
    AVAudioSessionPortDescription *routePort = session.currentRoute.outputs.firstObject;
    NSString *portType = routePort.portType;
    NSLog(@"current port type: %@",portType);


    NSError *audioPortError = nil;
    if(incomingSoundMode == IncomingSoundModeSpeaker)
        [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&audioPortError];
        [self muteChannel:NO];
     else if(incomingSoundMode == IncomingSoundModeHeadset)
        [session overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&audioPortError];
        [self muteChannel:NO];
     else if(incomingSoundMode == IncomingSoundModeBluetooth)
        [session overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&audioPortError];
        [self muteChannel:NO];
     else if(incomingSoundMode == IncomingSoundModeSilent)
        [self muteChannel:YES];
    

    if(audioPortError)
        NSLog(@"audioPortError - %@",audioPortError.localizedDescription);
    
    NSError *sessionError = nil;
    [session setActive: YES error:&sessionError];
    if(sessionError)
        NSLog(@"sessionError - %@",sessionError.localizedDescription);
    

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
        [self addAudioRouteChangedObserver];
    );


问题是当我在连接蓝牙耳机时尝试覆盖扬声器输出 - 它根本不会切换到扬声器。同样的功能适用于有线耳机,或将设备扬声器切换到耳机时:

[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&audioPortError];
[session setActive: YES error:&sessionError];

关于我在这里做错了什么的任何线索??

谢谢

【问题讨论】:

似乎airpods在设置AVAudioSessionPortOverrideSpeaker后触发了“NewDeviceAvailable”音频路由更改通知,系统再次自动将音频切换到airpods(另一个蓝牙设备工作正常)。我也在寻找解决方案。 你找到解决办法了吗? 【参考方案1】:

我正在处理的应用程序中存在完全相同的问题,并且只能在 iOS 12+ 上重现,并且仅适用于 W1 / H1 芯片蓝牙设备(AirPods / new Beats Studio 等)。

我向 WWDC 上的苹果音频工程师询问了这件事(通过显示我的错误报告),他们已经确认这是他们正在处理的一个已知问题。应该在 iOS 更新中修复.. 稍后:) 为了加快速度,您可以复制此错误报告:rdar://49734534

附:这个问题没有很好的解决方法,但是有几个选项:

    使用 MPVolumeView 的路由按钮。它有效,看起来像这样 WhatsApp 如何处理这种情况。 禁用 AVAudioSession 的蓝牙选项。远非完美的解决方案,但可能适用于某些应用。

【讨论】:

以上是关于连接蓝牙耳机时无法切换到扬声器输出的主要内容,如果未能解决你的问题,请参考以下文章

Android蓝牙耳机/扬声器音频切换

Android蓝牙耳机/扬声器音频切换

无法使用 OpenTok 在耳机模式下切换音频

如何获取可用输出音频源列表(扬声器、耳机、蓝牙)

插入耳机时强制将声音输出到内置扬声器

同时向扬声器和耳机输出音频?