我们将URL中的MP4视频加载到AVPlayer中。 AVPlayer位于骨骼图像的后面,当AVPlayer进入状态“ Ready To Play”时,我们将其隐藏。
我们希望在隐藏骨架图像后立即看到视频的第一帧。但是,视频的第一帧会在稍有延迟后出现。指示AVPlayer中的视频已加载并准备就绪的状态是什么?
func prepareVideo(videoUrl: URL?, owner: UIView, autoStart: Bool = false) {
self.player = AVPlayer(url: videoUrl!)
let playerController = AVPlayerViewController()
playerController.player = player
playerController.view.layer.shouldRasterize = true
playerController.view.frame = owner.frame
playerController.view.isOpaque = true
playerController.view.backgroundColor = UIColor.clear
playerController.view.layer.borderColor = UIColor.clear.cgColor
playerController.view.layer.borderWidth = 0
playerController.showsPlaybackControls = false
playerController.updatesNowPlayingInfoCenter = false
owner.addSubview(playerController.view)
owner.sendSubview(toBack: playerController.view)
timerStart() // this starts a timer that checks the AVPlayer status
if autoStart {
playVideo()
}
}
@objc func timerStatusCheck() {
// function called by a Timer and checks the status of AVPlayer
if player!.status == AVPlayerStatus.readyToPlay {
print("ready to play")
timerStop()
if (readyToPlayHandler != nil) {
self.readyToPlayHandler!() // here we hide the skeleton image that shows while video is loading
}
} else if player!.status == AVPlayerStatus.failed {
timerStop()
MessageBox.showError("Video Failed to start")
}
}
答案 0 :(得分:1)
当AVPlayer报告速率= 1时,它正在播放视频。但是,这并不意味着视频在AVPlayerViewController中可见。为此,您需要AVPlayerViewController的属性“ isReadyForDisplay”为true。
https://developer.apple.com/documentation/avkit/avplayerviewcontroller/1615830-isreadyfordisplay
请注意,AVPlayerViewController.isReadyForDisplay和AVPlayer.status都是可观察到的KVO,比使用Timer响应性更好。
还请注意,如果您使用AVPlayerLayer来显示视频(而不是AVPlayerViewController),则出于相同的原因,您需要观察AVPlayerLayer的“ isReadyForDisplay”。
@objc func timerStatusCheck() {
// function called by a Timer and checks the status of AVPlayer
if player!.status == AVPlayerStatus.readyToPlay {
print("ready to play")
// check that controller's view is showing video frames from player
if playerController.isReadyForDisplay == false {
print("view not yet showing video")
return
}
timerStop()
if (readyToPlayHandler != nil) {
self.readyToPlayHandler!() // here we hide the skeleton image that shows while video is loading
}
} else if player!.status == AVPlayerStatus.failed {
timerStop()
MessageBox.showError("Video Failed to start")
}
}