
IOS
在IOS应用开发中,我们经常会遇到需要使用进度条来展示音视频播放的进度。而在使用 AVPlayer 播放音视频时,我们可以通过监听其时间线来实现进度条的更新。本文将介绍如何利用 AVPlayer 的时间线来实现进度条,并提供相应的案例代码。
AVPlayer简介AVPlayer 是苹果提供的一个强大的媒体播放框架,可以用来播放音频和视频。它提供了丰富的功能和灵活的接口,可以满足开发者对媒体播放的各种需求。监听时间线要实现进度条的更新,我们需要监听 AVPlayer 的时间线。AVPlayer 提供了一个 KVO(Key-Value Observing)机制,可以监听它的属性变化。我们可以监听 AVPlayer 的 "currentItem" 属性,以获取当前播放的音视频项。然后,我们再监听当前音视频项的 "status" 属性和 "loadedTimeRanges" 属性,以获取当前音视频的加载状态和已加载的时间范围。当我们监听到 "status" 属性为 AVPlayerItemStatusReadyToPlay 时,表示音视频已经准备好可以播放了。而 "loadedTimeRanges" 属性是一个数组,包含了已加载的时间范围。我们可以通过遍历数组,获取已加载的最大时间范围,以计算出当前的加载进度。案例代码下面是一个简单的案例代码,演示了如何使用 AVPlayer 的时间线来更新进度条:Swiftimport UIKitimport AVFoundationclass ViewController: UIViewController { @IBOutlet weak var progressBar: UIProgressView! var player: AVPlayer? var playerItem: AVPlayerItem? var timeObserverToken: Any? override func viewDidLoad() { super.viewDidLoad() // 创建 AVPlayerItem let vIDEOURL = URL(string: "https://example.com/vIDEO.mp4") playerItem = AVPlayerItem(url: vIDEOURL!) // 创建 AVPlayer player = AVPlayer(playerItem: playerItem) // 监听 AVPlayerItem 的状态和已加载时间范围 playerItem?.addObserver(self, forKeyPath: "status", options: .new, context: nil) playerItem?.addObserver(self, forKeyPath: "loadedTimeRanges", options: .new, context: nil) // 添加时间线观察者 let interval = CMTime(seconds: 1, preferredTimescale: CMTimeScale(NSEC_PER_SEC)) timeObserverToken = player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.mAIn) { [weak self] time in self?.updateProgressBar() } } func updateProgressBar() { guard let playerItem = playerItem else { return } if playerItem.status == .readyToPlay { let duration = CMTimeGetSeconds(playerItem.duration) let currentTime = CMTimeGetSeconds(playerItem.currentTime()) let progress = Float(currentTime / duration) progressBar.progress = progress } } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "status" { if playerItem?.status == .readyToPlay { // 音视频已准备好可以播放 player?.play() } } else if keyPath == "loadedTimeRanges" { // 计算加载进度 let loadedTimeRanges = playerItem?.loadedTimeRanges let timeRange = loadedTimeRanges?.first?.timeRangeValue let startSeconds = CMTimeGetSeconds(timeRange?.start ?? CMTime.zero) let durationSeconds = CMTimeGetSeconds(timeRange?.duration ?? CMTime.zero) let loadedTime = startSeconds + durationSeconds // 更新进度条 let TotalTime = CMTimeGetSeconds(playerItem?.duration ?? CMTime.zero) let progress = Float(loadedTime / TotalTime) progressBar.progress = progress } } deinit { // 移除观察者和时间线观察者 playerItem?.removeObserver(self, forKeyPath: "status") playerItem?.removeObserver(self, forKeyPath: "loadedTimeRanges") if let timeObserverToken = timeObserverToken { player?.removeTimeObserver(timeObserverToken) } }}在上面的代码中,我们首先创建了一个 AVPlayerItem,其初始化使用了一个远程视频的 URL。然后,我们创建了一个 AVPlayer,并将 AVPlayerItem 设置为其当前项。接下来,我们监听了 AVPlayerItem 的 "status" 和 "loadedTimeRanges" 属性,以及 AVPlayer 的时间线。在 "updateProgressBar" 方法中,我们首先判断 AVPlayerItem 的状态是否为 .readyToPlay,如果是,则计算播放进度,并更新进度条的值。在 "observeValue" 方法中,我们分别处理了 "status" 和 "loadedTimeRanges" 属性的变化,计算已加载的时间范围,并更新进度条的值。最后,在视图控制器销毁时,我们移除了监听和时间线观察者,以释放相关资源。通过监听 AVPlayer 的时间线,我们可以实时更新进度条,展示音视频的播放进度。AVPlayer 提供了丰富的功能和灵活的接口,可以满足开发者对媒体播放的各种需求。希望本文对你在实现进度条时有所帮助。如果你对 AVPlayer 还不够熟悉,可以参考苹果的官方文档,了解更多关于 AVPlayer 的知识和用法。Copyright © 2025 IZhiDa.com All Rights Reserved.
知答 版权所有 粤ICP备2023042255号