Speaker automatically selected on callkit
If it is an audio call then it should use iPhone's built-in receiver (output).
How to make it possible?
https://stackoverflow.com/questions/50502518/issue-with-opentok-and-callkit
@mrazam110 thanks for this concise report. We'll work on that change.
Hi, any updates on this?
Hello, everyone :)
If you are using this example in your app and experiencing issue with speakerphone instead of headset, you need to do some changes in the custom audio driver - OTDefaultAudioDevice.
- Remove from audio session setup -
setupAudioSessionandsetupAudioSession:(AVAudioSession *)audioSessionsetting of default speaker option:
audioOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;
- In same session setup methods change audio session mode from
Video
[mySession setMode:AVAudioSessionModeVideoChat error:nil];
to Voice
[mySession setMode:AVAudioSessionModeVoiceChat error:nil];
- If you need to turn on headset by default (after previous steps it should be chosen by default, but if not...) you can force set it manually by calling
[self configureAudioSessionWithDesiredAudioRoute:AUDIO_DEVICE_HEADSET];
You can do this also in the setupAudioSession or before creation and connection to the OpenTok session.
Here is how setupAudioSession looks like after changes:
- (void) setupAudioSession
{
AVAudioSession *mySession = [AVAudioSession sharedInstance];
_previousAVAudioSessionCategory = mySession.category;
avAudioSessionMode = mySession.mode;
avAudioSessionPreffSampleRate = mySession.preferredSampleRate;
avAudioSessionChannels = mySession.inputNumberOfChannels;
[mySession setPreferredSampleRate: kSampleRate error: nil];
[mySession setPreferredInputNumberOfChannels:1 error:nil];
[mySession setPreferredIOBufferDuration:kPreferredIOBufferDuration
error:nil];
NSError *error = nil;
NSUInteger audioOptions = 0;
#if !(TARGET_OS_TV)
audioOptions |= AVAudioSessionCategoryOptionAllowBluetooth ;
[mySession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:audioOptions
error:&error];
#else
[mySession setCategory:AVAudioSessionCategoryPlayback
withOptions:audioOptions
error:&error];
#endif
[mySession setMode:AVAudioSessionModeVoiceChat error:nil];
if (error)
OT_AUDIO_DEBUG(@"Audiosession setCategory %@",error);
error = nil;
[self setupListenerBlocks];
[self configureAudioSessionWithDesiredAudioRoute:AUDIO_DEVICE_HEADSET];
[mySession setActive:YES error:&error];
if (error)
OT_AUDIO_DEBUG(@"Audiosession setActive %@",error);
}
- Don't forget to pre-heat audio session before starting CallKit's AudioSession as TokBox provided in example - in
CXStartCallActionandCXAnswerCallAction
Minor explanation why it's all happening with us :)
- When Audio Session configured with
AVAudioSessionCategoryOptionDefaultToSpeakerit's obviously uses speaker by default :) - When you choose
AVAudioSessionModeVideoChatmode, session obviously (for Apple :D) uses speaker by default and you can't switch because... it's Apple's logic, I suppose. - And if session is configured with
AVAudioSessionModeVoiceChatmode, iOS and CallKit behaves as voice call with ability yo switch between speakers (and also turning screen off when user brings phone to ear).
BTW, from Apples documentation:
/* Only valid with kAudioSessionCategory_PlayAndRecord. Reduces the number of allowable audio
routes to be only those that are appropriate for video chat applications. May engage appropriate
system-supplied signal processing. **Has the side effect of setting
AVAudioSessionCategoryOptionAllowBluetooth and AVAudioSessionCategoryOptionDefaultToSpeaker.** */
AVF_EXPORT AVAudioSessionMode const AVAudioSessionModeVideoChat API_AVAILABLE(ios(7.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);
And also, from documentation, Apple suggests to use AVAudioSessionModeVoiceChat for both audio and video calls.