我正在使用AVPlayer的-addBoundaryTimeOserverForTimes:queue:usingBlock:在我的视频中的特定时间执行一些代码(在这种情况下,我希望在我的视频到达其持续时间时取消隐藏按钮。代码如下:
- (void)viewWillAppear:(BOOL)animated
{
...
_player = [AVPlayer playerWithURL:videoURL];
AVPlayerLayer *newPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
[newPlayerLayer setFrame:_videoView.bounds];
[_videoView.layer addSublayer:newPlayerLayer];
_observer = [_player addBoundaryTimeObserverForTimes:@[[NSValue valueWithCMTime:_player.currentItem.duration]] queue:NULL usingBlock:^{
[someButton setHidden:NO];
}];
...
}
无论出于何种原因,有时代码块会触发,按钮变为可见,有时则不会。无法在此行为中找到模式。它经常(几乎总是)在模拟器中发生,偶尔在设备上发生。有谁遇到过这个问题?有什么想法可能会发生什么?
修改
另外,如果我在块上放置一个断点,它总是会触发。
答案 0 :(得分:0)
主队列有时不会调用。 您可以使用子队列,并在子队列的块中调用主队列。
// dispatch queue setting
dispatch_queue_t subQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
// notification setting
__block id blockObserver;
blockObserver = [self.queuePlayer addBoundaryTimeObserverForTimes:boundary
queue:subQueue // if NULL use mainQueue
usingBlock:^{
// do something
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
// do something
});
}];
答案 1 :(得分:0)
对于那些希望观察玩家何时结束的人:
我每年大约浏览一次此问题,因为我总是忘了对我有用的修复程序。这次我在MacOS上在上遇到了这个问题。我看到的是相同的行为,观察者块有时不会被调用。当我从正在调试为Xcode的应用程序切换回时,该块突然触发。这可能与OP中描述的在块中设置断点有关。
但是,这是解决方法:只需按照this answer中所述切换到AVPlayerItemDidPlayToEndTimeNotification
。但是请注意,顾名思义,通知的对象是播放器的当前项目,而不是播放器本身!
因为此通知在商品的结束时间触发,所以如果您需要的时间比商品的实际结束时间(即持续时间)长,则只需设置商品的forwardPlaybackEndTime
,而不是观察某些“边界时间”。