DoubleViewTubiPlayerActivity.java


Overview

`DoubleViewTubiPlayerActivity` is an Android activity class designed for advanced video playback scenarios involving **two simultaneous ExoPlayer instances**: one for the main content (movie) playback and another for advertisements (ads). It extends from `TubiPlayerActivity` and implements interfaces for dual player control (`DoublePlayerInterface`) and auto-play functionality (`AutoPlay`).

This class orchestrates the lifecycle, initialization, and coordination of these two players, integrates a finite state machine (FSM) for robust playback state management, handles VPAID ads via a WebView, and supports rich user interactions and UI updates through injected controllers.

Key Responsibilities:


Class: DoubleViewTubiPlayerActivity

public class DoubleViewTubiPlayerActivity extends TubiPlayerActivity implements DoublePlayerInterface, AutoPlay

Description

An activity class that extends the base `TubiPlayerActivity` to support **dual media playback** with two ExoPlayer instances, enabling seamless content and advertisement playback. It implements `DoublePlayerInterface` for controlling two players and `AutoPlay` for automated playback features.


Fields

Field

Type

Description

`TAG`

`String`

Logging tag for debugging (`"DoubleViewTubiPlayerAct"`)

`BANDWIDTH_METER_AD`

`DefaultBandwidthMeter`

Bandwidth meter for ad player adaptive track selection

`adPlayer`

`SimpleExoPlayer`

ExoPlayer instance dedicated to ad playback

`fsmPlayer`

`FsmPlayer`

Injected FSM player managing playback states

`playerUIController`

`PlayerUIController`

Injected UI controller updating player views

`adPlayingMonitor`

`AdPlayingMonitor`

Injected monitor for ad playback events

`cuePointMonitor`

`CuePointMonitor`

Injected monitor for cue point events

`adRetriever`

`AdRetriever`

Injected component to retrieve ad media

`cuePointsRetriever`

`CuePointsRetriever`

Injected component to retrieve cue points

`adInterface`

`AdInterface`

Injected interface for ad server communication

`playerComponentController`

`PlayerAdLogicController`

Injected controller coordinating ad playback logic

`vpaidClient`

`VpaidClient`

Injected client managing VPAID ads in WebView

`trackSelector_ad`

`DefaultTrackSelector`

Track selector for the ad player


Constructor and Lifecycle Methods

onCreate(Bundle savedInstanceState)


Dependency Injection

injectDependency()

protected void injectDependency() {
    DaggerFsmComonent.builder()
        .playerModuleDefault(new PlayerModuleDefault())
        .build()
        .inject(this);
}

dependencyPrepare()


Player Initialization and Lifecycle

initMoviePlayer()

setupAdPlayer()

TrackSelection.Factory adaptiveTrackSelectionFactory =
    new AdaptiveTrackSelection.Factory(BANDWIDTH_METER_AD);
trackSelector_ad = new DefaultTrackSelector(adaptiveTrackSelectionFactory);
adPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector_ad);

releaseMoviePlayer()

releaseAdPlayer()


Playback Position Management

updateResumePosition()

updateAdResumePosition()


FSM Preparation

prepareFSM()

playerUIController.setContentPlayer(mMoviePlayer);
if (!PlayerDeviceUtils.useSinglePlayer()) {
    playerUIController.setAdPlayer(adPlayer);
}
playerUIController.setExoPlayerView(mTubiPlayerView);
playerUIController.setVpaidWebView(vpaidWebView);

fsmPlayer.setController(playerUIController);
fsmPlayer.setMovieMedia(mediaModel);
fsmPlayer.setAdRetriever(adRetriever);
fsmPlayer.setCuePointsRetriever(cuePointsRetriever);
fsmPlayer.setAdServerInterface(adInterface);

playerComponentController.setAdPlayingMonitor(adPlayingMonitor);
playerComponentController.setTubiPlaybackInterface(this);
playerComponentController.setDoublePlayerInterface(this);
playerComponentController.setCuePointMonitor(cuePointMonitor);
playerComponentController.setVpaidClient(vpaidClient);

