近期处理了一个挂断电话后,莫名手机开始播放音乐的Bug。 所以顺便在这总结一下,对于IOS的AudioSession中断的几种处理情况。

一、通过C语言的init方法配置interruptionl回调。建议用这种方法,但有些细节需要注意,后续会谈到。

AudioSessionInitialize (NULL,                            // 1NULL,                            // 2interruptionListenerCallback,    // 3userData                         // 4
);

然后在回调,实现如下逻辑代码:

void interruptionListenerCallback ( void *inUserData,  UInt32  interruptionState ) {AudioViewController *controller = (AudioViewController *)inUserData;  if (interruptionState == kAudioSessionBeginInterruption) {         if (controller.audioRecorder) {[controller recordOrStop: (id) controller];                 } else if (controller.audioPlayer) {[controller pausePlayback];                                controller.interruptedOnPlayback = YES;                     }} else if ((interruptionState == kAudioSessionEndInterruption) && controller.interruptedOnPlayback) {[controller resumePlayback];controller.interruptedOnPlayback = NO;}
}

二、使用AVAudioSessionDelegate。如果你使用的是AVAudioPlayer或AVAudioRecorder,还可以使用对应的AVAudioPlayerDelegate和 AVAudioRecorderDelegate。但AVAudioSessionDelegate在6.0后被弃用,所以使用有局限性。后者没有被弃用。

- (void) beginInterruption {if (playing) {playing = NO;interruptedWhilePlaying = YES;[self updateUserInterface];}
}
NSError *activationError = nil;
- (void) endInterruption {if (interruptedWhilePlaying) {BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];if (!success) { /* handle the error in activationError */ }[player play];playing = YES;interruptedWhilePlaying = NO;[self updateUserInterface];}
}

三、如上所说,6.0弃用了AVAudioSessionDelegate。所以6.0之后使用AVAudioSessionInterruptionNotification来实现类似的功能。AVAudioSessionInterruptionNotification的userInfo中包括AVAudioSessionInterruptionTypeKey和AVAudioSessionInterruptionTypeEnded。

四、使用RouteChange的回调。对于音乐播放,如果当然当前是耳机模式,拔掉耳机一般是希望音乐暂停的。类似这种拔插设备,播放语音等声音设备切换,一般通过RouteChange的回调来控制。

注册RouteChange的回调:

   AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange,audioRouteChangeListenerCallback,nil);

回调处理代码:

void audioRouteChangeListenerCallback(void *inUserData, AudioSessionPropertyID inPropertyID, UInt32 inPropertyValueSize, const void *inPropertyValue) {if (inPropertyID != kAudioSessionProperty_AudioRouteChange)return;CFDictionaryRef routeChangeDictionary = inPropertyValue;CFNumberRef routeChangeReasonRef = CFDictionaryGetValue (routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason));CFStringRef oldRouteRef = CFDictionaryGetValue (routeChangeDictionary,CFSTR (kAudioSession_AudioRouteChangeKey_OldRoute));NSString *oldRouteString = (NSString *)oldRouteRef;SInt32 routeChangeReason;CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {if (oldRouteStringplaying ) { //需判断不可用Route为耳机时playing = NO;interruptedWhilePlaying = NO;  //清除中断标识,如电话中拔掉耳机挂断时,不需要继续播放
        }}
}

对于AudioSession的Route,有如下几种模式:

/* Known values of route:
*"Headset"
* "Headphone"
* "Speaker"
* "SpeakerAndMicrophone"
* "HeadphonesAndMicrophone"
* "HeadsetInOut"
* "ReceiverAndMicrophone"
* "Lineout"
*///ios5以后可使用的一些类型
const CFStringRef kAudioSessionOutputRoute_LineOut;
const CFStringRef kAudioSessionOutputRoute_Headphones;
const CFStringRef kAudioSessionOutputRoute_BluetoothHFP;
const CFStringRef kAudioSessionOutputRoute_BluetoothA2DP;
const CFStringRef kAudioSessionOutputRoute_BuiltInReceiver;
const CFStringRef kAudioSessionOutputRoute_BuiltInSpeaker;
const CFStringRef kAudioSessionOutputRoute_USBAudio;
const CFStringRef kAudioSessionOutputRoute_HDMI;
const CFStringRef kAudioSessionOutputRoute_AirPlay;

关于其他的一些总结:

1、对于SDK6.0,AudioSession中断是一个Bug版本。不会响应AVAudioSessionDelegate,且不响应AVAudioSessionInterruptionNotification。C语言中断,当使用AVPlayer后,不响应kAudioSessionBeginInterruption,但响应kAudioSessionEndInterruption。 这是苹果的Bug。对上这种Case,有如下处理办法:

  1)当收到kAudioSessionEndInterruption时,调用暂停播放更新UI。

  2)使用RouteChange来判断电话的接通和挂断情境。但如果是耳机模式,电话的接通和挂断,经测试,使用的是同一种Route。所以,对于SDK6.0,播放过程中未接耳机时,可通过RouteChange来恢复播放。而耳机模式播放时,来电恢复播放,目前看来无完善的处理方式。

