CallKit может повторно активировать звук после переключения вызова

Я разрабатываю приложение CallKit, у меня проблема. При удержании вызова не удается перезапустить звук при «замене» вызовов на экране CallKit до тех пор, пока пользователь не вернется на экран вызова в приложении. Я могу обойти это, обновив:

supportsHolding = false

но я могу решить эту проблему, например WhatsApp может сделать это правильно!

p.s. Я звоню по webrtc!

Благодарность!

РЕДАКТИРОВАТЬ:

Это код провайдера:

public func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {

    guard let call = conductor!.callWithUUID(uuid: action.callUUID) else {
        WebRtcConductor.debug("\(self.TAG) ???? failed to perform HeldAction: uuid: \(action.uuid), calluiid: \(action.callUUID)")
        action.fail()
        return
    }

    setIsHeld(call: call, isHeld: action.isOnHold)
    action.fulfill()
}

функция setIsHeld просто выполняет:

audioTrack.isEnabled = enabled

Если я использую кнопку отключения звука на экране callkit, все работает нормально, но если у меня есть 2 активных вызова, когда я перехожу от вызова webrtc к обычному вызову, вызывается CXSetHeldCallAction и звуковая дорожка отключена. Если я снова проведу пальцем до вызова webrtc, звуковая дорожка включена, но я ничего не слышу, если я вернусь на главный экран приложения, звук снова будет работать нормально!


person Luca Becchetti    schedule 21.11.2017    source источник
comment
Пожалуйста, покажите соответствующий код, который вы написали, но также четко объясните, что происходит и чего вы ожидаете.   -  person jbehrens94    schedule 21.11.2017
comment
Я добавил еще код! Благодарность!   -  person Luca Becchetti    schedule 21.11.2017
comment
Привет, @LucaBecchetti, тебе удалось исправить эту проблему?   -  person Elene Akhvlediani    schedule 20.08.2018


Ответы (2)


На самом деле в библиотеке Google WebRTC есть ограничение, которое приводит к описанной проблеме при реализации интеграции CallKit, которая поддерживает обмен вызовами.

WebRTC Issue 8126 известна уже больше года, но еще не интегрирован в главную ветку WebRTC. Однако вы можете найти необходимые изменения кода для решения этой проблемы в исходной заявке.

Однако в качестве временного решения вы можете активировать системное уведомление, которое подписывается внутри WebRTC.

Опубликуйте AVAudioSessionInterruptionType.ended Уведомление в методе «didActivate audioSession» поставщика CallKit:

var userInfo = Dictionary<AnyHashable, Any>()
let interrupttioEndedRaw = AVAudioSessionInterruptionType.ended.rawValue
userInfo[AVAudioSessionInterruptionTypeKey] = interrupttioEndedRaw
NotificationCenter.default.post(name: NSNotification.Name.AVAudioSessionInterruption, object: self, userInfo: userInfo)

PS: Посмотрите на билет, чтобы повысить шансы на слияние ;-)

person seb    schedule 25.09.2018
comment
Для Swift 4: NotificationCenter.default.post(name: AVAudioSession.interruptionNotification, object: self, userInfo: userInfo) - person nathanwhy; 06.12.2018
comment
Где мне его использовать? После заполнения? - person WorieN; 19.07.2019
comment
@WorieN в 'didActivate audioSession' - person seb; 20.07.2019
comment
Спасибо, что поработали для меня. func provider (_ provider: CXProvider, didActivate audioSession: AVAudioSession) {print (Provider - Activate Audio Session: (audioSession.category)) var userInfo = Dictionary ‹AnyHashable, Any› () let interrupttioEndedRaw = AVAudioSession.InterruptionType.endedInfoValue user [AVAudioSessionInterruptionTypeKey] = interrupttioEndedRaw NotificationCenter.default.post (имя: AVAudioSession.interruptionNotification, object: self, userInfo: userInfo)} - person YSR fan; 12.05.2020
comment
Круто для моего случая. Я использую Tokbox вместо Google WebRTC, пробовал все, но не смог заставить его работать, но запуск системного уведомления заставил его работать и для Tokbox! Спасибо! - person Bruce; 16.10.2020

Была такая же проблема. Если у меня 1 активный вызов, значит, поступают новые вызовы, я нажимаю «Удержать и принять». Новый вызов работает, но после использования Swap в CallKit звук перестает работать.

Выяснилось, что provider:performSetHeldCallAction: метод из CXProviderDelegate протокола - это то место, где вы можете фактически деактивировать / активировать звук для Swap вызовов через CallKit собственный интерфейс.

В моем случае я использовал метод audioController.deactivateAudioSession() для вызова OnHold. Но обнаружено, что тот же метод provider:performSetHeldCallAction: был запущен для другого вызова, который ставится активным (из состояния OnHold) при нажатии кнопки Swap через CallKit.

Таким образом, вам просто нужно деактивировать / активировать звук соответственно состоянию вызова (удерживать или нет).

Обычно это должно выглядеть так:

func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {
    // Retrieve the Call instance corresponding to the action's call UUID
    guard let call = callManager.callWithUUID(uuid: action.callUUID) else {
        action.fail()
        return
    }

    // Update the Call's underlying hold state.
    call.isOnHold = action.isOnHold

    // Stop or start audio in response to holding or unholding the call.
    if call.isOnHold {
        stopAudio()
    } else {
        startAudio()
    }

    // Signal to the system that the action has been successfully performed.
    action.fulfill()
}

P.S. Похоже, у вас должен быть какой-то класс, который отвечает за аудиосеанс. Он должен реализовывать вид activate audio session / deactivate audio session.

person Bogdan Laukhin    schedule 07.12.2017
comment
В моем случае это не сработало. Я также использую WebRTC и устанавливаю audioTrack.isEnabled на false (как для локального, так и для удаленного трека). Это может иметь какое-то отношение к внутренней обработке звука WebRTC. Однако при принудительном переводе приложения на передний план после переключения вызовов (путем нажатия кнопки «Мое приложение» в пользовательском интерфейсе CallKit) звук снова работает (как входящий, так и исходящий - это волшебство). - person seb; 25.09.2018
comment
Ох, я столкнулся с той же проблемой. Вам удалось это решить? - person Elsammak; 15.05.2019
comment
@ Богдан, вы нашли решение этой проблемы? - person Ahad Khan; 31.12.2019
comment
@AhadKhan К сожалению, этот проект был 2 года назад, с тех пор я не работал над ним. С тех пор изменилась и версия Swift. Так что вы можете использовать эту идею как подход или образец. Для меня это сработало и действительно решило проблему со звуком при обмене вызовами через собственный интерфейс iOS. - person Bogdan Laukhin; 02.01.2020
comment
@AhadKhan Насколько я понимаю, вы используете WebRTC. Это может быть проблемой. Вам необходимо проверить тип методов отключения / включения звука или проверить поток, если они приостановлены или возобновлены. - person Bogdan Laukhin; 02.01.2020
comment
@AhadKhan Методы startAudio () / stopAudio (), которые я использовал, были из библиотеки pjsip. Возможно, вы найдете что-то похожее в методах, связанных с WebRTC. См. Мой комментарий выше - person Bogdan Laukhin; 02.01.2020
comment
@BogdanLaukhin, Спасибо за ваше время, на самом деле проблема заключалась в получении и освобождении аудиосессии согласно обратным вызовам callKit. - person Ahad Khan; 05.01.2020
comment
привет, приятель, можешь предоставить коды? Спасибо - person famfamfam; 17.02.2021