在没有网络的情况下,音频的后台播放比较简单,google一下可以搜到很多资料,但是如果每次歌曲的请求都是通过网络,就不成了,有时可以也扛不了几首,这里总结下实现方法,可以实现像电台一样的功能,后台播放,网络请求歌曲,Remote控制,锁屏有封面,电话和听歌打断处理等。

 

初始化AudioSession和基本配置

音频播放器采用的AVPlayer ,自己进行了功能封装,暂且不谈,在程序启动的时候需要配置AudioSession,AudioSession负责应用音频的设置,比如支不支持后台,打断等等,这一步很重要,比如在viewdidload里初始化AVplayer以后要调用下面的函数:

-(void)setAudioSession{

//AudioSessionInitialize用于控制打断 ,后面会说

AudioSessionInitialize (

NULL,                          // ‘NULL’ to use the default (main) run loop

NULL,                          // ‘NULL’ to use the default run loop mode

ASAudioSessionInterruptionListener,  // a reference to your interruption callback

NULL                       // data to pass to your interruption listener callback

);

//这种方式后台,可以连续播放非网络请求歌曲,遇到网络请求歌曲就废,需要后台申请task

AVAudioSession *session = [AVAudioSession sharedInstance];

NSError *setCategoryError = nil;

BOOL success = [session setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];

if (!success)

{

/* handle the error condition */

return;

}

NSError *activationError = nil;

success = [session setActive:YES error:&activationError];

if (!success)

{

/* handle the error condition */

return;

}

}

AudioSessionInitialize用于处理中断处理,AVAudioSession主要调用setCategory和setActive方法来进行设置,AVAudioSessionCategoryPlayback一般用于支持后台播放,在官方文档可以看到其他的类型,每个分别适用于不同的场合:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryAmbient"]] >
<blockquote]] > AVAudioSessionCategoryAmbient</blockquote]] >
</a]] > ;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategorySoloAmbient"]] >
<blockquote]] > AVAudioSessionCategorySoloAmbient</blockquote]] >
</a]] > ;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryPlayback"]] >
<blockquote]] > AVAudioSessionCategoryPlayback</blockquote]] >
</a]] > ;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryRecord"]] >
<blockquote]] > AVAudioSessionCategoryRecord</blockquote]] >
</a]] > ;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryPlayAndRecord"]] >
<blockquote]] > AVAudioSessionCategoryPlayAndRecord</blockquote]] >
</a]] > ;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryAudioProcessing"]] >
<blockquote]] > AVAudioSessionCategoryAudioProcessing</blockquote]] >
</a]] > ;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryMultiRoute"]] >
<blockquote]] > AVAudioSessionCategoryMultiRoute</blockquote]] >
</a]] > ;
 
1
 

除了代码的初始化,很重要的一步是对info-plist的设置,让应用支持音频的后台播放

库的引入包括:

AudioToolBox.framework

MediaPlayer.framework

CoreMedia.framework

AVFoundation.framework

后台播放

正常情况下,如果配置了AVAudioSessionCategoryPlayback这个方法并修改了info-plist文件,应用就已经支持后台音频播放了,但是如果每一首歌曲都不存在本地,在网络的话就不行了,需要申请后台任务来进行处理,首先修改:

- (void)applicationDidEnterBackground:(UIApplication *)application {

[application beginReceivingRemoteControlEvents];
}

然后在播放器的播放函数里添加:

-(void)justPlay{

UIBackgroundTaskIdentifier bgTask = 0;

if([UIApplication sharedApplication].applicationState== UIApplicationStateBackground) {

NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx后台播放”);

[thePlayer play];

UIApplication*app = [UIApplication sharedApplication];

UIBackgroundTaskIdentifier newTask = [app beginBackgroundTaskWithExpirationHandler:nil];

if(bgTask!= UIBackgroundTaskInvalid) {

[app endBackgroundTask: bgTask];

}

bgTask = newTask;

}

else {

NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx前台播放”);

[thePlayer play];

}

}

这样播放就可以进行前台或者后台的判断,支持网络后台播放了,一首一首连续播放。

Remote控制

在播放视图的ViewController里加上这两个函数:

- (void)viewDidAppear:(BOOL)animated {

NSLog(@”viewDidAppear!!!”);

[super viewDidAppear:animated];

//Once the view has loaded then we can register to begin recieving controls and we can become the first responder

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

[self becomeFirstResponder];

}

- (void)viewWillDisappear:(BOOL)animated {

NSLog(@”viewWillDisappear!!!”);

[super viewWillDisappear:animated];

//End recieving events

[[UIApplication sharedApplication] endReceivingRemoteControlEvents];

[self resignFirstResponder];

}

当然也可以同理放到delegate.m里面的进入后台和回到前台的函数中,否则的话,上面的代码只是允许当前视图的情况下进入后台可以Remote控制

然后添加下面的代码:

-(void)remoteControlReceivedWithEvent:(UIEvent *)event{

//if it is a remote control event handle it correctly

if (event.type == UIEventTypeRemoteControl) {

if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {

[self playerTap];

} else if (event.subtype == UIEventSubtypeRemoteControlNextTrack){

[self nextSongAuto];

[self configNowPlayingInfoCenter];

}

}

}

//Make sure we can recieve remote control events

- (BOOL)canBecomeFirstResponder {

return YES;

}

锁屏封面

一般在每次切换歌曲或者更新信息的时候要调用这个方法

