[在使用多个AVPlayers时如何检测哪个视频结束?

问题描述 投票:0回答:3

我正在屏幕上并排播放两个视频,所以我有两个AVPlayer实例。我正在使用通知正常检测到视频播放结束。两个视频结束时都会被我的选择器(playerDidFinishPlaying)调用。

NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: .AVPlayerItemDidPlayToEndTime, object: nil) 

现在我的问题是在选择器(playerDidFinishPlaying)中,我想检测它为哪个avplayer调用了?如何唯一标识视频结束的AVPlayer?

ios swift avplayer avplayeritem avkit
3个回答
2
投票

通过通知对象进行唯一标识,

以对象.AVPlayerItemDidPlayToEndTime发布通知player.currentItem

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

简单方法:

以下代码有效,缺点是当一个播放器结束时,notify方法将被调用两次。

    var player = AVPlayer()
    var playerTwo = AVPlayer()


    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlay(_:)), name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlay(_:)), name: .AVPlayerItemDidPlayToEndTime, object: playerTwo.currentItem)

    }


     @objc func playerDidFinishPlay(_ noti: Notification) {
        if let p = noti.object as? AVPlayerItem, p == player.currentItem{
             print("1")
        }

        if let p = noti.object as? AVPlayerItem, p == playerTwo.currentItem{
             print("2")
        }
    }

跟踪状态方式:

有了通知,您可以看到玩家已经结束。

您需要找到播放器。

玩家必须遵守两个规则,它已经开始,并且已经结束。

使用var hasPlay: (one: Bool, two: Bool),找到正在播放的播放器。

使用isPlaying查找不再播放的播放器。

var player = AVPlayer()
var playerTwo = AVPlayer()

var hasPlay: (one: Bool, two: Bool) = (false, false)


override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlay), name: .AVPlayerItemDidPlayToEndTime, object: nil)
    }

    @IBAction func beepPressed(_ sender: UIButton) {
        hasPlay.one = true
        let url = // ...
        player = AVPlayer(url: url!)
        player.play()

    }


    @IBAction func beepPressedTwo(_ sender: UIButton) {
       hasPlay.two = true

       let url = // ...
       playerTwo = AVPlayer(url: url!)
       playerTwo.play()

    }

    @objc func playerDidFinishPlay() {

        if player.isPlaying == false, hasPlay.one == true{
            hasPlay.one = false
            print("1")
        }

        if playerTwo.isPlaying == false, hasPlay.two == true{
            hasPlay.two = false
            print("2")
        }


    }

}




extension AVPlayer {
    var isPlaying: Bool {
        return rate != 0 && error == nil
    }
}

1
投票

轻松更新了@ dengST30的方法一。

注册了两个通知后,任何结束方法都会被调用两次。

因此,需要添加一些互斥的。

var player = AVPlayer()
var playerTwo = AVPlayer()

var justEnded: (one: Bool, two: Bool) = (false, false)

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlay(_:)), name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
    NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlay(_:)), name: .AVPlayerItemDidPlayToEndTime, object: playerTwo.currentItem)
    playButton.tintColor = .systemBlue
}



@objc func playerDidFinishPlay(_ noti: Notification) {
           if let p = noti.object as? AVPlayerItem, p == player.currentItem {

                if justEnded.one == false{
                    print("1")
                }
                justEnded.one.toggle()
           }

           if let p = noti.object as? AVPlayerItem, p == playerTwo.currentItem{
                if justEnded.two == false{
                    print("2")
                }

                justEnded.two.toggle()
           }
       }

1
投票

另一个想法。更新了@black_pearl的方法

不同的通知注册,具有不同的通知方法。

    var player = AVPlayer()
    var playerTwo = AVPlayer()



    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlay(_:)), name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishMusic(_:)), name: .AVPlayerItemDidPlayToEndTime, object: playerTwo.currentItem)

    }


       @objc func playerDidFinishPlay(_ noti: Notification) {
           if let p = noti.object as? AVPlayerItem, p == player.currentItem {
                print("1")
           }
       }


    @objc func playerDidFinishMusic(_ noti: Notification) {
        if let p = noti.object as? AVPlayerItem, p == playerTwo.currentItem{
            print("2")
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.