AVPlayer boundary time observer fails to fire occasionally

末鹿安然 提交于 2019-12-22 11:05:27

问题


I'm using AVPlayer's -addBoundaryTimeOserverForTimes:queue:usingBlock: to execute some code at a specific time in my video (in this case, I want a un-hide a button when my video reaches its duration. Code is as follows:

- (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];
    }];

    ...
}

For whatever reason, sometimes the block of code fires and the button becomes visible, and sometimes it doesn't. Haven't been able to find a pattern in this behavior. It happens very often (almost always) in the simulator, and occasionally when on a device. Has anyone encountered this problem? Any ideas what might be going on?

Edit

Also, if I put a breakpoint on the block, it ALWAYS fires.


回答1:


Main queue sometimes not call. You can use Sub queue, and call Main queue in Sub-queue's block.

// 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
    });
}];



回答2:


For those wanting to observe when the player ends:

I browse this question about once a year because I always forget about the fix that works for me. This time around I had this issue on macOS. I am seeing the same behavior, the observer block sometimes does not get called. When I switch back from the app that is being debugged to Xcode the block suddenly fires. This might be related to having a breakpoint set in the block as described by the OP.

Here's the fix however: Simply switch to AVPlayerItemDidPlayToEndTimeNotification as described in this answer. Note however, as the name implies the notification's object is the player's current item not the player itself!

Because this notification triggers at the end time of an item, instead of observing some "boundary time" simply set the item's forwardPlaybackEndTime if you need another time than the item's actual end time, i.e. duration.



来源:https://stackoverflow.com/questions/15771549/avplayer-boundary-time-observer-fails-to-fire-occasionally

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!