美文网首页播放器
利用KTVHTTPCache实现列表视频播放预加载

利用KTVHTTPCache实现列表视频播放预加载

作者: 达摩君 | 来源:发表于2018-10-25 17:45 被阅读359次

新报道公司面试的时候问了一个问题,怎样可以让列表视频下面的5个视频都先加载5秒?当时对AVplayer的了解不够深刻,也没怎么答上来。
所以查阅资料发现官方AVPlayer是可以边播放边下载的~实现AVAssetResourceLoaderDelegate方法,可以截获AVPlayer发出的请求,进而自行控制网络数据的请求和接收,也就能够实现网络数据的自由缓存.
这个时候第一感觉就是多创建几个AVPlayer,让他在后面加载其他几个视频,但这个感觉可能比较繁琐吧,没尝试过~
采用了KTVHTTPCache唱吧开源的第三方缓存。在它的基础改造~
加载时机我初定为缓存时长大于播放时长加上20s来请求其他视频链接,当然完善的还很多,我这边主要检测下效果怎么样。比如判断当前网络情况啊,根据具体情况触发预加载时机,优化的地方还是很多的~

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(AVPlayerItem *)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"status"]) {
        switch (self.player.status) {
            case AVPlayerStatusUnknown:
                NSLog(@"KVO:未知状态,此时不能播放");
                break;
            case AVPlayerStatusReadyToPlay:
                NSLog(@"KVO:准备完毕,可以播放");
                [self.nowCell.activityIndicator stopAnimating];
                [self.player play];
                _playerLayer.frame = self.nowCell.bounds;
                [self.nowCell.bgView.layer addSublayer:_playerLayer];
                break;
            case AVPlayerStatusFailed:
                NSLog(@"KVO:加载失败,网络或者服务器出现问题");
                break;
            default:
                break;
        }
    } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
        NSArray *array = object.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval totalBuffer = startSeconds + durationSeconds;;
        NSLog(@"缓存总时长:%0.2f, 总时长: %0.2f, 已播放时间: %0.2f", totalBuffer, CMTimeGetSeconds(object.duration), self.nowTime);
        if (totalBuffer > self.nowTime + 20) {
            //缓存下面3个视频
            [self cacheNextVideo:self.nowIndex];
        }
    }
}

当然也没有完全加载整个视频,利用range控制加载的范围

for (NSString *url in urlArr) {
        NSString * URLString = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        
        NSString * proxyURLString = [KTVHTTPCache proxyURLStringWithOriginalURLString:URLString];
        
//        NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        NSURLSession *session = [NSURLSession sharedSession];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:proxyURLString]];
        //设置请求头range
        [request setValue:@"bytes" forHTTPHeaderField:@"Accept-Ranges"];
        [request setValue:@"bytes=0-3000000" forHTTPHeaderField:@"Range"];
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
            [task resume];
        });
    }

由于缓存这些第三方框架都给我们实现了,所以基本上只要请求下需要预加载的链接就可以下载到本地目录了,简单测试下来效果很明显。点击下个视频的加载速度,体验都提升了。
接下来就是该好好看看KTVHTTPCache的源码了~
demo地址

官方图 KTVCache.png

参考文档:
iOS基础之GCDAsyncSocket
读懂「 唱吧KTVHTTPCache 」设计思想
iOS--NSNetService和NSNetServiceBrowser(Bonjour网络编程)

相关文章

网友评论

    本文标题:利用KTVHTTPCache实现列表视频播放预加载

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