使用多个 AVPlayer 时如何检测哪个视频结束了?
Posted
技术标签:
【中文标题】使用多个 AVPlayer 时如何检测哪个视频结束了?【英文标题】:How to detect which video ended when using multiple AVPlayers? 【发布时间】:2019-11-09 12:55:52 【问题描述】:我在屏幕上并排播放两个视频,所以我有两个 AVPlayer 实例。我正在使用工作正常的通知检测视频播放结束。我的选择器(playerDidFinishPlaying)在两个视频结束时都会被调用。
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: .AVPlayerItemDidPlayToEndTime, object: nil)
现在我的问题出在选择器(playerDidFinishPlaying)中,我想检测它是为哪个 avplayer 调用的?如何唯一标识视频结束的 AVPlayer?
【问题讨论】:
我的选择器在两个视频结束时都被完美调用。我想唯一标识调用它的 avplayer。 【参考方案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")
【讨论】:
【参考方案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")
轨道状态方式:
通过Notification,你可以看到,有一个玩家结束了。
你需要找到播放器。
玩家必须遵守两条规则,开始,结束。
使用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
【讨论】:
我有两个玩家。那么我应该通过哪个对象? player1.currentItem 还是 player2.currentItem?【参考方案3】:更新了@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()
【讨论】:
以上是关于使用多个 AVPlayer 时如何检测哪个视频结束了?的主要内容,如果未能解决你的问题,请参考以下文章
使用swift 3点击单元格时如何在Avplayer中播放来自url的视频