Stop audio recording and continue audio playback - ios

My application plays music and records from mic at the same time. Recording can be started after playback is started or before playback is started
And now I want to stop recording but keep playback running at the same time.
How can I do this?
I can stop recording and playback by using
[[AVAudioSession sharedInstance] setActive:NO error:nil];
But the issue is: I want to stop recording only.
I tried to change category to AVAudioSessionCategoryPlayback using the following code
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error]
but that doesn't stop recording.

I solved the issue by explicitly stopping all recording activity without touching AVAudioSession at all.
The following warning
AVAudioSession.mm:623: -[AVAudioSession setActive:withOptions:error:]:
Deactivating an audio session that has running I/O. All I/O should be
stopped or paused prior to deactivating the audio session.
helped me to identify the issue.
Initially I forgot to call the AudioOutputUnitStop method of AudioUnit framework. Because of this recording process was still running and audio session were indicating that.

Related

AVAudioSession mix with WKWebview

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

AVAudioSession deactivate while another session is running

I have one audio session running in playAndRecord category and mixWithOthers option for a audio recorder. Let's call it recordAudioSession.
let recordAudioSession = AudioSession()
recordAudioSession.setCategory(.playAndRecord, options: [.mixWithOthers])
Also I have another audio session running in playback category and mixWithOthers option for playing audio stream. Let's call it playAudioSession.
let playAudioSession= AudioSession()
playAudioSession.setCategory(.playback, options: [.mixWithOthers])
I have one audio is playing through my playAudioSession using an AVAudioPlayer, at the same time there is a recorder is running through my recordAudioSession trying to record the audio.
Now, once audio finishes playing, I try to deactivate playAudioSession, but leave recordAudioSession alive:
audioPlayer.stop()
playAudioSession.setActive(false, options: .notifyOthersOnDeactivation)
So basically, One session finishes its task and I want to deactivate, the other one is still in use, so I want to keep it working.
But I'm getting an error log, and my recorder getting closed by system:
AVAudioSession.mm:692: -[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running i/o. all i/o should be stopped or paused prior to deactivating the audio session.
Is this error means any audio session cannot be running I/O while deactivating an audio session, or I'm doing it in an incorrect way?
Is there any way that I can keep that recorder reading and deactivate the playAudioSession?

AVAudioSession error: Deactivating an audio session that has running I/O

2017-02-24 14:56:44.280 PropertyManager[10172:5336578] 14:56:44.280 ERROR: [0x1a0a24000] AVAudioSession.mm:692: -[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
2017-02-24 14:56:44.281 PropertyManager[10172:5336578] error === Error Domain=NSOSStatusErrorDomain Code=560030580 "(null)"
PropertyManager was compiled with optimization - stepping may behave oddly; variables may not be available.
Your error log is very succinctly self-expressive:
Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session
It tells you the problem and also the solution.
Right now you're doing something like this:
[[AVAudioSession sharedInstance] setActive:NO
withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
error:nil];
You should however, first stop the audio player instance and then set the activation status to Yes or No.
[yourAudioPlayer stop];
[[AVAudioSession sharedInstance] setActive:NO
withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
error:nil];
Refer to Apple Documentation to see values of enum AudioSessionSetActiveOption.
Also see: Apple Documentation on setActive:withOptions method
As for your second error
PropertyManager was compiled with optimization - stepping may behave oddly; variables may not be available.
see this excellent answer.
#NSNoob is 100% correct. The player (or something else) is still active.
More from dani-mp. He said:
I'd say that pausing the player is not a synchronous operation, so we
shouldn't be deactivating the session before knowing that the player
has been paused (see the response in this thread).
A solution for this problem could be that we listen to changes to
timeControlStatus and deactivate the audio session once the player has
really been paused.
The answer in the thread says
This error indicates that something in your app is still using audio
I/O at the time when the AVAudioSession setActive:NO is being called.
It’s impossible to say which object without more information, but
sometimes it’s the result of calling an asynchronous stop method on a
player of some sort and not waiting for the notification that the
player has stopped before deactivating the audio session.
Make audio player to stop before making recording session false.. if u suppose to make audio player to be nil.. remove that line.. it works for me..

Error: Deactivating an audio session that has running I/O

My app uses device's microphone and manages AVAudioSession.
I want to check if there is other app playing audio, if so, I want my app to stop using microphone & stop my audio session, this is what I tried (the following code is periodically triggered to check is there other app playing audio):
BOOL isPlayingWithOthers = [[AVAudioSession sharedInstance] isOtherAudioPlaying];
if (isPlayingWithOthers) {
[[AVAudioSession sharedInstance] setActive:NO error:error];
}
I run my app, then, I open "My music" app, and playing a music, the above code is executed but I get the following error:
Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
Why I get this error? How to solve it in my case? (My app is running on iOS7 and above)

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