Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exoplayer playback error after interstitial ad

I am playing video with ExoPlayer and showing Google AdMob interstitial ad.

After ad has been gone there was trouble to play video and show error like:

Playback error.com.google.android.exoplayer2.ExoPlaybackException
   at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.throwDecoderInitError(MediaCodecRenderer.java:441)
   at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:428)
   at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:920)
   at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:503)
   at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:557)
   at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:518)
   at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:301)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:193)
   at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.qcom.video.decoder.avc, Format(1, null, video/avc, -1, null, [720, 420, -1.0], [-1, -1])
   at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:428) 
   at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:920) 
   at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:503) 
   at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:557) 
   at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:518) 
   at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:301) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:193) 
   at android.os.HandlerThread.run(HandlerThread.java:65) 

I am using libraries:

implementation 'com.google.android.exoplayer:exoplayer:2.8.1'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.8.1'
like image 532
Dinesh Shingadiya Avatar asked May 08 '19 08:05

Dinesh Shingadiya


1 Answers

This is quite hard to debug error, but it can be relatively easy to avoid.

The thing is that ExoPlayer is Google developed library. Obviously Google uses it in its own products. Google AdMob SDK uses ExoPlayer inside of it. More specifically it uses this player to show some of its interstitial and even banner ads. While on the general app screens usually it works seamlessly without errors and bugs(with a little amount of bugs).

The situation becomes different on the screens with the same ExoPlayer player that is being used inside the AdMob SDK. Both instances use the same resources - codecs, renderers etc. thus the device must provide this resources. Number of possible active simultaneous ExoPlayer instances may vary from 1(or maybe even 0 on old weak devices) to 10+ - it correlates with maximum number of hardware decoders the device can handle. More about this here (ExoPlayer issue 273).

The possible workaround to this limitation is to set up ExoPlayer to use software decoders. It may drastically reduce quality of the experience on weak devices though. How to create software decoder you may find in source code of the ExoPlayer in MediaCodecTrackRenderer.java class.

Your situation is a bit different because you have no control over at least one of instances - so I cannot predict whether it will work.

Either way I think this issue should be fixed architecturally rather than by the code brute force.

The simplest way is to release your instance of ExoPlayer right before the interstitial starts with the ExoPlayer.release() and initialize it once more only after the interstitial is finished. Gladly you have all the needed callback methods for that in AdMob SDK for interstitials. You may store playback time somewhere to resume from the place user stopped interrupted by an ad.

The more user friendly way is not to interrupt video with ads - show them before and after. Or include ads into video. But is completely dependent on your UI/UX and monetisation system.

I know it is not exactly an answer to your question but rather a thoughts around the theme but I hope it will help you someway.

like image 141
Pavlo Ostasha Avatar answered Nov 15 '22 02:11

Pavlo Ostasha