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

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

2013-12-11 21:13 1416人阅读 评论(0) 收藏 举报

 分类:

cocoa SDK(139) 

目录(?)[+]

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

 

初始化AudioSession和基本配置

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

[objc] view plain copy

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

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. [application beginReceivingRemoteControlEvents];
  3. }

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

[objc] view plain copy

  1. -(void)justPlay{
  2. UIBackgroundTaskIdentifier bgTask = 0;
  3. if([UIApplication sharedApplication].applicationState== UIApplicationStateBackground) {
  4. NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx后台播放”);
  5. [thePlayer play];
  6. UIApplication*app = [UIApplication sharedApplication];
  7. UIBackgroundTaskIdentifier newTask = [app beginBackgroundTaskWithExpirationHandler:nil];
  8. if(bgTask!= UIBackgroundTaskInvalid) {
  9. [app endBackgroundTask: bgTask];
  10. }
  11. bgTask = newTask;
  12. }
  13. else {
  14. NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx前台播放”);
  15. [thePlayer play];
  16. }
  17. }

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

Remote控制

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

[objc] view plain copy

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

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

然后添加下面的代码:

[objc] view plain copy

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

锁屏封面

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

[objc] view plain copy

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

打断处理

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

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

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

[objc] view plain copy

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

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

[objc] view plain copy

  1. - (void)handleInterruptionChangeToState:(NSNotification *)notification
  2. {
  3. AudioQueuePropertyID inInterruptionState=[[notification object] longValue];
  4. if (inInterruptionState == kAudioSessionBeginInterruption)
  5. {
  6. NSLog(@”begin interruption——->”);
  7. }
  8. else if (inInterruptionState == kAudioSessionEndInterruption)
  9. {
  10. NSLog(@”end interruption——->”);
  11. }
  12. }
时间: 2024-10-04 09:05:39

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

iOS音频流播放、后台播放、远程控制、锁屏封面等总结

1. 推荐音频流播放Framework 知名度比较高的Framework应该是github的 mattgallagher/AudioStreamer ,因为国内有一些论坛和教程网的例子是用这个Framework写的,而且有国人略微改进了一下这个Framework并加了中文注释.不过这个Framework的缺点在于不支持ARC,并且状态的改变通过notification来通知,并不是很灵活易用. 所以在这里推荐的是另一个Framework,同样来自github(虽然以前是放在google code

IOS Charles(代理服务器软件,可以用来拦截网络请求)

什么是Charles Charles是一款代理服务器软件,可以用来拦截网络请求 利用Charles能得知大部分公司app的数据来源和数据格式 下载地址:http://www.charlesproxy.com/download/

iOS开发简记(7):网络请求模块

主流的APP都少不了跟服务器交互,网络请求是少不了的事情. 开源的网络请求库,有很多,比如:AFNetworking.YTKNetwork.PPNetworkHelper.ASIHttpRequest,等等. 这里记录AFNetworking的使用. (1)安装afnetworking 跟使用QMUIKit一样,小程以cocoapods的方式来引入AFNetworking. 先用pod命令来查找AFNetworking的最新版本: pod search AFNetworking 查找结果如下:

iOS音频开发(录音+播放+剪辑+合成+压缩转码)

录音: //音频会话 AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *sessionError; /* AVAudioSessionCategoryPlayAndRecord :录制和播放 AVAudioSessionCategoryAmbient :用于非以语音为主的应用,随着静音键和屏幕关闭而静音. AVAudioSessionCategorySoloAmbient :类似AVAudioSessionCa

iOS 音频录制与播放

最近项目中增加了即时通讯功能,借鉴各位大侠的杰作简单的写了个集成了音频录制和播放功能的类,欢迎借鉴与改善,点此链接下载

iOS开发用AFNetworking和MJRefresh实现网络请求和下拉刷新、上拉加载

首先感谢iOS122提供的可以免费GET请求到的网络数据的接口 为了方便cell自适应高度,此处的cell是带Xib的.为了方便理解代码,此处没有应用MVC设计模式,实际开发中不能这样. #import "ViewController.h" #import "AFNetworking.h" #import "MJRefresh.h" #import "TestTableViewCell.h" @interface ViewCo

iOS音频的后台播放总结

在没有网络的情况下,音频的后台播放比较简单,google一下可以搜到很多资料,但是如果每次歌曲的请求都是通过网络,就不成了,有时可以也扛不了几首,这里总结下实现方法,可以实现像电台一样的功能,后台播放,网络请求歌曲,Remote控制,锁屏有封面,电话和听歌打断处理等.   初始化AudioSession和基本配置 音频播放器采用的AVPlayer ,自己进行了功能封装,暂且不谈,在程序启动的时候需要配置AudioSession,AudioSession负责应用音频的设置,比如支不支持后台,打断等

iOS音频的后台播放 锁屏

初始化AudioSession和基本配置 音频播放器采用的AVPlayer ,在程序启动的时候需要配置AudioSession,AudioSession负责应用音频的设置,比如支不支持后台,打断等等,这一步很重要,比如在viewdidload里初始化AVplayer以后要调用下面的函数: /** 设置音频会话 */  //这种方式后台,可以连续播放非网络请求歌曲,遇到网络请求歌曲就废,需要后台申请task -(void)setAudioSession{ AVAudioSession *audio

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

本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于AudioToolbox.framework框架.播放系统声音文件. 基于AVFoundation.framework框架.播放多种音频格式文件.具有高级音频播放器功能.如实时显示进度.功率,控制音量.播放时间等. 基于OPENAL框架.实现对本地音频文件播放,播放pcm音频文件,3D音频特效. 基