很多时候播放视频都有视频清晰度的需求,用户自己选择想要观看的分辨率.
一般切换清晰度就是切换NSURL
,需要重新加载视频,如果不做处理就会出现没有图像的黑屏,其实这是不是bug。如下图这样:
1、其实做出类似无缝切换的效果也不是难事,可以在切换的时候获取当前播放时间点的视频截图,然后用一个UIImageView
覆盖到当前的view
上
- (void)showVideoShotImage {
// 获取当前player的 sset
AVAsset *currentPlayerAsset = self.player.currentItem.asset;
if ([currentPlayerAsset isKindOfClass:AVURLAsset.class]) {
// 判断是否是 AVURLAsset,并转成 AVURLAsset
AVURLAsset *asset = (AVURLAsset *)currentPlayerAsset;
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = YES;
// 获取当前播放到的时间点
CMTime time = CMTimeMakeWithSeconds(self.playingTime, 600);
NSError *error = nil;
CMTime actualTime;
// 获取当前时间点的视频截图
CGImageRef image = [generator copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *shotImage = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);
self.ShotImageView.image = shotImage;
}
}
2、当视频缓冲的进度大于等于当前播放的时间,就开始播放视频,同时隐藏覆盖的视频截图,这时候的效果就类似无缝切换。
/**
处理观察到都播放器的状态数据
*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
AVPlayerItem *item = object;
if ([keyPath isEqualToString:@"status"]) {// 播放状态
} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {// 缓冲进度
[self handleLoadedTimeRangesWithPlayerItem:item];
} else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {// 跳转后没数据
} else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {// 跳转后有数据
}
}
/** 处理缓冲进度 */
- (void)handleLoadedTimeRangesWithPlayerItem:(AVPlayerItem *)item {
NSArray *loadArray = item.loadedTimeRanges;
CMTimeRange range = [[loadArray firstObject] CMTimeRangeValue];
float start = CMTimeGetSeconds(range.start);
float duration = CMTimeGetSeconds(range.duration);
NSTimeInterval totalTime = start + duration;// 缓存总长度
if (totalTime >= self.playingTime) {
// 隐藏视频截图
}
}
网友评论