Swift iOS -CMTimeMakeWithSeconds:警告:由于时间尺度非常短,引入了 -0.433 错误
Swift iOS -CMTimeMakeWithSeconds: warning: error of -0.433 introduced due to very low timescale
我正在使用 AVPlayer 播放视频。我跟着这个视频教程 Let's Build That App
我使用 UISlider/scrubber 来配合当前的 frame/time 视频。
我有一个 10.43 秒的视频,我使用快进功能将我带到最后。
@objc fileprivate func fastForwardButtonTapped() {
guard let playerItem = playerItem else { return }
guard let player = player else { return }
let duration: Float64 = CMTimeGetSeconds(playerItem.duration)
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1)
player.seek(to: seekTime)
}
视频走到了最后,但问题是滑块只走到了 10 秒点,我无法让它走到最后的 0.43 秒。我收到以下警告消息:
滑块的值在 player?.addPeriodicTimeObserver()
中确定因此,当我按快进而不是滑块走到尽头时,它会在几个点外停止(注意白色 space):
如何获得更准确的值,以便我的滑块可以一直滑动到最后?
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &playerItemContext)
let interval = CMTime(value: 1, timescale: 2)
timeObserverToken = player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: {
[weak self] (progressTime) in
let seconds = CMTimeGetSeconds(progressTime)
let secondsString = String(format: "%02d", Int(seconds) % 60)
let minutesString = String(format: "%02d", Int(seconds) / 60)
self?.currentTimeLabel.text = "\(minutesString):\(secondsString)"
if let duration = self?.playerItem!.duration{
let durationSeconds = CMTimeGetSeconds(duration)
self?.slider.value = Float(seconds / durationSeconds) // SLIDER IS UPDATED HERE
}
})
我做了一些研究,AVPlayer
有一个 seek
方法:
player.seek(to: <CMTime>, toleranceBefore: <CMTime>, toleranceAfter: <CMTime>)
使用这种方法,您可以对其设置容差以补偿截断溢出,在我的情况下是额外的 -0.433 秒。
在第一个参数中输入搜索时间,在第二个和第三个参数中输入 kCMTimeZero
。像这样:
// seekTime is the time I’m seeking to
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
我也遵循了 ,诀窍是当我为第二个参数初始化我的寻道时间时,我必须将 1000 设置为 1000 才能正常工作。像这样:
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
这是我的快进按钮的代码:
@objc fileprivate func fastForwardButtonTapped() {
guard let playerItem = playerItem else { return }
guard let player = player else { return }
let duration: Float64 = CMTimeGetSeconds(playerItem.duration)
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
}
我正在使用 AVPlayer 播放视频。我跟着这个视频教程 Let's Build That App
我使用 UISlider/scrubber 来配合当前的 frame/time 视频。
我有一个 10.43 秒的视频,我使用快进功能将我带到最后。
@objc fileprivate func fastForwardButtonTapped() {
guard let playerItem = playerItem else { return }
guard let player = player else { return }
let duration: Float64 = CMTimeGetSeconds(playerItem.duration)
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1)
player.seek(to: seekTime)
}
视频走到了最后,但问题是滑块只走到了 10 秒点,我无法让它走到最后的 0.43 秒。我收到以下警告消息:
滑块的值在 player?.addPeriodicTimeObserver()
中确定因此,当我按快进而不是滑块走到尽头时,它会在几个点外停止(注意白色 space):
如何获得更准确的值,以便我的滑块可以一直滑动到最后?
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &playerItemContext)
let interval = CMTime(value: 1, timescale: 2)
timeObserverToken = player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: {
[weak self] (progressTime) in
let seconds = CMTimeGetSeconds(progressTime)
let secondsString = String(format: "%02d", Int(seconds) % 60)
let minutesString = String(format: "%02d", Int(seconds) / 60)
self?.currentTimeLabel.text = "\(minutesString):\(secondsString)"
if let duration = self?.playerItem!.duration{
let durationSeconds = CMTimeGetSeconds(duration)
self?.slider.value = Float(seconds / durationSeconds) // SLIDER IS UPDATED HERE
}
})
我做了一些研究,AVPlayer
有一个 seek
方法:
player.seek(to: <CMTime>, toleranceBefore: <CMTime>, toleranceAfter: <CMTime>)
使用这种方法,您可以对其设置容差以补偿截断溢出,在我的情况下是额外的 -0.433 秒。
在第一个参数中输入搜索时间,在第二个和第三个参数中输入 kCMTimeZero
。像这样:
// seekTime is the time I’m seeking to
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
我也遵循了
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
这是我的快进按钮的代码:
@objc fileprivate func fastForwardButtonTapped() {
guard let playerItem = playerItem else { return }
guard let player = player else { return }
let duration: Float64 = CMTimeGetSeconds(playerItem.duration)
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
}