在没有网络的情况下,音频的后台播放比较简单,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. 1090 Highest Price in Supply Chain (25 分)(树的遍历)

    求所有叶节点中的最高价以及这个价格的叶节点个数 #include<bits/stdc++.h> using namespace std; ; vector<int>mp[N]; ...

  2. 线段树 (区间更新,区间查询) poj http://poj.org/problem?id=3468

    题目链接 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  3. [洛谷P4151][WC2011]最大XOR和路径

    题目大意:给你一张$n$个点$m$条边的无向图,求一条$1->n$的路径,使得经过路径值的异或值最大(重复经过重复计算) 题解:某条路$k$被重复走了两次,那么它的权值对答案的贡献就是$0$,但 ...

  4. 强军如歌(strong)

    强军如歌(strong) 题目描述 给定一个NN个数的序列AA,如果序列AA不是非降序的,你需要在其中选择一个数删掉,不断重复这个操作直到序列AA非降.求有多少种不同的删数方案.注意:删掉的数的集合相 ...

  5. Linux/unix inode

    一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...

  6. 服务器 阿里云服务器Ubuntu挂载数据盘

    服务器 阿里云服务器Ubuntu挂载数据盘  转自:http://www.codingyun.com/article/24.html coding云运行在阿里云的Ubuntu 12.04 64位操作系 ...

  7. 转 python数据类型详解

    python数据类型详解 目录 1.字符串 2.布尔类型 3.整数 4.浮点数 5.数字 6.列表 7.元组 8.字典 9.日期 1.字符串 1.1.如何在Python中使用字符串 a.使用单引号(' ...

  8. Microsoft SilverLightt是一个跨浏览器的、跨平台的插件,为网络带来下一代基于.NETFramework的媒体体验和丰富的交互式应用程序。

    Microsoft Silverlight是一个跨浏览器的.跨平台的插件,为网络带来下一代基于.NETFramework的媒体体验和丰富的交互式应用程序.Silverlight提供灵活的编程模型,并可 ...

  9. git代码仓库迁移(从github到oschina)【转】

    转自:http://blog.csdn.net/a5244491/article/details/44807937 版权声明:本文为博主原创文章,未经博主允许不得转载. 因为一些特殊原因,需要将公司原 ...

  10. 应用程序已被Java安全阻止

    提示 您的安全设置已阻止自签名的应用程序运行 控制面板-JAVA-安全-例外站点-https://域名或IP/或http://域名或IP/,注意结尾必须要加/否则还是会一直提示被阻止