Closed benlinton closed 7 years ago
I'll take a look at this today.
I did some more testing. Here's what I found so far:
This works
[_recordSession setActive:NO error:nil];
found in AudioRecorderManager.m
resolves the error as well, but there must be a better way than to skip deactivating the _recordSession
AVAudioSession
after stopped recording.Howler.js
resolves the error. But I need Howler.js to remain in this project so I'll have to figure something else out. It makes no sense to me why Howler.js
is part of the problem since it's a javascript library being ran inside a UIWebView
. Howler.js is supposed to utilize either HTML5 audio or the Audio Web API depending on the browser/device it's running on. Does the UIWebview then use AVAudioSession
under the covers somehow? Or maybe Howler.js uses additional resources which exposes a race condition (my first guess).
This does not help
withOptions:AVAudioSessionCategoryOptionMixWithOthers
to [_recordSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
found in AudioRecorderManager.m
did not help. https://developer.apple.com/reference/avfoundation/avaudiosessioncategoryoptions/avaudiosessioncategoryoptionmixwithotherswithOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
to [_recordSession setActive:NO error:nil];
found in AudioRecorderManager.m
did not help. https://developer.apple.com/reference/avfoundation/avaudiosessionsetactiveoptions/avaudiosessionsetactiveoptionnotifyothersondeactivationHowler.js
and AudioRecorder
audio were never playing at the same time. It did not help.Howler.js
to autoSuspend
audio did not help. https://github.com/goldfire/howler.js/#global-optionsHowler.js
to play audio with the HTML5 player (instead of Audio Web API) did not help.Could part of the problem be that the AudioRecorderManager.m
doesn't set a sessionCategory
when it creates _audioPlayer
so the session defaults to AVAudioSessionCategorySoloAmbient
instead of using AVAudioSessionCategoryPlayAndRecord
or AVAudioSessionCategoryPlayback
?
AudioRecorderManager.m
_audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:_audioRecorder.url
error:&error];
Update: I set the audio player session to use an AVAudioSessionCategoryPlayback
session category. And created both sessions with options withOptions:AVAudioSessionCategoryOptionMixWithOthers
. It did not help.
I looked at this a bit, but I'm not really sure what's causing it. I'm not using this plugin now and don't have a lot of time to work on it. I'd like to focus on releasing android support, then come back around to this issue. Let me know meanwhile if you find a solution!
Success!
It's gross but adding a delay in between stopping and deactivating the session fixes the problem.
Original code, not working
RCT_EXPORT_METHOD(stopRecording)
{
[_audioRecorder stop];
[_recordSession setActive:NO error:nil];
_prevProgressUpdateTime = nil;
}
Newly delayed code, it works!
RCT_EXPORT_METHOD(stopRecording)
{
[_audioRecorder stop];
_prevProgressUpdateTime = nil;
[self performSelector:@selector(stopSession) withObject:nil afterDelay:1000];
}
-(void)stopSession
{
[_recordSession setActive:NO error:nil];
}
It seems that stop
happens asynchronously. And deactivating the audio session before stop
is finished can result in a race condition issue on slower devices.
I tried to deactivate the audio session after the audioRecorderDidFinishRecording
event so we don't have to use a gross delay. But recorder stop
seems to still be doing it's thing even after the audioRecorderDidFinishRecording
event has been triggered.
Possibly, it's is still closing/encoding the recorded audio file? Unfortunately, the developer docs aren't much help in this regard.
We may need to file a bug to Apple in order to eventually remove the delay.
Is this still happening?
I have the same problem too. After I stop the record, I can not play all the media file (video and audio)
@benlinton if you're still seeing this, can you submit a PR with this change? Ideally the delay could be configurable.
I imagine so, but I haven't been working with this library for the last few months so I can't say for sure.
Just encountered this problem when developing a chat app
I have the same problem too. I read library react-native-audio and react-native-sound native code. I find this:
AVAudioSession
to be inactive in file AudioRecorderManager.m
RCT_EXPORT_METHOD(stopRecording)
{
[_audioRecorder stop];
[_recordSession setActive:NO error:nil];
_prevProgressUpdateTime = nil;
}
AVAudioSession
isn't set to be active. So, After added this code in my javascript file. It worked :
if (Platform.OS == 'ios') {SoundPlayer.enable(true);} // <---- this line
this.soundPlayer = new Sound(filename, SoundPlayer.DOCUMENT, (error) => {
...
}
Hope to be helpful.
@HermitCarb it worked for me, thank u~
Looks like this is solved, so closing.
When I stop a recording on my iPad Air device, I get the error below:
ERROR: [0x16e247000] 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.
And after that all audio played is silent.
When I'm in the iOS simulator I have no problems, recordings stop as expected and everything seems to work perfectly.
I'm playing sound effects within an React Native iOS WebView (using Howler.js v2.0.0) immediately before and after recording, so maybe that's part of the problem?