我正在屏幕上并排播放两个视频,所以我有两个AVPlayer实例。我正在使用通知正常检测到视频播放结束。两个视频结束时都会被我的选择器(playerDidFinishPlaying)调用。
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: .AVPlayerItemDidPlayToEndTime, object: nil)
现在我的问题是在选择器(playerDidFinishPlaying)中,我想检测它为哪个avplayer调用了?如何唯一标识视频结束的AVPlayer?
通过通知对象进行唯一标识,
以对象.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
}
}
轻松更新了@ 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()
}
}
另一个想法。更新了@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")
}
}