Возобновление вызова twilio после прерывания аудиосессии

Я разрабатываю приложение VoIP, которое использует Twilio для телефонии. Проблема, с которой я столкнулся, заключается в том, что если 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, связанную со звуком. Я считаю, что делаю правильные шаги. Пожалуйста, дайте любые предложения, как то, что я мог бы пропустить здесь.


person humblePilgrim    schedule 15.09.2015    source источник
comment
Когда вы отлаживаете эту проблему, какой оператор DLog вы получаете?   -  person TommyBs    schedule 15.09.2015
comment
Он регистрирует состояние аудиосессии, установленное успешно: каждый раз   -  person humblePilgrim    schedule 15.09.2015


Ответы (1)


Я состою в сети разработчиков 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];

Затем вы захотите использовать API KVO для регистрации обоих наборов уведомлений.

Уведомление 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];

Система может либо приостановить активный аудиосеанс, либо освободить его в зависимости от того, отвечаете ли вы или отклоняете входящий вызов. Эти 2 уведомления позаботятся об обоих сценариях. См. эту ссылку для получения дополнительной информации об AVAudioSessionMediaServicesWereResetNotification.

Вам также не нужно отключать аудиосеанс, если происходит уведомление, система сделает это за вас. При поступлении вызова приложение переходит в фоновый режим. Когда он вернется, вы должны подождать 1-2 секунды, прежде чем возобновить audioSession для обеспечения безопасности потоков. Итак, ваш оператор 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];
}

Надеюсь, это поможет! Дайте мне знать, если у вас есть еще вопросы.

person sraval    schedule 28.10.2015
comment
Привет, sraval, я попробовал сценарий после внесения изменений в код в соответствии с вашим предложением. Но та же проблема сохраняется. - person humblePilgrim; 28.10.2015
comment
Митхун, у тебя уведомления выводятся при поступлении звонка? Другими словами, вы видите, что дело о прерывании аудиосессии запущено. в вашей консоли всякий раз, когда поступает вызов? - person sraval; 28.10.2015
comment
Привет, sraval, да, всякий раз, когда поступает вызов FaceTime и приложение переходит в фоновый режим, поступает уведомление о прерывании аудиосеанса. Аналогичным образом, когда прерывание заканчивается, приходит уведомление. Следовательно, я пытаюсь активировать аудиосеанс, и это также возвращает успех. Но звука нет ни на входе, ни на выходе - person humblePilgrim; 30.10.2015
comment
Понятно. В этом случае см. этот stackoverflow.com/questions/27200453/, который у него был аналогичная проблема и перемещение метода к делегату устранили проблему. - person sraval; 30.10.2015
comment
Привет, сравал.. Извини за поздний ответ. Надеюсь, вы все еще следите за этим. Я просмотрел сообщение выше и попробовал решение, но проблема все еще сохраняется. Кроме того, не могли бы вы попробовать описанный выше сценарий в приложении Basic Phone, которое поставляется с Twilio SDK? Потому что я думаю, что это базовый вариант использования, и он должен обрабатываться в самом SDK или, по крайней мере, должна быть предоставлена ​​четкая информация как часть материалов для разработчиков Twilio. - person humblePilgrim; 09.12.2015