【问题标题】:AVPlayerItemDidPlayToEndTime never reaches selector on Swift 3AVPlayerItemDidPlayToEndTime 永远不会到达 Swift 3 上的选择器
【发布时间】:2016-09-23 20:26:13
【问题描述】:

我正在使我的应用适应 Swift 3,但我遇到了这个问题。这曾经在 Swift 2.2 上工作,但现在它被打破了。 moviePlayBackFinished 永远不会被调用。我尝试以多种方式添加观察者,但均未成功。

    NotificationCenter.default.addObserver(self, selector: #selector(self.moviePlayBackFinished(_:)),
                                           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem);

    NotificationCenter.default.addObserver(self, selector: #selector(moviePlayBackFinished(_:)),
                                           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem);

    NotificationCenter.default.addObserver(self, selector: #selector(self.moviePlayBackFinished(sender:)),
                                           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem);

// (...)

@objc func moviePlayBackFinished(sender : AnyObject) {
    print("playbackFinished");
    let zeroCM : CMTime = CMTime(seconds: 0, preferredTimescale: 1000000000);
    playerLayer.player?.seek(to: zeroCM);
}

@objc func moviePlayBackFinished(_ notification: Notification) {
    print("playbackFinished");
    let zeroCM : CMTime = CMTime(seconds: 0, preferredTimescale: 1000000000);
    playerLayer.player?.seek(to: zeroCM);
}

任何想法都会被采纳。

谢谢

【问题讨论】:

    标签: swift avplayer swift3


    【解决方案1】:

    这个问题有多种可能的原因。

    NotificationCenter
        .default
        .addObserver(self, 
                     selector: #selector(self.moviePlayBackFinished(sender:)),
                     name: .AVPlayerItemDidPlayToEndTime,
                     object: player.currentItem)
    

    首先,您必须将 object 设置为 nil。 AVPlayerItemDidPlayToEndTime 通知自动将对象设置为最后到达的AVPlayerItem。如果您手动更改它,您将不会收到任何AVPlayerItemDidPlayToEndTime 的通知。

    其次,根据AVPlayerItemDidPlayToEndTime文档:

    重要

    此通知可能发布在与观察者注册的线程不同的线程上。

    所以,为了确保您应该检查通知是否在您想要的线程上。

    从UIViewController 或AVPlayer 子类添加观察者并不重要。

    【讨论】:

    • 是否有关于“AVPlayerItemDidPlayToEndTime”通知以原子方式将对象设置为 AVPlayerItem 的文档?因为对我来说发生了什么,两个 playerItems 被委派了结束时间消息。
    • Check this link。它说The notification’s object is the item that finished playing.
    • 我正在使用 AVQueuePlayer,只有在队列中的第一个项目播放完毕后才会触发此通知。队列中的任何其他项目都没有调用选择器。
    • @SPS 你找到解决方案了吗?
    【解决方案2】:

    使用此代码..

    NotificationCenter.default.addObserver(self, selector: #selector(detailViewController.playw), name:NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
    

    playw 是函数名,你必须让函数像

    func playw(){
    //do here whatever you want to do
    
        }
    

    还有什么问题可以问我。

    【讨论】:

    • 如何返回点击 AVPlayer 中的“完成”按钮。 ?请帮帮我。
    【解决方案3】:

    瑞恩是对的!

    从 UIViewController 或 AVPlayer 子类观察都没关系。

    只需使用

    addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void)
    

    而不是

    addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)
    

    【讨论】:

      【解决方案4】:

      好的,问题是我试图从包含视频的子类中添加观察者,而不是从包含视频视图的 ViewController 中添加它。

      所以为了解决这个问题,我基本上将 NotificationCenter.default.addObserver 调用移动到 UIViewController 和 presto,一切都解决了。

      谢谢大家

      【讨论】:

      • 这不是一个正确的答案。应该是线程问题。根据AVPlayerItemDidPlayToEndTime、Important This notification may be posted on a different thread than the one on which the observer was registered.的快速帮助文档。一个简单的解决方法是使用基于块的 NSNotificationCenter 观察。
      猜你喜欢
      • 1970-01-01
      • 2016-06-22
      • 2020-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 2016-06-21
      相关资源
      最近更新 更多