AVAudioSession mix with WKWebview - ios

I am working on a VoIP app. For that I had set the category of AVAudioSession to AVAudioSessionCategoryPlayAndRecord.
All the app functionality was working fine till now.
Then we had a new requirement where within app when the voice call is going on, user can play one video embedded in WKWebView.
Now when user plays video from WKWebView, video plays successfully and the volume of video is also as expected. But when user stops/pauses the video then voice call gets disconnected.
So I came to know that WKWebView runs in different process than the app, so in order to make my app's audio mixable with WKWebview I have to set the AVAudioSession as mixwithOthers.
I have done that with the following code...
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *errorInSettingCategory;
BOOL success = [session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions: AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionAllowBluetooth error:&errorInSettingCategory];
Now after playing video form WKWebView I am able continue with my voice call.
But this approach introduced the new bug.
As now the AVAudioSession is mixable, volume of the video from WKWebView is quite low and app's audio (voice call audio) is quite dominant.
I have tried different setcategory options but with no luck.
I want to have volume of app's audio and volume of WKWebView's video at same level.
Thank you for any help.

Try setting the duckOthers property of your AVAudioSession to false:
https://developer.apple.com/documentation/avfoundation/avaudiosession/categoryoptions/1616618-duckothers

Related

YouTube volume is very low when played during a WebRTC session

I am working on an iOS app with WebRTC. During the chat, volume is fine. But if I play an embedded youtube video through WKYTPlayerView, volume of the video is very low. If I disconnect the chat, video volume becomes normal again.
I have tried several things and I have been looking at this issue for few days. Here is how I am setting the category for audio session;
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions: AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker
error: &error];
if (error != nil) {
NSLog(#"Problem setting AVAudioSession to mix with others");
}
Any help is very much appreciated.
AFAIK, there are raised WebRTC issues. Here's 2 of them:
Low sound volume during calls
AGC sets volume to zero
You may want to check the given fix which is putting up a CL to fix the problem in all platforms. See if it also works for you.
Otherwise, you can try using mediastream-gain which is useful for controlling rhe volume of your microphone input before it's sent accross a peer connection in a WebRTC call.
Lastly, you may want to also check this thread for additional insights on application sharing to play YouTube videos.

Do not allow other apps play music

We are developing a VOIP application and while there is an active call, we want not to allow other apps play music or something (like Whatsapp does). Is there any way of doing it in a normal way, can you help please?
Edit 1: I think we need to start with listening the observer AVAudioSessionInterruptionNotification.
Accepted Answer Edit 2:
When sound interruption begins, try to only active the AudioSession again. This works. Thank you KudoCC.
Here is a link talks about audio category, there is a table in it:
As your app supports VoIP, so it need to play and record audio, and you need interrupt non-mixable apps audio, so AVAudioSessionCategoryPlayAndRecord is the right category. Also you should re-active your audio session when you're playing/recording audio so that the category takes effect.
Try this code in your app to pause the background audio when calls,
[[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
It is helpful when other apps uses AVAudioPlayer.
For more detail refer this Link

Unity sound not working after AVAudioSession is disabled

I'm currently working on a Unity3D iOS plugin. I'm trying to change the category of the app's AVAudioSession in order to implement audio ducking (i.e. Music app volume goes down while my sound effects are playing), which requires the AVAudioSession to be set as inactive and then as active again.
Well, after I set the session as inactive by using [[AVAudioSession sharedInstance] setActive:NO error:nil], Unity sounds simply won't work anymore, even after the session is set as active again. Native sounds still work, as I tested an AVAudioPlayer and it works perfectly.
Any idea on what's wrong?
User daniel_liu from Unity Answers helped me with this: Instead of setting the AVAudioSession as active/inactive by using the code I posted in the question, one should use UnitySetAudioSessionActive(true) and UnitySetAudioSessionActive(false).

Setting AVAudioSession Category has no effect on sound from WKWebView

I can not seem to override the AVAudioSession category or port when audio is being played from a WKWebView. The same code works perfectly when using a normal UIWebView.
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];
I've also tried activating the sharedInstance like this, but it did not help:
[session setActive: YES error: nil];
The above code has no effect on audio coming from a WKWebView. I did find some reports on Twitter that iOS 8.1 is mixing WKWebView audio with background app audio, but I couldn't find the source for that. See this twitter thread for reference: https://twitter.com/marcoarment/status/530881842900373504
So apparently WKWebView runs in a separate process from your app. Which probably means, it has its own AudioSession separate from your app's AudioSession as well. That's why changes to your app's AudioSession won't affect the webView. And also why it works with UIWebView (no separate process). At least that's what I gathered so far...
The solution for me was to allow my app's AudioSession to mix with others:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:&error];
Of course this has other implications as well. Your app's audio will be mixed with all other apps' audio, not just your webview's.

How to force play audio on iPhone speaker?

I'm developing a mobile application to record audio. Functionality as follows. There is one static audio file on my application (which plays drum sound). When user start recording he can play this drum sound and start speaking/singing. Here I'm facing a problem with the static sound, when the recording is done and the user play back the same recorded audio file the static audio file sound (Drum sound in my case) is not audible properly like the way how user voice audible. If I can route the static audio file sound to the iPhone speaker even ear phone plugged in that will solve the problem. Can any one please help me how can I force play audio through speaker even though ear phone plugged in ? Thank you so much,
You can try this, it solves my problem.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
Try this,
do {
try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.Speaker)
} catch _ {
}

Resources