简体   繁体   English

AVPlayer,播放/暂停状态的通知?

[英]AVPlayer, notification for play/pause state?

I'm searching for a way to get notified the exact moment when AVPlayer starts playing.我正在寻找一种方法来在AVPlayer开始播放的确切时刻得到通知。 There's the "rate" property, but currently I am checking it periodically with an NSTimer to get updates.有“rate”属性,但目前我正在使用NSTimer定期检查它以获取更新。

I tried KVO, but apparently it's not KVO compliant.我尝试过 KVO,但显然它不符合 KVO。

I know that there are events when the player ENDED .我知道当玩家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.我还 KVO 订阅了AVPlayerItem's “状态”,但它显示 HTTP 资产何时完成缓存,没有播放/暂停。 I also started collecting all calls of play/pause, requesting an instant UI update afterwards, but it takes some more runloops before AVPlayer really starts playing.我还开始收集所有播放/暂停调用,之后请求即时 UI 更新,但在AVPlayer真正开始播放之前需要更多运行循环。 I'd just love to update my button instantly .我只想立即更新我的按钮。

Why do you say that "rate" is not KVO complaint?为什么说“rate”不是KVO投诉? 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 i OS 10 onwards You can check new property of AVPlayer timeControlStatus .对于 i OS 10以后,您可以检查 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) AVPalyer 作为默认观察者来跟踪视频的当前持续时间,当您暂停或恢复视频时,您可以通过使用一个全局变量来获得暂停时间(内部观察者更新该变量)

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;
    }
}
    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:将观察者添加到您的AVPlayer对象的rate值:

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

And override the method that will be called when the rate changes:和覆盖的方法时,将调用rate的变化:

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")
        }
    }
}

If you're targeting iOS 13 and up, you can pull this off elegantly using Combine :如果您的目标是 iOS 13 及更高版本,则可以使用Combine优雅地完成此操作:

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

where status is any case of AVPlayer.TimeControlStatus其中statusAVPlayer.TimeControlStatus任何case

Need to add an observer to AVPlayer<\/code> object's rate<\/code> value:需要给AVPlayer<\/code>对象的rate<\/code>值添加一个观察者:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM