【问题标题】:Detect if AVPlayerViewController is playing video or buffering and add overlay to the player检测 AVPlayerViewController 是否正在播放视频或缓冲并将覆盖添加到播放器
【发布时间】:2016-08-03 14:11:58
【问题描述】:
  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")
}

check here for project

【问题讨论】:

    标签: ios swift avplayer avplayerviewcontroller


    【解决方案1】:
    1. 检查我的答案:https://stackoverflow.com/a/38867386/5109911,这向您展示了如何检查播放器是否正在加载缓冲区,要检查它是否准备好播放,您必须同时检查 player.currentItem.statusplayer.status

    2. 要向 AVPlayer 添加叠加层,我建议在 AVPlayer 层上方使用 UIView

    【讨论】:

    • 1.谢谢你的伙伴,我已经这样做了,它可以工作。2.第二次我添加了 uiview 并添加了按钮 bt 无法匹配 avplayer 的控制器和视图..请检查github中的项目。我刚刚上传了该项目,如果可能,请对其进行修改。我也无法显示该视频全屏模式。如果可能,请也检查一下。
    【解决方案2】:

    我对类似问题采取了稍微不同的方法 - 在 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/

    关于问题 #2,我同意 Marco 的建议,即在 AVPlayer 层之上使用 UIView。

    【讨论】:

    • 亲爱的 Evan,如果在 Swift 3.2 中使用过类似的解决方案,但它在 Swift 4 中不再起作用。请您好心,将您的解决方案转换为 Swift 4 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多