Reputation: 6777
I have an AVPlayer
object that I am using to play a video. When the user taps a button, the video is swapped out for a different video, which continues playing. Just using replaceCurrentItem(with:)
is resulting in a few tenths of a second of a black frame appearing on my AVPlayerLayer
that is displaying the video content.
I have code in place to render an image at the current frame before the AVPlayerItem
is swapped out, to bridge the gap before the new AVPlayerItem
has a frame ready to display, but the black frame is blocking this image from view. Is there any way to control what the AVPlayerLayer
will render before it has actual video data to display?
Alternatively, is there a way to be notified that the AVPlayerLayer
(or the AVPlayerItem
has actually begun displaying video data? Observing for when the state of the item becomes .readyToPlay
triggers too early, hiding the image at that point still leaves the black frame visible.
Upvotes: 3
Views: 1741
Reputation: 1592
I had the same flash problem with my macOS app. I resolved it by renewing AVPlayerLayer
each time I play a new file.
I have an AVPlayer
subclass. The function below removes AVPlayerLayer
from its super layer and add a new layer to the view.
class MyVideoPlayer: AVPlayer {
func addLayer(view: NSView) {
view.layer!.sublayers?
.filter { $0 is AVPlayerLayer }
.forEach { $0.removeFromSuperlayer() }
let layer = AVPlayerLayer.init(player: self)
layer.videoGravity = AVLayerVideoGravity.resize
layer.frame = view.bounds
view.layer!.addSublayer(layer)
}
}
In my ViewController
, I call this before I play a video content.
myVideoPlayer.addLayer(view: self.view)
Upvotes: 1