iOS音频Error
最近在cocos应用上发现一个比较奇怪的bug,当应用正在调用录音的时候,按下home键回到后台,然后打开一个音乐播放器播放一个音乐,再回到游戏中游戏就会卡死。
之前录音和播放设置是下方:
播放:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
录音:
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
恢复正常
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
个人思路:
音频输出作为硬件资源,对于iOS系统来说是唯一的。
音乐播放器在播放器占用了游戏的硬件资源。导致游戏卡死。
cocos爆出的errorLog也印证了这一点
Log:
D/AudioEngine-inl.mm (198): Audio session is still interrupted, pause director!
经过查询,特别感谢https://www.jianshu.com/p/3e0a399380df
是否引起不支持混音的APP中断。
后面把设置修改为
播放:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:nil];
录音:
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers|AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
恢复正常:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:nil];
问题解决。
AVAudioSessionCategoryOptionDefaultToSpeaker 是为了设置扬声器播放,原因:切换成录音状态时会改为听筒播放
!!!
emmm,上面方法虽然可以解决问题,但是会出现一点:每次录音都要切换状态会重新走一遍准备录音环境的流程,在应用中就是会卡顿一丢丢。如果对程序有较高的要求,出现这个问题明显是不行的。
最后解决方案:
在每次调用录音单例类的时候调用一下状态切换
+ (void)initRecorder{ AVAudioSession *session = [AVAudioSession sharedInstance]; [session setActive:YES error:nil]; [session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers|AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
然后切换播放环境不改变category,因为前面用的是PlayAndRecord。
什么时候切换成默认状态呢,这个需要cocos端在退出需要录音环境的页面是来通知一下iOS端,然后我们
+ (void)finish{ if (player.playing) { [player stop]; } if (recorder.recording){ [recorder stop]; } [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:nil]; }
这个真的是我认为的最优解了。。有更好的解放方案的同学可以在下方留言一起探讨。