音乐播放器-锁屏处理 - (Obj-C)

上篇文章做了后台播放切歌处理

目前手机播放音乐锁屏后的效果:

音乐播放器-锁屏处理 - (Obj-C)_第1张图片
锁屏处理_01.PNG

除了音量条外,上面的三个媒体按钮都是无效的,而且没有任何显示,接下来做锁屏处理

锁屏时的UI部分内容也是需要实时更新的,所以封装一个更新锁屏视图UI方法,在定时器的计时方法中,调用锁屏处理方法
这里需要使用到类库

1.导入头文件
音视频处理,和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
     */

}

这样设置完成后,在锁屏时就会实时显示基本信息了

锁屏处理_02.PNG

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;
}

这样锁屏界面显示歌词也就实现了

锁屏处理_03.PNG

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];

这样锁屏界面的媒体按钮点击事件也处理完成,至此锁屏处理设置完成

你可能感兴趣的:(音乐播放器-锁屏处理 - (Obj-C))