检测AVPlayer播放的时间

Jos*_*nor 5 ios avplayer

你怎么知道什么时候AVPlayer玩?在play()调用函数和实际播放视频之间似乎有一点延迟.

Ida*_*dan 8

对于视频:

AVPlayer有一个被称为的参数rate (Float),如果rate大于0.0,则有一个当前播放的视频.

您可以检查是否rate!=0:(速率可以是负的,如果玩家会倒流)

if vidPlayer != nil && vidPlayer.rate != 0 {
  println("playing")
}
Run Code Online (Sandbox Code Playgroud)

AVPlayer类引用


HSG*_*HSG 8

据我所知,我同意你的看法,在play()调用函数和实际播放视频之间会有一点延迟(换句话说,视频的第一帧被渲染的时间).延迟取决于一些标准,如视频类型(视频点播或直播),网络条件......但幸运的是,我们能够知道视频的第一帧渲染,我的意思是视频实际播放的时间.

通过观察status当前AVPlayerItem和无论何时AVPlayerItemStatusReadyToPlay,都应该是第一帧被渲染.

[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];

-(void)observeValueForKeyPath:(NSString*)path ofObject:(id)object change:(NSDictionary*)change context:(void*) context {

    if([self.playerItem status] == AVPlayerStatusReadyToPlay){
        NSLog(@"The video actually plays")
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,还有另一种解决方案,我们观察readyForDisplay状态AVPlayerLayer,它还表示视频呈现的时间.但是,该解决方案具有Apple文档中提到的缺点

/*!
     @property      readyForDisplay
     @abstract      Boolean indicating that the first video frame has been made ready for display for the current item of the associated AVPlayer.
     @discusssion   Use this property as an indicator of when best to show or animate-in an AVPlayerLayer into view. 
                    An AVPlayerLayer may be displayed, or made visible, while this propoerty is NO, however the layer will not have any 
                    user-visible content until the value becomes YES. 
                    This property remains NO for an AVPlayer currentItem whose AVAsset contains no enabled video tracks.
 */
@property(nonatomic, readonly, getter=isReadyForDisplay) BOOL readyForDisplay;
Run Code Online (Sandbox Code Playgroud)

这是示例代码

self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 
[self.playerLayer addObserver:self forKeyPath:@"readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];

-(void)observeValueForKeyPath:(NSString*)path ofObject:(id)object change:(NSDictionary*)change context:(void*) context {
    if([self.playerLayer isReadyForDisplay]){
        NSLog(@"Ready to display");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,[self.playerLayer isReadyForDisplay]应该返回YES,但是,作为文件,它不能保证.

我希望这会有所帮助.

  • 我不得不添加更多的东西,这是测试,如果状态是AVPlayerStatusReadyToPlay AND player.rate> 0.我需要确保播放器正在播放,但否则,完美的答案 (2认同)

ZAF*_*007 5

斯威夫特 4

方法一

var rateObserver: NSKeyValueObservation?

self.rateObserver = myPlayer.observe(\.rate, options:  [.new, .old], changeHandler: { (player, change) in
     if player.rate == 1  {
          print("Playing")
      }else{
           print("Stop")
      }
 })

 // Later You Can Remove Observer      
 self.rateObserver?.invalidate()
Run Code Online (Sandbox Code Playgroud)

方法二

myPlayer.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions(rawValue: NSKeyValueObservingOptions.new.rawValue | NSKeyValueObservingOptions.old.rawValue), context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
      if keyPath == "rate" { 
          if player.rate == 1  {
              print("Playing")
          }else{
               print("Stop")
          }
      }
 }
Run Code Online (Sandbox Code Playgroud)