How do I replace MPMoviePlayer notifications?

2019-04-25 23:11发布

问题:

In iOS 9 MPMoviePlayer and all his components are deprecated. We used MPMoviePlayerController notifications, like MPMoviePlayerLoadStateDidChangeNotification, MPMovieDurationAvailableNotification, MPMoviePlayerPlaybackStateDidChangeNotification, MPMoviePlayerReadyForDisplayDidChangeNotification, to track video service quality. But now with AVPlayerViewController I can't find properly replacement for these notifications.

How do I replace these notifications now?

回答1:

AVPlayerViewController is a lot different in its usage from the MPMoviePlayerViewController. Instead of using notifications you use Key Value Observing to determine the current characteristics of the AVPlayer object associated with the AVPlayerViewController. According to the docs:

You can observe the status of a player using key-value observing. So that you can add and remove observers safely, AVPlayer serializes notifications of changes that occur dynamically during playback on a dispatch queue. By default, this queue is the main queue (see dispatch_get_main_queue). To ensure safe access to a player’s nonatomic properties while dynamic changes in playback state may be reported, you must serialize access with the receiver’s notification queue. In the common case, such serialization is naturally achieved by invoking AVPlayer’s various methods on the main thread or queue.

For instance, if you want to know when your player has been paused add an observer on the rate property of the AVPlayer object:

[self.player addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context: &PlayerRateContext];

Then in the observe method check if the new value is equal to zero:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    if (context == &PlayerRateContext) {
        if ([[change valueForKey:@"new"] integerValue] == 0) {
            // summon Sauron here (or whatever you want to do)
        }
        return;
    }

    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    return;
}

A lot of properties on the AVPlayer are observable. Go through the Class reference.

Also apart from this there are several Notifications available for the AVPlayerItem object which are limited but still helpful.

Notifications

AVPlayerItemDidPlayToEndTimeNotification

AVPlayerItemFailedToPlayToEndTimeNotification

AVPlayerItemTimeJumpedNotification

AVPlayerItemPlaybackStalledNotification

AVPlayerItemNewAccessLogEntryNotification

AVPlayerItemNewErrorLogEntryNotification

I find AVPlayerItemDidPlayToEndTimeNotification particularly useful to seek the Item to the start once playback has finished.

Using these two options together you should be able to replace most if not all notifications for the MPMoviePlayerController



回答2:

I looked at the documentation for both MPMoviePlayerNotifications and AVPlayerItemNotifications and I notice two things.

  1. MPMoviePlayerNotifications don't show they were deprecated:

  2. AVPlayerItemNotifications don't have any replacements that I could see:

So, I am confused that you are saying MPMoviePlayerNotifications are deprecated, because the docs are saying they are available. Also, I don't think AVPlayerItemNotifications has a replacement for MPMoviePlayerNotifications.