ExoPlayer是什么
浅显来讲,ExoPlayer是一个google开源的视频播映器,而且被youtube、google video等大型运用运用。具体介绍参阅官网
为什么要用ExoPlayer播映广告
- 原生的MediaPlayer 存在ANR等一系列稳定性问题
- Google背书,内部支持各种协议以及IMA
- Facebook、Mintegral等广告SDK内部也用的ExoPlayer
[com.mbridge.msdk.playercommon.exoplayer2.video]
怎样运用ExoPlayer
简略运用去播映视频能够直接参阅演示指南样例一步一步来
假如要再视频中播映广告根据官网的过程刺进广告即可,演示demo
假如只是简略的接入完结来说,全体仍是比较简略的
咱们应该怎么去完结只播映广告资源呢
以下的代码改动都是根据演示demo,能够随改随验
1.运用MediaItem
只设置广告,不设置流媒体资源
MediaItem mediaItem =
new MediaItem.Builder()
// .setUri(contentUri)
.setAdsConfiguration(new MediaItem.AdsConfiguration.Builder(adTagUri).build())
.build();
确实能够只播映广告资源,但是在AdEventListener
中收不到播映完结时COMPLETED
的回调,此刻会直接抛出反常,能够测验tricky的做法在主流程中try-catch该反常,触发反常时认为广告播映完结,但这种做法并不推荐
2.运用MediaSource
只设置广告
AdsMediaSource adsMediaSource = new AdsMediaSource(
new SilenceMediaSource(1000000), new DataSpec(adTagUri), 0, new DefaultMediaSourceFactory(this),
adsLoader, playerView);
player.setMediaSource(adsMediaSource);
但是该adTagUri
只能是网络地址,假如咱们要用VAST/VMAP这种XML格局的文件,则需要运用SDK中提供的Util转化
new DataSpec(Util.getDataUriForString("application/xml", adTagUri)
然后…就呈现了如下崩溃
Exception in ADS_LOADER.REQUEST_ADS
com.google.ads.interactivemedia.v3.internal.zzwa: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
at com.google.ads.interactivemedia.v3.internal.zzvi.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:7)
at com.google.ads.interactivemedia.v3.internal.zzvd.zzb(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:2)
at com.google.ads.interactivemedia.v3.internal.zzhb.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
at com.google.ads.interactivemedia.v3.internal.zzgt.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
at com.google.ads.interactivemedia.v3.internal.zzgx.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:13)
at com.google.ads.interactivemedia.v3.internal.zzdq.call(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
at com.google.ads.interactivemedia.v3.internal.zzvy.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
at com.google.ads.interactivemedia.v3.internal.zzvp.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:4)
at com.google.ads.interactivemedia.v3.internal.zzvz.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
本以为是vast格局的问题,就运用googleads.github.io/googleads-i… 测试vast xml一切正常
在github中github.com/androidx/me… 得到是IMA SDK版本过高的问题,所以下降版本处理
此刻总算能够正常只播映广告,且播映状态回调正常!
但随之引入了新问题 即
广告播映完结后最终一帧直接黑屏,怎么处理?
- 设置shutter view布景透明
(通过Layout Inspector
工具检查布局得知有shutter view作为播映器的远景)
设置playerView.setShutterBackgroundColor(Color.TRANSPARENT);
使透明
切换前后台后又是黑屏,怎么处理?
- 设置PlayerView为TextureView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:surface_type="texture_view"/>
- 新增ImageView,截取最终一帧bitmap并设置到ImageView上
if (eventType == AdEvent.AdEventType.COMPLETED) {
// 广告播映完结
close.setVisibility(View.VISIBLE);
bitmap = ((TextureView)playerView.getVideoSurfaceView()).getBitmap();
lastFrame.setBackground(new BitmapDrawable(bitmap));
Log.e(LOG_TAG, "ALL_ADS_COMPLETED");
}
广告点击跳转怎么处理?
- 由于混杂原因
com.google.ads.interactivemedia.v3.impl.data.c
不是一个定值;是SDK对应版本的com.google.ads.interactivemedia.v3.api.Ad
接口的完结类
private void adClick() {
String actionUrl = ((com.google.ads.interactivemedia.v3.impl.data.c) event.getAd()).getClickThruUrl();
if (TextUtils.isEmpty(actionUrl)) {
return;
}
Intent intent = new Intent().setAction(Intent.ACTION_VIEW)
.setData(Uri.parse(actionUrl))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}