如何在启动AVPlayer时显示暂停的视频而不是黑屏



我能够成功创建一个播放器,但对最初的黑屏感到恼火。我决定覆盖一个UIImageView并在播放器启动后隐藏它。这很有效,但我不想为我所有的视频创建和维护图像。

我可以通过播放并在实例化后立即暂停播放器来获得我想要的确切结果。唯一的问题是,有时播放器的状态被错误地记录,所以当我再次启动播放器时,即使播放器被暂停,状态也被列为已在"播放"。

我开始考虑使用AVPlayerItem seekToTime,但没有找到任何可行的解决方案。有没有一种"非黑客"的方式来实现这一点?

如果您使用的是AVPlayerViewController,这是对播放器控制器的contentOverlayView属性的完美使用。这是播放器层和完全为此目的暴露的控件之间的UIView

首先,创建屏幕截图:

let asset = AVAsset(URL: URL(string: "")!) // link to some video
let imageGenerator = AVAssetImageGenerator(asset: asset)
let screenshotTime = CMTime(seconds: 1, preferredTimescale: 1)
if let imageRef = try? imageGenerator.copyCGImageAtTime(screenshotTime, actualTime: nil) {
    let image = UIImage(CGImage: imageRef)
    // see part 2 below
}

现在,在播放器控制器中添加图像作为contentOverlayView的子视图:

// in the same try block
let imageView = UIImageView(image: image)
let playerVC = AVPlayerViewController()
let playerItem = AVPlayerItem(asset: asset)
playerVC.player = AVPlayer(playerItem: playerItem)
self.presentViewController(playerVC, animated: true) { 
    playerVC.contentOverlayView?.addSubview(imageView)
    // adjust the frame of your imageView to fit on the player controller's contentOverlayView
}

然后,当玩家开始播放资产时,或缓冲完成时,移除imageView子视图。

与玩家关联的AVPlayerLayer具有readyForDisplay属性。

您可以尝试使主机视图成为该值的观察者,并在设置为true后立即进行刷新。

当第一帧准备好渲染时,它被设置为true,因此在玩家有足够的数据播放并将其状态设置为readyToPlay之前。

最新更新