Create a custom opportunity detector

The custom opportunity detector is a class that monitors the playback timeline and detects ad placement opportunities.

The packager scans the playlist files for special cues and detects if they contain any ad placement information. An example of a cue entry for HLS stream is:
#EXT-X-CUE:TYPE=SpliceOut,ID=7687, TIME=578123.41,DURATION=30.0,AVAIL-NUM=0,AVAILS-EXPECtED=0, PROGRAM-ID=0
  1. Add the following code:
    public class CustomPlacementOpportunityDetector implements PlacementOpportunityDetector {
    	// ...
    
    	@Override
    	public List<PlacementOpportunity> process(List<TimedMetadata> timedMetadataList, Metadata metadata) {
    		PMPDemoApp.logger.i(LOG_TAG + "#process", "Processing ["
    			+ timedMetadataList.size()
    			+ "] timed metadata, in order to provide placement opportunities.");
    		List<PlacementOpportunity> opportunities = new ArrayList<PlacementOpportunity>();
    
    		for (TimedMetadata timedMetadata : timedMetadataList) {
    			if (isPlacementOpportunity(timedMetadata)) {
    				boolean shouldProcessTimedMetadata = timedMetadata.getTime() > _timeOfLastDetectedOpportunity;
    			if (shouldProcessTimedMetadata) {
    				_timeOfLastDetectedOpportunity = timedMetadata.getTime();
    
    			// The airingId (CAID) is in another tag. Iterate through the timedMetadata list and find
    			// the CAID associated with this ad cue point.
    
    			String airingId = getAiringIdForTime(timedMetadata.getTime(), timedMetadataList);
    			PlacementOpportunity opportunity = createPlacementOpportunity(timedMetadata, airingId, metadata);
  2. Also add:
    if (opportunity != null) {
    		PMPDemoApp.logger.i(LOG_TAG + "#process", "Created new placement opportunity at time "
    			+ opportunity.getPlacementInformation().getTime()
    			+ ", with a duration of "
    			+ opportunity.getPlacementInformation().getDuration()
    			+ "ms.");
    		opportunities.add(opportunity);
    	} else {
    		PMPDemoApp.logger.w(LOG_TAG + "#process", "Ad placement opportunity creation has failed. Probably has invalid metadata."
    			+ " opportunity time = " + String.valueOf(timedMetadata.getTime())
    			+ ", metadata: " + timedMetadata.getMetadata()
    			+ ", processing time = " + String.valueOf(_timeOfLastDetectedOpportunity) +
    			"].");
    		}
    	} else {
    		PMPDemoApp.logger.w(LOG_TAG + "#process", "Ad placement opportunity
    			skipped. It was either already processed or its position is in the past (previous to the play
    			head). 
    			[" + " opportunity time= " + String.valueOf(timedMetadata.getTime()) +
    			", processing time=" + String.valueOf(_timeOfLastDetectedOpportunity) +
    			"].");
    			}
    		}
    	}
    }