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

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

目录(?)[+]

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

 

初始化AudioSession和基本配置

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

[objc] view plaincopy
  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 plaincopy
  1. - (void)applicationDidEnterBackground:(UIApplication *)application {
  2. [application beginReceivingRemoteControlEvents];
  3. }

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

[objc] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  1. static void ASAudioSessionInterruptionListener(voidvoid *inClientData, UInt32 inInterruptionState)
  2. {
  3. [[ToolManager defaultManager] handleInterruption:inInterruptionState];
  4. }

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

[objc] view plaincopy
  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. }

转载于:https://www.cnblogs.com/ios4app/p/6947622.html

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

  1. iOS 音频录制、播放(本地、网络)

    文章目录一.录音机(AVAudioRecorder)1.简介2.如何使用3.具体实现(开始.暂停.停止.播放 四个功能)4.附件实现demo二.播放音频1.播放本地音频文件(AVAudioPlayer ...

  2. iOS音乐后台播放、锁屏封面及播放控制

    在默认情况下App被切换到后台时,音乐的就停止播放了,但音乐类App的一般都会需要在后台继续播放,这样用户就可以一边听音乐,一边操作其他的App.对于这种情况我们可以对App做一些简单的配置,实现后台 ...

  3. Android okHttp网络请求之缓存控制Cache-Control

    前言: 前面的学习基本上已经可以完成开发需求了,但是在项目中有时会遇到对请求做个缓存,当没网络的时候优先加载本地缓存,基于这个需求我们来学习一直okHttp的Cache-Control. okHttp ...

  4. android 后台播放,实现后台播放  |  Android 开发者  |  Android Developers

    在 TV 设备上观看内容的用户可能会随时决定切换到 TV 启动器.如果用户在使用 TV 播放应用时切换到启动器,默认情况下,此应用会暂停.由于用户没有明确要求暂停播放,因此这种默认行为可能会显得非常突 ...

  5. android h5控制锁屏,WebView播放H5课件时,锁屏解锁后,页面重新绘制的问题

    难题描述:H5页面播放 ,锁屏,解锁后,重新加载了页面,三星不会出现(onpause onstop ,onresume),但在小米.魅族会调用 onpause onstop ondestroy,onr ...

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

    录音: //音频会话 AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *sessionError; /* AVAu ...

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

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

  8. iOS音频的后台播放总结

    在没有网络的情况下,音频的后台播放比较简单,google一下可以搜到很多资料,但是如果每次歌曲的请求都是通过网络,就不成了,有时可以也扛不了几首,这里总结下实现方法,可以实现像电台一样的功能,后台播放 ...

  9. iOS - 音频后台播放设置及锁屏界面的显示与控制

    音频后台播放设置 1.先在项目 的Capabilities中进行设置,开启后台模式 2.激活音频会话 其它地方也可以,只要保证能执行到以下代码块的内容即可,这里我选择在AppDelegate.m里设置 ...

最新文章

  1. 死锁产生条件-不剥夺条件
  2. [Azure] Azure 中国服务使用注意事项及兼容版存储访问工具
  3. [POJ3253]Fence Repair
  4. 【数据挖掘】决策树 分类 ( 抽取分类规则 | 过拟合 | 剪枝 | 先剪 | 后剪 | 连续数值离散化 | 最优化分点 | 增益率选择划分属性 )
  5. VCL界面控件DevExpress VCL Controls发布v18.2.5|附下载
  6. php crc16校验算法,PHP串口通信中计算crc16校验码
  7. Redis集群理论知识
  8. c语言程序设计王新萍课后答案,C语言程序设计教程
  9. vue中el-row使用
  10. Q78:规则网格(Regular Grids)——Ray Tracing中的一种加速技术
  11. Uber如何使用Mesos的?答曰:和Cassandra一起用
  12. NIUDAY 七牛美图 AI 共享日 | 大咖云集 邀您共同探索各场景下的 AI 应用与落地...
  13. OUTEROS常用命令
  14. IOS 中的Notification 学习
  15. struts2入门第一天----------一个简单例
  16. verilog实现四位全加器(基于一位全加器)
  17. c语言谷歌坐标转百度坐标,百度经纬度和google经纬度转换测试
  18. darknet测试voc数据集精度
  19. idea安装findBugs 报idea运行项目报错Cannot run program
  20. 写给新的一年(2015)

热门文章

  1. .NET设计模式(3): 抽象工厂模式
  2. 广西河池计算机考试考什么,2021上半年广西壮族自治区河池市计算机等级考试时间...
  3. 解决JupyterLab中tqdm_notebook进度条不显示问题
  4. 【渗透测试】cookie注入笔记
  5. 【例题+习题】【数值计算方法复习】【湘潭大学】(三)
  6. 对比关系生成模型(Comparative Relation Generative Model)
  7. 非正交坐标系-模态正交的物理及几何意义
  8. Apache HttpClient 4 3开发指南
  9. VueJS实现用户管理系统
  10. SpringBoot执行流程