【问题标题】:AVPlayer when user is seeking the video should pause当用户正在寻找视频时,AVPlayer 应该暂停
【发布时间】:2018-09-06 07:25:47
【问题描述】:

我正在使用 AVPlayer 播放视频,我只想在用户不浏览视频时播放视频。如果用户想在视频中走得更远(即他寻找),视频将暂停,当用户完成寻找时,播放器应该从寻找结束的地方继续播放。

有没有办法做到这一点?
这就是我现在播放器中的内容。

final class PlayerViewController {
    private var playPosition: Int = 0
    private var didInitialSetup = false
    var mainPlayerItem: AVPlayerItem?
    var player: AVPlayer?
    var playerController: AVPlayerViewController!

    private var avPlayerItems: [AVPlayerItem] = []

    weak var delegate: PlayerViewControllerDelegate?

    override var mainPlayerItem: AVPlayerItem? {
        willSet {
            observers.forEach { observer in
                observer.invalidate()
            }
            observers.removeAll()

            let statusObserver = newValue?.observe(\.status, options: [.old, .new], changeHandler: { [weak self] item, _ in
                guard let strongSelf = self else { return }
                switch item.status {
                case .readyToPlay:
                    if strongSelf.didInitialSetup == false {
                        strongSelf.initialSetup()
                    }
                case .failed:
                    if let playError = item.error {
                        strongSelf.displayError(error: playError)
                    }
                case .unknown:
                    break
                }
            })

            if let observer = statusObserver {
                self.observers.append(observer)
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.loadAVPlayerItems()
    }

    // MARK: - Private methods

    private func loadAVPlayerItems() {
        self.player = AVQueuePlayer(items: self.avPlayerItems)
        self.playerController.player = self.player
        self.player?.play()

        let rateObserver = self.player?.observe(\.rate, options: [.new], changeHandler: { [weak self] player, _ in
            guard let strongSelf = self else { return }
            if player.rate == 0 {
                strongSelf.cancelNext()
            }
        })

        if let observer = rateObserver {
            self.observers.append(observer)
        }

        if let lastItem = avPlayerItems.last {
            NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemDidReachEnd), name: .AVPlayerItemDidPlayToEndTime, object: lastItem)
        }
    }

    @objc func playerItemDidReachEnd() {
        if let time = self.player?.currentItem?.currentTime() {
            self.eventsLogger?.playerDidComplete(playHeadCMTime: time)
        }

        self.playheadTimer?.invalidate()
        self.playheadTimer = nil

        self.mainPlayerItem = nil
        self.player?.pause()
        self.playPosition = 0

        self.dismiss(animated: true, completion: nil)
    }

    private func initialSetup() {
        guard self.isViewLoaded && (self.view.window != nil) else {
            self.player?.pause()
            return
        }

        self.didInitialSetup = true

        let timePosition = CMTime(seconds: Double(self.playPosition), preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        if self.playPosition > 1 {
            self.player?.seek(to: timePosition)
        }

        self.eventsLogger?.playerDidStart(playHeadCMTime: timePosition)
        self.playheadTimer?.invalidate()
        self.playheadTimer = nil
        self.startPlayheadTimer()
    }
}
class CustomAVPlayer: AVPlayer {
    override func seek(to time: CMTime, toleranceBefore: CMTime, toleranceAfter: CMTime, completionHandler: @escaping (Bool) -> Void) {
        super.seek(to: time, toleranceBefore: toleranceBefore, toleranceAfter: toleranceAfter, completionHandler: completionHandler)
        print(">> user scrubbing")
    }
}

【问题讨论】:

  • 是的,有一种方法可以做到这一点,但是当您说“滚动浏览视频”时......您的意思是浏览它吗?或在屏幕上滚动?此外,如果您显示该文件的代码,可能对我们有用……这样我们就可以确定在哪里添加内容。
  • 是的,如果用户通过它寻找。我编辑了我的回答
  • 用户的“Seek”操作使用了什么?
  • 我尝试使用一个扩展(我现在编辑),但我不知道如何在 loadAVPlayerItems() 方法中使用它。

标签: swift avplayer


【解决方案1】:

我会尽量根据我的理解来回答,并参考一般情况。

另外,我假设您正在构建自己的视频播放器。


看看你可以使用观察的玩家变量。 AVFoundation 有很多可观察的属性,你应该利用它来发挥你的优势。以下是一些需要研究的属性:

  • AVPlayerItem 的playbackBufferEmpty 向前搜索时会收到通知。除非您的视频播放完毕。一般情况下,当缓冲区为空时应该暂停,当缓冲区空时继续。

  • AVPlayer的rate一般来说,如果不是1.0并且播放器没有暂停,就应该暂停。那是如果您期望正常的播放速率。但是,如果您支持不同的播放速度(例如使用 canPlaySlowForward 之类的东西),那么您可能需要稍微玩一下。

    Apple says:

    值 0.0 会暂停视频,而值 1.0 会以自然速率播放当前项目。

  • AVPlayer 的status

  • AVPlayerItem 的status


当我说观察时,我的意思是在拥有你的播放器的类中使用类似 observeValueForKeyPath:ofObject:change:context: 的东西。

您可以对照您要观察的值检查keyPath

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 2019-05-07
    • 2012-06-30
    • 1970-01-01
    相关资源
    最近更新 更多