- (void)configNowPlayingInfoCenter {

NSDictionary *albumDic=[currentParserSongArray objectAtIndex:songIndex];

if (NSClassFromString(@”MPNowPlayingInfoCenter”)) {

NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];

[dict setObject:[albumDic objectForKey:@"name"] forKey:MPMediaItemPropertyTitle];

[dict setObject:[albumDic objectForKey:@"singer"] forKey:MPMediaItemPropertyArtist];

[dict setObject:[albumDic objectForKey:@"album"] forKey:MPMediaItemPropertyAlbumTitle];

MPMediaItemArtwork * mArt = [[MPMediaItemArtwork alloc] initWithImage:cdCoverImgView.image];

[dict setObject:mArt forKey:MPMediaItemPropertyArtwork];

[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;

[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];

}

}

打断处理

试用了官方文档上的各种代理方法,打断通知,都没用,后来用C函数处理可以控制打断,首先AudioToolBox.framework是需要引入的

在设定session的时候调用了ASAudioSessionInterruptionListener这个函数 ,就是处理打断的,在所需加入的类的实现

@implementation前面加入这个静态方法

static void ASAudioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState)

{

[[ToolManager defaultManager] handleInterruption:inInterruptionState];

}

每次打断结束或者开始都会调用这个方法  ,inInterruptionState来判断是开始还是结束,因为是C函数,不可以直接调用类中[self  xxx]方法,通知也没用 ,故写了个单例类,接收这个参数,然后进行判断

- (void)handleInterruptionChangeToState:(NSNotification *)notification

{

AudioQueuePropertyID inInterruptionState=[[notification object] longValue];

if (inInterruptionState == kAudioSessionBeginInterruption)

{

NSLog(@”begin interruption——->”);

}

else if (inInterruptionState == kAudioSessionEndInterruption)

{

NSLog(@”end interruption——->”);

}

}

iOS音频的后台播放总结的更多相关文章

  1. iOS音频的后台播放 锁屏

    初始化AudioSession和基本配置 音频播放器采用的AVPlayer ,在程序启动的时候需要配置AudioSession,AudioSession负责应用音频的设置,比如支不支持后台,打断等等, ...

  2. iOS从零开始学习直播之音频2.后台播放和在线播放

    本篇主要讲音频的后台播放和在线播放. 后台播放   上一篇写的工程运行之后程序退至后台,发现运行不了,歌停止了,这显然不行,音乐后台播放是标配啊.今天就来讲一下后台播放. 1.在plist文件里,告诉 ...

  3. iOS AvPlayer AvAudioPlayer音频的后台播放问题

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

  4. iOS后台播放音乐

    iOS实现在后台播放音乐 iOS4之后就支持后台播放音频了.只需下面两步就可以实现后台播放音频操作了. 1. 在Info.plist中,添加"Required background mode ...

  5. IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE

    本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于 ...

  6. iOS设备后台播放音乐方法

    iOS设备后台播放音乐方法 1 在设置Capabliites中打开Background Modes,选择Audio And AirPlay 2 在控制viewDidLoad中添加下面代码 AVAudi ...

  7. IOS 音频播放

    iOS音频播放 (一):概述 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也因此对于iOS下的音频播放实现有了一定的研究.写这个系列的博客目的一方面希望能够抛砖 ...

  8. iOS音频播放(二):AudioSession

    (本文转自码农人生) 前言 在实施前一篇中所述的7个步骤步之前还必须面对一个麻烦的问题,AudioSession.   AudioSession简介 AudioSession这个玩意的主要功能包括以下 ...

  9. iOS音频播放、录音、视频播放、拍照、视频录制

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

随机推荐

  1. 团队冲刺Alpha(九)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...

  2. 【bzoj3747】[POI2015]Kinoman 线段树区间合并

    题目描述 一个长度为n的序列,每个数为1~m之一.求一段连续子序列,使得其中之出现过一次的数对应的价值之和最大. 输入 第一行两个整数n,m(1<=m<=n<=1000000). 第 ...

  3. poj 1743 Musical Theme (后缀数组+二分法)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16162   Accepted: 5577 De ...

  4. 转 Android_开源框架_AndroidUniversalImageLoader网络图片加载

    转自:http://www.cnblogs.com/wanqieddy/p/3836485.html 1.功能概要 Android-Universal-Image-Loader是一个开源的UI组件程序 ...

  5. centos 搭建web平台

    centos 查询是否安装apacherpm -qa httpd 出现类似 httpd--.el6.centos..x86_64 ,说明已安装 yum -y install httpd    // 安 ...

  6. 母函数(Generation Function) 入门 + 模板

    转自:母函数 入门 + 模板  感谢 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用母函数解决问题的 ...

  7. Topcoder SRM 605 div1 题解

    日常打卡- Easy(250pts): 题目大意:你有n种汉堡包(统统吃掉-),每一种汉堡包有一个type值和一个taste值,你现在要吃掉若干个汉堡包,使得它们taste的总和*(不同的type值的 ...

  8. jquery.uploadify不支持MVC的Authorize

    原文发布时间为:2011-10-18 -- 来源于本人的百度文章 [由搬家工具导入] 为什么jquery.uploadify不支持MVC的Authorize呢,因为flash的cookie跟服务端的不 ...

  9. 接下来打算写一下visual stuido 2013使用git进行远端管理。

    虽然我有了vs的账号,也vs2013开始已经可以进行远端的账户管理了,可是vs的版控毕竟有些依赖vs,想想还是用git吧 今天把这个环境的整套都弄地基本熟了.记录一下,算是一个小结.开始搭建系统框架

  10. [bzoj2245][SDOI2011]工作安排——费用流

    题目大意: 传送门 题解: 很容易建模,把每一个工作人员拆成两个点,由第一个点向第二个点连S+1条边即可. 这水题没什么难度,主要是longlong卡的丧心病狂... 代码 #include < ...