繁体   English   中英

防止AVPlayer一次播放多个曲目的最佳方法

[英]Best way to prevent AVPlayer playing more than one track at a time

我正在使用AVPlayer播放流音频,并希望防止它一次播放多个音频轨道。 最好的方法是什么? 我的方法完全是编程的-我不使用情节提要。 将网址发送到ViewController(VC,委托)时,它会设置播放器的新实例-我认为这是问题所在,但我不确定。 谢谢。

 //this routine returns the url from control to the VC (delegate)
  func selectedAudio(_ audioUrl:String?) {
    if let urlString = audioUrl {
      setupPlayer(urlString)
    }
  }

    //single button which toggles between play/pause
  func playOrPauseTouched() {
    if isPlaying  {
      pausePlayer()
    } else {
      playPlayer()
    }
  }

  func playPlayer() {
    if player == nil || selectedTrackName != currentTrackLabel.text{
      if let urlString = selectedAudioUrl {
        setupPlayer(urlString)
        currentTrackLabel.text = "Playing: \(selectedTrackName ?? "")"
      }
    }
    player?.play()
    isPlaying = true
    playPauseButton.setImage(UIImage(named: "pause"), for: .normal)
    activityIndicatorView.startAnimating()
  }

  func pausePlayer() {
    player?.pause()
    isPlaying = false
    playPauseButton.setImage(UIImage(named: "play"), for: .normal)
  }

  func setupPlayer(_ urlString:String) {
    if let url = URL(string:urlString) {
      player = AVPlayer(url: url)
      let playerLayer = AVPlayerLayer(player: player)
      player?.addObserver(self, forKeyPath: "currentItem.loadedTimeRanges", options: .new, context: nil)
      let interval = CMTime(value: 1, timescale: 5) //gives smooth thumb movement w/short clips
      player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { (progressTime) in
        let seconds = CMTimeGetSeconds(progressTime)
        let secondsString = String(format: "%02d", Int(seconds.truncatingRemainder(dividingBy: 60)))
        let minutesString = String(format: "%02d", Int(seconds / 60))
        self.currentTimeLabel.text = "\(minutesString):\(secondsString)"
        if let duration = self.player?.currentItem?.duration {
          let durationSeconds = CMTimeGetSeconds(duration)
          self.audioSlider.value = Float(seconds / durationSeconds)
        }
      })
    }
  }

我的意见是使用KVO ,它将通知您AVPlayerItem当前状态。

意味着你会得到state ,这将帮助您识别当前项目正在播放,推,缓冲或完成打。

因此,您应该选择一个可以处理当前项目state flag

防爆。

  • 播放项目时将标志设置为true
  • 项目播放完毕时,将标志设置为false。
  • 当您点击按钮播放另一个项目时,请检查标记,例如if flag == false然后开始播放另一个项目,否则不播放。

第二种方式:

如下所示使用NotificationCenter

NotificationCenter.default.addObserver(self, selector: Selector(("playerDidFinishPlaying:")), 
       name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)

项目播放完毕后,以下自动呼叫

func playerDidFinishPlaying(note: NSNotification) {
    print("Item finished playing ")
   // Set flag here 
}

与托管标志相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM