检测AVPlayerViewController是否正在播放视频或缓冲,并向播放器添加覆盖层。

5
  1. 我需要检测视频是处于播放还是缓冲模式。我从一个URL加载视频。我尝试了下面的代码,能够在视频开始播放后跟踪,但无法在缓冲状态下进行跟踪。
  2. 此外,我想在我的播放器中添加一个覆盖视图。我已经尝试在AVPlayer中添加覆盖视图,但在全屏模式下,覆盖视图会消失。

需要一些建议。提前致谢。以下是我的代码:

    let playerAV = AVPlayerViewController()
    var player = AVPlayer()
    player = AVPlayer(URL: url)
    print(url)
    playerAV.player = player
    playerAV.view.frame = CGRectMake(0, 0,  self.videoView.frame.width,  self.videoView.frame.height)
    self.addChildViewController(playerAV)
    self.videoView.addSubview(playerAV.view)
    playerAV.didMoveToParentViewController(self)
    playerAV.player?.play()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ChannelDetailViewController.notificationObserver(_:)), name:AVPlayerItemDidPlayToEndTimeNotification , object: player.currentItem)
        _ = UIDevice.beginGeneratingDeviceOrientationNotifications
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ChannelDetailViewController.deviceOrientationDidChange(_:)) , name:
        UIDeviceOrientationDidChangeNotification, object: nil)
    player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.New, context: nil)
  player.addPeriodicTimeObserverForInterval(CMTime(value: 1, timescale: 3), queue: dispatch_get_main_queue()) { [weak self] time in
    self?.handlePlayerStatus(time)
  }

  func handlePlayerStatus(time: CMTime) {
     if player.status == .ReadyToPlay {
     // buffering is finished, the player is ready to play
     print("playing")
  }
  if player.status == .Unknown{
    print("Buffering")
  }
 }

 override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    if keyPath == "rate" {
        if let rate = change?[NSKeyValueChangeNewKey] as? Float {
          if player.currentItem!.status == AVPlayerItemStatus.ReadyToPlay{
            if rate != 0 && player.error == nil {

              print("normal playback")
            }
            else{
              print("playback stopped")
            }

          }else if player.currentItem?.status == AVPlayerItemStatus.Unknown{
            print("test")
          }
        }
    }
    print("you are here")
}

点击此处查看项目

2个回答

1
  1. 检查我的答案:https://dev59.com/5VkT5IYBdhLWcg3wPtMv#38867386,这个链接展示了如何检查播放器是否正在加载缓存,如果要检查播放器是否准备好播放,需要同时检查 player.currentItem.statusplayer.status

  2. 要在AVPlayer上添加叠加层,建议使用一个位于AVPlayer图层之上的 UIView


  1. 谢谢伙计,我已经完成了这个并且它有效。
  2. 对于第二个问题,我已经添加了UIView并添加了按钮,但是我无法匹配AVPlayer的控制器和视图。请在GitHub上检查该项目。我刚刚上传了该项目,如果可能,请修改它。我也无法将视频显示为全屏模式。如果可能,请也检查一下这个问题。
- Prashant Ghimire

1
我采取了与类似问题略有不同的方法——在AVPlayer开始实际播放时更新UI(在我们的情况下,是音频播放,但同样的原理也适用)。我们使用一个边界时间,在播放开始后的1/3秒执行一个块,同时更新UI以与可听播放同步。
let times = [NSValue(time:CMTimeMake(1,3))]
_ = self.player.addBoundaryTimeObserver(forTimes: times, queue: DispatchQueue.main, using: {
    [weak self] time in
    // Code to update the UI goes here, e.g.
    self?.someUIView.isHidden = false
})

我在我们公司的博客上提供了更详细的方法说明(以及一个示例Xcode项目):http://www.artermobilize.com/blog/2017/02/09/detect-when-ios-avplayer-finishes-buffering-using-swift/

至于第二个问题,我同意Marco的建议,使用UIView覆盖在AVPlayer图层上方。


亲爱的Evan,我之前在Swift 3.2中使用了一个类似的解决方案,但在Swift 4中不再有效。能否请你帮忙将你的解决方案转换为Swift 4呢?谢谢! - ixany

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接