【问题标题】:AVPlayer, notification for play/pause state?AVPlayer,播放/暂停状态的通知?
【发布时间】:2011-11-26 09:23:47
【问题描述】:

我正在寻找一种在AVPlayer 开始播放的确切时刻获得通知的方法。有“rate”属性,但目前我定期使用NSTimer 检查它以获取更新。

我尝试过 KVO,但显然它不符合 KVO。

我知道有events当玩家ENDED。但我在这里说的是暂停。

我还订阅了 KVO AVPlayerItem's“状态”,但它显示 HTTP 资产何时完成缓存,没有播放/暂停。我还开始收集所有播放/暂停调用,之后请求即时 UI 更新,但在 AVPlayer 真正开始播放之前需要更多运行循环。我只想立即更新我的按钮。

【问题讨论】:

标签: ios avplayer


【解决方案1】:

为什么说“率”不是 KVO 投诉? 它对我有用。

这是我所做的:

- (void)viewDidLoad
{
    ...

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

然后:

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

【讨论】:

  • 真的吗?你在iOS4或iOS5上试过吗?会重新做我的测试;也许这毕竟只是我的错误。
  • 我在iOS5中试过了。为了让我的观察者被调用,我必须添加带有选项的观察者:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
  • iOS 10 有替代方案吗?
  • @AymenHARRATH 检查我对 iOS 10 的回答。
【解决方案2】:

对于 iOS 10 起您可以检查 AVPlayer timeControlStatus 的新属性。

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

【讨论】:

  • 但是当它发生变化时你是如何真正得到通知的呢?
【解决方案3】:

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

【讨论】:

    【解决方案4】:
        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")
            }
        }
    }
    

    迅速

    【讨论】:

      【解决方案5】:

      如果您的目标是 iOS 13 及更高版本,您可以使用 Combine 优雅地完成此操作:

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

      其中statusAVPlayer.TimeControlStatus 中的任何case

      【讨论】:

        【解决方案6】:

        将观察者添加到您的 AVPlayer 对象的 rate 值:

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

        并覆盖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")
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-12
          • 1970-01-01
          • 1970-01-01
          • 2011-08-05
          • 2021-09-02
          • 1970-01-01
          • 2019-10-18
          • 1970-01-01
          相关资源
          最近更新 更多