iOS音频的后台播放总结(后台网络请求歌曲,Remote控制,锁屏封面,各种打断)

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

 

 

初始化AudioSession和基本配置

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

[objc] view
plain
copy

  1. -(void)setAudioSession{  
  2.   
  3. //AudioSessionInitialize用于控制打断 ,后面会说  
  4.   
  5. AudioSessionInitialize (  
  6.   
  7. NULL,                          // ‘NULL’ to use the default (main) run loop  
  8.   
  9. NULL,                          // ‘NULL’ to use the default run loop mode  
  10.   
  11. ASAudioSessionInterruptionListener,  // a reference to your interruption callback  
  12.   
  13. NULL                       // data to pass to your interruption listener callback  
  14.   
  15. );  
  16.   
  17. //这种方式后台,可以连续播放非网络请求歌曲,遇到网络请求歌曲就废,需要后台申请task  
  18.   
  19. AVAudioSession *session = [AVAudioSession sharedInstance];  
  20.   
  21. NSError *setCategoryError = nil;  
  22.   
  23. BOOL success = [session setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];  
  24.   
  25. if (!success)  
  26.   
  27. {  
  28.   
  29. /* handle the error condition */  
  30.   
  31. return;  
  32.   
  33. }  
  34.   
  35. NSError *activationError = nil;  
  36.   
  37. success = [session setActive:YES error:&activationError];  
  38.   
  39. if (!success)  
  40.   
  41. {  
  42.   
  43. /* handle the error condition */  
  44.   
  45. return;  
  46.   
  47. }  
  48.   
  49. }  

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文件,应用就已经支持后台音频播放了,但是如果每一首歌曲都不存在本地,在网络的话就不行了,需要申请后台任务来进行处理,首先修改:

[objc] view
plain
copy

  1. - (void)applicationDidEnterBackground:(UIApplication *)application {  
  2.   
  3. [application beginReceivingRemoteControlEvents];  
  4. }  

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

[objc] view
plain
copy

  1. -(void)justPlay{  
  2.   
  3. UIBackgroundTaskIdentifier bgTask = 0;  
  4.   
  5.    
  6.   
  7. if([UIApplication sharedApplication].applicationState== UIApplicationStateBackground) {  
  8.   
  9. NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx后台播放”);  
  10.   
  11. [thePlayer play];  
  12.   
  13. UIApplication*app = [UIApplication sharedApplication];  
  14.   
  15. UIBackgroundTaskIdentifier newTask = [app beginBackgroundTaskWithExpirationHandler:nil];  
  16.   
  17. if(bgTask!= UIBackgroundTaskInvalid) {  
  18.   
  19. [app endBackgroundTask: bgTask];  
  20.   
  21. }  
  22.   
  23. bgTask = newTask;  
  24.   
  25. }  
  26.   
  27. else {  
  28.   
  29. NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx前台播放”);  
  30.   
  31. [thePlayer play];  
  32.   
  33. }  
  34.   
  35. }  

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

Remote控制

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

[objc] view
plain
copy

  1. - (void)viewDidAppear:(BOOL)animated {  
  2.   
  3. NSLog(@”viewDidAppear!!!”);  
  4.   
  5. [super viewDidAppear:animated];  
  6.   
  7. //Once the view has loaded then we can register to begin recieving controls and we can become the first responder  
  8.   
  9. [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];  
  10.   
  11. [self becomeFirstResponder];  
  12.   
  13. }  
  14.   
  15. - (void)viewWillDisappear:(BOOL)animated {  
  16.   
  17. NSLog(@”viewWillDisappear!!!”);  
  18.   
  19. [super viewWillDisappear:animated];  
  20.   
  21. //End recieving events  
  22.   
  23. [[UIApplication sharedApplication] endReceivingRemoteControlEvents];  
  24.   
  25. [self resignFirstResponder];  
  26.   
  27. }  

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

 

然后添加下面的代码:

 

