5
  1. I have to detect whether the video is in playing or buffering mode.I am loading the video from a URL. I have tried the below code and I am able to track after once the video has started playing, but not when it is in buffering state.
  2. Also, I want to add an overlay view in my player. I have tried to add the overlay in AVPlayer but when in full screen mode the overlay disappears.

Need some suggestions. Thanks in advance. Below is my code:

    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

Prashant Ghimire
  • 518
  • 4
  • 20

2 Answers2

1
  1. Check my answer: https://stackoverflow.com/a/38867386/5109911, this shows you how check if the player is loading the buffer, to check if it is ready to play you have to check both player.currentItem.status and player.status

  2. To add an overlay to AVPlayer I suggest using an UIView above your AVPlayer layer.

Community
  • 1
  • 1
Marco Santarossa
  • 4,058
  • 1
  • 29
  • 49
  • 1.thank you mate i have done this already and it works.2.for second i have added uiview and added button bt am not able to match controller of avplayer and the view..please check the project in github.i have just uploaded that project and if possible please modify it.and i am also not able to display that video fullscreen mode.if possible please check that too. – Prashant Ghimire Aug 11 '16 at 03:36
1

I took a slightly different approach to a similar problem - updating the UI when the AVPlayer starts actual playback (in our case, it was audio playback, but the same principle would apply).

We used a boundary time to execute a block at the start of playback – specifically after 1/3 of a second of playback – to update the UI at the same time as audible playback:

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

I have a little more detail on the approach (and a sample Xcode project) on our company blog: http://www.artermobilize.com/blog/2017/02/09/detect-when-ios-avplayer-finishes-buffering-using-swift/

As to question #2, I concur with Marco's suggestion of using an UIView overtop of the AVPlayer layer.

Evan Kirkwood
  • 418
  • 4
  • 14
  • Dear Evan, if’ve used a similar solution in Swift 3.2, but it does not work any longer in Swift 4. Would you please be so kind and convert your solution to Swift 4? – ixany Aug 31 '17 at 09:26