使用AVPlayer自定义支持全屏的播放器(三)
2017-02-28 本文已影响1735人
季末微夏
前言
前段时间封装了一个视频播放器使用AVPlayer自定义支持全屏的播放器(二),还有很多没有完善的功能,最近花时间完善了一下,修复了很多bug,也增加了一些功能,最主要的还是使用Masonry重构了播放器的工具条,将工具条单独封装出来,方便大家自己修改。本篇文章主要讲新增加的功能。
新增功能
新增加了视频卡顿监听,加载视频失败处理,增加了视频拉伸方式。
1.视频卡顿监听
很多时候播放视频并不是那么理想的网络环境,这时候为了优化用户体验,我们就需要增加卡顿时候的逻辑,主要思路是增加一个播放器的状态属性,再通过监听播放器的status
,loadedTimeRanges
,playbackBufferEmpty
,playbackLikelyToKeepUp
这几个属性来调用状态属性的set方法,在set方法中集中处理各种不同状态。这里主要借鉴参考了ZFPlayer
监听代码
#pragma mark - 监听
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"status"]) {
if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
self.state = CLPlayerStatePlaying;
}
else if (self.player.currentItem.status == AVPlayerItemStatusFailed) {
self.state = CLPlayerStateFailed;
}
} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
// 计算缓冲进度
NSTimeInterval timeInterval = [self availableDuration];
CMTime duration = self.playerItem.duration;
CGFloat totalDuration = CMTimeGetSeconds(duration);
[self.maskView.progress setProgress:timeInterval / totalDuration animated:NO];
} else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
// 当缓冲是空的时候
if (self.playerItem.playbackBufferEmpty) {
self.state = CLPlayerStateBuffering;
[self bufferingSomeSecond];
}
} else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
// 当缓冲好的时候
if (self.playerItem.playbackLikelyToKeepUp && self.state == CLPlayerStateBuffering){
self.state = CLPlayerStatePlaying;
}
}
}
状态的set方法
- (void)setState:(CLPlayerState)state{
_state = state;
if (state == CLPlayerStateBuffering) {
[self.maskView.activity startAnimating];
}else if (state == CLPlayerStateFailed){
[self.maskView.activity stopAnimating];
NSLog(@"加载失败");
self.maskView.failButton.hidden = NO;
}else{
[self.maskView.activity stopAnimating];
[self playVideo];
}
}
2.视频加载失败处理
和卡顿类似,也是通过监听视频播放状态来实现,在视频加载失败的时候显示一个提示按钮,点击按钮重新加载视频url即可。
加载失败按钮点击事件
#pragma mark - 播放失败按钮点击事件
-(void)cl_failButtonAction:(UIButton *)button{
//重置url
[self setUrl:_url];
//刷新UI
[self setNeedsLayout];
[self layoutIfNeeded];
}
3.视频拉伸方式
AVPlayer的API中就有一个视频拉伸方式,这里只是给了一个初始值简单封装了一下。
封装后的拉伸方式
typedef NS_ENUM(NSInteger,VideoFillMode){
Resize = 0, //拉伸占满整个播放器,不按原比例拉伸
ResizeAspect, //按原视频比例显示,是竖屏的就显示出竖屏的,两边留黑
ResizeAspectFill, //按照原比例拉伸占满整个播放器,但视频内容超出部分会被剪切
};
播放器效果图
效果图1.gif 效果图2.gif 效果图3.gif总结
其实主要的还是完善了很多细节,修改了许多bug,具体请在github下载CLPlayer , 如果喜欢,欢迎star。