IOS后台运行 之 后台播放音乐
来源:互联网 发布:万国数据科技公司电话 编辑:程序博客网 时间:2024/05/16 15:04
http://www.cnblogs.com/easy-coding/p/3569227.html
IOS后台运行 之 后台播放音乐
iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了。如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,AvPlayer播放的话,要实现完美的后台音频播放,依据app的功能需要,可能需要实现几个关键的功能。
首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionCategoryPlayback即可。模式意义及其他模式请参考文档。
1 //后台播放音频设置2 AVAudioSession *session = [AVAudioSession sharedInstance];3 [session setActive:YES error:nil];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在定义的时候自定一些控件可以调节系统的音量大小,不需要用户调整音量按钮。经查看相关的资料总结出有两种方法:
一种是调用控件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 }
一种是监听内核层DarwinNotification,在Darwin中,有很多的系统事件,但apple的api文档描述这些api使用有限制,也就是灰色地带的api,所以能不用则不用;
另一种方法可以通过notify_get_state来获取com.apple.springboard.hasBlankedScreen 的状态值,通过状态值我们可以判断屏幕状态,屏幕亮或者暗系统会给出不同状态值,然后根据状态值,通过NotificationCenter发送消息通知给相应的函数处理。
- IOS后台运行 之 后台播放音乐
- IOS后台运行 之 后台播放音乐
- IOS后台运行 之 后台播放音乐
- IOS后台运行 之 后台播放音乐
- IOS后台运行 之 后台播放音乐
- IOS后台运行 之 后台播放音乐
- IOS后台运行 之 后台播放音乐
- IOS 后台运行 播放音乐
- iOS学习笔记50-IOS后台运行 之 后台播放音乐
- ios后台播放音乐
- iOS后台播放音乐
- ios 音乐后台播放
- iOS后台播放音乐
- iOS后台播放音乐
- iOS后台播放音乐
- iOS后台播放音乐
- iOS后台播放音乐
- iOS后台播放音乐
- 有符号和无符号整型数据溢出问题
- 我爱智慧石!分享咯~
- 关于黑客公司被黑,这些隐情需要知道
- 利用Android studio开发JNI工程
- error C2027: use of undefined type 'A' see declaration of 'A'
- IOS后台运行 之 后台播放音乐
- iOS入门(十四)函数指针
- 关于Python的super用法研究
- gcc/g++使用简介
- 动态规划之 最优二叉搜索数 递归实现
- hdoj 1875 畅通工程再续 【最小生成树】
- UNIX网络编程卷一:第十一章 名字与地址转换
- 一个清华学生留学香港后对人生的思考
- hdu 1863 畅通工程【kruskal & prim】