iOS 4開始引入的multitask。我们能够实现像ipod程序那样在后台播放音频了。

假设音频操作是用苹果官方的AVFoundation.framework实现。像用AvAudioPlayer。AvPlayer播放的话。要实现完美的后台音频播放,根据app的功能须要。可能须要实现几个关键的功能。

首先,播放音频之前先要设置AVAudioSession模式。通常仅仅用来播放的App能够设为AVAudioSessionCategoryPlayback就可以。模式意义及其它模式请參考文档。

  1. 1 //后台播放音频设置
  2. 2 AVAudioSession *session = [AVAudioSession sharedInstance];
  3. 3 [session setActive:YES error:nil];
  4. 4 [session setCategory:AVAudioSessionCategoryPlayback error:nil];

1.通知IOS该app支持background audio。缺省情况下,当按下home键时。当前正在执行的程序被suspend,状态从active变成in-active。也就是说假设正在播放音频,按下HOME后就会停止。这里须要让app在按在HOME后。转到后台执行而非被suspend,解决的方法是在程序的-info.plist中添加required background modes这个key项。并选择App plays audio or streams audio/video using AirPlay这个value项(假设用过Xcode5.0,在TARGETS-Capabilities-Background
Modes设置为ON,勾选Audio and AirPlay选项)。

2.假设你在后台播放使用的时载入网络音频,恰巧网速非常慢,音频被停止下来这时候程序也随之suspend。以前有山寨的解决的方法是专门起一个player的实例连续不停的放同一无声音片断,阻止程序被suspend。

这里提供的方法是通过申请后台taskID达到后台切换播放文件的功能。

即使声明taskID也最多仅仅能在后台执行600秒钟。

(在ios7sdk中能够使用NSURLSession来实现后台缓冲)

