经过了,总要留些痕迹 - iOS应用

iOS多播放源抢占扬声器主声道问题

2019-03-20  本文已影响0人  Dylan_J
声波图

  刚入职一周,接到一个调研的任务。问题是这样的,首先App的场景是开启着直播播放功能,然后同时开启一个UIWebView加载着可交互的网页,网页中同样包含着声音,这时在直播声音播放的同时UIWebView播放声音在iOS端会有UIWebView上的声音很小的问题。

问题重现

  因为刚入职嘛,忙于熟悉工作环境、搭建开发环境、熟悉代码,并没有太深入的了解到功能的实现方案。刚听到这个调研需求的时候,我的内心是懵*状态的。起初都没有理解到到底是什么任务,在前一天晚上有个类似的声音混响问题,我先入为主的以为就是那个问题。还好技术总监和公司现在的iOS老哥很好,在我问了几个问题之后,我正确了解到这个问题和问题发生的环境及功能实现的大概架构。
  需求确定之后,下面就是看一下具体的现象的。在iOS老哥的帮助下,我们搭好了测试的环境(新来的没有账号和权限)。于是老哥忙着搞上线,我就开始重现问题。在搭建好环境的基础上重现这个问题还是很容易的,很快问题的现象就出现在了我的面前。嗯~ 是个问题,不太好弄,不过为了证明自己的能力,搞吧!其实问题解决也得益于技术总监和iOS老哥给出了一个现象,就是点击Home键之后,UIWebView上的声音就会变大。知道了这种现象在我感觉就有了解决问题的切入点。

问题解决

  既然知道了什么情况下问题可以得到使问题得到解决,那么就模拟这个过程就可以了。首先需要清楚App的生命周期:

iOS App生命周期
// 发送进入后台的通知
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];
// 发送进入前台的通知
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];

这个方案可以临时解决声音小的问题,但是有一个相对不妥的地方:发送系统的通知,自己的代码里监听系统通知的方法也会被调用,根据逻辑的不同我们很难说清楚会不会导致什么问题。那就再研究研究。
  因为涉及到播放硬件,所以我就在想别的播放硬件会不会有什么影响呢?结果用耳机试了一下,惊喜的是耳机声音是大的,由此我想到可以模拟耳机插拔,但是是类似于上面提到的,也会有一定的影响,不过很明显这个模拟系统通知的影响一定程度上的危险级别就比上面小了,于是方案二就尝试出来了:

- (void)webViewDidFinishLoadAction {
   [self devicePushRouteChangeWithValue:AVAudioSessionRouteChangeReasonNewDeviceAvailable];
   [self devicePushRouteChangeWithValue:AVAudioSessionRouteChangeReasonOldDeviceUnavailable];
}
- (void)devicePushRouteChangeWithValue:(AVAudioSessionRouteChangeReason)value {
   NSDictionary * dataDic = @{
                              AVAudioSessionRouteChangeReasonKey : [NSNumber numberWithInteger:value]
                              };
   [[NSNotificationCenter defaultCenter] postNotificationName:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance] userInfo:dataDic];
}

由此作为初步解决问题的方案。
之后的一段时间内我一直查找问题出现的原理,后经过看了一些文章发现与AVAudioSession有可能有一定的关系:


Audio Session

  可以看到AVAudioSession就是用来管理多个APP对音频硬件设备(麦克风,扬声器)的资源使用。
举例一下AVAudioSession可以做这些事情

  Category:

  AVAudioSession的属性名为:

@property(readonly) NSArray<NSString *> *availableCategories;

  开发需求中有时候需要对Category进行微调整,我们发现这个接口还有两个参数Mode和Options

  Mode:

  options:

  在了解了上述知识后,我又做了一些尝试去修改音频的播放:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:nil];

  由此我猜测是直播服务商对于音频的播放做了处理,导致其他的声音播放时变小。经过询问和沟通验证了我的猜测,所以对于服务商做了相应的功能调整需求,直至服务商修改完成,这个出现的异常情况得到了根源性的修正。

上一篇 下一篇

猜你喜欢

热点阅读