我是做基于SIP消息的webrtc语音通话功能,app需要兼容蓝牙耳机,中间出现过好多莫名其妙的问题,总的体验就是,代码很简单,但是一旦出现问题,基本束手无策!这是研究过程中踩过的坑,留念!
1、voip实时通话,需要设置Category为AVAudioSessionCategoryPlayAndRecord,这个不要改变,否则会出现各种没声音的问题。
2、适配蓝牙耳机的时候,不需要专门修改options为AVAudioSessionCategoryOptionAllowBluetooth
3、一个程序可以多次设置Category,但是最好不要这样做,否则出现各种声音问题,最好设置一次就OK
4、蓝牙状态下切换免提和听筒,直接上代码吧:
-(BOOL) setSpeakerEnabled:(BOOL)enabled{
#if TARGET_OS_IPHONE
UInt32 audioRouteOverride = enabled ? kAudioSessionOverrideAudioRoute_Speaker : kAudioSessionOverrideAudioRoute_None;
NSError *audioError = nil;
BOOL success = NO;
if (enabled) {
NSLog(@"******ws bluetooth setSpeakerEnabled 扬声器***");
success = [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&audioError];
} else {
NSLog(@"***ws bluetooth setSpeakerEnabled 听筒***");
// success = [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&audioError];
NSArray* builtinRoutes = @[AVAudioSessionPortBuiltInMic];
NSArray* routes = [[AVAudioSession sharedInstance] availableInputs];
AVAudioSessionPortDescription* builtinPort;
for (AVAudioSessionPortDescription* route in routes)
{
if ([builtinRoutes containsObject:route.portType])
{
builtinPort = route;
}
}
success = [[AVAudioSession sharedInstance] setPreferredInput:builtinPort
error:&audioError];
}
if (success) {
return YES;
}
return NO;
#else
return NO;
#endif
}
备注:特别是切换听筒的那部分代码,如果用上面备注的代码,会出现切换听筒之后,通话没声音的现象,但是用现有代码则一切正常!
5、AVAudioSessionRouteChangeNotification这个通知,当蓝牙耳机连接上的时候,可以通过AVAudioSessionRouteChangeReasonNewDeviceAvailable这个直接就捕获到,但是当蓝牙耳机断开的时候,通过AVAudioSessionRouteChangeReasonOldDeviceUnavailable这个未必能捕获到,所以当蓝牙耳机断开,需要通过两个手段去捕获,一种是AVAudioSessionRouteChangeReasonOldDeviceUnavailable,另外一种则是applicationWillEnterForeground(因为耳机断开一般都要切到设置里面点击断开去操作)