AVPlayerLayer sometimes doesn't render video frames

Hi,


I've been investigating an issue where video playback occasionally becomes audio only playback. I'm debugging on on iPhone 6 plus with iOS 9.3 (13E233).

Are there any hints for what to check when an AVPlayerLayer doesn't render the video frames?


The app has a UIView where layerClass is set to AVPlayerLayer.self.

For debugging purposes the background color of the AVPlayerLayer is set to green.


The flow in the code:

1) The player view is displayed (the entire display becomes green)


The following is not on the main thread/queue, but I don't think this is required?

2) An AVPlayerItem is created

3) An AVPlayer() is created (not on the main thread)

4) The AVPlayer is set to the AVPlayerLayer (not on the main thread/queue, but I don't think this is required?)

5) replaceCurrentItemWithPlayerItem() is called on the player with the player item.


Later I get "playbackLikelyToKeepUp" with status "ReadyToPlay".

At this time I dispatch_async to the main queue and call player.seekToTime() and player.play()


This works the majority of the time, but occasionally the display remains green and only audio is played.


Any suggestion on could be the cause of this?


Thanks!

Accepted Reply

It looks like this is infact related to not using the main queue for setting the player to the layer and calling AVPlayer.replaceCurrentItemWithPlayerItem().

And it is documented the AVPlayer functions should be synced with the observer queue, which is the main queue.


Fixing this seems to have cured the issue.

Replies

After some more investigation it seems that every time this happens the layer's videoRect is (0, 0, 0, 0).

Normally it is updated when the layer receives a KVO for "currentItem.presentationSize", but for the non working case this doesn't happen.


But logging currentItem.presentationSize form my code does show it has a size but for some reason the value change notification was not triggered...


Suggestions are welcome :-)

It looks like this is infact related to not using the main queue for setting the player to the layer and calling AVPlayer.replaceCurrentItemWithPlayerItem().

And it is documented the AVPlayer functions should be synced with the observer queue, which is the main queue.


Fixing this seems to have cured the issue.