会议音频被第三方App中断
在会议中,可能会收到第三方App的来电通知,如:系统电话、闹钟、微信语音/视频等,某些应用会导致小鱼会议音频中断,此时需要做一些场景检测处理。
问题原因
iOS系统的AVAudioSession是全局共享单例,第三方支持录音/播放类的App在使用相关音频功能时会造成小鱼会议音频中断,常见的如系统电话、微信,造成小鱼会议中自己讲话远端听不到,远端讲话自己听不到的问题。
解决方法
场景一、先进入小鱼会议,再启动第三方App音视频
此场景会造成小鱼音频中断,触发回调“- (void)nemoSDKDidAudioInterrupt:(BOOL)began;”,中断开始时began=YES,中断结束后began=NO,您需要监听此回调停止和打开音频,此回调是小鱼SDK内部监听系统的“AVAudioSessionInterruptionNotification”通知上报的,您也可以在上层自行监听,需要注意的是:根据官方说明,AVAudioSessionInterruptionNotification通知只会在主线程回调,如果App在后台处于非活跃状态,系统会在App回到前台时上报此通知。
示例代码:
- (void)nemoSDKDidAudioInterrupt:(BOOL)began {
if (began) {
//音频被中断
[[NemoSDK sharedInstance] stopAudio];
} else {
//音频中断结束,重新开启音频
[[NemoSDK sharedInstance] startAudio];
}
}
特别注意:有时候收到了中断开始的回调,但是收不到中断结束的回调,这是属于正常现象,Apple官网已有相关说明:https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioInterruptions/HandlingAudioInterruptions.html#//apple_ref/doc/uid/TP40007875-CH4-SW5
建议在中断开始时记录相关状态,等App重新活跃时增加一些AVAudioSession状态校验逻辑,在适当的条件下调用[[NemoSDK sharedInstance] startAudio]重新开启音频。
判断当前是否有其他App占用音频:[AVAudioSession sharedInstance].isOtherAudioPlaying 或[AVAudioSession sharedInstance].secondaryAudioShouldBeSilencedHint
场景二、先启动第三方App音视频,在进入小鱼会议
此场景下,因为第三方App占用系统音频单元,小鱼会议音频模块初始化报错,导致入会后没有声音也听不远端声音。因为第三方App音频占用在前,小鱼入会在后,所以小鱼SDK无法监听到音频中断的状态回调,此场景主要出现在系统电话接通的情况下,进入小鱼会议,因为系统电话会强制中断小鱼音频,所以在系统电话未结束期间,小鱼音频都属于停用状态,您需要监听系统电话结束的通知,以便重启小鱼音频。
示例代码:
“CTCallStateDialing、CTCallStateIncoming、CTCallStateConnected”三种状态下,小鱼音频会被中断,调用[[NemoSDK sharedInstance] stopAudio]停止音频,“CTCallStateDisconnected”状态下,表示系统电话已经结束,调用[[NemoSDK sharedInstance] startAudio]重新启动音频
//监听系统电话
- (void)addTelephonyObserver {
self.observer = [CTCallCenter new];//self.observer不能销毁,否则收不到通知回调
[(CTCallCenter *)self.observer setCallEventHandler:^(CTCall * _Nonnull call) {
if ([call.callState isEqualToString:CTCallStateDialing]) {
NSLog(@"正在拨打电话");
} else if ([call.callState isEqualToString:CTCallStateIncoming]) {
NSLog(@"收到来电");
} else if ([call.callState isEqualToString:CTCallStateConnected]) {
NSLog(@"电话接通");
} else if ([call.callState isEqualToString:CTCallStateDisconnected]) {
NSLog(@"电话挂断");
}
}];
}