fsmPlayer.setPlayerComponentController(playerComponentController);
fsmPlayer.setLifecycle(getLifecycle());

if (fsmPlayer.isInitialized()) {
    fsmPlayer.updateSelf();
    Utils.hideSystemUI(this, true);
} else {
    fsmPlayer.transit(Input.INITIALIZE);
}

User Interaction View

addUserInteractionView()


Intent Handling and Navigation

onNewIntent(Intent intent)

onBackPressed()

ingoreWebViewBackNavigation(WebView vpaidWebView)


Media Source and Ads Preparation

createMediaSource(MediaModel videoMediaModel)

onPrepareAds(@Nullable AdMediaModel adMediaModel)


Playback Event Callbacks

These methods respond to playback events and update monitors or UI accordingly:


Playback Control

playNext(MediaModel nextVideo)


Important Implementation Details


Interaction with Other Components


Usage Example

// Starting the activity with a media model (from somewhere in the app)
Intent intent = new Intent(context, DoubleViewTubiPlayerActivity.class);
intent.putExtra(TubiPlayerActivity.TUBI_MEDIA_KEY, mediaModel);
context.startActivity(intent);

Inside the activity, the dual players are initialized, and playback begins with FSM coordination, automatically handling ads and content according to cue points and playback state.


Mermaid Class Diagram

classDiagram
    class DoubleViewTubiPlayerActivity {
        -static final String TAG
        -static final DefaultBandwidthMeter BANDWIDTH_METER_AD
        -SimpleExoPlayer adPlayer
        -FsmPlayer fsmPlayer
        -PlayerUIController playerUIController
        -AdPlayingMonitor adPlayingMonitor
        -CuePointMonitor cuePointMonitor
        -AdRetriever adRetriever
        -CuePointsRetriever cuePointsRetriever
        -AdInterface adInterface
        -PlayerAdLogicController playerComponentController
        -VpaidClient vpaidClient
        -DefaultTrackSelector trackSelector_ad
        +onCreate(Bundle)
        +addUserInteractionView() View
        +injectDependency()
        +dependencyPrepare()
        +initMoviePlayer()
        +onPlayerReady()
        +releaseMoviePlayer()
        +updateResumePosition()
        +prepareFSM()
        +onNewIntent(Intent)
        +onBackPressed()
        +createMediaSource(MediaModel)
        +onPrepareAds(AdMediaModel)
        +onProgress(MediaModel, long, long)
        +onSeek(MediaModel, long, long)
        +onPlayToggle(MediaModel, boolean)
        +onLearnMoreClick(MediaModel)
        +onSubtitles(MediaModel, boolean)
        +onQuality(MediaModel)
        +onCuePointReceived(long[])
        +playNext(MediaModel)
    }
    DoubleViewTubiPlayerActivity --|> TubiPlayerActivity
    DoubleViewTubiPlayerActivity ..> FsmPlayer : injected
    DoubleViewTubiPlayerActivity ..> PlayerUIController : injected
    DoubleViewTubiPlayerActivity ..> AdPlayingMonitor : injected
    DoubleViewTubiPlayerActivity ..> CuePointMonitor : injected
    DoubleViewTubiPlayerActivity ..> AdRetriever : injected
    DoubleViewTubiPlayerActivity ..> CuePointsRetriever : injected
    DoubleViewTubiPlayerActivity ..> AdInterface : injected
    DoubleViewTubiPlayerActivity ..> PlayerAdLogicController : injected
    DoubleViewTubiPlayerActivity ..> VpaidClient : injected
    DoubleViewTubiPlayerActivity o-- SimpleExoPlayer : adPlayer
    DoubleViewTubiPlayerActivity o-- DefaultTrackSelector : trackSelector_ad

Summary

`DoubleViewTubiPlayerActivity` is a specialized Android activity enabling advanced dual-player video playback scenarios, managing separate ExoPlayer instances for content and ads. It tightly integrates with a finite state machine to manage playback states and transitions, supports VPAID ads via WebView, and leverages dependency injection for modular design. This class is pivotal in delivering a smooth, robust video playback experience with advanced ad insertion capabilities on the Tubi platform.