SwiftUI中AVPlayer添加时间观察者导致滑动卡顿问题求助
SwiftUI音乐播放器滑块卡顿问题解决
问题原因
你的代码中,AVPlayer的时间观察者直接在主队列每秒更新@Published var progress,这会触发SwiftUI视图的频繁重绘。当用户滑动滑块时,主队列需要同时处理触摸交互事件和观察者的UI更新任务,导致主线程阻塞,出现滑动卡顿。
解决方案
1. 将时间观察者回调移到后台队列
把观察者的执行队列从主队列改为后台队列,仅在需要更新UI时回到主队列,减少主线程压力:
func currentTimeAddObserver() { self.timeObserver = self.player.addPeriodicTimeObserver( forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: 1), queue: DispatchQueue.global(qos: .utility) // 使用后台队列执行回调 ) { [weak self] time in guard let self = self else { return } guard !self.isSeekingToTime else { return } // 仅在非滑动时,回到主队列更新进度 DispatchQueue.main.async { self.progress = CMTimeGetSeconds(time) } } }
2. 确保滑动状态判断的及时性
在SwiftUI的Slider组件中,通过onEditingChanged实时更新isSeekingToTime,确保滑动过程中观察者完全停止更新progress,避免和用户操作冲突:
Slider( value: $musicPlayer.progress, in: 0...musicPlayer.totalDuration, onEditingChanged: { isEditing in musicPlayer.isSeekingToTime = isEditing // 滑动结束后再同步播放器进度 if !isEditing { let targetTime = CMTimeMakeWithSeconds(musicPlayer.progress, preferredTimescale: 1) musicPlayer.player.seek(to: targetTime) } } )
3. 补充观察者的正确移除逻辑
确保在播放器销毁时移除时间观察者,避免内存泄漏(虽然不直接解决卡顿,但属于必要优化):
func removeObserver() { if let observer = timeObserver { player.removeTimeObserver(observer) timeObserver = nil } } deinit { removeObserver() }
额外优化
AVPlayer的volume属性范围是0.0~1.0,设置为2.0不会有额外效果,建议改为_player.volume = 1.0,避免无效配置。
内容的提问来源于stack exchange,提问作者Zain W
相关产品推荐
相关产品推荐

