我正在开发一个使用Twilio进行电话的VoIP应用程序。我面临的问题是,如果AVAudioSession在呼叫正在进行时被中断,例如通过传入的FaceTime呼叫,那么在中断结束后我无法继续使用音频会话。通话不会断开,但听不到声音,麦克风也没有录音。
我已注册AVAudioSessionInterruptionNotification,在通知处理程序中,我执行以下操作:
// get the user info dictionary
NSDictionary *interuptionDict = notification.userInfo;
// get the AVAudioSessionInterruptionTypeKey enum from the dictionary
NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
// decide what to do based on interruption type here...
switch (interuptionType)
{
case AVAudioSessionInterruptionTypeBegan:
DLog(@"Audio Session Interruption case started.");
[self setAudioSessionActive:NO];
break;
case AVAudioSessionInterruptionTypeEnded:
{
DLog(@"Audio Session Interruption case ended.");
[self setAudioSessionActive:YES];
break;
}
default:
DLog(@"Audio Session Interruption Notification case default.");
break;
}
// Activate or deactivate the app's audio session
- (void)setAudioSessionActive:(BOOL)active
{
BOOL success = NO;
NSError *error = nil;
success = [[AVAudioSession sharedInstance] setActive:active error:&error];
if (error)
{
DLog(@"Error setting audio session : %@", [error description]);
}
else if (success)
{
DLog(@"Audio session state set successfully :")
}
}
我没有收到任何错误,但正在进行的通话不起作用。
我已阅读音频会话编程指南,音频和其他音频相关Apple文档的人机界面指南。我相信我正在遵循正确的步骤。 请提供任何建议,因为我可能会在这里缺少。
答案 0 :(得分:0)
我是Twilio开发者网络的一部分。从您的帖子中,无论何时发生中断事件,都不清楚是否正在调用通知。无论如何,您需要确保为2组通知注册音频会话单例。您目前只注册了一个通知。
首先改变这个
// get the user info dictionary
NSDictionary *interuptionDict = notification.userInfo;
// get the AVAudioSessionInterruptionTypeKey enum from the dictionary
NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
到这个
NSNumber *interruptionType = [notification.userInfo objectForKey:AVAudioSessionInterruptionTypeKey];
NSNumber *interruptionOption = [notification.userInfo objectForKey:AVAudioSessionInterruptionOptionKey];
接下来,您将要使用KVO API注册这两组通知。
通知1(你有这个):AVAudioSessionInterruptionNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:aSession];
通知2(添加此项):AVAudioSessionMediaServicesWereResetNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleMediaServicesReset)
name:AVAudioSessionMediaServicesWereResetNotification
object:aSession];
系统可以暂停活动的音频会话或取消分配,具体取决于您是应答还是拒绝来电。这两个通知会处理这两种情况。有关AVAudioSessionMediaServicesWereResetNotification的更多信息,请参阅this链接
如果发出通知,您也不需要将音频会话设置为非活动状态,系统会为您执行此操作。当有来电时,应用会移动到后台。返回时,应该在恢复audioSession之前允许1-2秒,以确保线程安全。所以你的switch语句看起来应该是这样的
switch (interruptionType.unsignedIntegerValue) {
case AVAudioSessionInterruptionTypeBegan:{
// • Your session is already inactive, you can update the UI if necessary
} break;
case AVAudioSessionInterruptionTypeEnded:{
if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1), dispatch_get_main_queue(), ^{
// • Update the session here
[self setAudioSessionActive:YES];
});
}
} break;
default:
break;
}
最后,在第二个通知调用的方法中,确保将音频会话重置为活动状态。
- (void)handleMediaServicesReset {
[self setAudioSessionActive:YES];
}
希望有所帮助!如果您有任何其他问题,请告诉我。