Ios 更新AVPlayer时UISlider跳转
我尝试用UISlider实现简单播放器,以指示当前音频文件的时间 在代码中,我添加了两个观察者:Ios 更新AVPlayer时UISlider跳转,ios,swift,avplayer,uislider,Ios,Swift,Avplayer,Uislider,我尝试用UISlider实现简单播放器,以指示当前音频文件的时间 在代码中,我添加了两个观察者: slider.rx.value.subscribe(onNext: { value in let totalTime = Float(CMTimeGetSeconds(self.player.currentItem!.duration)) let seconds = value * totalTime let time = CMTime(se
slider.rx.value.subscribe(onNext: { value in
let totalTime = Float(CMTimeGetSeconds(self.player.currentItem!.duration))
let seconds = value * totalTime
let time = CMTime(seconds: Double(seconds), preferredTimescale: CMTimeScale(NSEC_PER_SEC))
self.player.seek(to: time)
}).disposed(by: bag)
let interval = CMTime(seconds: 0.1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
player.addPeriodicTimeObserver(forInterval: interval, queue: nil) { [weak self] time in
self?.updateSlider(with: time)
}
有一个私人功能:
private func updateSlider(with time: CMTime) {
let currentTime = CMTimeGetSeconds(time)
var totalTime = CMTimeGetSeconds(player.currentItem!.duration)
if totalTime.isNaN {
totalTime = 0
}
startLabel.text = Int(currentTime).descriptiveDuration
endLabel.text = Int(totalTime).descriptiveDuration
slider.value = Float(currentTime / totalTime)
}
当音频播放时,一切都很好,滑块也得到了更新。当我试图在播放音频时手动移动滑块,然后它跳转时,就会出现问题。为什么?
更新:
我知道为什么。因为我更新了两次:手动更新和玩家观察更新,但是如何防止这种行为呢?我不知道;)请提供帮助。一个简单的方法是防止
addPeriodicTimeObserver
在触摸滑块时调用self?.updateSlider(with:time)
这可以通过UISlider
sisTracking
属性来确定:
iTracking
一个布尔值,指示控件当前是否正在跟踪
触摸事件
在跟踪触摸事件的过程中,控件设置
将此属性的值设置为true。当跟踪结束或取消时
无论出于何种原因,它都会将此属性设置为false
参考:
这存在于所有UIControl
元素中,您可以这样使用:
player.addPeriodicTimeObserver(forInterval: interval, queue: nil) { [weak self] time in
//check if slider is being touched/tracked
guard self?.slider.isTracking == false else { return }
//if slider is not being touched, then update the slider from here
self?.updateSlider(with: time)
}
一般示例:
我确信还有其他(更好的)方法,但我在RxSwift方面还没有做太多工作。
我希望现在这已经足够好了。请参见此以获取帮助:在
addPeriodicTimeObserver
块中处理案例,以便在触摸滑块时立即返回?@staticVoidMan您希望如何实现它?;)请回答你的想法,我会试试。@Bartłomiejsemanńczyk嗯,基本的想法是防止滑块在被触摸/移动时更新。我会记下一个例子:)
@IBOutlet var slider: UISlider!
//...
func startSlider() {
slider.value = 0
slider.maximumValue = 10
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] (timer) in
print("Slider at: \(self?.slider.value)")
guard self?.slider.isTracking == false else { return }
self?.updateSlider(to: self!.slider.value + 0.1)
}
}
private func updateSlider(to value: Float) {
slider.value = value
}