I am playing video with ExoPlayer and showing Google AdMob's Interstitial Video Ad.
After closing ads getting issue to play video again.
I am getting error as below:
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)
Here is my dependency:
I am using libraries:
implementation 'com.google.android.exoplayer:exoplayer:2.8.1'
Code of Activity:
private ActivityVideoMakingBinding mBinding;
private Activity mContext;
private SimpleExoPlayer player;
private PlayerView exoPlayerView;
private long pause_dur = 0;
private FirebaseRemoteConfig mFirebaseRemoteConfig;
private InterstitialAd mInterstitialAd;
private com.facebook.ads.InterstitialAd interstitialAd;
private DataSource.Factory dataSourceFactory;
private MediaSource mediaSource;
private AdsLoader adsLoader;
private void releaseAdsLoader() {
if (adsLoader != null) {
adsLoader.release();
adsLoader = null;
exoPlayerView.getOverlayFrameLayout().removeAllViews();
}
}
private void releasePlayer() {
if (player != null) {
pause_dur = player.getCurrentPosition();
player.release();
player = null;
mediaSource = null;
}
if (adsLoader != null) {
releaseAdsLoader();
}
}
private DataSource.Factory buildDataSourceFactory() {
return MyApplication.getInstance().buildDataSourceFactory(null);
}
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle savedInstanceState){
mBinding = DataBindingUtil.setContentView(mContext, R.layout.activity_video_making);
mContext = VideoMakingActivity.this;
outputVideo = getDirectoryPath(mContext) +
zipFileName + File.separator + "output.mp4";
exoPlayerView = mBinding.exoPlayerVideoDetail;
initializeExoPlayer();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mBinding.adView != null)
mBinding.adView.destroy();
releasePlayer();
}
@Override
protected void onResume() {
super.onResume();
isOnPause = false;
if (mBinding.adView != null)
mBinding.adView.resume();
if (flagIsFirstTime) {
flagIsFirstTime = false;
} else {
initializeExoPlayer();
}
}
@Override
protected void onPause() {
super.onPause();
isOnPause = true;
releasePlayer();
if (mBinding.adView != null)
mBinding.adView.pause();
}
private void showAdsSettings() {
mFirebaseRemoteConfig.fetch(3600).addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
mFirebaseRemoteConfig.activate();
requestNewInterstitial();
}
});
}
private void requestNewInterstitial() {
if (mFirebaseRemoteConfig.getString(Globals.ad_network_boo).equalsIgnoreCase("facebook")
&& getInstalled()) {
interstitialAd = new com.facebook.ads.InterstitialAd(mContext,
getResources().getString(R.string.fb_video_making_inter));
interstitialAd.loadAd();
try {
interstitialAd.setAdListener(new AbstractAdListener() {
@Override
public void onInterstitialDismissed(Ad ad) {
super.onInterstitialDismissed(ad);
if (interstitialAd != null) {
interstitialAd.destroy();
interstitialAd.loadAd();
goNextScreen();
}
}
});
} catch (Exception ignored) {
}
} else {
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId(getString(R.string.gl_video_making_inter));
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener() {
@Override
public void onAdClosed() {
super.onAdClosed();
mInterstitialAd.loadAd(new AdRequest.Builder().build());
goNextScreen();
}
});
}
}
private boolean getInstalled() {
try {
mContext.getPackageManager().getApplicationInfo("com.facebook.katana", 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
try {
mContext.getPackageManager().getApplicationInfo("com.facebook.lite", 0);
return true;
} catch (Exception ex) {
return false;
}
}
}
private void goNextScreen() {
Intent intent = new Intent(mContext, VideoPreviewActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("filePath", finalVideoPath);
intent.putExtra("fileName", fileName);
intent.putExtra("video_object", new Gson().toJson(mVideoData));
startActivity(intent);
}
private void initializeExoPlayer() {
if (player == null) {
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), new DefaultLoadControl());
exoPlayerView.setPlayer(player);
exoPlayerView.setBackgroundColor(Color.BLACK);
exoPlayerView.setUseController(false);
mBinding.viewMain.setOnClickListener(v -> {
isPlaying = false;
playPausePlayer(false);
});
mBinding.previewControls.rlPreviewControl.setOnClickListener(v -> {
Globals.playSound(mContext, R.raw.button_tap);
if (flagChanges) {
strExportVideo = "preview";
exportVideo();
} else {
isPlaying = true;
playPausePlayer(true);
}
});
player.addListener(new Player.DefaultEventListener() {
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
super.onPlayerStateChanged(playWhenReady, playbackState);
if (playbackState == Player.STATE_ENDED) {
mBinding.progressBarExoplayer.setVisibility(View.GONE);
player.seekTo(0);
} else if (playbackState == Player.STATE_BUFFERING) {
mBinding.progressBarExoplayer.setVisibility(View.VISIBLE);
} else if (playbackState == Player.STATE_READY) {
mBinding.progressBarExoplayer.setVisibility(View.GONE);
} else if (playbackState == Player.STATE_IDLE) {
mBinding.progressBarExoplayer.setVisibility(View.GONE);
}
}
});
playPausePlayer(true);
}
prepareExoPlayer(outputVideo);
}
private void playPausePlayer(boolean play) {
if (player != null)
if (play) {
mBinding.exoThumb.setVisibility(View.GONE);
player.seekTo(pause_dur);
player.setPlayWhenReady(true);
player.getPlaybackState();
} else {
pause_dur = player.getCurrentPosition();
player.setPlayWhenReady(false);
player.getPlaybackState();
}
}
private void prepareExoPlayer(String path) {
Uri uri = Uri.parse(path);
mediaSource = buildLocalMediaSource(uri);
player.prepare(mediaSource, true, false);
}
private MediaSource buildLocalMediaSource(Uri uri) {
return buildMediaSource(uri, null);
}
private MediaSource buildMediaSource(Uri uri, @androidx.annotation.Nullable String overrideExtension) {
@C.ContentType int type = Util.inferContentType(uri, overrideExtension);
switch (type) {
case C.TYPE_HLS:
return new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
case C.TYPE_OTHER:
return new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
default:
throw new IllegalStateException("Unsupported type: " + type);
case C.TYPE_DASH:
throw new IllegalStateException("Unsupported type: " + type);
case C.TYPE_SS:
throw new IllegalStateException("Unsupported type: " + type);
}
}
private String getDirectoryPath(Context mContext) {
String externalDirectory = mContext.getFilesDir().getAbsolutePath();
File dir = new File(externalDirectory + File.separator +
mContext.getResources().getString(R.string.zip_directory));
if (!dir.exists())
dir.mkdir();
return dir.getAbsolutePath() + File.separator;
}
}
In above activity
I am using single instance
of DataSourceFactory
So, Here is code of MyApplication.java
:
public class MyApplication extends MultiDexApplication {
protected String userAgent;
private static MyApplication sInstance;
@Override
public void onCreate() {
super.onCreate();
MultiDex.install(this);
//Common User Agent for all player
userAgent = Util.getUserAgent(this, "ExoPlayerDemo");
sInstance = this;
}
public static MyApplication getInstance() {
return sInstance;
}
/**
* Returns a {@link DataSource.Factory}.
*/
public DataSource.Factory buildDataSourceFactory(TransferListener<? super DataSource> listener) {
return new DefaultDataSourceFactory(this, listener, buildHttpDataSourceFactory(listener));
}
/**
* Returns a {@link HttpDataSource.Factory}.
*/
public HttpDataSource.Factory buildHttpDataSourceFactory(
TransferListener<? super DataSource> listener) {
return new DefaultHttpDataSourceFactory(userAgent, listener);
}
}
Well after analysis for some days, com.google.android.gms.internal.ads.zzgb
error for interstitial ad is occurs whenever I used Video ads in Interstitial ad and its working fine when I off video ads which in general contains image ads only.
This thing is happening with Admob network only because I am using FB audience network also and its working with ExoPlayer.
Anyone can help? Thanks in advance.