iOS音乐后台播放、锁屏封面及播放控制
在默认环境下App被切换到后台时,音乐的就停止播放了,但音乐类App的一般都会需要在后台继续播放,这样用户就可以一边听音乐,一边操作其他的App。对于这种情况我们可以对App做一些简单的配置,实现后台播放功能。当app切换到后台,用户就无法控制和查看app当前播放歌曲了。这个对于用户来说并不是很友好。既然是后台播放,那么就应该提供便捷的播放控制方式。iOS系统已经预留了接口,允许开发者在锁屏界面显
在默认情况下App被切换到后台时,音乐的就停止播放了,但音乐类App的一般都会需要在后台继续播放,这样用户就可以一边听音乐,一边操作其他的App。对于这种情况我们可以对App做一些简单的配置,实现后台播放功能。
当app切换到后台,用户就无法控制和查看app当前播放歌曲了。这个对于用户来说并不是很友好。既然是后台播放,那么就应该提供便捷的播放控制方式。iOS系统已经预留了接口,允许开发者在锁屏界面显示播放歌曲信息(以下称为锁屏封面),以及在底部菜单栏提供播放控制器。下面我们就来给App添加这些功能吧。
一、后台播放
然后再程序中添加入下代码:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
二、添加播放控制器(Remote Control Events)
首先我们要告诉系统,我要接受系统的播放控制消息,这样系统才会给我们发送播放控制命令。流程是这样的:
App启动 -> 告诉系统我需要接受播放控制消息 -> 等待 -> 用户点击系统播放控制器按钮 -> 系统传递消息给App -> 我们接受到消息,做出相应的响应。
想要接收播放控制消息,我们必须要做三件事:
- 成为Frist Responder
- 请求系统,要求开始监听播放控制消息(Remote Control Events)
- 开始播放音频。
请注意第三点,我们的App必须在开始播放音频后,才能收到控制消息。否则,即使你满足了前两点,也无法接收到控制消息。
//AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//告诉系统,我们要接受远程控制事件
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
/// 系统回调接受远程事件
/// @param event event
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
[self ul_remoteControlReceivedWithEvent:event];
}
//响应远程音乐播放控制消息
- (void)ul_remoteControlReceivedWithEvent:(UIEvent *)event {
if(event.type == UIEventTypeRemoteControl) {// 判断是否远程控制
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:// 播放
[self playActionDealWith];
break;
case UIEventSubtypeRemoteControlPause:// 暂停
[self pauseActionDealWith];
break;
case UIEventSubtypeRemoteControlNextTrack:// 下一首
[self nextTrackActionDealWithAutoEnd:NO];
[self resetCloseUntilCurrentDone];
break;
case UIEventSubtypeRemoteControlPreviousTrack:// 上一首
[self previousTrackActionDealWith];
[self resetCloseUntilCurrentDone];
break;
case UIEventSubtypeRemoteControlTogglePlayPause:
if ([ULRadioDramaPlayerManager shareInstance].isPlaying) {
[self pauseActionDealWith];
}else{
[self playActionDealWith];
}
break;
default:
break;
}
ULLogInfo(@"锁屏状态操作类型:%ld",(long)event.subtype);
}
}
播放音频的代码,这里给出一段简单的示例:
- (void)playBtnClicked{
NSError *error = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:@"music" ofType:@"mp3"];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:&error];
if (error) {
NSLog(@"Error:%@", [error localizedDescription]);
}
[player play];
}
在开始播放音频后,使用耳机线控的播放暂停等按键,或者锁屏封面上的播放控制按键,就能够收到控制消息了。
关于耳机线控的一点说明
苹果耳机的线控上有三个按钮:加号,中部,减号。其中加号和减号是用于控制音量,这两个按钮点击是收不到消息的——UIEventSubtype没有音量改变的事件类型。而中部按钮的点击,是可以收到消息的,按一下是播放/暂停切换,快按两下是播放下一首,快按三下是播放上一首,快按两下并摁住是快进,快按三下并摁住是快退。
三、在锁屏界面显示播放歌曲信息
代码如下,其实就是设置一个全局变量的值,当系统处于音乐播放状态时,锁屏界面就会将NowPlayingInfo中的信息展示出来。可惜的是,这里的定制性不是太强,例如歌曲图片无法平铺整个屏幕大小,根据我的测试,歌曲图片在320×320时,可以完整显示在屏幕中央位置,两侧不会留下黑边。
#import <MediaPlayer/MediaPlayer.h>
- (void)updatePlayInfo {
NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];
UIImage *image = [UIImage imageNamed:@"image"];
MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:image];
//歌曲名称
[songInfo setObject:@"深夜地下铁" forKey:MPMediaItemPropertyTitle];
//演唱者
[songInfo setObject:@"陶钰玉" forKey:MPMediaItemPropertyArtist];
//专辑名
[songInfo setObject:@"深夜地下铁" forKey:MPMediaItemPropertyAlbumTitle];
//专辑缩略图
[songInfo setObject:albumArt forKey:MPMediaItemPropertyArtwork];
[songInfo setObject:[NSNumber numberWithDouble:10.0] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; //音乐当前已经播放时间
[songInfo setObject:[NSNumber numberWithFloat:1.0] forKey:MPNowPlayingInfoPropertyPlaybackRate];//进度光标的速度 (这个随 自己的播放速率调整,我默认是原速播放)
[songInfo setObject:[NSNumber numberWithDouble:30.0] forKey:MPMediaItemPropertyPlaybackDuration];//歌曲总时间设置
// 设置锁屏状态下屏幕显示音乐信息
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
}
经过了如上配置后,程序应该就能够正常显示了。
简单demo地址 : 音频后台播放、锁屏封面及播放控制
发现一个系统特性, 正常启动app并开始播放, 这时候会把锁屏信息设置上, 然后在退后台, 把app杀死, 此时锁屏信息被系统清理掉, 目前都是正常且符合预期的,
但是通过系统工具栏点击播放, 此时系统会默默的启动上一次设置播放信息的app, 并调用remoteControlReceivedWithEvent:尝试再次播放音频,如果app记录了上次播放的音频地址,那就可以做到再次播放,当然player也需要重新初始化,并且再次点击app, 发现这次启动是一次热启动, app已经在首页位置了.
但是一般用户看到工具栏上什么信息都没有也是不会点的,点击了也不会有预期上次的音频继续播放,所以这个就作为一个iOS的小特性吧.
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)