(普通情况下。按HOME将程序送到后台,能够有5或10秒时间能够进行一些收尾工作,详细时间[[UIApplication sharedApplication] backgroundTimeRemaining]返回值,超时后app会被suspend。

3.ipod播放程序在后台时,双击HOME键,会有个控制界面。能够对它进行播放控制(暂停開始、上一曲、下一曲)。假设您想让您的app能够像ipod一样在后台也能够方便的通过双击HOME键来控制(在ios7中是使用上拉菜单控制)。就要用到远程控制事件了。

首先在viewdidload等初始化的地方声明App接收远程控制事件。并在对应地方结束声明

  1. - (void) viewWillAppear:(BOOL)animated
  2. {
  3. [super viewWillAppear:animated];
  4. [UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  5. [self becomeFirstResponder];
  6. }
  7.  
  8. - (void) viewWillDisappear:(BOOL)animated
  9. {
  10. [super viewWillDisappear:animated];
  11. [UIApplication sharedApplication] endReceivingRemoteControlEvents];
  12. [self resignFirstResponder];
  13. }
  14.  
  15. - (BOOL)canBecomeFirstResponder
  16. {
  17. return YES;
  18. }

当然也不一定是在viewcontroller中,也能够是在applicationDidEnterBackground:方法中開始接受远程控制。applicationDidBecomeActive:中结束接受远程控制,可是当前的appdelegate中要继承与UIResponder。由于在激活远程控制以后要把当前类变成第一响应,重写canBecomeFirstResponder方法。

最后定义 remoteControlReceivedWithEvent,处理详细的播放、暂停、前进、后退等详细事件

  1. //重写父类方法。接受外部事件的处理
  2. - (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
  3. if (receivedEvent.type == UIEventTypeRemoteControl) {
  4.  
  5. switch (receivedEvent.subtype) {
  6.  
  7. case UIEventSubtypeRemoteControlTogglePlayPause:
  8. [self playAndStopSong:self.playButton];
  9. break;
  10.  
  11. case UIEventSubtypeRemoteControlPreviousTrack:
  12. [self playLastButton:self.lastButton];
  13. break;
  14.  
  15. case UIEventSubtypeRemoteControlNextTrack:
  16. [self playNextSong:self.nextButton];
  17. break;
  18.  
  19. case UIEventSubtypeRemoteControlPlay:
  20. [self playAndStopSong:self.playButton];
  21. break;
  22.  
  23. case UIEventSubtypeRemoteControlPause:
  24. [self playAndStopSong:self.playButton];
  25. break;
  26.  
  27. default:
  28. break;
  29. }
  30. }
  31. }

其他外部事件也可通过这样的方式实现。如“摇一摇”响应等。

4. 至此,您有播放App已经基本完毕了,其次插拔耳机是否响应停止播放时间须要进一步研究耳机检測和声音路由切换的问题,再次不具体讲述。

5. 另一些开发人员可能会发现,有一些音视频app在定义的时候自定一些控件能够调节系统的音量大小,不须要用户调整音量button。经查看相关的资料总结出有两种方法:

一种是调用控件MPVolumeView在屏幕中创建一个音量条。拖动能够改变系统的音量大小。

还有一种是使用MPMusicPlayerController类,能够自己定义控件调整系统音量的大小(可是在ios7sdk中已经被弃用。预计以后几个版本号中可能找不到这种方法了)。

  1. MPMusicPlayerController *mpc = [MPMusicPlayerController applicationMusicPlayer];
  2. mpc.volume = 0; //0.0~1.0

6. 在一些其它的音乐播放软件中如:酷我、qq音乐等,你会发在播放的时候。当设备锁屏以后依旧能够看到用户播放的音乐名称、演唱者、专辑名称、音乐时长、专辑图片等信息。

这些就须要在用户切换完歌去的时候,在程序中设置信息了。

  1. //设置锁屏状态,显示的歌曲信息
  2. -(void)configNowPlayingInfoCenter{
  3. if (NSClassFromString(@"MPNowPlayingInfoCenter")) {
  4. NSDictionary *info = [self.musicList objectAtIndex:_playIndex];
  5. NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
  6.  
  7. //歌曲名称
  8. [dict setObject:[info objectForKey:@"name"] forKey:MPMediaItemPropertyTitle];
  9.  
  10. //演唱者
  11. [dict setObject:[info objectForKey:@"singer"] forKey:MPMediaItemPropertyArtist];
  12.  
  13. //专辑名
  14. [dict setObject:[info objectForKey:@"album"] forKey:MPMediaItemPropertyAlbumTitle];
  15.  
  16. //专辑缩略图
  17. UIImage *image = [UIImage imageNamed:[info objectForKey:@"image"]];
  18. MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:image];
  19. [dict setObject:artwork forKey:MPMediaItemPropertyArtwork];
  20.  
  21. //音乐剩余时长
  22. [dict setObject:[NSNumber numberWithDouble:self.player.duration] forKey:MPMediaItemPropertyPlaybackDuration];
  23.  
  24. //音乐当前播放时间 在计时器中改动
  25. //[dict setObject:[NSNumber numberWithDouble:0.0] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
  26.  
  27. //设置锁屏状态下屏幕显示播放音乐信息
  28. [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
  29. }
  30. }

上面的if (NSClassFromString(@”MPNowPlayingInfoCenter”))语句,说是为了避免了版本号兼容问题,这个API貌似仅仅出如今5里面。

7. 以下就在计时器中不断刷新锁屏状态下的播放进度条了。

  1. //计时器改动进度
  2. - (void)changeProgress:(NSTimer *)sender{
  3. if(self.player){
  4. //当前播放时间
  5. NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[[MPNowPlayingInfoCenter defaultCenter] nowPlayingInfo]];
  6. [dict setObject:[NSNumber numberWithDouble:self.player.currentTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; //音乐当前已经过时间
  7. [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
  8.  
  9. }
  10. }

8. 当前的非常多常见的播放器都能够在锁屏状态下显示显示歌词,经过一番查找后,最终找到方法(详情:点击查看)。大致就是依据播放的时间和歌词显示时间。利用计时器不断的用歌词和专辑封面合成图片。达到显示歌词的效果。还有就是在屏幕变暗停止这一操作、屏幕点亮的时候開始计时器,以节省电量和cpu,有两种方法能够监听上述现象:

一种是监听内核层DarwinNotification,在Darwin中,有非常多的系统事件,但apple的api文档描写叙述这些api使用有限制,也就是灰色地带的api,所以能不用则不用;

还有一种方法能够通过notify_get_state来获取com.apple.springboard.hasBlankedScreen 的状态值。通过状态值我们能够推断屏幕状态,屏幕亮或者暗系统会给出不同状态值,然后依据状态值。通过NotificationCenter发送消息通知给对应的函数处理。

from:http://www.cnblogs.com/easy-coding/p/3569227.html

IOS 后台执行 播放音乐的更多相关文章

  1. IOS 后台执行

    在IOS后台执行是本文要介绍的内容,大多数应用程序进入后台状态不久后转入暂停状态.在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除.应用程序提供特定的服务,用户可以请求后台执行时间 ...

  2. IOS后台执行

    大多数应用程序进入后台状态不久后转入暂停状态.在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除.应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务. 判断是否支持多线 ...

  3. IOS开发之----详解在IOS后台执行

    文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间. 还有三种类型的可以运行在后以,1.音乐2.location 3.voip 文二 ...

  4. IOS后台执行机制 与 动作

    当用户按下"Home"键或者系统启动另外一个应用时,前台foreground应用首先切换到Inactive状态,然后切换到Background状态.此转换将会导致先后调用应用代理的 ...

  5. MUI---IOS切换到后台继续播放音乐

    应用切换到后台继续音乐播放HBuilder默认生成的应用在iOS是不支持后台音乐播放的,当应用切换到后台时音乐将暂停播放,下次切换到前台继续播放.如果要支持应用切换到后台后继续播放音乐功能需要进行额外 ...

  6. iOS后台运行播放无声音频 测试可行

    如果打回来了,就自认倒霉吧 制作无声音频. @interface AppDelegate () { NSInteger count; } @property(strong, nonatomic)NST ...

  7. ios微信自动播放音乐

    <!DOCTYPE html> <html> <head lang="en">     <meta charset="UTF-8 ...

  8. iOS后台运行

    http://www.cocoachina.com/bbs/read.php?tid=149564 文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后 ...

  9. iOS 后台运行实现 --备用

    文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间. 还有三种类型的可以运行在后以,1.音乐2.location 3.voip 文二 ...

随机推荐

  1. Jetty:配置概览-须要配置什么

    上一节讲述了怎么配置Jetty,这节将告诉你使用Jetty你须要配置些什么. 配置Server Server实例是Jetty服务端的中心协调对象,它为全部其它Jetty服务端组件提供服务和生命周期管理 ...

  2. c#--foreach遍历的用法与split的用法

    一. foreach循环用于列举出集合中所有的元素,foreach语句中的表达式由关键字in隔开的两个项组成.in右边的项是集合名,in左边的项是变量名,用来存放该集合中的每个元素.      该循环 ...

  3. QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)

    QThread 继承 QObject..它可以发送started和finished信号,也提供了一些slot函数. QObject.可以用于多线程,可以发送信号调用存在于其他线程的slot函数,也可以 ...

  4. GDSOI2015 task4 ACU

    题目大意 只要你有耐心看完题目,你就可以得到以下模型: 给出一个有向图,有若干询问,每次询问对于某条边\((v,u)\),求删掉这条边后,\(v\)到\(u\)的最短路. 算法1 暴力出奇迹,期望得分 ...

  5. Android Camera系列开发 (二)通过Intent录制视频

    Android Camera系列开发 (二)通过Intent录制视频 作者:雨水  2013-8-18 CSDN博客:http://blog.csdn.net/gobitan/ 概述 使用Camera ...

  6. [Android系列—] 1. Android 开发环境搭建与Hello World

    前言 開始之前先熟悉几个名词: SDK -- Software Development Kit, 软件开发工具包.这个词并不陌生, JDK,就是Jave Development Kit,相同对于And ...

  7. Mysql zip 安装(windows)

    Mysql Windows zip包安装 Mysql 下载地址: http://dev.mysql.com/downloads/mysql/ 下载windows 版本对应的zip,之后解压 在C:\P ...

  8. 2014 I/O归来:Google连接一切

    6月,WWDC 2014与Google I/O  (大部分演讲视频都公开.Youtube须要FQ,很值得一看)相继召开.今年是我第三年參加Google I/O大会. 三年间.Google积累了非常多技 ...

  9. Scala中Stream的应用场景及事实上现原理

    欢迎訪问我的独立博客:http://cuipengfei.me/blog/2014/10/23/scala-stream-application-scenario-and-how-its-implem ...

  10. 图解C#_事件

    概述 今天用来演示事件的例子是模拟实现一个文件下载类,在这个类中我将定义一个DownLoad事件,这个事件用来在文件下载的过程中,向订阅这个事件的用户发出消息,而这个消息将用DownLoadEvent ...