在 swift 中向 AVPlayer 添加自定义控件
Add custom controls to AVPlayer in swift
我正在尝试创建一个 table 视图以便我能够播放视频。我可以使用 AVPlayer 和层来做到这一点。
我想在视频视图的底部添加一个带有滑块的自定义播放和暂停按钮。
AVPlayerController 内置了这些控件。
如何在 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
}
}
}
}
我正在尝试创建一个 table 视图以便我能够播放视频。我可以使用 AVPlayer 和层来做到这一点。
我想在视频视图的底部添加一个带有滑块的自定义播放和暂停按钮。
AVPlayerController 内置了这些控件。
如何在 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
}
}
}
}