Dual Player Setup

Purpose

The Dual Player Setup addresses the challenge of managing two distinct media playback streams within a single player activity: one for the main content video and another dedicated to advertisements. This setup is essential for seamless integration of video ads (preroll, midroll, postroll) without interrupting or complicating the content playback experience. By maintaining separate ExoPlayer instances for content and ads, the system can independently control playback states, buffering, and transitions, ensuring smoother ad insertion and better user experience.

Functionality

This subtopic primarily manages the lifecycle, preparation, and coordination of two `SimpleExoPlayer` instances:

Key workflows and features include:

  1. Initialization and Injection
    The activity injects dependencies such as the FSM player, UI controllers, ad retrievers, and monitors. It initiates the content player and conditionally sets up the ad player based on device capabilities.

  2. Creation of ExoPlayer Instances

    • Content player is initialized via superclass methods.

    • Ad player is created with an adaptive track selector and bandwidth meter to optimize streaming quality during ads:

    TrackSelection.Factory adaptiveTrackSelectionFactory =
         new AdaptiveTrackSelection.Factory(BANDWIDTH_METER_AD);
    trackSelector_ad = new DefaultTrackSelector(adaptiveTrackSelectionFactory);
    adPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector_ad);
    
  3. Media Source Preparation
    Each media model (content or ad) has its own media source created and assigned, allowing independent playback control.

  4. Playback State and Position Management
    Resume positions for both players are tracked separately to enable smooth resumption after interruptions or lifecycle changes:

    int adResumeWindow = adPlayer.getCurrentWindowIndex();
    long adResumePosition = adPlayer.isCurrentWindowSeekable() ? Math.max(0, adPlayer.getCurrentPosition())
             : C.TIME_UNSET;
    playerUIController.setAdResumeInfo(adResumeWindow, adResumePosition);
    
  5. FSM Integration
    The FSM player is configured with references to both players via the PlayerUIController, enabling state-driven control of content and ad playback:

    playerUIController.setContentPlayer(mMoviePlayer);
    playerUIController.setAdPlayer(adPlayer);
    
  6. Lifecycle and Resource Management
    On activity destruction or release, both players are properly released, and their resume positions updated to preserve playback state.

  7. Ad Playback Control and Cue Point Monitoring
    The ad player works in concert with monitors and retrievers that trigger ad playback at appropriate cue points, maintaining synchronization with the FSM states.

Integration

The Dual Player Setup is a foundational subtopic that directly supports the broader "Dual Player Activity" main topic. It provides the concrete implementation of managing two separate ExoPlayer instances, which the FSM player and UI controllers depend on to orchestrate complex playback scenarios involving both content and advertisements.

It complements other subtopics by:

This clear separation of players ensures that the FSM can effectively manage state transitions such as switching from content playback to ad playback and back, without player conflicts or complex internal juggling.

Diagram

flowchart LR
    subgraph Player Lifecycle
        direction TB
        Init[Initialize Content Player]
        InitAd[Initialize Ad Player]
        PrepareContent[Prepare Content Media Source]
        PrepareAd[Prepare Ad Media Source]
        PlayContent[Play Content]
        PlayAd[Play Ad]
        TrackContentPos[Track Content Resume Position]
        TrackAdPos[Track Ad Resume Position]
        ReleaseAd[Release Ad Player]
        ReleaseContent[Release Content Player]
    end

    Init --> PrepareContent --> PlayContent --> TrackContentPos
    InitAd --> PrepareAd --> PlayAd --> TrackAdPos
    PlayAd --> PlayContent
    TrackAdPos --> ReleaseAd
    TrackContentPos --> ReleaseContent

    PlayerUIController -.-> PlayContent
    PlayerUIController -.-> PlayAd
    FSMPlayer --> PlayerUIController
    FSMPlayer --> Init
    FSMPlayer --> InitAd

This flowchart illustrates the lifecycle management of two separate ExoPlayer instances — content and ad players — highlighting their initialization, preparation, playback, tracking of resume positions, and release. The FSM player orchestrates these through the `PlayerUIController`, enabling smooth transitions and independent control.


By implementing this dual player setup, the system achieves robust, modular playback capable of handling complex ad integration scenarios without compromising content experience or requiring convoluted player state management.