swift - 如何在队列播放器的 currentItem 上设置观察者?
问题描述
我正在尝试为currentItem
of设置一个观察者,AVQueueplayer
但我收到一个名为EXC_BAD_ACCESS
. 有人能帮助我吗?感谢您的关注。我期待着您的回复。这是我的代码:
struct VideoPlayerS : UIViewControllerRepresentable {
var work : WorkoutDeS
@Binding var player : AVQueuePlayer
var playerLayer = AVPlayerLayer()
public func makeUIViewController(context: Context) -> AVPlayerViewController {
let items = [
AVPlayerItem(url: URL(fileURLWithPath: String(work.url1))),
AVPlayerItem(url: URL(fileURLWithPath: String(work.url2)))
]
let player = AVQueuePlayer(items: items)
let controller = AVPlayerViewController()
DispatchQueue.main.async {
self.player = player
}
controller.player = player
controller.videoGravity = .resizeAspectFill
player.actionAtItemEnd = .none
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { _ in
self.player.seek(to: CMTime.zero)
self.player.play()
}
player.play()
player.currentItem?.addObserver(AVQueuePlayer(), forKeyPath: "status", options: NSKeyValueObservingOptions(), context: nil)
func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status" {
print("Hello")
player.currentItem?.removeObserver(AVQueuePlayer(), forKeyPath: "status")
}
}
return controller
}
func rewindVideo(notification: Notification) {
playerLayer.player?.seek(to: .zero)
}
public func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayerS>) {
}
}
解决方案
Representable,即struct,不能用于KVO观察者。您可以Coordinator
用作观察者。
这是使用可能方法的修改代码:
struct VideoPlayerS : UIViewControllerRepresentable {
var work : WorkoutDeS
@Binding var player : AVQueuePlayer
var playerLayer = AVPlayerLayer()
public func makeUIViewController(context: Context) -> AVPlayerViewController {
let items = [
AVPlayerItem(url: URL(fileURLWithPath: String(work.url1))),
AVPlayerItem(url: URL(fileURLWithPath: String(work.url2)))
]
let player = AVQueuePlayer(items: items)
let controller = AVPlayerViewController()
DispatchQueue.main.async {
self.player = player
}
controller.player = player
controller.videoGravity = .resizeAspectFill
player.actionAtItemEnd = .none
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { _ in
self.player.seek(to: CMTime.zero)
self.player.play()
}
player.currentItem?.addObserver(context.coordinator, forKeyPath: "status", options: [.new], context: nil)
player.play()
return controller
}
func makeCoordinator() -> Coordinator {
Coordinator(owner: self)
}
class Coordinator: NSObject {
var owner : VideoPlayerS
init(owner: VideoPlayerS) {
self.owner = owner
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard let item = object as? AVPlayerItem else { return }
if keyPath == "status" {
print("Hello")
item.removeObserver(self, forKeyPath: "status")
}
}
}
func rewindVideo(notification: Notification) {
playerLayer.player?.seek(to: .zero)
}
public func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayerS>) {
}
}
推荐阅读
- python - 从 OrderDict 到字典 python
- bash - 在 VSTS 上的 bash 脚本中使用变量组中的变量
- javascript - 使用 Trianglify 作为网站背景?
- javascript - 使用 CodeIgniter 中的复选框生成特定行的 excel 报告
- python - 如何计算 torando 中的网络延迟?
- javascript - 如何更改传单归属
- regex - 使用 bash 和 awk 将多个子域分成所有可能的子域组合
- vb.net - 在 MsgBox 中单击 Dialog 结果后如何保持显示的表单?
- centos6 - 为什么在centos6上执行'pip install shadowsocks'时系统提示'无效语法'
- vue.js - 借助 VueJs 实现登录和注册