Implement a custom opportunity/content resolver

You can implement your own resolvers based on the default resolvers.

  1. Develop a custom ad resolver by extending the PTContentResolver abstract class. PTContentResolver is an Interface that must be implemented by any content resolver class. An abstract class of the same name is also available that handles the configuration automatically (getting the delegate).
    Note: PTContentResolver is exposed through the PTDefaultMediaPlayerClientFactory class. Clients can register a new content resolver extending the PTContentResolver abstract class. By default and unless specifically removed, a PTDefaultAdContentResolver is registered in the PTDefaultMediaPlayerClientFactory.
    @protocol PTContentResolver <NSObject>
    @required
    + (BOOL)shouldHandleOpportunity:(PTPlacementOpportunity *)opportunity; 
    //Detector returns YES/NO if it should handle the following placement opportunity
    - (void)configWithPlayerItem:(PTMediaPlayerItem *)item 
                  delegate:(id<PTContentResolverDelegate> delegate);
    - (void)process:(PTPlacementOpportunity *)opportunity;
    - (void)timeout:(PTPlacementOpportunity *)opportunity; 
    //The timeout method gets invoked if the PSDK decides that the 
    //PTContentResolver is taking too much time to respond.
    @end
     
    @interface PTContentResolver : NSObject <PTContentResolver>
     
    @property (readonly) id<PTContentResolverDelegate> delegate;
    @property (readonly) PTMediaPlayerItem *playerItem;
     
    - (BOOL)shouldHandleOpportunity:(PTPlacementOpportunity *)opportunity;
    - (void)configWithPlayerItem:(PTMediaPlayerItem *)item 
                   delegate:(id<PTContentResolverDelegate>) delegate;
    - (void)process:(NSArray *)opportunities;
    - (void)cancel:(NSArray *)opportunities;
    @end
  2. Implement shouldResolveOpportunity and return YES if it should handle the received PTPlacementOpportunity.
  3. Implement resolvePlacementOpportunity, which starts loading the alternate content or ads.
  4. When the ads are loaded, prepare a PTTimeline with the information about the content to insert. Some useful information about timelines:
    1. There can be multiple PTAdBreaks of types pre-roll, mid-roll, and post-roll. A PTAdBreak has:
      1. A CMTimeRange that has the start time and duration of the break. This is set as the range property of PTAdBreak.
      2. NSArray of PTAds. This is set as the ads property of PTAdBreak.
    2. A PTAd represents the ad itself. Each PTAd has:
      1. A PTAdHLSAsset set as the primary asset property of the ad.
      2. Could also have multiple PTAdAsset instances as clickable ads or banner ads.
    For example:
    NSMutableArray *ptBreaks = [[[NSMutableArray alloc] init] autorelease];
      
    // Prepare the primary asset of the ad - links to ad m3u8
    PTAdHLSAsset *ptAdAsset = [[[PTAdHLSAsset alloc] init] autorelease];
    ptAdAsset.source = AD_SOURCE_M3U8;
    ptAdAsset.id = FAKE_NUMBER_ID;
    ptAdAsset.format = @"video";
      
    // Prepare the ad itself.
    PTAd *ptAd = [[[PTAd alloc] init] autorelease];
    ptAd.primaryAsset = ptAdAsset;
    ptAd.primaryAsset.ad = ptAd;
      
    // Prepare the break and add the ad created above.
    PTAdBreak *ptBreak = [[[PTAdBreak alloc] init] autorelease];
    ptBreak.relativeRange = CMTimeRangeMake(BREAK_START_TIME, BREAK_DURATION_VALUE);
    [ptBreak addAd:ptAd];
      
    // Add the break to array of breaks.
    [ptBreaks addObject:adBreak];
      
    // Once all breaks have been prepared, they can be set on timeline
    PTTimeline *_timeline = [[PTTimeline alloc] init];
    _timeline.adBreaks = ptBreaks;
  5. Call didFinishResolvingPlacementOpportunity, providing the PTTimeline.
  6. Register your custom content/ad resolver to the default media player factory by calling registerContentResolver.
    //Remove default content/ad resolver
    [[PTDefaultMediaPlayerFactory defaultFactory] clearContentResolvers];
     
    //Create an instance of your content/ad resolver (id <PTContentResolver>)
    CustomContentResolver *contentResolver = [[CustomContentResolver alloc] init];
     
    //Set custom content/ad resolver
    [[PTDefaultMediaPlayerFactory defaultFactory] registerContentResolver:[contentResolver autorelease]];
  7. If you implemented a custom opportunity resolver, register it to the default media player factory.
    Note: Registering a custom opportunity resolver is not required to register a custom content/ad resolver.
    //Remove default opportunity resolver
    [[PTDefaultMediaPlayerFactory defaultFactory] clearOpportunityResolvers];
     
    //Create an instance of your opportunity resolver (id <PTOpportunityResolver>)
    CustomOpportunityResolver *opportunityResolver = [[CustomOpportunityResolver alloc] init];
     
    //Set custom opportunity resolver
    [[PTDefaultMediaPlayerFactory defaultFactory] 
               registerOpportunityResolver:[opportunityResolver autorelease]];
When the player loads the content and it is determined to be of type VOD or LIVE:
  • If VOD, custom content resolver is used to get the ad timeline of the whole video.
  • If LIVE, custom content resolver is called every time a placement opportunity (cue point) is detected in the content.