Audio Session Interruption
近期处理了一个挂断电话后,莫名手机开始播放音乐的Bug。 所以顺便在这总结一下,对于IOS的AudioSession中断的几种处理情况。
一、通过C语言的init方法配置interruptionl回调。建议用这种方法,但有些细节需要注意,后续会谈到。
AudioSessionInitialize (
NULL, //
NULL, //
interruptionListenerCallback, //
userData //
);
然后在回调,实现如下逻辑代码:
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这个变量重置。
Audio Session Interruption的更多相关文章
- IOS Audio session
iOS实现长时间后台的两种方法:Audio session和VOIP socket 十二月 04 我们知道 iOS 开启后台任务后可以获得最多 600 秒的执行时间,而一些需要在后台下载或者与服务器保 ...
- AVAudioSession(2):定义一个 Audio Session
本文转自:AVAudioSession(2):定义一个 Audio Session | www.samirchen.com 本文内容主要来源于 Defining an Audio Session. A ...
- audio session config
#pragma mark - #pragma mark - audio session config - (void)setAudioSessionConfig { NSError *error; A ...
- AVAudioSession(3):定制 Audio Session 的 Category
本文转自:AVAudioSession(3):定制 Audio Session 的 Category | www.samirchen.com 本文内容主要来源于 Working with Catego ...
- AVAudioSession(1):iOS Audio Session 概览
本文转自:AVAudioSession(1):iOS Audio Session 概览 | www.samirchen.com 本文内容主要来源于 Audio Session Programming ...
- Audio Session Programming Guide
http://www.cocoachina.com/ios/20150615/12119.html
- iOS播放器 - AVAudioPlayer
今天记录一下AVAudioPlayer,这个播放器类苹果提供了一些代理方法,主要用来播放本地音频. 其实也可以用来播放网络音频,只不过是将整个网络文件下载下来而已,在实际开发中会比较耗费流量不做推荐. ...
- iOS -- AVAudioPlayer播放音乐
一. AVAudioPlayer: 声明音乐控件AVAudioPlayer,必须声明为全局属性变量,否则可能不会播放,AVAudioPlayer只能播 ...
- AVFoundation 框架初探究(一)
夜深时动笔 前面一篇文章写了视频播放的几种基本的方式,算是给这个系列开了一个头,这里面最想说和探究的就是AVFoundation框架,很想把这个框架不敢说是完全理解,但至少想把它弄明白它里面到底有什么 ...
随机推荐
- 20145304 《Java程序设计》课程总结
每周读书笔记链接汇总 第一周读书笔记 第二周读书笔记 第三周读书笔记 第四周读书笔记 第五周读书笔记 第六周读书笔记 第七周读书笔记 第八周读书笔记 第九周读书笔记 第十周读书笔记 实验报告链接汇总 ...
- ubifs总体设计分析
1. 设计需求 flash设备区别与一般的块设备,有如下特点: 存在坏块 使用寿命较短 存储介质不稳定 读写速度慢 不支持随机访问(nand) 只能通过擦除将0改成1 最小读写单位为page ...
- 【BZOJ2242】【SDoi2011】计算器 快速幂+EXGCD+BSGS
Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给 ...
- 实现UITableView循环利用
tableViewUITableView循环利用 前言 大家都知道UITableView,最经典在于循环利用,这里我自己模仿UITableView循环利用,写了一套自己的TableView实现方案,希 ...
- js之获取窗口大小和位置信息
除IE外的浏览器查看窗口大小和位置信息: //The overall size of the browser window on the desktop var windowWidth = windo ...
- mac 终端乱码
我系统是英文的 export LANG=en_US.UTF-8export LC_ALL=en_US.UTF-8 中文的 export LANG=zh_CN.UTF-8 export LANG=en_ ...
- GO语言练习:channel 工程实例
1.工程代码 2.编译及运行 1.工程目录结构 $ tree cgss cgss ├── cgss.go └── src ├── cg │ ├── centerclient.go │ ├── ...
- osgearth各个例子功能概述
osgearth各个例子功能概述 转自:http://blog.csdn.net/wl198302/article/details/21177309 最近在学习osgearth,对其还不是很理解,有些 ...
- Radar Installation
Radar Installation 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86640#problem/C 题目: De ...
- js判断微信浏览器
function is_weixin(){ //检查是否是微信浏览器 var ua = navigator.userAgent.toLowerCase(); if(ua.match(/MicroMes ...