在我的应用中,用户可以通过点击UI元素来调用视频播放,然后执行以下代码段:
self.loadingView.frame = _frameWhereItShouldBeLocated;
[self.loadSpinner startAnimating]; // self.loadSpinner is an UIActivityIndicatorView
self.loadingView.hidden = FALSE;
AVPlayer *player = [AVPlayer playerWithURL:fileUrl]; // fileUrl is where is the video file is hosted, which is not a local path
if ([player.currentItem.asset isPlayable])
{
if (!self.playerController) {
self.playerController = [[AVPlayerViewController alloc] init];
self.playerController.transitioningDelegate = self;
self.playerController.modalPresentationStyle = UIModalPresentationCustom;
}
self.playerController.player = player;
self.playerController.showsPlaybackControls = TRUE;
[self.navigationController presentViewController:self.playerController animated:YES completion:nil];
[self.playerController.player play];
}
我希望在用户点击后立即可以看到加载视图,然后在一段时间后,播放器控制器会出现并播放视频。但是,在加载视图可见之前会发生明显的延迟。
这就是我的预期:
User tap -> loading view shown -> (some time for loading the video, etc) -> play video
相反,这就是我所拥有的:
User tap -> (significant time delay) -> loading view shown -> play video
经过一些调试后,我发现延迟是由[player.currentItem.asset isPlayable]
调用引起的,即加载视图仅在返回调用后才可见。我尝试将段放在dispatch_async
调用的加载视图显示下方,但它没有区别。
无论如何要处理它以使其表现如预期一样吗?
非常感谢!
答案 0 :(得分:0)
Ins string[count]
检查这个
if ([player.currentItem.asset isPlayable])
或者
您可以为if ((player.rate != 0) && (player.error == nil)) {
// player is playing
}
属性添加通知,如下所示
rate
然后检查观察到的速率的新值是否为零,这意味着由于某种原因播放已停止,例如由于空缓冲区而到达终点或停止。
[player addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionNew
context:NULL];
对于rate == 0.0的情况,要知道究竟是什么原因导致播放停止,您可以进行以下检查:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context {
if ([keyPath isEqualToString:@"rate"]) {
float rate = [change[NSKeyValueChangeNewKey] floatValue];
if (rate == 0.0) {
// Playback stopped
} else if (rate == 1.0) {
// Normal playback
} else if (rate == -1.0) {
// Reverse playback
}
}
}
根据以上条件隐藏您的指标视图。 并在主线程上加载指标视图。
if (self.player.error != nil) {
// Playback failed
}
if (CMTimeGetSeconds(self.player.currentTime) >=
CMTimeGetSeconds(self.player.currentItem.duration)) {
// Playback reached end
} else if (!self.player.currentItem.playbackLikelyToKeepUp) {
// Not ready to play, wait until enough data is loaded
}