在 swift 中向 AVPlayer 添加自定义控件

Add custom controls to AVPlayer in swift

我正在尝试创建一个 table 视图以便我能够播放视频。我可以使用 AVPlayer 和层来做到这一点。

我想在视频视图的底部添加一个带有滑块的自定义播放和暂停按钮。

A​​VPlayerController 内置了这些控件。

如何在 AVPlayer 中实现这些。我一直在寻找例子。但是我还没有找到。

是否有任何 GitHub 我可以遵循的示例或代码示例?任何帮助将不胜感激。

这里我加点,大家可以根据自己的需要定制。

第一步

最初隐藏您的 AVPlayer 控件,

 YourAVPlayerViewController.showsPlaybackControls = false

第 2 步

创建类似

的结构

one label for current Duration, One label for overall Duration, one UIbutton for pause and play your current player and one UISlider for seek The video.

第 3 步

先关闭简单的步骤。

first stop and play the player using button action , currentPlayer is your AVPlayer name.

@IBAction func handlePlayPauseButtonPressed(_ sender: UIButton) {
   //  sender.isSelected ?  currentPlayer.pause() :   currentPlayer.play()
    if sender.isSelected {
        currentPlayer.pause()
    }
    else {
        currentPlayer.play()
    }
}

second set the video duration, as like

    let duration : CMTime = currentPlayer.currentItem!.asset.duration
    let seconds : Float64 = CMTimeGetSeconds(duration)

    lblOverallDuration.text = self.stringFromTimeInterval(interval: seconds)

third set the player current time to current duration label

    let duration : CMTime = currentPlayer.currentTime()
    let seconds : Float64 = CMTimeGetSeconds(duration)

    lblcurrentText.text = self.stringFromTimeInterval(interval: seconds)

the following method is convert from NSTimeinterval to HH:MM:SS

func stringFromTimeInterval(interval: TimeInterval) -> String {

    let interval = Int(interval)
    let seconds = interval % 60
    let minutes = (interval / 60) % 60
    let hours = (interval / 3600)
    return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}

finally we go for slider control for calulate the seek time

_playheadSlider.addTarget(self, action: #selector(self.handlePlayheadSliderTouchBegin), for: .touchDown)
_playheadSlider.addTarget(self, action:    #selector(self.handlePlayheadSliderTouchEnd), for: .touchUpInside)
_playheadSlider.addTarget(self, action: #selector(self.handlePlayheadSliderTouchEnd), for: .touchUpOutside)
_playheadSlider.addTarget(self, action: #selector(self.handlePlayheadSliderValueChanged), for: .valueChanged)

lets we go for action, initially when touchbegin is start then stop the player

handlePlayheadSliderTouchBegin

@IBAction func handlePlayheadSliderTouchBegin(_ sender: UISlider) {
currentPlayer.pause()
}

set the current item label for calculate the sender.value * CMTimeGetSeconds(currentPlayer.currentItem.duration)

@IBAction func handlePlayheadSliderValueChanged(_ sender: UISlider) {

        let duration : CMTime = currentPlayer.currentItem!.asset.duration
     let seconds : Float64 = CMTimeGetSeconds(duration) * sender.value
 //   var newCurrentTime: TimeInterval = sender.value * CMTimeGetSeconds(currentPlayer.currentItem.duration)
lblcurrentText.text = self.stringFromTimeInterval(interval: seconds)
   }

finally move the player based on seek

 @IBAction func handlePlayheadSliderTouchEnd(_ sender: UISlider) {

  let duration : CMTime = currentPlayer.currentItem!.asset.duration
var newCurrentTime: TimeInterval = sender.value * CMTimeGetSeconds(duration)
var seekToTime: CMTime = CMTimeMakeWithSeconds(newCurrentTime, 600)
currentPlayer.seek(toTime: seekToTime)
}

除了 Anbu.Karthik 的回答之外,还可以在如下单个函数中更好地处理滑块处理:

slider.addTarget(self, action: #selector(self.handlePlayheadSliderValueChanged(sender:event:)), for: .valueChanged)

滑块值变化:

注意 switch cases 处理滑块事件的所有阶段

@objc func handlePlayheadSliderValueChanged(sender: UISlider, event: UIEvent) {
    if let duration: CMTime = player?.currentItem?.asset.duration {
        let newCurrentTime: Float64 = CMTimeGetSeconds(duration) * Double(sender.value)
        videoLengthLabel.text = self.stringFromTimeInterval(interval: newCurrentTime)
        if let touchEvent = event.allTouches?.first {
            switch (touchEvent.phase) {
            case .began:
                // on slider touch begin
                pauseVideo()
                break
            case .moved:
                // on slider movement
                let seekToTime: CMTime = CMTimeMakeWithSeconds(newCurrentTime, preferredTimescale: 600)
                player?.seek(to: seekToTime, completionHandler: { (completedSeek) in
                    // any additional operation upon seek completion
                })
                break
            case .ended:
                // on slider touch end (finger lift)
                playVideo()
                break
            default:
                break
            }
        }
    }
}