要解决AVPlayer控件在播放滑动窗口HLS流时显示错误的持续时间,可以使用KVO(键值观察)来观察AVPlayerItem的时间相关属性。以下是一个使用KVO观察播放器时间的示例代码:
首先,创建一个AVPlayer实例并设置AVPlayerItem:
import AVKit
// 创建播放器
let player = AVPlayer()
// 创建要播放的URL链接
let url = URL(string: "your_hls_stream_url")
let playerItem = AVPlayerItem(url: url)
// 将AVPlayerItem关联到AVPlayer
player.replaceCurrentItem(with: playerItem)
然后,观察AVPlayerItem的时间相关属性,比如duration和currentTime:
// 观察播放器状态
playerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil)
// 观察播放器缓冲进度
playerItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: .new, context: nil)
// 观察播放器当前时间
player.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 1), queue: DispatchQueue.main) { [weak self] time in
// 更新UI显示
self?.updatePlayerUI(time: time)
}
在观察者的回调方法中处理时间相关属性的变化:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard let keyPath = keyPath else { return }
switch keyPath {
case "status":
// 播放器状态变化
if let status = change?[.newKey] as? AVPlayerItem.Status {
switch status {
case .readyToPlay:
// 播放器准备好播放
player.play()
case .failed:
// 播放器加载失败
print("播放器加载失败")
case .unknown:
// 播放器状态未知
print("播放器状态未知")
}
}
case "loadedTimeRanges":
// 缓冲进度变化
if let timeRanges = playerItem.loadedTimeRanges.first as? CMTimeRange {
let startTime = CMTimeGetSeconds(timeRanges.start)
let duration = CMTimeGetSeconds(timeRanges.duration)
// 更新缓冲进度UI显示
updateBufferProgress(startTime: startTime, duration: duration)
}
default:
break
}
}
func updatePlayerUI(time: CMTime) {
let currentTime = CMTimeGetSeconds(time)
let duration = CMTimeGetSeconds(playerItem.duration)
// 更新播放进度UI显示
updatePlayProgress(currentTime: currentTime, duration: duration)
}
最后,记得在适当的时候移除观察者:
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
playerItem.removeObserver(self, forKeyPath: "status")
playerItem.removeObserver(self, forKeyPath: "loadedTimeRanges")
player.removeTimeObserver(self)
}
通过使用KVO观察AVPlayerItem的时间相关属性,你可以在播放滑动窗口HLS流时正确显示实时的持续时间。