[objc] view
plain
copy

  1. -(void)remoteControlReceivedWithEvent:(UIEvent *)event{  
  2.   
  3. //if it is a remote control event handle it correctly  
  4.   
  5. if (event.type == UIEventTypeRemoteControl) {  
  6.   
  7. if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {  
  8.   
  9. [self playerTap];  
  10.   
  11. } else if (event.subtype == UIEventSubtypeRemoteControlNextTrack){  
  12.   
  13. [self nextSongAuto];  
  14.   
  15. [self configNowPlayingInfoCenter];  
  16.   
  17. }  
  18.   
  19. }  
  20.   
  21. }  
  22.   
  23. //Make sure we can recieve remote control events  
  24.   
  25. - (BOOL)canBecomeFirstResponder {  
  26.   
  27. return YES;  
  28.   
  29. }  

锁屏封面

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

[objc] view
plain
copy

  1. - (void)configNowPlayingInfoCenter {  
  2.   
  3. NSDictionary *albumDic=[currentParserSongArray objectAtIndex:songIndex];  
  4.   
  5. if (NSClassFromString(@”MPNowPlayingInfoCenter”)) {  
  6.   
  7. NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];  
  8.   
  9. [dict setObject:[albumDic objectForKey:@"name"] forKey:MPMediaItemPropertyTitle];  
  10.   
  11. [dict setObject:[albumDic objectForKey:@"singer"] forKey:MPMediaItemPropertyArtist];  
  12.   
  13. [dict setObject:[albumDic objectForKey:@"album"] forKey:MPMediaItemPropertyAlbumTitle];  
  14.   
  15. MPMediaItemArtwork * mArt = [[MPMediaItemArtwork alloc] initWithImage:cdCoverImgView.image];  
  16.   
  17. [dict setObject:mArt forKey:MPMediaItemPropertyArtwork];  
  18.   
  19. [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;  
  20.   
  21. [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];  
  22.   
  23. }  
  24.   
  25. }  
  26.   
  27.    

打断处理

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

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

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

[objc] view
plain
copy

  1. static void ASAudioSessionInterruptionListener(voidvoid *inClientData, UInt32 inInterruptionState)  
  2.   
  3. {  
  4.   
  5. [[ToolManager defaultManager] handleInterruption:inInterruptionState];  
  6.   
  7. }  

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

[objc] view
plain
copy

  1. - (void)handleInterruptionChangeToState:(NSNotification *)notification  
  2.   
  3. {  
  4.   
  5. AudioQueuePropertyID inInterruptionState=[[notification object] longValue];  
  6.   
  7.    
  8.   
  9. if (inInterruptionState == kAudioSessionBeginInterruption)  
  10.   
  11. {  
  12.   
  13. NSLog(@”begin interruption——->”);  
  14.   
  15. }  
  16.   
  17. else if (inInterruptionState == kAudioSessionEndInterruption)  
  18.   
  19. {  
  20.   
  21. NSLog(@”end interruption——->”);  
  22.   
  23.    
  24.   
  25. }  
  26.   
  27. }  
时间: 2024-10-31 04:30:55

iOS音频的后台播放总结(后台网络请求歌曲,Remote控制,锁屏封面,各种打断)的相关文章

iOS开发中使用NSURLConnection类处理网络请求的方法_IOS

NSURLConnection 作为 Core Foundation / CFNetwork 框架的 API 之上的一个抽象,在 2003 年,随着第一版的 Safari 的发布就发布了.NSURLConnection 这个名字,实际上是指代的 Foundation 框架的 URL 加载系统中一系列有关联的组件:NSURLRequest.NSURLResponse.NSURLProtocol. NSURLCache. NSHTTPCookieStorage.NSURLCredentialStor

【IOS-COCOS2D游戏开发之十八】解决滚屏背景/拼接地图有黑边(缝隙)/图片缩放后模糊透明/图片不清晰【2013年12月13日补充】/动画播放出现毛边以及禁止游戏中自动锁屏问题!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2d/507.html 本章节主要为大家介绍在游戏开发过程中经常遇到的两个问题:  1. 解决滚屏背景或拼接地图有黑边! 对于游戏开发中,背景(游戏地图)是必要的元素之一,那么对于大部分游戏的背景都是动态,或者不断移动的:例如RPG中的背景随着人物.主角而移动,那么一般情况下背景都是由地图编辑器(图块)拼出来的,要不就

