前一阵做音视频会议,底层用webRTC实现的,音频通话实现扬声器和听筒切换时遇到了不少问题,查了很多的资料的,但都不能很好的实现扬声器和听筒的切换,下面写一下我们最后的实现方案,供跟我一样正在研究听筒和扬声器切换的程序员参考指正,然而,虽然实现了基本功能,但还是存在一定的问题,希望大家能给出好的建议。下面直接上程序代码:
//监听声道的变化
- (void)observeHeadset {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(roteChange:) name:AVAudioSessionRouteChangeNotification object:nil];
}
- (void)roteChange:(NSNotification *)noti {
if (![self isHeadPhoneEnable]) {//没有耳机根据当前状态切换
if (self.isSpeaker) {
[self switchAudioCategaryWithSpeaker:YES];
} else {
[self switchAudioCategaryWithSpeaker:NO];
}
} else {//有耳机走听筒
[self switchAudioCategaryWithSpeaker:NO];
}
}
- (BOOL)isHeadPhoneEnable {//判断是否插入耳机
AVAudioSessionRouteDescription *route = [[AVAudioSession sharedInstance] currentRoute];
BOOL isHeadPhoneEnable = NO;
for (AVAudioSessionPortDescription *desc in [route outputs]) {
if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones]) {
isHeadPhoneEnable = YES;
}
}
return isHeadPhoneEnable;
}
//扬声器和听筒的切换
- (void)switchAudioCategaryWithSpeaker:(BOOL)isSpeaker {
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
if (isSpeaker) {
[[UIDevice currentDevice] setProximityMonitoringEnabled:NO];
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
} else {
[[UIDevice currentDevice] setProximityMonitoringEnabled:YES];
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:nil];
}
}
每次点击按钮切换扬声器和听筒时,调用- (void)switchAudioCategaryWithSpeaker:(BOOL)isSpeaker
方法对扬声器和听筒进行切换,但此时的切换好像并没有真正的生效,而是通过系统的通知,监听到roteChange:
然后进行扬声器和听筒的实现真正切换。猜测是因为webRTC的底层对音频做了操作,但没有仔细的去研究webRTC底层的代码,如果有什么问题欢迎大家批评指正,谢谢。