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:
Content Player (
mMoviePlayer): Handles the playback of the main media content.Ad Player (
adPlayer): Dedicated to playing advertisement media streams.
Key workflows and features include:
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.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);Media Source Preparation
Each media model (content or ad) has its own media source created and assigned, allowing independent playback control.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);FSM Integration
The FSM player is configured with references to both players via thePlayerUIController, enabling state-driven control of content and ad playback:playerUIController.setContentPlayer(mMoviePlayer); playerUIController.setAdPlayer(adPlayer);Lifecycle and Resource Management
On activity destruction or release, both players are properly released, and their resume positions updated to preserve playback state.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:
Enabling Dependency Injection Integration to inject and manage player instances and controllers cleanly.
Working alongside Ad and Cue Point Management by feeding playback events and positions that trigger ad loading and transitions.
Supporting Media Playback and UI Controls by exposing both players to UI components for user interaction and status display.
Allowing VPAID Ad Integration to coexist by isolating ad playback streams, including those managed via WebView, without interfering with content playback.
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.