阿里云播放器SDK的端侧广告插入播放(CSAI)能力支持IMA SDK,提供广告媒资请求、广告播放、广告状态上传等全套广告流程处理能力。本文介绍如何在Android端使用阿里云播放器SDK进行广告插入播放。
使用限制
当前仅支持Android平台;
支持的Android端阿里云播放器SDK版本为:com.aliyun.sdk.android:AliyunPlayer:7.4.0-full-46755290。
支持的Android端 AlivcImaExtension SDK版本为:com.aliyun.sdk.android:AlivcImaExtension:7.4.0-46755290。
暂不支持在直播播放中插入广告播放。
前提条件
集成阿里云播放器SDK,且SDK版本为上述指定版本,详情见快速接入。
概览
阿里云播放器SDK提供多种线性广告插入方式,实现广告播放和正片播放的无缝衔接,同时免去了广告播放与 IMA SDK 的复杂交互。
AliyunPlayer 支持两种广告插入方式:
基于单个VAST 或 VMAP adTagUri的广告插入播放。
基于单个或多个自定义播放位置的广告插入播放。
广告请求逻辑
单个
adTagUri
的广告插入播放:起播时先请求adTagUri
获取广告位置。对于 VAST 请求,该广告通常作为前插 (Pre) 广告播放。自定义播放位置的广告插入播放:在播放到达该位置前发起广告请求。
广告/正片切换播放逻辑
当广告播放完毕或到达播放位置时,无论是广告切正片还是正片切广告,接入“播放不连续”回调事件(OnPositionDiscontinuityListener)后,回调会通知切换前后的播放信息。
广告播放期间,大部分播放控制或信息获取API都会对广告播放生效。
可区分广告/正片播放的个性化配置
当前支持对广告和正片进行差异化配置(如 PlayConfig、播放选项等),相关 API 可设置为:仅广告播放生效、仅正片播放生效或对全部播放生效。
Android 端关键实现
集成IMA插件
IMA插件是AliyunPlayer支持的拓展插件,内置了Google IMA SDK,无需重复集成。当前支持 Maven 集成,需在项目的 build.gradle
文件中添加依赖,示例如下:
def player_ima_sdk_extension_version = "7.4.0-46755290" // player ima extension sdk current version
def player_sdk_version = "7.4.0-full-46755290" //player sdk current version that support ads
//ImaExtension
implementation "com.aliyun.sdk.android:AlivcImaExtension:$player_ima_sdk_extension_version"
//player sdk
implementation "com.aliyun.sdk.android:AliyunPlayer:$player_sdk_version"
设置广告播放
初始化(广告播放器、加载器)。
//initial adsLoader,may choose start debug mode AdsLoader mAdsLoader = new ImaAdsLoader.Builder(getApplicationContext()).setDebugModeEnabled(false).build(); //initial AliPlayerWithAds, to locate problem online, inputing traceId is recommended. AliPlayerWithAds mPlayerWithAds = AliPlayerFactory.createAliPlayerWithAds(getApplicationContext(), "your_traceId", mAdsLoader); //bind the player with adsloader mAdsLoader.setPlayer(mPlayerWithAds); //optional, set mMaxBufferDuration to 20s only to content player PlayerConfig config = mPlayerWithAds.getConfig(IPlayerWithAds.MethodEffectType.Effect_Only_Content); config.mMaxBufferDuration = 20000; mPlayerWithAds.setConfig(config, IPlayerWithAds.MethodEffectType.Effect_Only_Content);
设置监听事件。
//onPositionDiscontinuityListener, callback when ad/content transplayback IPlayerWithAds.OnPositionDiscontinuityListener onPositionDiscontinuityListener = new IPlayerWithAds.OnPositionDiscontinuityListener() { @Override public void onPositionDiscontinuity(PositionInfo oldInfo, PositionInfo newInfo) { } }; mPlayerWithAds.setOnPositionDiscontinuityListener(onPositionDiscontinuityListener); //onPlaybackListReadyListener, callback when playlist ready IPlayerWithAds.OnPlaybackListReadyListener onPlaybackListReadyListener = new IPlayerWithAds.OnPlaybackListReadyListener() { @Override public void onPlaybackListReady(long contentPositionMs, long contentDurationMs, AdGroupBean[] adGroupBeans) { } }; mPlayerWithAds.setOnPlaybackListReadyListener(onPlaybackListReadyListener); //set content preparedListener mPlayerWithAds.setOnPreparedListener(new IPlayer.OnPreparedListener() { @Override public void onPrepared() { } }, IPlayerWithAds.MethodEffectType.Effect_Only_Content); //set firstRender listener, callback when content or ad first Render //maybe callback multi times mPlayerWithAds.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() { @Override public void onRenderingStart() { } }, IPlayerWithAds.MethodEffectType.Effect_WhatEver); //SurfaceTextureListener, setSurface to player when surface ready TextureView mTextureView = findViewById(R.id.surface_view); mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) { mSurface = new Surface(surface); mPlayerWithAds.setSurface(mSurface); } @Override public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) { return false; } @Override public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) { } });
配置广告源,有如下两种配置方式:
说明以下两种方式互斥,不可同时使用
setSingleAdTagUri
和addAdItems
。基于单个VAST 或 VMAP adTagUri的广告插入播放。
String mediaUri = "https://player.alicdn.com/video/aliyunmedia.mp4"; //single inline adTagUri(vast) String adTagUri = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator="; AdsUrlSource adsUrlSource = new AdsUrlSource(); adsUrlSource.setUri(mediaUri); adsUrlSource.setSingleAdTagUri(adTagUri); mPlayerWithAds.setDataSource(adsUrlSource);
基于单个或多个自定义播放位置的广告插入播放。
String mediaUri = "https://player.alicdn.com/video/aliyunmedia.mp4"; //single inline adTagUri(vast), not support vmap adtaguri to this adItem String singleInlineVastAdTagUri = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator="; AdsUrlSource adsUrlSource = new AdsUrlSource(); adsUrlSource.setUri(mediaUri); AdsSourceBase.AdItem preItem = new AdsSourceBase.AdItem(0, singleInlineVastAdTagUri); AdsSourceBase.AdItem midItem15s = new AdsSourceBase.AdItem(15 * 1000, singleInlineVastAdTagUri); AdsSourceBase.AdItem midItem50Percent = new AdsSourceBase.AdItem("50%", singleInlineVastAdTagUri); AdsSourceBase.AdItem postItem = new AdsSourceBase.AdItem("post", singleInlineVastAdTagUri); adsUrlSource.addAdItems(preItem, midItem15s, midItem50Percent, postItem);
开始播放。
//setAutoPlay when player prepared mPlayerWithAds.setAutoPlay(true); mPlayerWithAds.prepare();