我正在使用AVPlayer
在其中使用URL
显示正在播放的视频。它分为两个部分:
1. 首先,我使用AVPlayer
将AVPlayerLayer
嵌入到视图的子层中,即
var player: AVPlayer?
func configure() {
let urlString = "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
if let url = URL(string: urlString) {
self.player = AVPlayer(url: url)
let playerLayer = AVPlayerLayer(player: self.player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()
}
}
上面的代码工作正常,正在播放视频。
2. 其次,在
UIButton
上,我使用与我之前创建的AVPlayerViewController
实例相同的AVPlayer
呈现AVPlayerViewController
。@IBAction func onTapVideoButton(_ sender: UIButton) {
self.player?.pause()
let controller = AVPlayerViewController()
controller.player = self.player
self.present(controller, animated: true) {
self.player?.play()
}
}
我在这里面临的问题是,在
AVPlayerLayer
打开之后,视频停止播放,但音频仍在播放。我想要的是同步
AVPlayerViewController
和ojit_code中的视频。 最佳答案
我认为将已创建的播放器共享到AVPlayerViewController时出现问题。我不确定为什么要停止,但是如果为该控制器创建一个新的AVPlayer则不会发生。同步播放器和AVPlayerViewController的方法可能是这样的:
首先,创建一个将在关闭AVPlayerViewController时使用的通知名称(Apple无法让您知道用户何时关闭AVPlayerViewController的方式):
extension Notification.Name {
static let avPlayerDidDismiss = Notification.Name("avPlayerDidDismiss")
}
然后,您将扩展AVPlayerViewController以便在将其关闭时发布此通知,并发送用户离开视频的时间:
extension AVPlayerViewController {
open override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let seekTime = player?.currentTime() {
let userInfo = ["seekTime": seekTime]
NotificationCenter.default.post(name: .avPlayerDidDismiss, object: nil, userInfo: userInfo)
}
}
}
在您的ViewController中,您会观察到该通知,获取要使用的seekTime并使用它来设置avPlayer:
class ViewController: UIViewController {
var player: AVPlayer?
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
configure()
NotificationCenter.default.addObserver(self, selector: #selector(avPlayerDidDismiss), name: .avPlayerDidDismiss, object: nil)
}
func configure() {
self.player = getPlayer()
let playerLayer = AVPlayerLayer(player: self.player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
self.player?.play()
}
@IBAction func onTapVideoButton(_ sender: UIButton) {
self.player?.pause()
let controllerPlayer = getPlayer()
controllerPlayer.currentItem?.seek(to: self.player!.currentTime(), completionHandler: nil)
let controller = AVPlayerViewController()
controller.player = controllerPlayer
self.present(controller, animated: true, completion: {
controller.player?.play()
})
}
func getPlayer() -> AVPlayer {
let url = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!
return AVPlayer(url: url)
}
@objc
private func avPlayerDidDismiss(_ notification: Notification) {
if let seekTime = notification.userInfo?["seekTime"] as? CMTime {
player?.currentItem?.seek(to: seekTime, completionHandler: nil)
player?.play()
}
}
}
缺点:它将为每个AVPlayerViewController发送通知。需要此信息时,可以使用add you作为观察者。希望能有所帮助。
关于ios - 在AVPlayerLayer和AVPlayerViewController中同步视频,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53352205/