美文网首页
AVPlayer无缝切换源

AVPlayer无缝切换源

作者: 黑暗森林的歌者 | 来源:发表于2018-08-02 11:42 被阅读195次

    AVPlayer无缝切换源

    很多时候播放视频都有视频清晰度的需求,用户自己选择想要观看的分辨率.

    一般切换清晰度就是切换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) {
            // 隐藏视频截图
        }
    }
    

    相关文章

      网友评论

          本文标题:AVPlayer无缝切换源

          本文链接:https://www.haomeiwen.com/subject/onyjvftx.html