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

时间:2017-07-28 08:55:12

标签: ios swift3 avplayer audiotrack

我使用AVPlayer播放流媒体音频,并希望一次播放多个音轨。最好的方法是什么?我的方法完全是程序化的 - 我不会使用故事板。当一个url被发送到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)
        }
      })
    }
  }

1 个答案:

答案 0 :(得分:1)

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

意味着您将获得state,以帮助您识别正在播放,推送,缓冲或完成播放的当前项目。

因此,您应该使用一个flag处理当前项state

<强>实施例

  • 正在播放项目时设置标志为
  • 当项目结束播放时设置标志为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 
}

管理旗帜一样。