首页 文章

如何检测AVPlayer视频何时结束播放?

提问于
浏览
44

我正在使用AVPlayer在Swift中播放本地视频文件(mp4) . 有没有人知道如何检测视频完成播放?谢谢

9 回答

  • 58

    For SWIFT 3.0 这很好用

    class PlayVideoViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PlayVideoViewController.finishVideo), name: NSNotification.Name.AVPlayerItemDidPlayToEndTimeNotification, object: nil)
        }
    
        func finishVideo()
        {
            print("Video Finished")
        }
    }
    
  • 7

    要获得 AVPlayerItemDidPlayToEndTimeNotification ,您的对象需要是 AVPlayerItem .

    为此,只需使用 AVPlayer 上的 .currentItem 属性即可

    现在,一旦视频结束,您将收到通知!

    看我的例子:

    let videoPlayer = AVPlayer(URL: url)       
    
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:",
            name: AVPlayerItemDidPlayToEndTimeNotification, object: videoPlayer.currentItem)
    
    func playerDidFinishPlaying(note: NSNotification) {
        print("Video Finished")
    }
    

    Swift 3

    let videoPlayer = AVPlayer(URL: url)       
    
    NotificationCenter.default.addObserver(self, selector: Selector(("playerDidFinishPlaying:")), 
           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: videoPlayer.currentItem)
    
    func playerDidFinishPlaying(note: NSNotification) {
        print("Video Finished")
    }
    

    不要忘记删除 deinit 中的观察者

  • 2

    Swift 3.0

    let videoPlayer = AVPlayer(URL: url)
    
    NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
    
    @objc func playerDidFinishPlaying(note: NSNotification){
            print("Video Finished")
        }
    
  • 2

    Swift 4.0

    这个对我有用 . 感谢@Channel

    private func playVideo(fileURL: String) {
    
                // Create RUL object
                let url = URL(string: fileURL)
    
                // Create Player Item object
                let playerItem: AVPlayerItem = AVPlayerItem(url: url!)
                // Assign Item to Player
                let player = AVPlayer(playerItem: playerItem)
    
                // Prepare AVPlayerViewController
                let videoPlayer = AVPlayerViewController()
                // Assign Video to AVPlayerViewController
                videoPlayer.player = player
    
                NotificationCenter.default.addObserver(self, selector: #selector(myViewController.finishVideo), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
    
                // Present the AVPlayerViewController
                present(videoPlayer, animated: true, completion: {
                        // Play the Video
                        player.play()
                })
    
        }
    
        @objc func finishVideo()
        {
                print("Video Finished")
        }
    
  • 33

    Swift 3.0

    let videoPlayer = AVPlayer(URL: url)
    NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
    
    func playerDidFinishPlaying(note: NSNotification){
        //Called when player finished playing
    }
    
  • 1

    在Swift 3和RxSwift 3.5中,您所要做的就是:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        NotificationCenter.default.rx.notification(Notification.Name.AVPlayerItemDidPlayToEndTime)
            .asObservable().subscribe(onNext: { [weak self] notification in
    
                //Your action
    
            }).addDisposableTo(disposeBag)
    }
    
  • 2

    Swift 4.2版本:

    var player: AVPlayer!
      //
      //
    // Configure Player
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        let filepath: String? = Bundle.main.path(forResource: "selectedFileName", ofType: "mp4")
        if let filepath = filepath {
            let fileURL = URL.init(fileURLWithPath: filepath)
            player = AVPlayer(url: fileURL)
            let playerLayer = AVPlayerLayer(player: player)
            // Register for notification
            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(playerItemDidReachEnd),
                                                             name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                                                             object: nil) // Add observer
    
            playerLayer.frame = self.view.bounds
            self.view.layer.addSublayer(playerLayer)
            player.play()
        }
    }
    // Notification Handling
    @objc func playerItemDidReachEnd(notification: NSNotification) {
        player.seek(to: CMTime.zero)
        player.play()
    }
    // Remove Observer
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
  • 5

    For SWIFT 3.0

    这里'fullUrl'是视频的网址,并确保网址中没有空格,您应该将'Space'替换为'%20',以便网址可以正常工作 .

    let videoURL = NSURL(string: fullUrl)
      let player = AVPlayer(url: videoURL! as URL)
    
      playerViewController.delegate = self
      playerViewController.player = player
      self.present(playerViewController, animated: false) {
    
        self.playerViewController.player!.play()
    
        NotificationCenter.default.addObserver(self, selector: #selector(yourViewControllerName.playerDidFinishPlaying), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem)
      }
    

    在视图控制器中添加以下给定方法 .

    func playerDidFinishPlaying(){    
    print("Video Finished playing in style")
    }
    
  • 0

    我知道这里有很多可接受的答案......

    但是,另一条路线可能是向AVPlayer添加边界时间观察器 . 你必须拥有视频的持续时间,你可以从 player.currentItem 获得,然后将其添加为你想要的时间边界 .

    fileprivate var videoEndObserver: Any?
    
    func addVideoEndObserver() {
        guard let player = YOUR_VIDEO_PLAYER else { return }
    
        // This is just in case you are loading a video from a URL.
        guard let duration = player.currentItem?.duration, duration.value != 0 else {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: { [weak self] in
                self?.addVideoEndObserver()
            })
    
            return
        }
    
        let endTime = NSValue(time: duration - CMTimeMakeWithSeconds(0.1, duration.timescale))
        videoEndObserver = player.addBoundaryTimeObserver(forTimes: [endTime], queue: .main, using: {
            self.removeVideoEndObserver()
    
            // DO YOUR STUFF HERE...
        })
    }
    
    func removeVideoEndObserver() {
        guard let observer = videoEndObserver else { return }
    
        videoPlayer.player?.removeTimeObserver(observer)
        videoEndObserver = nil
    }
    

相关问题