扬声器的 CallKit 问题,接听电话后自动打开
CallKit issue with Speaker, Automatically turned On after receiving the call
我正在使用 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];
}
}
有没有人有任何建议,或者这里有没有人已经纠正了这个状态?
我也相信很多像我一样的人正在经历这个问题。
任何帮助都将不胜感激。
谢谢
我已经通过 opentok 支持,他们认真对待这个问题,并且由于该服务仅用于视频聊天,因此他们在 CallKit UI 中启用了该扬声器。要通过使用他们的 Objective C class 即 OTDefaultAudioDevice.h
和 OTDefaultAudioDevice.m
使其禁用或仅用于音频通话,那么我们必须在 [=12] 中注释以下行=] 文件.
audioOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;
希望它能拯救很多人。
谢谢。
终于解决了这个问题。解决方案是@AbhishekMitra 和我自己发现的东西的混合体
首先,我已将 Objective C class OTDefaultAudioDevice 替换为 DefaultAudioDevice.swift,此处找到:
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];
我正在使用 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];
}
}
有没有人有任何建议,或者这里有没有人已经纠正了这个状态?
我也相信很多像我一样的人正在经历这个问题。
任何帮助都将不胜感激。
谢谢
我已经通过 opentok 支持,他们认真对待这个问题,并且由于该服务仅用于视频聊天,因此他们在 CallKit UI 中启用了该扬声器。要通过使用他们的 Objective C class 即 OTDefaultAudioDevice.h
和 OTDefaultAudioDevice.m
使其禁用或仅用于音频通话,那么我们必须在 [=12] 中注释以下行=] 文件.
audioOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;
希望它能拯救很多人。
谢谢。
终于解决了这个问题。解决方案是@AbhishekMitra 和我自己发现的东西的混合体
首先,我已将 Objective C class OTDefaultAudioDevice 替换为 DefaultAudioDevice.swift,此处找到: 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];