2、当后台播放歌曲时,打开游戏之类APP,声道会被其APP占用。这种Case会有kAudioSessionBeginInterruption。但返回时不会有kAudioSessionEndInterruption。所以,这种Case在回到APP时,需要interruptedWhilePlaying这个变量重置。

转载于:https://www.cnblogs.com/simalone/p/3275293.html

Audio Session Interruption相关推荐

  1. IOS音视频(四十三)AVFoundation 之 Audio Session

    IOS音视频(四十三)AVFoundation 之 Audio Session 1.音频会话概述 2. 配置音频会话 2.1 音频会话默认行为 2.2 配置音频会话 2.3 使用多路由类别扩展选项 2 ...

  2. Audio Session Programming Guide

    http://www.cocoachina.com/ios/20150615/12119.html 转载于:https://www.cnblogs.com/itlover2013/p/4576413. ...

  3. iOS音频开发相关(二)录音 `AVAudioRecorder`

    录音 AVAudioRecorder 初始化方法 AVFormatIDKey AVSampleRateKey AVNumberOfChannelsKey linear PCM keys AVLinea ...

  4. Core Audio音频基础概述

    Core Audio Core Audio提供了数字音频服务为iOS与OS X, 它提供了一系列框架去处理音频. Core Audio中包含我们最常用的Audio Toolbox与Audio Unit ...

  5. iOS 音视频开发:Audio Unit播放FFmpeg解码的音频

    本文档描述了iOS播放经FFmpeg解码的音频数据的编程步骤,具体基于Audio Toolbox框架的Audio Session和Audio Unit框架提供的接口实现.在iOS 7及以上平台Audi ...

  6. Android Audio代码分析7 - stream type

    在看AudioTrack代码的时候,我们看到,要创建一个AudioTrack对象,需要指定一个StreamType. 今天我们只把stream type相关的代码抽取出来,详细看看stream typ ...

  7. 使用Core Audio实现VoIP通用音频模块

    最近一直在做iOS音频技术相关的项目,由于单项直播SDK,互动直播SDK(iOS/Mac),短视频SDK,都会用到音频技术,因此在这里收集三个SDK的音频技术需求,开发一个通用的音频模块用于三个SDK ...

  8. 【实战分享】使用Core Audio实现VoIP通用音频模块

    最近一直在做iOS音频技术相关的项目,由于单项直播SDK,互动直播SDK(iOS/Mac),短视频SDK,都会用到音频技术,因此在这里收集三个SDK的音频技术需求,开发一个通用的音频模块用于三个SDK ...

  9. Windows Core Audio APIs(一)介绍

    文章目录 Windows Core Audio APIs(一)介绍 Core Audio 架构介绍 Core Audio 架构图 音频高级API Core Audio APIs 共享模式和独占模式 音 ...

最新文章

  1. mysql的聚合查询_MySql聚合查询
  2. SQL Server中的几个方法和Transact SQL 常用语句以及函数[个人推荐]
  3. MATLAB实战系列(三十七)-MATLAB基于PQ解耦风电场并网潮流计算
  4. 黑马程序员之《String 类练习》
  5. 杭电信工2018期末c语言试卷,2018C程序设计期末试卷(2018杭电A卷).doc
  6. 8086汇编-实验9-字符打印
  7. vue路由传参的三种基本方式
  8. PHP+MySql+PDO实现简单增加、删除、修改、查询
  9. dfs深度优先搜索_图的深度优先搜索(DFS)
  10. 要些一个在win98下的socket服务程序,大家推荐一下用啥控件?Indy?
  11. 删除已配对的View Security Server、View Replica Server
  12. 信息论与编码_学术动态 | “中大网络信息理论与编码研讨会”成功举办
  13. 长时间佩戴蓝牙耳机哪个款式好用?这几款半入耳式佩戴稳定舒适,不要错过
  14. JavaScript在线教程网址
  15. 帝国CMS教程,使用灵动标签调用上一篇下一篇的文章标题图片的方法
  16. 利用tensorflow训练自己的图片数据(1)——预处理
  17. nandwrite 参数
  18. 关于SIO_RCVALL
  19. 多多情报通:拼多多发布机会商品是谁发货?该怎么发货?
  20. MTK平台LK中的APP_START(LK app service)介绍

热门文章

  1. Ms Press China MVP-书评活动-王万利 Microsoft Active Directory Administrator's Pocket Consultant...
  2. 智能实验室-杀马(Defendio) 3.0.0.580 beta 4
  3. Linux基础命令---添加/删除组
  4. java 线程方法join的简单总结
  5. 关于C#应用的授权认证
  6. Nginx虚拟机主机根据不同的域名使用不同的root路径
  7. MySQL Concurrency Problems
  8. java.util.concurrent.locks.Condition 源码
  9. html2canvas如何在元素隐藏的情况下生成截图
  10. 如何提高UI自动化测试的质量