Swift iOS -CMTimeMakeWithSeconds:警告:由于时间尺度非常低而引入了 -0.433 的错误

Posted

技术标签:

【中文标题】Swift iOS -CMTimeMakeWithSeconds:警告:由于时间尺度非常低而引入了 -0.433 的错误【英文标题】:Swift iOS -CMTimeMakeWithSeconds: warning: error of -0.433 introduced due to very low timescale 【发布时间】:2018-03-15 04:02:35 【问题描述】:

我正在使用 AVPlayer 播放视频。我跟着这个视频教程Let's Build That App

我使用 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)

视频走到了最后,但问题是滑块只到了 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
    
)

【问题讨论】:

【参考方案1】:

我做了一些研究,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)

我也关注了this answer,诀窍是当我为第二个参数初始化我的搜索时间时,我必须输入 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)

【讨论】:

或者你可以使用CMTimeScale(NSEC_PER_SEC)而不是1000。 使用它有什么好处?

以上是关于Swift iOS -CMTimeMakeWithSeconds:警告:由于时间尺度非常低而引入了 -0.433 的错误的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发中OC和swift的对比

ios OC、swift混编制作framework

iOS-swift-基础篇1

iOS开发系列--Swift 3.0

swift 2016年 - iOS / PlayerViewController.swift

swift iOS URL Schemes Swift