AndrewBoryk / ABMediaView

Media view which subclasses UIImageView, and can display & load images, videos, GIFs, and audio and from the web, and has functionality to minimize from fullscreen, as well as show GIF previews for videos.
MIT License
82 stars 9 forks source link

AVPlayer Cannot Decode Error When After Making Several ABMediaView Instances #3

Open insanj opened 6 years ago

insanj commented 6 years ago

After using a few ABMediaView instances, they all break until restarting the app. This is easily reproducible. Create a new ABMediaView instance and present it, wait for it to load and begin playing, then present another instance. After a dozen or so of these instances, they will all fail with the error:

AVPlayer Error Error Domain=AVFoundationErrorDomain Code=-11839 "Cannot Decode" UserInfo={NSLocalizedDescription=Cannot Decode, NSUnderlyingError=0x1d4e4b490 {Error Domain=NSOSStatusErrorDomain Code=-12913 "(null)"}, NSLocalizedRecoverySuggestion=Stop any other actions that decode media and try again., NSLocalizedFailureReason=The decoder required for this media is busy.}

This Stackoverflow post explains the issue as being related to the reuse of AVFoundation resources:

There is a limit on the number of concurrent video players that AVFoundation will allow. It is due to the limitations of iOS hardware. The limit for current devices is 4 players. If you create a 5th player, you will get the "cannot decode" error. It is not a limit on the number of instances of AVPlayer, or AVPlayerItem. Rather,it is the association of AVPlayerItem with an AVPlayer which creates a "render pipeline", and you are limited to 4 of these.

What can I do to dump the AVFoundation resources that ABMediaView is blocking up? Calling resetVariables and resetMediaInView in mediaViewDidDismiss was a hopeful solution of mine that didn't seem to do anything.


Edit: According to this post, it seems like using AVPlayerLayer's replaceCurrentItem would work... although I'm not sure what to do when a layer is not actually being reused (like in the case of multiple media views):

In the end, I decided to initialize the view controller’s AVPlayer right off the bat with its playerItem set to nil. Then I changed my setup function like so... Replacing the player’s playerItem instead of initializing it with a new playerItem each time (even though the player was previously set to nil), seems to prevent that weird “cannot decode” error (so far, at least). I’d like to know more about this error and why exactly it occurs, just out of nerdy curiosity.

insanj commented 6 years ago

Note: I would use the new Swift framework but it is not Objective-C compatible.

AndrewBoryk commented 6 years ago

Hi Julian!

I’ve been working on several projects that have been pulling me away from Open Source, sorry. But yes, I can investigate the issue, however if you find a solution and PR it to the dev branch, I can review it.

My Swift version is incomplete, and I also want to make sure all is Objective-C compatible. But there was a lot in terms of video playing that is vastly improved in that project.

I will try to get to these issues as soon as I can, but again, if you find a solution and would like to PR, I can definitely review it.