如何实现端侧广告插入播放

阿里云播放器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 支持两种广告插入方式:

  1. 基于单个VAST 或 VMAP adTagUri的广告插入播放。

  2. 基于单个或多个自定义播放位置的广告插入播放。

广告请求逻辑

  • 单个 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"

设置广告播放

  1. 初始化(广告播放器、加载器)。

    //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);
  2. 设置监听事件。

    //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) {
        }
    });
  3. 配置广告源,有如下两种配置方式:

    说明

    以下两种方式互斥,不可同时使用 setSingleAdTagUri 和 addAdItems

    1. 基于单个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);
      
    2. 基于单个或多个自定义播放位置的广告插入播放。

      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);
  4. 开始播放。

    //setAutoPlay when player prepared
    mPlayerWithAds.setAutoPlay(true);
    
    mPlayerWithAds.prepare();