开发者

AVPlayer, notification for play/pause state?

I'm searching for a way to get notified the exact moment when AVPlayer starts playing. There's the "rate" property, but currently I am checking it periodically with an NSTimer to get updates.

I tried KVO, but apparently it's not KVO compliant.

I know that there are events when the player ENDED. But i'm talking about pause here.

I also KVO subscribed to AVPlayerItem's "status", but it's showing me when the HTTP asset has finished caching, no play/pause. I also started collecting all calls of play/pause, requesting an instant UI update afterwar开发者_JAVA百科ds, but it takes some more runloops before AVPlayer really starts playing. I'd just love to update my button instantly.


Why do you say that "rate" is not KVO complaint? It works for me.

Here is what I did:

- (void)viewDidLoad
{
    ...

    [self.player addObserver:self forKeyPath:@"rate" options:0 context:nil];
}

And then:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"rate"]) {
    if ([self.player rate]) {
        [self changeToPause];  // This changes the button to Pause
    }
    else {
        [self changeToPlay];   // This changes the button to Play
    }
}
}


For iOS 10 onwards You can check new property of AVPlayer timeControlStatus.

if(avPlayerObject.timeControlStatus==AVPlayerTimeControlStatusPaused)
{
//Paused mode
}
else if(avPlayerObject.timeControlStatus==AVPlayerTimeControlStatusPlaying)
{
 //Play mode
}


AVPalyer as default observer to track the current duration of the video ,when you pause or resume the video you can get paused time by using one global variable (inside observer update that variable)

CMTime interval = CMTimeMake(1, 1);

//The capture of self here is coming in with your implicit property access of self.currentduration - you can't refer to self or properties on self from within a block that will be strongly retained by self.

//You can get around this by creating a weak reference to self before accessing timerDisp inside your block
__weak typeof(self) weakSelf = self;

self.timeObserverToken = [_player addPeriodicTimeObserverForInterval:interval queue:NULL usingBlock: ^(CMTime time)
{
    _currentDuration = (int)CMTimeGetSeconds (_player.currentTime);

    if(!_isPlaying)
    {
        _pausedDuration = _currentDuration;
    }
}


If you're targeting iOS 13 and up, you can pull this off elegantly using Combine:

cancellable = myAVPlayerInstance.publisher(for: \.timeControlStatus)
    .sink { [unowned self] status in
       ...
    }

where status is any case of AVPlayer.TimeControlStatus


    player = AVPlayer(url: URL(fileURLWithPath: path))
player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.new, context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "rate" {
        if player.rate > 0 {
            print("video started")
        }
    }
}

in swift


Add an observer to your AVPlayer object's rate value:

player.addObserver(self, forKeyPath: "rate", options: [], context: nil)

And override the method that will be called when the rate changes:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "rate", let player = object as? AVPlayer {
        if player.rate == 1 {
            print("Playing")
        } else {
            print("Paused")
        }
    }
}


Need to add an observer to AVPlayer object's rate value:

player?.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.new, context: nil)

Override below method to observe changes in rate property

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "rate" {
        if let status = player?.timeControlStatus {
            switch status{
            case .paused:
                //Paused mode
                print("paused")
            case .waitingToPlayAtSpecifiedRate:
                //Resumed
                print("resumed")
            case .playing:
                //Video Ended
                print("ended")
            @unknown default:
                print("For future versions")
            }
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