ios-iOS 后台播放音乐,同时打开另一个app录音应该怎么实现?

问题描述 iOS 后台播放音乐,同时打开另一个app录音应该怎么实现? 实现的功能,比如酷狗音乐在后台运行播放,同时我打开另一个app对后台播放的音乐进行录制 请问我应该怎么实现? 解决方案 iOS学习笔记51-iOS 音乐类App必备功能:后台播放.锁屏封面.远程播放控制iOS中实现音乐的后台播放iOS实现在后台播放音乐 解决方案二: http://www.zhihu.com/question/43656987 解决方案三: 调用系统库来实现,结合C语法

新版iOS 7系统存在着“锁屏漏洞”

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;   据国外媒体报道,在苹果WWDC产品发布会之后, 开发者在使用新版iOS 7系统时发现,测试版的系统存在着"锁屏漏洞". 此前,在iOS 6发布之后,开发者们同样发现了系统中存在着"锁屏漏洞"这一漏洞.而漏洞同样存在于新版的iOS 7中. 有技术人员表示,人们可以通过"锁屏漏洞"轻松的入侵手机.只需在锁屏

iOS - Mac 锁屏快捷键设置

Mac 锁屏快捷键设置 control + shift + Eject 锁屏快捷键 如果用户要离开电脑一段时间,可以选择直接把笔记本直接合上.但是这样原先在跑的进程就会挂起或者结束,如果正在下载,那么下载就被暂停(有时还不能恢复),如果正在提供网络服务,那么因为网络断了,别人也连不上你的笔记本.锁屏可以解决这个问题,在 Windows 下用 Win+L 快捷键就锁屏了,但 Mac OS X 下一直没有默认的快捷键. 1)方法一 1> Finder –> 应用程序 –> 实用工具 –>

iOS后台音频播放及锁屏界面显示音频信息

iOS后台播放音乐及用户交互处理 后台播放是任何一个音频软件都支持的功能,在上一篇博客中,详细介绍了使用AVAudioPlayer播放音频的方法,这篇博客将对后台的处理做介绍,关于播放与设置音频的博客地址:http://my.oschina.net/u/2340880/blog/420129. 一.设置后台播放 iOS设置后台音频播放的步骤非常简单,首先需要在系统设置的plist文件中添加一个键Required background modes,值为App plays audio or stre

代码-ios音频后台播放,怎么实现(在线)

问题描述 ios音频后台播放,怎么实现(在线) ios音频后台播放,怎么实现,在线播放的最好有直接执行的代码 解决方案 IOS后台运行 之 后台播放音乐 iOS后台播放音乐 解决方案二: 使用服务,即Service就可以满足你的要求.给你我以前自己写的示例: import java.util.List;import android.annotation.SuppressLint;import android.app.Service;import android.content.Broadcast

与众不同windows phone (15) Media(媒体)之后台播放音频

介绍 与众不同 windows phone 7.5 (sdk 7.1) 之媒体 通过 AudioPlayerAgent 实现在后台播放音频 示例 演示如何通过后台代理的方式来实现音频在后台的播放 1.后台代理 MyAudioPlayerAgent/AudioPlayer.cs /* * 本例演示如何播放后台音频(以 AudioPlayerAgent 为例,另 AudioStreamingAgent 用于流式播放音频) * 建议使用 AudioPlaybackAgent 类型的模板创建此项目 *

与众不同 windows phone (15) - Media(媒体)之后台播放音频

原文:与众不同 windows phone (15) - Media(媒体)之后台播放音频 [索引页][源码下载] 与众不同 windows phone (15) - Media(媒体)之后台播放音频 作者:webabcd 介绍与众不同 windows phone 7.5 (sdk 7.1) 之媒体 通过 AudioPlayerAgent 实现在后台播放音频 示例演示如何通过后台代理的方式来实现音频在后台的播放1.后台代理MyAudioPlayerAgent/AudioPlayer.cs /*