专业知识分享(iOS)

iOS锁屏控制与后台播放

2019-04-08  本文已影响0人  王沐凡

今天要说的代码在这里【Light & Shadow】(https://github.com/RonbeKing/Light-Shallow/blob/master/Light%20%26%20Shallow/Light%20%26%20Shallow/VideoView/LSVideoPlayerView.m)


我们要实现的功能是在APP进入后台后,仍然可以进行音视频的播放,并且在锁屏情况下进行播放控制。

播放中.png 锁屏.png

1、后台播放

类似QQ音乐的后台音频播放比较简单,因为只有音频,没有视频,可以使用AVAudioPlayer,只需要对AVAudioSession进行一下设置

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    [audioSession setActive:YES error:nil];
然后开启background mode中音频播放就可以了,如下图: capabilities.jpg

到这里就可以锁屏播放音频了。
再复杂一点的情况是,使用AVPlayer进行视频播放时,也希望可以后台播放音频,类似虎牙APP在看直播的时候,APP进入后台,虽然画面看不到了,但依然可以听到直播的声音。这需要额外做两件事,在APP进入后台时,将AVPlayerLayer移除;在APP进入前台时,再次添加AVPlayerLayer。如下:

监听.jpg

到这里实现了后台的音频播放。下面介绍锁屏控制。

2、锁屏控制

锁屏控制分两部分来讲,一是锁屏界面显示,二是锁屏界面控制。

1)锁屏界面显示

设置锁屏界面信息显示,直接看代码就好,就是设置各个参数:

- (void)updateRemoteInfoCenter{
    if (!self.player) {
        return;
    }
    MPNowPlayingInfoCenter* infoCenter = [MPNowPlayingInfoCenter defaultCenter];
    NSMutableDictionary* info = [NSMutableDictionary dictionary];
    // 歌曲名
    [info setObject:@"歌曲名称" forKey:MPMediaItemPropertyTitle];
    [info setObject:@"专辑名称" forKey:MPMediaItemPropertyAlbumTitle];
    // 封面图片
    MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithBoundsSize:CGSizeMake(250, 250) requestHandler:^UIImage * _Nonnull(CGSize size) {
        UIImage* image = [UIImage imageNamed:@"cover3.jpg"];
        return image;
    }];
    [info setObject:artwork forKey:MPMediaItemPropertyArtwork];
    // 设置进度
    NSNumber* duration = @(CMTimeGetSeconds(self.player.currentItem.duration));
    NSNumber* currentTime = @(CMTimeGetSeconds(self.player.currentItem.currentTime));
    if (!duration || !currentTime) {
        return;
    }
    [info setObject:duration forKey:MPMediaItemPropertyPlaybackDuration];
    [info setObject:currentTime forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
    [info setObject:@(self.player.rate) forKey:MPNowPlayingInfoPropertyPlaybackRate];
    
    infoCenter.nowPlayingInfo = info;
}

2)添加播放控制

锁屏界面除了歌曲item的曲目信息,还有播放、暂停、进度控制等,我们需要通过MPRemoteCommandCenter来创建MPRemoteCommand实例,如下:

#pragma mark -- MPRemoteCommandCenter

- (void)addMediaPlayerRemoteCommands{
    MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
    MPRemoteCommand* pauseCommand = [commandCenter pauseCommand];
    [pauseCommand setEnabled:YES];
    [pauseCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
        [self pause];
        return MPRemoteCommandHandlerStatusSuccess;
    }];
    
    MPRemoteCommand* playCommand = [commandCenter playCommand];
    [playCommand setEnabled:YES];
    [playCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
        [self play];
        return MPRemoteCommandHandlerStatusSuccess;
    }];
    
    if (@available(ios 9.1, *)) {
        MPRemoteCommand* changeProgressCommand = [commandCenter changePlaybackPositionCommand];
        [changeProgressCommand setEnabled:YES];
        [changeProgressCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
            MPChangePlaybackPositionCommandEvent * playbackPositionEvent = (MPChangePlaybackPositionCommandEvent *)event;
            CMTime time = CMTimeMakeWithSeconds(playbackPositionEvent.positionTime, self.player.currentItem.duration.timescale);
            [self seekToTime:time];
            return MPRemoteCommandHandlerStatusSuccess;
        }];
    }
}

到这里基本就已经实现了锁屏控制,需要注意的是,在界面销毁时,需要向MPRemoteCommandCenter注销代理,否则会导致界面在内存中无法销毁。

- (void)removeMediaPlayerRemoteCommands{
    MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
    [[commandCenter playCommand] removeTarget:self];
    if (@available(iOS 9.1, *)) {
        [[commandCenter pauseCommand] removeTarget:self];
    }
    [[commandCenter changePlaybackPositionCommand] removeTarget:self];
}
上一篇下一篇

猜你喜欢

热点阅读