suifengqjn/TBPlayer

视频卡住和无法保存

Opened this issue · 4 comments

我在使用这个播放器的时候,发现了一些问题,会导致视频卡住和无法保存

大概是视频正在加载时,连续调整进度条的位置(当前缓存的位置还大300k),会触发TBVideoRequestTask

  • (void)setUrl:(NSURL *)url offset:(NSUInteger)offset;

方法,去发送新的网络请求,但旧的请求并没有取消

从而导致之前的网络请求依然在回调方法

  • (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

里返回了,而你在这个回调方法里执行了[self.taskArr addObject:connection],导致**数组self.taskArr里含有不止一个对象**。

从而导致在回调方法

  • (void)connectionDidFinishLoading:(NSURLConnection *)connection;

里,执行保存的时候由于判断了if (self.taskArr.count < 2)但返回false,所以视频无法保存。

与此同时由于旧的网络还在回调,会导致视频获取到不合适的数据,引发了卡顿的现象。

还有我在使用了一些视频url的时候,视频在开头的时候就会连续执行了TBloaderURLConnection类里的回调方法

  • (void)dealWithLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest;

而且前几次执行判断self.task.offset + self.task.downLoadingOffset + 1024 * 300 < range.location的判断的时候,返回都为true,我还不知道这是为什么,但也导致了连续执行setUrl: offset:的方法,所以这些视频总会在一开始前几秒就卡住。

最后的最后,这真的是一个好的项目,我在看到这个之前也在使用在App里开启httpSever的方法,但这个项目真的聪明很多,我受益了不少!!

缓存机制是这样的,如果self.taskArr.count只有在一个的情况下才进行保存,因为只有在这种情况下视频的数据才是完整的。例如现在正常缓存到10分钟的位置,而你拖动到20分钟的位置,那么会终止原先的connection,新建立一个从20分钟位置开始请求的connection,然后把得到的数据补充给播放器。第二点:在拖动的情况下,会产生好多个loadingRequest,有好多没有finish,也没有从pendingRequests数组中移除,但是这个不受影响。我试过把一些"多余"的loadingRequest给移除了,但是效果是一样的,为了保险,我最后还是保留了。拖动的时候大于当前300k再建立新connection,可以根据自己的需求改动。我建议这里可以适当的调大一点。这个demo我自己也是研究了一段时间,我也是走了不少的坑,当然里面也还有很多不足之处,至于你说的卡顿现象,在我调试的时候我觉得应该是解决了的。有时间我会继续完善的,如果你有好的建议或改动,还请联系我

噢,关于上面的第二条,我有个新的疑问,关于这个回调方法

  • (void)dealWithLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest;

每次请求数据的时候,应该都是请求一定数据量的,有时候在某个点上网络不太给力,然后触发这个回调的时候,假设刚好请求了几百k,而这时候这点和正在播放的点的的距离超过了设置的300k,这个时候就会触发新的connection去请求,但这个请求并不是因为手动调整了进度条而触发的,视频是无间断播放的。

我觉得这里还是可以优化一下,不光是判断超过300k的,还应该判断一下这个请求是不是拖动进度条触发的,否则有时候从头到尾播放完了一个视频,但最后没有缓存到。

楼上说的触发新的请求,其实可以不用这样去考虑,如果回来的数据位置和自己请求的位置不对应有两种可能:1.自己选取的点位的包还没到,但是后面的数据包到了;2.视频切片没有锁定到这个点,直接反悔了后面的包;
所以可以考虑直接以返回第一个包的位置为新的选取点,将视觉上拖拽后的进度条进行重调;就类似于AVPlayer seekToTime方法一样其实并不能准确定位到某个时间点,而是定位到附近的关键帧一样

我在使用这个播放器的时候,发现了一些问题,会导致视频卡住和无法保存

大概是视频正在加载时,连续调整进度条的位置(当前缓存的位置还大300k),会触发TBVideoRequestTask

  • (void)setUrl:(NSURL *)url offset:(NSUInteger)offset;

方法,去发送新的网络请求,但旧的请求并没有取消

从而导致之前的网络请求依然在回调方法

  • (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

里返回了,而你在这个回调方法里执行了[self.taskArr addObject:connection],导致**数组self.taskArr里含有不止一个对象**。

从而导致在回调方法

  • (void)connectionDidFinishLoading:(NSURLConnection *)connection;

里,执行保存的时候由于判断了if (self.taskArr.count < 2)但返回false,所以视频无法保存。

与此同时由于旧的网络还在回调,会导致视频获取到不合适的数据,引发了卡顿的现象。

还有我在使用了一些视频url的时候,视频在开头的时候就会连续执行了TBloaderURLConnection类里的回调方法

  • (void)dealWithLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest;

而且前几次执行判断self.task.offset + self.task.downLoadingOffset + 1024 * 300 < range.location的判断的时候,返回都为true,我还不知道这是为什么,但也导致了连续执行setUrl: offset:的方法,所以这些视频总会在一开始前几秒就卡住。

最后的最后,这真的是一个好的项目,我在看到这个之前也在使用在App里开启httpSever的方法,但这个项目真的聪明很多,我受益了不少!!

对于卡顿最后是如何解决的?我也发现了这个问题