上篇文章做了后台播放切歌处理
目前手机播放音乐锁屏后的效果:
除了音量条外,上面的三个媒体按钮都是无效的,而且没有任何显示,接下来做锁屏处理
锁屏时的UI部分内容也是需要实时更新的,所以封装一个更新锁屏视图UI方法,在定时器的计时方法中,调用锁屏处理方法
这里需要使用到<MediaPlayer/MediaPlayer.h>类库
1.导入<MediaPlayer/MediaPlayer.h>头文件
音视频处理,和AVFoundation类似
2.设置正在播放信息中心
#pragma mark -- 更新锁屏UI
- (void)updateLockedUI{
// 获取当前的歌曲
JSMusicModel *music = self.musicList[self.currentMusicIndex];
// 设置锁屏界面 设置正在播放中心
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
// 设置数据
// 设置封面图片
MPMediaItemArtwork *artworkImage = [[MPMediaItemArtwork alloc]initWithImage:[UIImage imageNamed:music.image]];
center.nowPlayingInfo = @{
MPMediaItemPropertyAlbumTitle:music.album,
MPMediaItemPropertyArtist:music.singer,
MPMediaItemPropertyArtwork:artworkImage,
MPMediaItemPropertyPlaybackDuration:@([JSMusciManager sharedMusicManager].duration),
MPMediaItemPropertyTitle:music.name,
MPNowPlayingInfoPropertyElapsedPlaybackTime:@([JSMusciManager sharedMusicManager].currentTime)
};
/* 设置数据时对应的Key
currently supported include 主要的
// MPMediaItemPropertyAlbumTitle 专辑标题
// MPMediaItemPropertyAlbumTrackCount 专辑歌曲数
// MPMediaItemPropertyAlbumTrackNumber 专辑歌曲编号
// MPMediaItemPropertyArtist 艺术家/歌手
// MPMediaItemPropertyArtwork 封面图片 MPMediaItemArtwork类型
// MPMediaItemPropertyComposer 作曲
// MPMediaItemPropertyDiscCount 专辑数
// MPMediaItemPropertyDiscNumber 专辑编号
// MPMediaItemPropertyGenre 类型/流派
// MPMediaItemPropertyPersistentID 唯一标识符
// MPMediaItemPropertyPlaybackDuration 歌曲时长 NSNumber类型
// MPMediaItemPropertyTitle 歌曲名称
Additional metadata properties 额外的
MP_EXTERN NSString *const MPNowPlayingInfoPropertyElapsedPlaybackTime 当前时间 NSNumber
MP_EXTERN NSString *const MPNowPlayingInfoPropertyPlaybackRate
MP_EXTERN NSString *const MPNowPlayingInfoPropertyDefaultPlaybackRate
MP_EXTERN NSString *const MPNowPlayingInfoPropertyPlaybackQueueIndex
MP_EXTERN NSString *const MPNowPlayingInfoPropertyPlaybackQueueCount
MP_EXTERN NSString *const MPNowPlayingInfoPropertyChapterNumber
MP_EXTERN NSString *const MPNowPlayingInfoPropertyChapterCount
MP_EXTERN NSString *const MPNowPlayingInfoPropertyAvailableLanguageOptions MPNowPlayingInfoLanguageOptionGroup
MP_EXTERN NSString *const MPNowPlayingInfoPropertyCurrentLanguageOptions
*/
}
这样设置完成后,在锁屏时就会实时显示基本信息了
3.设置锁屏界面显示歌词
因为MPNowPlayingInfoCenter的nowPlayingInfo属性的Key中没有预留歌词的设置,目前我们根据计时器方法实时更新数据,可以将歌词绘制到专辑图片上,达到显示歌词的效果
继续封装一个方法,用来绘制锁屏界面的图片
在设置nowPlayingInfo的时候,使用自定义的方法获取带有歌词的图片
再通过设置MPMediaItemPropertyArtwork的Key值,实现显示歌词的效果
// 设置封面图片 (自定义方法绘制带歌词的图片)
MPMediaItemArtwork *artworkImage = [[MPMediaItemArtwork alloc]initWithImage:[self createImage]];
static CGFloat const kJSLyricLockedLabelHeight = 40;//锁屏界面歌词Label高度
获取带有歌词的专辑图片方法:
#pragma mark -- 绘制带有歌词的专辑图片
- (UIImage *)createImage{
// 获取当前歌曲的封面图片
JSMusicModel *currentMusicModel = self.musicList[self.currentMusicIndex];
UIImage *currentMusicImage = [UIImage imageNamed:currentMusicModel.image];
// 获取当前歌曲正在播放的那句歌词
JSLyricModel *currentLyricModel = self.lyricModelArray[self.currentLyricIndex];
// 设置尺寸 (需要考虑横竖屏,取宽、高中的最小值,设置一个正方形)
CGFloat imgageWidthAndHeight = MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
// 开启一个bitmap类型图形上下文 (参数1:大小 参数2:是否不透明 参数3:缩放比 0.0代表当前设备缩放比)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(imgageWidthAndHeight, imgageWidthAndHeight), YES, 0.0);
// 将封面图片绘制到图形上下文
[currentMusicImage drawInRect:CGRectMake(0, 0, imgageWidthAndHeight, imgageWidthAndHeight)];
// 设置歌词填充色
[[UIColor whiteColor] setFill];
// 将歌词绘制到图形上下文
[currentLyricModel.content drawInRect:CGRectMake(0, imgageWidthAndHeight - kJSLyricLockedLabelHeight, imgageWidthAndHeight, kJSLyricLockedLabelHeight) withFont:[UIFont systemFontOfSize:17] lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter];
// 从图形上下文获取图片
UIImage *ImageWithLyric = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图形上下文
UIGraphicsEndImageContext();
// 返回带有歌词的图片
return ImageWithLyric;
}
这样锁屏界面显示歌词也就实现了
4.锁屏界面媒体按钮处理
回到控制器接收锁屏界面媒体按钮的点击事件
实现remoteControlReceivedWithEvent:(UIEvent *)event方法
通过UIEvent的subtype属性(枚举类型),判断当前接收到的事件类型
分别调用播放/暂停按钮点击事件、下一曲按钮点击事件和上一曲按钮点击事件即可
#pragma mark -- 当接收到远程控制事件时调用(锁屏按钮,耳机线控等)
- (void)remoteControlReceivedWithEvent:(UIEvent *)event{
/*
UIEventSubtypeNone = 0,
// for UIEventTypeMotion, available in iPhone OS 3.0
UIEventSubtypeMotionShake = 1, 摇晃事件(从iOS3.0开始支持此事件)
// for UIEventTypeRemoteControl, available in iOS 4.0 从iOS4.0开始支持远程控制事件
UIEventSubtypeRemoteControlPlay = 100, 播放事件【操作:停止状态下,按耳机线控中间按钮一下】
UIEventSubtypeRemoteControlPause = 101, 暂停事件
UIEventSubtypeRemoteControlStop = 102, 停止事件
UIEventSubtypeRemoteControlTogglePlayPause = 103, --> 播放或者暂停
UIEventSubtypeRemoteControlNextTrack = 104, --> 下一曲
UIEventSubtypeRemoteControlPreviousTrack = 105, --> 上一曲
UIEventSubtypeRemoteControlBeginSeekingBackward = 106, 快退开始【操作:按耳机线控中间按钮三下不要松开】
UIEventSubtypeRemoteControlEndSeekingBackward = 107, 快退停止【操作:按耳机线控中间按钮三下到了快退的位置松开】
UIEventSubtypeRemoteControlBeginSeekingForward = 108, 快进开始【操作:按耳机线控中间按钮两下不要松开】
UIEventSubtypeRemoteControlEndSeekingForward = 109, 快进停止【操作:按耳机线控中间按钮两下到了快进的位置松开】
*/
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay: // 播放
[[JSMusciManager sharedMusicManager].audioPlayer play];
break;
case UIEventSubtypeRemoteControlPause: // 暂停
[[JSMusciManager sharedMusicManager].audioPlayer pause];
break;
case UIEventSubtypeRemoteControlNextTrack: // 下一曲
[self clickNextButton:self.nextButton];
break;
case UIEventSubtypeRemoteControlPreviousTrack: // 上一曲
[self clickPreviousButton:self.previousButton];
break;
default:
break;
}
}
视图中自定义的媒体按钮(播放暂停按钮)是通过修改button的selected状态实现的,这里我在音乐播放单例工具类中,将audioPlayer属性提到了.h文件中,这样在控制器下通过单例可以直接访问,通过audioPlay的pause/play属性操控播放器的暂停和播放,也可以调用自己封装的播放/暂停方法,两种方式来实现播放/暂停功能
// 方式一:
[[JSMusciManager sharedMusicManager].audioPlayer pause];
[[JSMusciManager sharedMusicManager].audioPlayer play];
// 方式二:
[self clickPlayButton:self.playButton];
这样锁屏界面的媒体按钮点击事件也处理完成,至此锁屏处理设置完成