我有一个AVPlayer正在播放一个中等大的视频(~150 is )。当最初加载视频时,我发现播放机在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];
}
现在,谈这个问题。假设视频长度为~100 in,下面是上述方法中的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请求只是为了评估缓冲状态的原因。这需要很长时间。
以下是我尝试过的:
play
playImmediatelyAtRate:
代替playImmediatelyAtRate:
我在网上看到了这个建议。我想逻辑是,立即演奏就能做到这一点,立即演奏。这不起作用,因为玩家在比赛前仍然要花时间(和请求)来评估缓冲率的原因。
将AVPlayer的NO
设置为
automaticallyWaitsToMinimizeStalling
似乎是合理的。我们可以告诉球员不要等待,以尽量减少拖延。不幸的是,这失败了,因为玩家在播放前仍然会发出相同的请求来评估缓冲速率(但是,奇怪的是,在进行此操作时,reasonForWaitingToPlay
是null
)。
finishLoading
方法,以立即加快缓冲速率评估这里的逻辑是,在AVPlayer计算缓冲速率时,我可以立即发出加载已经完成的信号,而不是触发实际的HTTP请求。结果各不相同。在一些测试中,视频会立即播放,但只播放几秒钟,而在其他测试中,视频根本无法播放,并且会超时。
总之,在播放更大的视频时,有没有办法避免这种延迟?在开始一个视频之前,AVPlayer必须评估缓冲率,这真的有必要吗?
发布于 2022-02-07 09:31:18
苹果公司已经证实,问题不在于视频的大小,而是一个有太多moof+mdat原子的畸形moof+mdat。
到目前为止,这已被确定为是按计划进行的。虽然,我希望看到一些方法来避免这种最初的缓冲在未来,即使MP4是错误的。
https://stackoverflow.com/questions/70616620
复制相似问题