前言
前段時間封裝了一個視頻播放器使用AVPlayer自定義支持全屏的播放器(二)蚤假,還有很多沒有完善的功能,最近花時間完善了一下吧兔,修復(fù)了很多bug磷仰,也增加了一些功能,最主要的還是使用Masonry重構(gòu)了播放器的工具條境蔼,將工具條單獨封裝出來灶平,方便大家自己修改。本篇文章主要講新增加的功能箍土。
新增功能
新增加了視頻卡頓監(jiān)聽逢享,加載視頻失敗處理,增加了視頻拉伸方式吴藻。
1.視頻卡頓監(jiān)聽
很多時候播放視頻并不是那么理想的網(wǎng)絡(luò)環(huán)境瞒爬,這時候為了優(yōu)化用戶體驗,我們就需要增加卡頓時候的邏輯沟堡,主要思路是增加一個播放器的狀態(tài)屬性侧但,再通過監(jiān)聽播放器的status
,loadedTimeRanges
,playbackBufferEmpty
,playbackLikelyToKeepUp
這幾個屬性來調(diào)用狀態(tài)屬性的set方法,在set方法中集中處理各種不同狀態(tài)航罗。這里主要借鑒參考了ZFPlayer
監(jiān)聽代碼
#pragma mark - 監(jiān)聽
- (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"]) {
// 當(dāng)緩沖是空的時候
if (self.playerItem.playbackBufferEmpty) {
self.state = CLPlayerStateBuffering;
[self bufferingSomeSecond];
}
} else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
// 當(dāng)緩沖好的時候
if (self.playerItem.playbackLikelyToKeepUp && self.state == CLPlayerStateBuffering){
self.state = CLPlayerStatePlaying;
}
}
}
狀態(tài)的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.視頻加載失敗處理
和卡頓類似禀横,也是通過監(jiān)聽視頻播放狀態(tài)來實現(xiàn),在視頻加載失敗的時候顯示一個提示按鈕伤哺,點擊按鈕重新加載視頻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, //按照原比例拉伸占滿整個播放器茫舶,但視頻內(nèi)容超出部分會被剪切
};
播放器效果圖
總結(jié)
其實主要的還是完善了很多細節(jié)戈二,修改了許多bug腕柜,具體請在github下載CLPlayer 彩郊, 如果喜歡毒坛,歡迎star。