Swift iOS -CMTimeMakeWithSeconds:警告:由于时间比例非常低,引入了-0.433错误

Lan*_*ria 2 uislider ios avplayer cmtime swift

我正在使用AVPlayer播放视频。我遵循了此视频教程,让我们构建该应用程序

我使用UISlider / scrubber以及视频的当前帧/时间。

我有一个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)
}
Run Code Online (Sandbox Code Playgroud)

视频播放到最后,但问题是滑块仅到达10秒点,而我无法到达最后的0.43秒。我收到以下警告消息:

在此处输入图片说明

滑块的值在中确定。player?.addPeriodicTimeObserver()因此,当我快速向前按而不是滑块到达终点时,它会停止几个点的距离(请注意空白):

在此处输入图片说明

如何获得更准确的值,以便滑块可以一直擦洗到底?

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
    }
})
Run Code Online (Sandbox Code Playgroud)

Lan*_*ria 5

我做了一些研究,AVPlayer并找到了解决seek方法:

player.seek(to: <CMTime>, toleranceBefore: <CMTime>, toleranceAfter: <CMTime>)
Run Code Online (Sandbox Code Playgroud)

使用这种方法,您可以在其上设置公差以补偿截断的溢出,在我的情况下,该溢出是额外的-0.433秒。

在第一个参数中,您花费了寻求的时间;在第二个和第三个参数中,您输入了kCMTimeZero。像这样:

// seekTime is the time I’m seeking to
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
Run Code Online (Sandbox Code Playgroud)

我也遵循了这个答案,诀窍在于,当我为第二个参数初始化搜索时间时,必须投入1000才能正常工作。像这样:

let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
Run Code Online (Sandbox Code Playgroud)

这是我的快进按钮的代码:

@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)
}
Run Code Online (Sandbox Code Playgroud)