我有一个AVPlayer在播放一个大小适中的视频(约150mb)。在最初加载视频时,我发现播放器在
我正在使用自定义资源加载程序(尽管在没有使用自定义资源加载程序的情况下也会出现相同的行为)。以下是创建AVPlayer的相关代码(所有标准样板):
AVPlayerWaitingWhileEvaluatingBufferingRateReason
状态下保持不活跃长达10-15秒。我的问题很简单:如何防止AVPlayer评估缓冲速率原因这么长时间,而是立即播放视频?我正在使用自定义资源加载程序(尽管在没有使用自定义资源加载程序的情况下也会出现相同的行为)。以下是创建AVPlayer的相关代码(所有标准样板):
AVURLAsset * const playerAsset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
[[playerAsset resourceLoader] setDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)];
AVPlayerItem * const playerItem = [[AVPlayerItem alloc] initWithAsset:playerAsset];
AVPlayer * const player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
[player play];
_player = player;
我随后有一种处理数据请求的方法,可以使用它来获取更多关于AVPlayer正在尝试加载什么内容的信息:
-(void)handleDataRequest:(AVAssetResourceLoadingDataRequest *)dataRequest loadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {
NSLog(@"handleDataRequest: %lld-%lld (%@)",[dataRequest requestedOffset],[dataRequest requestedOffset] + [dataRequest requestedLength],[[self player] reasonForWaitingToPlay]);
NSMutableURLRequest * const request = ... // construct the request
[request setValue:[NSString stringWithFormat:@"bytes=%lld-%lld",[dataRequest requestedOffset],[dataRequest requestedOffset] + [dataRequest requestedLength]] forHTTPHeaderField:@"Range"];
NSURLSession * const downloadURLSession = ... // get the session
NSURLSessionDataTask * const dataTask = [downloadURLSession dataTaskWithRequest:request];
[dataTask resume];
}
现在,我们来看一下问题。假设视频长度为 ~100mb,在上述方法中,handleDataRequest
日志的结果如下:
handleDataRequest: 0-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 3080192-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 5570560-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 7143424-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 9699328-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 12713984-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 14811136-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 17235968-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 20054016-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 22675456-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 25427968-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 28311552-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 30932992-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 32374784-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 35192832-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 37224448-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 39780352-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 41549824-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 43778048-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 46465024-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 49414144-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 52166656-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 54984704-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 57802752-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 60293120-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 62783488-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 65732608-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 68550656-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 70975488-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 73531392-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 76480512-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 79495168-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 82313216-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 83951616-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 86573056-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 88866816-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 91422720-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 92667904-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 95289344-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 98172928-100000000 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 32768-5570560 (AVPlayerWaitingWhileEvaluatingBufferingRateReason)
handleDataRequest: 2032769-5570560 (AVPlayerWaitingToMinimizeStallsReason)
handleDataRequest: 4032770-5570560 (AVPlayerWaitingToMinimizeStallsReason)
handleDataRequest: 5668864-22675456 ((null))
handleDataRequest: 7668865-22675456 ((null))
handleDataRequest: 9668866-22675456 ((null))
handleDataRequest: 11668867-22675456 ((null))
handleDataRequest: 13668868-22675456 ((null))
如您所见,仅为评估缓冲状态原因,就有近40个HTTP请求。这需要很长时间。
这是我尝试过的:
- 使用AVPlayer的
playImmediatelyAtRate:
而不是play
我在网上看到了这个建议。我想逻辑是立即播放即可播放。但实际上,播放器仍然需要花费时间(和请求)来评估缓冲速率原因才能播放,因此它并不能起到作用。
- 将AVPlayer的
automaticallyWaitsToMinimizeStalling
设置为NO
看起来很合理。我们可以告诉播放器不要等待最小化停顿。不幸的是,这种方法失败了,因为播放器在播放之前仍会发出相同的请求来评估缓冲速率(奇怪的是,当这种情况发生时,reasonForWaitingToPlay
为空)。
- 调用加载请求的
finishLoading
方法以立即加速缓冲速率评估
这里的逻辑是,在AVPlayer评估缓冲速率时,我可以立即发出加载完成的信号,而不是发送实际的HTTP请求。这样做的结果各不相同。在某些测试中,视频会立即播放,但仅播放几秒钟,而在其他测试中,视频无法播放并超时。
总之,在播放大型视频时有没有避免此延迟的方法?AVPlayer是否必须在开始视频之前评估缓冲速率?
preferredForwardBufferedDuration
设置为什么值,播放器仍然停留在AVPlayerWaitingWhileEvaluatingBufferingRateReason
状态。 - Aaron Wojnowski