Я реализовал OpenTok с CallKit. Всякий раз, когда я начинаю исходящий звонок, мой поток никогда не публикуется. На панели инструментов инспектора написано:
Попытка публикации sh с потоком 54B02465-0E26-4AF0-8715-9D333BF6E9F C (публикация в сеанс еще не началась)
никогда не удается опубликовать.
Более того, я получаю сообщение об ошибке в журнале:
ОШИБКА [OpenTok]: ошибка аудиоустройства: startCapture.AudioOutputUnitStart вернула ошибку: -66637
Является ли ошибка публикации из-за этой ошибки?
Я добавил файл OTDefaultAudioDevice из демонстрационной версии, предоставленной на GitHub.
Ниже приведен мой код:
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
// Create & configure an instance of SpeakerboxCall, the app's model class representing the new outgoing call.
let call = SpeakerboxCall(uuid: action.callUUID, isOutgoing: true)
call.handle = action.handle.value
/*
Configure the audio session, but do not start call audio here, since it must be done once
the audio session has been activated by the system after having its priority elevated.
*/
// https://forums.developer.apple.com/thread/64544
// we can't configure the audio session here for the case of launching it from locked screen
// instead, we have to pre-heat the AVAudioSession by configuring as early as possible, didActivate do not get called otherwise
// please look for * pre-heat the AVAudioSession *
configureAudioSession()
/*
Set callback blocks for significant events in the call's lifecycle, so that the CXProvider may be updated
to reflect the updated state.
*/
call.hasStartedConnectingDidChange = {
provider.reportOutgoingCall(with: call.uuid, startedConnectingAt: call.connectingDate)
}
call.hasConnectedDidChange = {
provider.reportOutgoingCall(with: call.uuid, connectedAt: call.connectDate)
}
self.outgoingCall = call
// Signal to the system that the action has been successfully performed.
action.fulfill()
}
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
print("Received (#function)")
// If we are returning from a hold state
if answerCall?.hasConnected ?? false {
//configureAudioSession()
// See more details on how this works in the OTDefaultAudioDevice.m method handleInterruptionEvent
sendFakeAudioInterruptionNotificationToStartAudioResources();
return
}
if outgoingCall?.hasConnected ?? false {
//configureAudioSession()
// See more details on how this works in the OTDefaultAudioDevice.m method handleInterruptionEvent
sendFakeAudioInterruptionNotificationToStartAudioResources()
return
}
if outgoingCall != nil{
startCall(withAudioSession: audioSession) { success in
if success {
self.outgoingCall?.hasConnected = true
self.addCall(self.outgoingCall!)
self.startAudio()
}
}
}
if answerCall != nil{
answerCall(withAudioSession: audioSession) { success in
if success {
self.answerCall?.hasConnected = true
self.startAudio()
}
}
}
}
func sendFakeAudioInterruptionNotificationToStartAudioResources() {
var userInfo = Dictionary<AnyHashable, Any>()
let interrupttioEndedRaw = AVAudioSession.InterruptionType.ended.rawValue
userInfo[AVAudioSessionInterruptionTypeKey] = interrupttioEndedRaw
NotificationCenter.default.post(name: AVAudioSession.interruptionNotification, object: self, userInfo: userInfo)
}
func configureAudioSession() {
// See https://forums.developer.apple.com/thread/64544
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(AVAudioSession.Category.playAndRecord, mode: .default)
try session.setActive(true)
try session.setMode(AVAudioSession.Mode.voiceChat)
try session.setPreferredSampleRate(44100.0)
try session.setPreferredIOBufferDuration(0.005)
} catch {
print(#file)
print(#function)
print(error)
}
}
Когда я удаляю зависимость от OTDefaultAudioDevice, все падает правильно, но без звука.
Я упомянул следующее: