开发者社区> 问答> 正文

为什么AVPlayer周期性观察器显示设备上开始时间之前的当前时间?

带着AVPlayer,在寻求特定的时间(例如0.5s)并调用play()之后,定期观察器对玩家的回调很少currentTime() 以前寻找位置。下面是代码:

试验波档案

import AVFoundation

class Player {

    init() {
        let session = AVAudioSession.sharedInstance()
        do {
            try session.setCategory(.playAndRecord, mode: .videoRecording)
            try session.setActive(true)
            session.requestRecordPermission { allowed in
                if !allowed {
                    fatalError("you must allow mic access")
                }
            }
        } catch {
            fatalError(error.localizedDescription)
        }

        addPeriodicTimeObserver(to: player)

        if let url = Bundle.main.url(forResource: "test_loop", withExtension: "wav") {
            let item = AVPlayerItem(asset: AVAsset(url: url))
            player.replaceCurrentItem(with: item)
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
            self?.seek() {
                DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                    self?.play()
                }
            }
        }
    }

    func addPeriodicTimeObserver(to player: AVPlayer) {
        let time = CMTime(seconds: 0.04, preferredTimescale: timeScale)

        _ = player.addPeriodicTimeObserver(forInterval: time, queue: .main) { [unowned self] _ in
            if
                self.playCalled == true &&
                self.player.currentItem?.status == .readyToPlay &&
                self.player.status == .readyToPlay &&
                self.player.timeControlStatus == .playing {
                print("currentTime \(self.player.currentTime().seconds)")
            }
        }
    }

    func seek(completion: @escaping () -> Void) {
        let time = CMTime(seconds: 0.5, preferredTimescale: timeScale)
        player.seek(to: time, toleranceBefore: .zero, toleranceAfter: .zero) { [unowned self] in
            if $0 {
                print("seek current time: \(self.player.currentTime().seconds)")
                completion()
            }
        }
    }

    func play() {
        if let currentItem = player.currentItem, currentItem.status == .readyToPlay {
            player.play()
            playCalled = true
        }
    }

    let player = AVPlayer()
    let timeScale = CMTimeScale(NSEC_PER_SEC)

    var playCalled: Bool = false

}

它产生:

seek current time: 0.5
currentTime 0.475462793
currentTime 0.475983585
currentTime 0.48074996
currentTime 0.521489168
currentTime 0.561431835
currentTime 0.601529793
currentTime 0.641514043
[...]

重要注记只有在设备上运行时才会发生这种情况。模拟器运行如出一辙。

正如您所看到的,我试图保护自己,因为我无法在任何当前时间打印任何可能相关的时间,但我仍然得到了令人困惑的结果。关于这个问题可能是什么以及如何解决它,有什么想法吗?我很想看到现在的时间盯着我寻找的那一刻:)

展开
收起
游客5akardh5cojhg 2019-12-11 18:44:08 525 0
0 条回答
写回答
取消 提交回答
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载