Swift iOS - 如何管理 Notification.Name.AVPlayerItemDidPlayToEndTime 多个 类 中的不同视频
Swift iOS -How to manage Notification.Name.AVPlayerItemDidPlayToEndTime for different videos in multiple classes
我的应用使用 AVFoundation 在 vc 秒内播放视频。例如,FirstController 播放视频,然后用户可以推动也播放视频的 SecondController,然后他们可以推动也播放视频的 ThirdController ... 如果他们切换选项卡,同样的事情也适用。 TabOne、TabTwo 和 TabThree 上有一个视频屏幕。
我没有在每个 class 中设置与 AVFoundation 关联的所有 playLayer 代码,而是创建了一个包含 AVPlayerViewController()
的 class 并将 class 添加到每个 vc 使用 addChildViewController()
.
问题是因为我有一个 class 来管理 AVFoundation Notification.Name.AVPlayerItemDidPlayToEndTime
在播放器完成播放时收到通知无法区分一个 vc 上的一个视频与另一个视频在不同的vc。例如,在视频播放完毕后,我会显示一个重播按钮。如果第一个选项卡中的视频正在播放,当我切换到 TabTwo 时我会暂停该视频,在 TabTwo 上的视频结束并且出现 replayButton 之后,如果我切换回 TabOne,replayButton 也会出现在 TabOne 的屏幕上(它应该仍然显示暂停按钮)。
问题是即使我有不同的 AVFoundationManager
实例,所有实例都访问通知触发时触发的那个 showReplayButton() function
。
我该如何解决这个问题?
我知道我可以检查 AVFoundationManager 的 parent
以找出哪个父级正在管理它并在 showReplayButton()
函数中使用它,但我不知道要检查哪个 运行就可以了。
AVFoundationManager:
class AVFoundationManager: UIViewController {
....
override func viewDidLoad() {
super.viewDidLoad()
configureAVPlayerController()
}
func configureAVPlayerController() {
let avPlayerVC = AVPlayerViewController()
avPlayerVC.player = player
avPlayerVC.view.frame = view.bounds
avPlayerVC.showsPlaybackControls = false
avPlayerVC.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
addChildViewController(avPlayerVC)
view.addSubview(avPlayerVC.view)
avPlayerVC.didMove(toParentViewController: self)
player?.replaceCurrentItem(with: playerItem!)
player?.play()
NotificationCenter.default.addObserver(self, selector: #selector(showReplayButton), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &itemContext)
}
@obj func showReplayButton(){
// if self.parent ... run a bool on the parent and enclose these two in the paranthesis?
pausePlayButton.isHidden = true
replayButton.isHidden = false
}
}
TabOneClass:
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
TabTwoClass:
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
TabThree 中的 FirstController(根):
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
TabThree 中的第二个控制器(子):
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
我并不是说这是最好的答案,如果有人能想出更好的解决方案,请 post :)
据我了解,玩家无法区分观察者的数量。
(旁注,目前在我的 phone 上,对伪代码深表歉意)
class PlayerViewController {
// other code and functions
func removeObservers() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
在viewWillDisappear
调用remove observers函数
请记住在需要时重新初始化观察者,无论是在显示视图时,还是在初始化下一个视频时。
我得到了the answer from here
在通知中,不要将最后一个参数 object
设置为 nil
,而是将其设置为 player.currentItem
:
像这样:
NotificationCenter.default.addObserver(self, selector: #selector(showReplayButton),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: player?.currentItem)
我的应用使用 AVFoundation 在 vc 秒内播放视频。例如,FirstController 播放视频,然后用户可以推动也播放视频的 SecondController,然后他们可以推动也播放视频的 ThirdController ... 如果他们切换选项卡,同样的事情也适用。 TabOne、TabTwo 和 TabThree 上有一个视频屏幕。
我没有在每个 class 中设置与 AVFoundation 关联的所有 playLayer 代码,而是创建了一个包含 AVPlayerViewController()
的 class 并将 class 添加到每个 vc 使用 addChildViewController()
.
问题是因为我有一个 class 来管理 AVFoundation Notification.Name.AVPlayerItemDidPlayToEndTime
在播放器完成播放时收到通知无法区分一个 vc 上的一个视频与另一个视频在不同的vc。例如,在视频播放完毕后,我会显示一个重播按钮。如果第一个选项卡中的视频正在播放,当我切换到 TabTwo 时我会暂停该视频,在 TabTwo 上的视频结束并且出现 replayButton 之后,如果我切换回 TabOne,replayButton 也会出现在 TabOne 的屏幕上(它应该仍然显示暂停按钮)。
问题是即使我有不同的 AVFoundationManager
实例,所有实例都访问通知触发时触发的那个 showReplayButton() function
。
我该如何解决这个问题?
我知道我可以检查 AVFoundationManager 的 parent
以找出哪个父级正在管理它并在 showReplayButton()
函数中使用它,但我不知道要检查哪个 运行就可以了。
AVFoundationManager:
class AVFoundationManager: UIViewController {
....
override func viewDidLoad() {
super.viewDidLoad()
configureAVPlayerController()
}
func configureAVPlayerController() {
let avPlayerVC = AVPlayerViewController()
avPlayerVC.player = player
avPlayerVC.view.frame = view.bounds
avPlayerVC.showsPlaybackControls = false
avPlayerVC.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
addChildViewController(avPlayerVC)
view.addSubview(avPlayerVC.view)
avPlayerVC.didMove(toParentViewController: self)
player?.replaceCurrentItem(with: playerItem!)
player?.play()
NotificationCenter.default.addObserver(self, selector: #selector(showReplayButton), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &itemContext)
}
@obj func showReplayButton(){
// if self.parent ... run a bool on the parent and enclose these two in the paranthesis?
pausePlayButton.isHidden = true
replayButton.isHidden = false
}
}
TabOneClass:
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
TabTwoClass:
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
TabThree 中的 FirstController(根):
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
TabThree 中的第二个控制器(子):
let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)
我并不是说这是最好的答案,如果有人能想出更好的解决方案,请 post :) 据我了解,玩家无法区分观察者的数量。
(旁注,目前在我的 phone 上,对伪代码深表歉意)
class PlayerViewController {
// other code and functions
func removeObservers() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
在viewWillDisappear
调用remove observers函数
请记住在需要时重新初始化观察者,无论是在显示视图时,还是在初始化下一个视频时。
我得到了the answer from here
在通知中,不要将最后一个参数 object
设置为 nil
,而是将其设置为 player.currentItem
:
像这样:
NotificationCenter.default.addObserver(self, selector: #selector(showReplayButton),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: player?.currentItem)