Show Menu
TOPICS×

Skip ad breaks for a period of time

By default, TVSDK forces an ad break to play when the user seeks over an ad break. You can customize the behavior to skip an ad break if the time elapsed from a previous break completion is within a certain number of minutes.
If you have to complete an internal seek to forgive an ad, there might be a slight pause during the playback.
To override the default TVSDK ad break behavior, you can extend the default ad policy selector. There are four ad break policies available:
  • PLAY
  • SKIP
    The SKIP ad break policy might not work as expected for live streams when an ad is present at the live point. For example, for a pre-roll, SKIP will cause a seek to the end of the ad break, which could be greater than the live point. In this case, TVSDK may seek to the middle of an ad.
  • REMOVE_AFTER
  • REMOVE
    The REMOVE ad break policy is slated for deprecation. Adobe recommends that you use the SKIP ad break policy in place of REMOVE .
The following example of a customized ad policy selector skips ads in the next five minutes (wall clock time) after a user has watched an ad break.
  1. When the user finishes watching an ad break, save the current system time.
    @Override 
    public void onAdBreakComplete(AdBreak adBreak) { 
        ... 
        if (isShouldPlayUpcomingAdBreakRuleEnabled()) { 
            CustomAdPolicySelector.setLastAdBreakPlayedTime(System.currentTimeMillis()); 
            ... 
        } 
    }
    
    
  2. Extend AdPolicySelector .
    package com.adobe.mediacore.sample.advertising; 
    
    import com.adobe.mediacore.MediaPlayerItem; 
    import com.adobe.mediacore.MediaPlayerItemConfig; 
    import com.adobe.mediacore.timeline.advertising.policy.*; 
    import com.adobe.mediacore.timeline.advertising.AdBreakTimelineItem; 
    import com.adobe.mediacore.metadata.AdvertisingMetadata; 
    
    import java.util.ArrayList; 
    import java.util.List; 
    
    public class CustomAdPolicySelector implements AdPolicySelector { 
    
        private static final long MIN_BREAK_INTERVAL = 300000; // 5 minutes for next ad break to be played 
        private MediaPlayerItem _mediaPlayerItem; 
        private static long _lastAdBreakPlayedTime; 
        private AdBreakWatchedPolicy watchedPolicy = AdBreakWatchedPolicy.WATCHED_ON_BEGIN; 
    
        public CustomAdPolicySelector(MediaPlayerItem mediaPlayerItem) { 
            _mediaPlayerItem = mediaPlayerItem; 
            _lastAdBreakPlayedTime = 0; 
    
            if (mediaPlayerItem != null) { 
                watchedPolicy = extractWatchedPolicy(mediaPlayerItem.getConfig()); 
            } 
        } 
    
        @Override 
        public AdBreakPolicy selectPolicyForAdBreak(AdPolicyInfo adPolicyInfo) { 
            if (shouldPlayAdBreaks() && adPolicyInfo.getAdBreakTimelineItems() != null) { 
    
                AdBreakTimelineItem item = adPolicyInfo.getAdBreakTimelineItems().get(0); 
    
                // This condition will remove the pre-roll ad from live stream after watching 
                if (item.getTime() == 0 && _mediaPlayerItem.isLive()) { 
                    return AdBreakPolicy.REMOVE_AFTER_PLAY; 
                } 
                if (item.getTime() == 0) { 
                    return AdBreakPolicy.PLAY; 
                } 
    
                // This condition will remove every ad break that has been watched once.  
                // Comment this section if you want to play watched ad breaks again. 
                if (item.isWatched()) { 
                    return AdBreakPolicy.SKIP; 
                } 
    
                return AdBreakPolicy.REMOVE_AFTER_PLAY; 
            } 
    
            return AdBreakPolicy.SKIP; 
        } 
    
        @Override 
        public List<AdBreakTimelineItem> selectAdBreaksToPlay(AdPolicyInfo adPolicyInfo) { 
    
            if (shouldPlayAdBreaks()) { 
    
                List<AdBreakTimelineItem> timelineItems = adPolicyInfo.getAdBreakTimelineItems(); 
                AdBreakTimelineItem item; 
                List<AdBreakTimelineItem> selectedItems = new ArrayList<AdBreakTimelineItem>(); 
    
                if (timelineItems != null && timelineItems.size() > 0) { 
    
                    // Seek Forward Condition 
                    if (adPolicyInfo.getCurrentTime() <= adPolicyInfo.getSeekToTime()) { 
                        item = timelineItems.get(0); 
    
                        // Resume logic - This will be helpful in resuming the content  
                        // from last saved playback session, and just play the pre-roll ad 
                        if(adPolicyInfo.getCurrentTime() == 0) { 
                            if(item.getTime() == 0 && !item.isWatched()) { 
                                // comment this line if you just need to seek to the user's  
                                // last known position without playing pre-roll ad. ZD#820 
                                selectedItems.add(item); 
                                return selectedItems; 
                            } 
                            else{ 
                                return null; 
                            } 
                        } else { 
                            item = timelineItems.get(timelineItems.size()-1); 
                            if (!item.isWatched()) { 
                                selectedItems.add(item); 
                                return selectedItems; 
                            } 
                        } 
    
                        // Seek backward condition 
                    } else if (adPolicyInfo.getCurrentTime() > adPolicyInfo.getSeekToTime()) { 
                        item = timelineItems.get(0); 
    
                        if(!item.isWatched()) { 
                            selectedItems.add(item); 
                            return selectedItems; 
                        } else { 
                            return null; 
                        } 
                    } 
                } 
            } 
            return null; 
        } 
    
        @Override 
        public AdPolicy selectPolicyForSeekIntoAd(AdPolicyInfo adPolicyInfo) { 
            // Simple Ad Policy selector 
            // if the first ad in the break was watched,  
            // skip to the next add after the seek position 
            // otherwise, play the ads in the break from the beginning 
    
            List<AdBreakTimelineItem> timelineItems = adPolicyInfo.getAdBreakTimelineItems(); 
            if (timelineItems != null && timelineItems.size() > 0) { 
                if (timelineItems.get(0).isWatched()) { 
                    return AdPolicy.SKIP_TO_NEXT_AD_IN_AD_BREAK; 
                } 
            } 
    
            // Resume play from the next ad in the break 
            return AdPolicy.PLAY_FROM_AD_BREAK_BEGIN; 
    
        } 
    
        @Override 
        public AdBreakWatchedPolicy selectWatchedPolicyForAdBreak(AdPolicyInfo adPolicyInfo) { 
            return watchedPolicy; 
        } 
    
        public static void setLastAdBreakPlayedTime(long lastAdBreakPlayedTime) { 
            _lastAdBreakPlayedTime = lastAdBreakPlayedTime; 
        } 
    
        private boolean shouldPlayAdBreaks() { 
            long currentTime = System.currentTimeMillis(); 
    
            if (_lastAdBreakPlayedTime <= 0) { 
                return true; 
            } 
    
            if (_lastAdBreakPlayedTime > 0 &&  
              (currentTime - _lastAdBreakPlayedTime) > MIN_BREAK_INTERVAL) { 
                return true; 
            } 
    
            // return false for not playing Ad if this  
            // Ad occurs with 5 minutes of last Ad playback 
            return false; 
        } 
    
        private AdBreakWatchedPolicy extractWatchedPolicy(MediaPlayerItemConfig config) { 
            if (config != null) { 
                AdvertisingMetadata metadata = config.getAdvertisingMetadata(); 
                if (metadata != null) { 
                    return metadata.getAdBreakWatchedPolicy(); 
                } 
            } 
            return AdBreakWatchedPolicy.WATCHED_ON_BEGIN; 
        } 
    }