- 初始化 AVPlayer 和 UI
首先,你需要設(shè)置一個 AVPlayer 實例和一個 AVPlayerLayer 來顯示視頻。你還需要一些 UI 控件,比如播放/暫停按鈕、進(jìn)度條等。
import UIKit
import AVFoundation
class VideoPlayerViewController: UIViewController {
var player: AVPlayer?
var playerLayer: AVPlayerLayer?
override func viewDidLoad() {
super.viewDidLoad()
// 初始化 AVPlayer
guard let url = URL(string: "https://your-video-url.com/video.mp4") else { return }
player = AVPlayer(url: url)
// 初始化 AVPlayerLayer 并添加到視圖
playerLayer = AVPlayerLayer(player: player)
playerLayer?.frame = self.view.bounds
playerLayer?.videoGravity = .resizeAspect
if let playerLayer = playerLayer {
self.view.layer.addSublayer(playerLayer)
}
// 添加播放按鈕和進(jìn)度條(自定義 UI)
setupUI()
}
func setupUI() {
// 在這里添加播放按鈕和進(jìn)度條的代碼
}
}
- 播放和暫停功能
要實現(xiàn)播放和暫停功能,你可以在播放按鈕的點擊事件中切換 AVPlayer 的狀態(tài):
@objc func playPauseButtonTapped() {
if player?.timeControlStatus == .playing {
player?.pause()
} else {
player?.play()
}
}
- 跟蹤和更新視頻播放進(jìn)度
使用 AVPlayer 的 addPeriodicTimeObserver(forInterval:queue:using:) 方法來跟蹤視頻的播放進(jìn)度。你可以將此進(jìn)度與進(jìn)度條同步。
func addPeriodicTimeObserver() {
let interval = CMTime(seconds: 1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
player?.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] time in
let currentTime = CMTimeGetSeconds(time)
// 更新進(jìn)度條和時間標(biāo)簽
self?.updateProgress(currentTime: currentTime)
}
}
func updateProgress(currentTime: Double) {
// 更新 UI 中的進(jìn)度條和標(biāo)簽
}
- 跳轉(zhuǎn)到特定的時間
可以使用 seek(to:) 方法跳轉(zhuǎn)到視頻中的特定時間:
@objc func sliderValueChanged(_ slider: UISlider) {
let targetTime = CMTime(seconds: Double(slider.value), preferredTimescale: CMTimeScale(NSEC_PER_SEC))
player?.seek(to: targetTime)
}
- 處理視頻結(jié)束的情況
通過 NotificationCenter 來監(jiān)聽視頻播放結(jié)束的通知:
func addEndTimeObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying),
name: .AVPlayerItemDidPlayToEndTime, object: player?.currentItem)
}
@objc func playerDidFinishPlaying() {
// 視頻播放完成后的操作,比如重置播放器或播放下一個視頻
}
- 清理和釋放資源
在視頻播放結(jié)束或控制器銷毀時,清理和釋放資源非常重要:
deinit {
NotificationCenter.default.removeObserver(self)
player?.pause()
player = nil
}
- 錯誤處理
確保添加一些錯誤處理代碼來處理播放過程中可能出現(xiàn)的錯誤:
func observePlayerItem() {
player?.currentItem?.addObserver(self, forKeyPath: "status", options: [.new, .old], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status" {
if player?.status == .failed {
// 處理錯誤
print("Failed to load video: \(String(describing: player?.error?.localizedDescription))")
}
}
}
結(jié)論
通過上述步驟,你可以實現(xiàn)一個基本的自定義視頻播放器。你可以根據(jù)需要進(jìn)一步擴展功能,比如添加全屏切換、倍速播放、音量控制等。希望這些步驟能夠幫助你更好地理解和實現(xiàn) Swift 中的自定義視頻播放器功能。