【问题标题】:AVPlayer Seek not accurate even with toleranceBefore: kCMTimeZeroAVPlayer 即使使用了toleranceBefore,Seek也不准确:kCMTimeZero
【发布时间】:2019-02-08 09:11:18
【问题描述】:

我们有一个可以播放长 mp3 文件(1 小时)的应用。我们希望能够从文件中的设定点开始播放。但是,当我们这样做时,它最多有 10 秒的误差。

代码如下:

  let trackStart = arrTracks![MediaPlayer.shared.currentSongNo].samples

  let frameRate : Int32 = (MediaPlayer.shared.player?.currentItem?.asset.duration.timescale)!

  MediaPlayer.shared.player?.seek(to: CMTimeMakeWithSeconds(Double(trackStart), frameRate), 
    toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
  • 我们必须使用 AVPlayer,因为我们需要质量更好的“频谱:”AVAudioTimePitchAlgorithm。
  • 我们没有遇到 AVAudioPlayer 的问题,但是(AFAIK)我们必须使用 AVPlayer,因为我们需要质量更好的“频谱:”AVAudioTimePitchAlgorithm。

  • [编辑:] - 错误是一致的 - 对于给定的请求位置,它总是从相同(错误)的位置播放。重启后也是这样。

非常感谢任何帮助!谢谢

[编辑:]

  • 我们已经尝试过preferredTimescale: playerTimescale
  • 也试过kCMTimeIndefinite而不是kCMTimeZero

【问题讨论】:

  • 这听起来像是 AVURLAsset 的 AVURLAssetPreferPreciseDurationAndTimingKey developer.apple.com/documentation/avfoundation/… 的工作
  • @RhythmicFistman 修复了它。非常感谢,非常感谢您对此的帮助。出于某种原因,我无法单击勾选来接受此答案,因为它在评论中,但如果您重新发布为答案,我会接受它。
  • 太棒了!我已经把我的推测变成了一个权威的答案。

标签: swift avplayer avaudioplayer seek seektotime


【解决方案1】:

我做过类似的事情,但用一个滑块来改变播放的秒数并且效果很好。

 @objc func handleSliderChange(sender: UISlider?){
        if let duration = player?.currentItem?.duration{
            let totalSeconds = CMTimeGetSeconds(duration)
            let value = Float64(videoSlider.value) * totalSeconds
            let seekTime = CMTime(value: CMTimeValue(value), timescale: 1)
            player?.seek(to: seekTime , completionHandler: { (completedSeek) in
                //do smthg later
            })
        }
    }

在你的情况下,这将是这样的:

let trackStart = arrTracks![MediaPlayer.shared.currentSongNo].samples
let value = Float64(trackStart)
let seekTime = CMTime(value: CMTimeValue(value), timescale: 1)
MediaPlayer.shared.player?.seek(to: seekTime , completionHandler: { (completedSeek) in
                //do smthg later
            })

【讨论】:

  • 感谢 Enea,我们已经尝试过了,但没有帮助,不过感谢您的建议。
【解决方案2】:

这就是AVURLAssetAVURLAssetPreferPreciseDurationAndTimingKey 的用途。

Apple's documentation.

注意这会增加加载时间。

【讨论】:

    【解决方案3】:

    试试这个,对我来说效果很好

    @IBAction func playbackSliderValueChanged(_ playbackSlider: UISlider) {
        let seconds : Int64 = Int64(playbackSlider.value)
        let targetTime: CMTime = CMTimeMake(value: seconds, timescale: 1)
        DispatchQueue.main.async {
            self.player!.seek(to: targetTime)
            if self.player!.rate == 0 { // if the player is not yet started playing
                self.player?.play()
            }
        }
    }
    

    【讨论】:

    • 感谢 Naveen,我们尝试了这个,但最终它是 AVURLAssetPreferPreciseDurationAndTimingKey 。但感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 2015-08-06
    • 2019-09-18
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    相关资源
    最近更新 更多