【问题标题】:How to detect AVPlayer actually started to play in swift如何检测 AVPlayer 实际上开始在 swift 中播放
【发布时间】:2017-04-08 11:34:32
【问题描述】:

您好,我已将 UISliderminimum 值设置为 0.00。然后我以这种方式设置它的最大值。

self.viewPlayer.layer.addSublayer(playerLayer)
    let duration : CMTime = avPlayer.avPlayer.currentItem!.asset.duration
    let seconds : Float64 = CMTimeGetSeconds(duration)

    sliderBar.maximumValue=Float(seconds)
    sliderBar!.isContinuous = false
    sliderBar!.tintColor = UIColor.green

但是我遇到了这个异常

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempting to set a slider's minimumValue (0.000000) to be larger than the maximumValue (nan)'
enter code here

我知道在prepareForPlay() 到实际播放之后,真正播放视频需要一些时间。那么如何检测播放器何时真正开始播放视频呢? 请帮我。 谢谢

【问题讨论】:

标签: ios swift3 avplayer uislider


【解决方案1】:

超级简单的 SWIFT 4-5 解决方案:

只需检查timeControlStatus!:(也适用于 PlayerQueue)

    if avPlayer?.timeControlStatus.rawValue == 2 {
       
    //video is playing (playing)

    } else if avPlayer?.timeControlStatus.rawValue == 0 { 
    
    //video is not playing (paused)
    
    }

原始值将为您提供其当前状态:)

【讨论】:

    【解决方案2】:

    另一种更简单的方法类似于:

    if videoPlayer.rate != 0 && videoPlayer.error == nil {
                print("video player is playing.................")
            } else {
                print("video player is NOT playing.")
            } 
    

    videoPlayer 显然是 AVPlayer 类型。

    【讨论】:

    • 但它没有反应
    【解决方案3】:

    声明 AVPlayer 全局

    var streamPlayer = AVPlayer()
    
    func playStreamAudio( for audioUrl:String)
        {
            guard streamPlayer.timeControlStatus != .playing else {
                streamPlayer.pause()
                return
            }
            let url = audioUrl //"http://192.168.71.11:7891/rec.wav"
            let playerItem = AVPlayerItem(url: URL(string:url)!)
            streamPlayer = AVPlayer(playerItem:playerItem)
            streamPlayer.rate = 1.0;
            streamPlayer.volume = 1.0
            streamPlayer.play()
        }
    

    【讨论】:

      【解决方案4】:

      从 iOS 10 开始,您可以观察到 AVPlayer 的 timeControlStatus 属性。可以是.playing

      查看代码:

      private func setupAVPlayer() {
          avPlayer.addObserver(self, forKeyPath: "status", options: [.old, .new], context: nil)
          if #available(iOS 10.0, *) {
              avPlayer.addObserver(self, forKeyPath: "timeControlStatus", options: [.old, .new], context: nil)
          } else {
              avPlayer.addObserver(self, forKeyPath: "rate", options: [.old, .new], context: nil)
          }
      }
      
      override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
          if object as AnyObject? === avPlayer {
              if keyPath == "status" {
                  if avPlayer.status == .readyToPlay {
                      avPlayer.play()
                  }
              } else if keyPath == "timeControlStatus" {
                  if #available(iOS 10.0, *) {
                      if avPlayer.timeControlStatus == .playing {
                          videoCell?.muteButton.isHidden = false
                      } else {
                          videoCell?.muteButton.isHidden = true
                      }
                  }
              } else if keyPath == "rate" {
                  if avPlayer.rate > 0 {
                      videoCell?.muteButton.isHidden = false
                  } else {
                      videoCell?.muteButton.isHidden = true
                  }
              }
          }
      }
      

      【讨论】:

      • 非常感谢!
      【解决方案5】:

      来自 Apple 的docs You can observe an AVPlayerLayer object’s readyForDisplay property to be notified when the layer has user-visible content. In particular, you might insert the player layer into the layer tree only when there is something for the user to look at and then perform a transition from

      【讨论】:

        【解决方案6】:

        这是我实际知道视频开始(而不是刚刚准备开始)时所做的。

        斯威夫特 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")
                }
            }
        }
        

        【讨论】:

        • @AmritTiwari 好吧,它是 Swift 4。
        • 你检查过 observeValue() 是否在做某事吗?
        • 是的,我已经使用 timeobserver 方法完成了,感谢您的回复。
        • 这就像一个魅力,当播放器开始和停止时,非常感谢
        【解决方案7】:

        你可以像这样在你的 AVPlayer 的对象上添加一个观察者

        player.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
        

        你可以像这样用你的 AVPlayer 检查状态变化

         func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutableRawPointer) {
            if keyPath == "status" {
                print(player.status)
            }
        }
        

        【讨论】:

        • player.status == AVPlayerStatusReadyToPlay 这是否意味着视频开始播放?
        • 这意味着avplayer现在将开始播放。
        • 这只是打印为 AVPlayerStatus
        • 当状态为 readyToPlay 时,您是否尝试过在此处获取持续时间?
        • @Rajat 这并不能说明视频是否开始播放。它只说视频已准备好播放。 readyToPlay.
        猜你喜欢
        • 1970-01-01
        • 2017-01-07
        • 1970-01-01
        • 1970-01-01
        • 2015-09-07
        • 2015-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多