Audio Session Interruption
近期处理了一个挂断电话后,莫名手机开始播放音乐的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相关推荐
- IOS音视频(四十三)AVFoundation 之 Audio Session
IOS音视频(四十三)AVFoundation 之 Audio Session 1.音频会话概述 2. 配置音频会话 2.1 音频会话默认行为 2.2 配置音频会话 2.3 使用多路由类别扩展选项 2 ...
- Audio Session Programming Guide
http://www.cocoachina.com/ios/20150615/12119.html 转载于:https://www.cnblogs.com/itlover2013/p/4576413. ...
- iOS音频开发相关(二)录音 `AVAudioRecorder`
录音 AVAudioRecorder 初始化方法 AVFormatIDKey AVSampleRateKey AVNumberOfChannelsKey linear PCM keys AVLinea ...
- Core Audio音频基础概述
Core Audio Core Audio提供了数字音频服务为iOS与OS X, 它提供了一系列框架去处理音频. Core Audio中包含我们最常用的Audio Toolbox与Audio Unit ...
- iOS 音视频开发:Audio Unit播放FFmpeg解码的音频
本文档描述了iOS播放经FFmpeg解码的音频数据的编程步骤,具体基于Audio Toolbox框架的Audio Session和Audio Unit框架提供的接口实现.在iOS 7及以上平台Audi ...
- Android Audio代码分析7 - stream type
在看AudioTrack代码的时候,我们看到,要创建一个AudioTrack对象,需要指定一个StreamType. 今天我们只把stream type相关的代码抽取出来,详细看看stream typ ...
- 使用Core Audio实现VoIP通用音频模块
最近一直在做iOS音频技术相关的项目,由于单项直播SDK,互动直播SDK(iOS/Mac),短视频SDK,都会用到音频技术,因此在这里收集三个SDK的音频技术需求,开发一个通用的音频模块用于三个SDK ...
- 【实战分享】使用Core Audio实现VoIP通用音频模块
最近一直在做iOS音频技术相关的项目,由于单项直播SDK,互动直播SDK(iOS/Mac),短视频SDK,都会用到音频技术,因此在这里收集三个SDK的音频技术需求,开发一个通用的音频模块用于三个SDK ...
- Windows Core Audio APIs(一)介绍
文章目录 Windows Core Audio APIs(一)介绍 Core Audio 架构介绍 Core Audio 架构图 音频高级API Core Audio APIs 共享模式和独占模式 音 ...
最新文章
- mysql的聚合查询_MySql聚合查询
- SQL Server中的几个方法和Transact SQL 常用语句以及函数[个人推荐]
- MATLAB实战系列(三十七)-MATLAB基于PQ解耦风电场并网潮流计算
- 黑马程序员之《String 类练习》
- 杭电信工2018期末c语言试卷,2018C程序设计期末试卷(2018杭电A卷).doc
- 8086汇编-实验9-字符打印
- vue路由传参的三种基本方式
- PHP+MySql+PDO实现简单增加、删除、修改、查询
- dfs深度优先搜索_图的深度优先搜索(DFS)
- 要些一个在win98下的socket服务程序,大家推荐一下用啥控件?Indy?
- 删除已配对的View Security Server、View Replica Server
- 信息论与编码_学术动态 | “中大网络信息理论与编码研讨会”成功举办
- 长时间佩戴蓝牙耳机哪个款式好用?这几款半入耳式佩戴稳定舒适,不要错过
- JavaScript在线教程网址
- 帝国CMS教程,使用灵动标签调用上一篇下一篇的文章标题图片的方法
- 利用tensorflow训练自己的图片数据(1)——预处理
- nandwrite 参数
- 关于SIO_RCVALL
- 多多情报通:拼多多发布机会商品是谁发货?该怎么发货?
- MTK平台LK中的APP_START(LK app service)介绍
热门文章
- Ms Press China MVP-书评活动-王万利 Microsoft Active Directory Administrator's Pocket Consultant...
- 智能实验室-杀马(Defendio) 3.0.0.580 beta 4
- Linux基础命令---添加/删除组
- java 线程方法join的简单总结
- 关于C#应用的授权认证
- Nginx虚拟机主机根据不同的域名使用不同的root路径
- MySQL Concurrency Problems
- java.util.concurrent.locks.Condition 源码
- html2canvas如何在元素隐藏的情况下生成截图
- 如何提高UI自动化测试的质量