我正在使用CallKit
和TokBox
以及它如何处理一个错误,即在收到呼叫后,扬声器变为活动状态,无法通过点击它来禁用。电话是从主动扬声器开始的,我认为这是一个错误,但WhatsApp和FBMassenger使用了相同的自定义呼叫屏幕视图,但是他们的扬声器在接到电话后变为非活动状态,我搜索过,没有相关的答案我被发现所以远。
在TokBox
中,他们提供了OTDefaultAudioDevice.h
和OTDefaultAudioDevice.m
文件,他们用CallKitSpeakerBox
配置了所有关于音频的文件。我在哪里找到了以下配置:
#define AUDIO_DEVICE_HEADSET @"AudioSessionManagerDevice_Headset"
#define AUDIO_DEVICE_BLUETOOTH @"AudioSessionManagerDevice_Bluetooth"
#define AUDIO_DEVICE_SPEAKER @"AudioSessionManagerDevice_Speaker"
已按以下方式使用:
- (BOOL)configureAudioSessionWithDesiredAudioRoute:(NSString*)desiredAudioRoute
{
OT_AUDIO_DEBUG(@"configureAudioSessionWithDesiredAudioRoute %@",desiredAudioRoute);
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err;
//ios 8.0 complains about Deactivating an audio session that has running
// I/O. All I/O should be stopped or paused prior to deactivating the audio
// session. Looks like we can get away by not using the setActive call
if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"7.0")) {
// close down our current session...
[audioSession setActive:NO error:nil];
}
if ([AUDIO_DEVICE_BLUETOOTH isEqualToString:desiredAudioRoute]) {
[self setBluetoothAsPrefferedInputDevice];
}
if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"7.0")) {
// Set our session to active...
if (![audioSession setActive:YES error:&err]) {
NSLog(@"unable to set audio session active: %@", err);
return NO;
}
}
if ([AUDIO_DEVICE_SPEAKER isEqualToString:desiredAudioRoute]) {
// replace AudiosessionSetProperty (deprecated from iOS7) with
// AVAudioSession overrideOutputAudioPort
#if !(TARGET_OS_TV)
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
error:&err];
#endif
} else
{
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone
error:&err];
}
return YES;
}
AVAudioSessionPortOverrideSpeaker
用于所有设备,我认为这是启用扬声器的主要原因,但我不确切知道。即
if ([AUDIO_DEVICE_SPEAKER isEqualToString:desiredAudioRoute]) {
// replace AudiosessionSetProperty (deprecated from iOS7) with
// AVAudioSession overrideOutputAudioPort
#if !(TARGET_OS_TV)
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
error:&err];
#endif
} else
{
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone
error:&err];
}
}
到目前为止,是否有人有任何建议或在此纠正过该州的任何人?
我也相信像我这样的很多人都会遇到这个问题。
任何帮助都会很明显。
由于
答案 0 :(得分:1)
我已经完成了opentok支持,他们认真对待这个问题,并且由于服务仅用于视频聊天,因此他们在CallKit UI中启用了扬声器启用。要通过使用他们的Objective C类(OTDefaultAudioDevice.h
和OTDefaultAudioDevice.m
来禁用或仅用于音频调用,那么我们必须在.m
文件中注释以下行。
audioOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;
希望它能挽救很多日子。
感谢。
答案 1 :(得分:1)
最后,我设法解决了这个问题。解决方案是@AbhishekMitra和我发现自己的混合物
首先,我使用DefaultAudioDevice.swift替换Objective C类OTDefaultAudioDevice: https://github.com/opentok/opentok-ios-sdk-samples-swift/blob/master/Custom-Audio-Driver/Custom-Audio-Driver/DefaultAudioDevice.swift
相当于objc,注释出Abhishek建议的行,并在同一函数中添加了另一行,即:
configureAudioSessionWithDesiredAudioRoute(desiredAudioRoute: DefaultAudioDevice.kAudioDeviceHeadset)
这是整个功能
fileprivate func setupAudioSession() {
let session = AVAudioSession.sharedInstance()
previousAVAudioSessionCategory = session.category
avAudioSessionMode = session.mode
avAudioSessionPreffSampleRate = session.preferredSampleRate
avAudioSessionChannels = session.inputNumberOfChannels
do {
try session.setPreferredSampleRate(Double(DefaultAudioDevice.kSampleRate))
try session.setPreferredIOBufferDuration(0.01)
let audioOptions = AVAudioSessionCategoryOptions.mixWithOthers.rawValue |
AVAudioSessionCategoryOptions.allowBluetooth.rawValue
//|
//AVAudioSessionCategoryOptions.defaultToSpeaker.rawValue
try session.setCategory(AVAudioSessionCategoryPlayAndRecord, mode: AVAudioSessionModeVideoChat, options: AVAudioSessionCategoryOptions(rawValue: audioOptions))
setupListenerBlocks()
//set the audio to headset
configureAudioSessionWithDesiredAudioRoute(desiredAudioRoute: DefaultAudioDevice.kAudioDeviceHeadset)
try session.setActive(true)
} catch let err as NSError {
print("Error setting up audio session \(err)")
} catch {
print("Error setting up audio session")
}
}
这最终解决了我的问题,当通话激活时,设备不在扬声器上。如果您有任何问题,请告诉我。
这一行的objc版本是:
[self configureAudioSessionWithDesiredAudioRoute:
AUDIO_DEVICE_HEADSET];