部分廣告插入

您可以啟用類似電視的體驗,讓您能夠在廣告中間加入即時串流。

「部分廣告插播」功能可讓您模擬類似電視的體驗,如果用戶端在midroll中啟動即時串流,則會在midroll中啟動。 它類似於切換電視頻道,廣告也順暢運作。

例如,如果使用者在90秒廣告插播(3個30秒廣告)的中間加入,在第二個廣告中加入10秒(亦即,在廣告插播中加入40秒),則會發生下列情況:

  • 第二個廣告會在剩餘的持續時間(20秒)內播放,接著是第三個廣告。
  • 部分播放廣告(第二個廣告)的廣告追蹤器不會引發。 只會引發第三個廣告的追蹤器。

預設情況下不啟用此行為。 若要在您的應用程式中啟用此功能,請執行下列動作。

  1. 使用AdvertisingMetadata類別的方法setEnableLivePreroll停用即時預覽。

    advertisingMetadata.setEnableLivePreroll(String.valueOf(false))
    
  2. 開啟「部分插入廣告插入」偏好設定。 使用MediaPlayer介面中的新方法setPartialAdBreakPref來開啟此功能。 使用getPartialAdBreakPref方法來尋找此偏好設定的目前狀態。

    MediaPlayer mediaPlayer = DefaultMediaPlayer.create(getActivity().getApplicationContext());
    
           mediaPlayer.setPartialAdBreakPref(true);
    
  3. 這項功能需要您實作自訂廣告原則選擇器以自訂行為。 如果您尚未自訂AdvertisingFactory類別的實作,請新增新的AdvertisingFactory實作。 覆寫createAdPolicySelector方法。 此方法會傳回AdPolicySelector實作的新例項。

    以下提供範例實作供您參考。 下列範例實作可從com.adobe.mediacore套件使用。 但是,它已簡化,以方便參考,不建議按原樣使用。

    1. 廣告政策選擇器範例

       package com.adobe.mediacore;
      
      import com.adobe.mediacore.logging.Log;
      import com.adobe.mediacore.logging.Logger;
      import com.adobe.mediacore.metadata.*;
      import com.adobe.mediacore.timeline.advertising.*;
      
      import java.util.ArrayList;
      import java.util.List;
      
      public class PartialAdBreakAdPolicySelector implements AdPolicySelector {
          private static final String LOG_TAG = "[PSDK]::" + DefaultAdPolicySelector.class.getSimpleName();
          private final Logger _logger = Log.getLogger(LOG_TAG);
      
          private final MediaPlayerItem _mediaPlayerItem;
          private final AdBreakAsWatched _adBreakAsWatchedPolicy;
      
          public PartialAdBreakAdPolicySelector(MediaPlayerItem mediaPlayerItem) {
              _mediaPlayerItem = mediaPlayerItem;
              _adBreakAsWatchedPolicy = extractAdBreakAsWatchedPolicy(_mediaPlayerItem);
          }
      
          @Override
          public AdBreakPolicy selectPolicyForAdBreak(AdPolicyInfo adPolicyInfo) {
              _logger.i(LOG_TAG + "#selectPolicyForAdBreak", "currentTime=" + adPolicyInfo.getCurrentTime() + " seekToTime="
                      + adPolicyInfo.getSeekToTime() + " rate=" + adPolicyInfo.getRate() + " adPolicyMode=" + adPolicyInfo.getMode());
      
              if (adPolicyInfo.getAdBreakPlacements().size() > 0) {
                  AdBreakPlacement adBreakTimelineItem = adPolicyInfo.getAdBreakPlacements().get(0);
                  if (adPolicyInfo.getMode() == AdPolicyMode.SEEK && adBreakTimelineItem.getAdBreak().isWatched()) {
                      return AdBreakPolicy.SKIP;
                  }
              }
      
              AdSignalingMode adSignalingMode = AdSignalingMode.DEFAULT;
              if (_mediaPlayerItem != null) {
                  MetadataNode metadata = (MetadataNode) _mediaPlayerItem.getResource().getMetadata();
                  if (metadata != null) {
                      AdvertisingMetadata advertisingMetadata = (AdvertisingMetadata) metadata.getNode(DefaultMetadataKeys.ADVERTISING_METADATA.getValue());
                      if (advertisingMetadata != null) {
                          adSignalingMode = advertisingMetadata.getSignalingMode();
                      }
                  }
              }
      
              // can't remove main content due to a ave bug, need to check if stream is live or ad signaling mode is manifest cue
              if (_mediaPlayerItem.isLive() || adSignalingMode == AdSignalingMode.MANIFEST_CUES) {
                  return AdBreakPolicy.PLAY;
              }
      
              return AdBreakPolicy.REMOVE_AFTER_PLAY;
          }
      
          @Override
          public List<AdBreakPlacement> selectAdBreaksToPlay(AdPolicyInfo adPolicyInfo) {
              _logger.i(LOG_TAG + "#selectAdBreaksToPlay", "currentTime=" + adPolicyInfo.getCurrentTime() + " seekToTime="
                      + adPolicyInfo.getSeekToTime() + " rate=" + adPolicyInfo.getRate() + " adPolicyMode=" + adPolicyInfo.getMode());
      
              List<AdBreakPlacement> adBreakPlacements = adPolicyInfo.getAdBreakPlacements();
              if (adBreakPlacements != null) {
                  int size = adBreakPlacements.size();
                  List<AdBreakPlacement> adBreaks = new ArrayList<AdBreakPlacement>();
                  if (size > 0 && adPolicyInfo.getCurrentTime() <= adPolicyInfo.getSeekToTime()) {
                      AdBreakPlacement adBreak = adBreakPlacements.get(size - 1);
                      if (!adBreak.getAdBreak().isWatched()) {
                          adBreaks.add(adBreak);
                          return adBreaks;
                      }
                  }
              }
      
              return null;
          }
      
          @Override
          public AdPolicy selectPolicyForSeekIntoAd(AdPolicyInfo adPolicyInfo) {
              _logger.i(LOG_TAG + "#selectPolicyForSeekIntoAd", "currentTime=" + adPolicyInfo.getCurrentTime() + " seekToTime="
                      + adPolicyInfo.getSeekToTime() + " rate=" + adPolicyInfo.getRate() + " adPolicyMode=" + adPolicyInfo.getMode());
      
              // If you really want to allow seek during ads (you likely do not).
              return AdPolicy.PLAY;
          }
      
          @Override
          public AdBreakAsWatched selectWatchedPolicyForAdBreak(AdPolicyInfo adPolicyInfo) {
              _logger.i(LOG_TAG + "#selectWatchedPolicyForAdBreak", "currentTime=" + adPolicyInfo.getCurrentTime() + " seekToTime="
                      + adPolicyInfo.getSeekToTime() + " rate=" + adPolicyInfo.getRate() + " adPolicyMode=" + adPolicyInfo.getMode());
      
              return _adBreakAsWatchedPolicy;
          }
      
          /**
           * Extract the ad break watched policy for the specified media player item.
           *
           * @param item Associated media player item.
           * @return a valid ad break watched policy.
           */
          private AdBreakAsWatched extractAdBreakAsWatchedPolicy(MediaPlayerItem item) {
              AdBreakAsWatched adBreakWatchedPolicy = AdBreakAsWatched.AD_BREAK_AS_WATCHED_ON_BEGIN;
      
              if (item != null) {
                  MetadataNode metadata = (MetadataNode) item.getResource().getMetadata();
                  if (metadata != null) {
                      AdvertisingMetadata advertisingMetadata = (AdvertisingMetadata) metadata.getNode(DefaultMetadataKeys.ADVERTISING_METADATA.getValue());
                      if (advertisingMetadata != null) {
                          adBreakWatchedPolicy = advertisingMetadata.getAdBreakAsWatched();
                      }
                  }
              }
      
              return adBreakWatchedPolicy;
          }
      }
      
    2. 範例廣告廠

      private AdvertisingFactory createPartialAdBreakFactory() {
      return new AdvertisingFactory() {
      @Override
                   public AdPolicySelector
      createAdPolicySelector(MediaPlayerItem mediaPlayerItem) {
                      return new PartialAdBreakAdPolicySelector(mediaPlayerItem);
                   }
      
      // Rest of the interface methods can be overridden as per your
      // customization needs
      // As shown next
      @Override
      public AdPolicySelector
      createAdPolicySelector(MediaPlayerItem mediaPlayerItem) {
         return new PartialAdBreakAdPolicySelector(mediaPlayerItem);
        }
      // . . .
      
       }
      }
      
    3. 向媒體播放器註冊我們的AdvertisingFactory

      AdvertisingFactory advertisingFactory = createPartialAdBreakFactory();
      
      if (advertisingFactory != null) {
                  mediaPlayer.registerAdClientFactory(advertisingFactory);
      }
      
    4. 覆寫createAdPolicySelector方法

      @Override
      public AdPolicySelector
      createAdPolicySelector(MediaPlayerItem mediaPlayerItem) {
         return new PartialAdBreakAdPolicySelector(mediaPlayerItem);
      }
      

本頁內容