TubiPlayerActivity.java
Overview
`TubiPlayerActivity` is an **abstract base activity** that manages the lifecycle and setup of a single instance of ExoPlayer (`SimpleExoPlayer`) intended for video content playback within the Tubi media application. It provides a reusable foundation for media playback activities by:
Initializing and configuring the ExoPlayer with adaptive streaming support.
Preparing media sources based on streaming type (SmoothStreaming, DASH, HLS, or others).
Handling subtitle integration via sideloaded subtitle sources.
Managing UI components including the main player view (
TubiExoPlayerView), VPAID ad WebView, and cue point indicators.Managing player lifecycle events in accordance with Android activity lifecycle to optimize resources.
Exposing abstract methods for subclasses to customize user interaction views, captions, resume position handling, and player readiness behavior.
This class can be extended directly to create a standalone video player activity with custom UI controls and support for various adaptive streaming formats.
Class: TubiPlayerActivity
Declaration
public abstract class TubiPlayerActivity extends LifeCycleActivity implements PlaybackActionCallback
Superclass:
LifeCycleActivity(likely an activity with enhanced lifecycle tracking)Interfaces:
PlaybackActionCallback(to handle playback-related user actions/callbacks)
Purpose
Manages ExoPlayer setup, media source construction, lifecycle-aware player release, and UI initialization. Provides hooks for subclasses to extend and customize behavior.
Fields
Field Name | Type | Description |
|---|---|---|
`BANDWIDTH_METER` | `DefaultBandwidthMeter` (static final) | Monitors bandwidth to enable adaptive track selection. |
`TUBI_MEDIA_KEY` | `String` (static) | Intent extra key for passing serialized `MediaModel`. |
`mMoviePlayer` | `SimpleExoPlayer` | The main ExoPlayer instance used for playback. |
`mTubiPlayerView` | `TubiExoPlayerView` | Custom player view managing video surface and UI controls. |
`vpaidWebView` | `WebView` | WebView for rendering VPAID ads. |
`cuePointIndictor` | `TextView` | UI element for showing cue point indicators during playback. |
`mTrackSelector` | `DefaultTrackSelector` | Selects media tracks adaptively. |
`isActive` | `boolean` | Indicates if the player is active and ready. |
`mediaModel` | `MediaModel` (non-null) | Model containing metadata and URLs for the media to play. |
`mMainHandler` | `Handler` | Handler for main thread tasks and callbacks. |
`mMediaDataSourceFactory` | `DataSource.Factory` | Factory to create media data sources for ExoPlayer. |
`mEventLogger` | `EventLogger` | Logs playback events for analytics/debugging. |
Abstract Methods
Subclasses **must** implement these to provide customized behavior:
Method | Return Type | Description |
|---|---|---|
`addUserInteractionView()` | `View` | Supplies a custom user interaction view to be added inside the player view for UI controls. |
`onPlayerReady()` | `void` | Callback invoked once the player is ready after setup, useful for subclass initialization or UI updates. |
`updateResumePosition()` | `void` | Called before player release to save or update the playback resume position (e.g., for resume playback). |
`isCaptionPreferenceEnable()` | `boolean` | Returns whether subtitles/captions should be enabled by default, e.g., read from user preferences. |
Lifecycle Methods and Player Management
onCreate(Bundle savedInstanceState)
Parses the incoming intent to extract the
MediaModel.Hides system UI for immersive playback.
Initializes the data source factory (with bandwidth metering enabled).
Sets up the activity layout and player view.
parseIntent()
Extracts the serialized
MediaModelfrom the intent extras.Throws error if no media is supplied.
initLayout()
Sets content view.
Finds and initializes views:
TubiExoPlayerView,WebViewfor ads, cue point indicator.Inserts the user interaction view provided by subclass via
addUserInteractionView().
onStart() / onResume() / onPause() / onStop()
Manages player initialization and release according to lifecycle and SDK version:
setupExo()initializes the player if required.releaseMoviePlayer()releases resources properly.
setupExo()
Calls
initMoviePlayer()to create and configure the ExoPlayer.Enables captions if preferred.
Marks playback as active.
Calls subclass
onPlayerReady().
initMoviePlayer()
Creates the
DefaultTrackSelectorwith adaptive track selection.Instantiates
SimpleExoPlayer.Attaches
EventLoggerfor analytics.Binds
SimpleExoPlayertoTubiExoPlayerView.Passes the
MediaModelto the player view.
releaseMoviePlayer()
Saves resume position via
updateResumePosition().Releases ExoPlayer and clears references.
Marks player as inactive.
Media Source Construction
buildMediaSource(MediaModel model)
Builds appropriate ExoPlayer `MediaSource` depending on the media type:
Determines the streaming type via URL extension or content type inference.
Supports:
SmoothStreaming (
SsMediaSource)DASH (
DashMediaSource)HLS (
HlsMediaSource)Progressive or other (
ExtractorMediaSource)
If subtitles URL is provided, creates a
SingleSampleMediaSourcewith SUBRIP format.Returns a
MergingMediaSourcethat combines video and subtitle sources.
**Throws:** `IllegalStateException` for unsupported media types.
Data Source Factory
buildDataSourceFactory(boolean useBandwidthMeter)
Delegates to
MediaHelper.buildDataSourceFactory.Optionally attaches the global bandwidth meter for adaptive streaming.
Caption Toggle
setCaption(boolean isOn)
Enables or disables subtitles using the player controller interface.
Checks for availability of subtitle URL and control view before toggling.
Player Controller Access
getPlayerController()
Returns the
TubiPlaybackControlInterfacefromTubiExoPlayerViewif available.Returns
nullif player view or controller is not initialized.
Usage Example
A subclass would typically extend `TubiPlayerActivity` and implement abstract methods:
public class MyPlayerActivity extends TubiPlayerActivity {
@Override
public View addUserInteractionView() {
// Inflate and return a custom controls view
return getLayoutInflater().inflate(R.layout.my_custom_controls, null);
}
@Override
protected void onPlayerReady() {
// Perform UI updates or start playback
mMoviePlayer.setPlayWhenReady(true);
}
@Override
protected void updateResumePosition() {
// Save current playback position for resuming later
long position = mMoviePlayer.getCurrentPosition();
// Persist position as needed
}
@Override
protected boolean isCaptionPreferenceEnable() {
// Return user preference for captions
return true;
}
}
Important Implementation Details
Uses ExoPlayer’s adaptive track selector with a bandwidth meter for smooth adaptive streaming.
Handles multiple streaming protocols seamlessly by selecting appropriate media source types.
Supports sideloaded subtitles via a merged media source.
Manages player lifecycle tightly with Android activity lifecycle and SDK version differences to optimize resource use.
Abstract design promotes reuse and customization for different playback scenarios.
Integrates VPAID ads support via a WebView component (though actual ad control is expected in subclass or related components).
Interaction with Other System Components
TubiExoPlayerView: Acts as the video rendering surface and UI container, tightly coupled with this activity.MediaModel: Provides all metadata and URLs necessary for playback; passed in via intent.PlaybackActionCallback: Interface implemented by this activity to receive playback-related user actions from UI controls.MediaHelper: Utility class used to build data source factories with network and bandwidth monitoring.Event Logger: Used for analytics and debugging playback events.
Subclasses: Extend this base to add UI controls, caption preferences, resume logic, and custom player-ready behavior.
Ad Playback Components: VPAID WebView and cue point indicator support ad metadata display and interaction.
Mermaid Class Diagram
classDiagram
class TubiPlayerActivity {
- static BANDWIDTH_METER: DefaultBandwidthMeter
- static TUBI_MEDIA_KEY: String
- mMoviePlayer: SimpleExoPlayer
- mTubiPlayerView: TubiExoPlayerView
- vpaidWebView: WebView
- cuePointIndictor: TextView
- mTrackSelector: DefaultTrackSelector
- isActive: boolean
- mediaModel: MediaModel
- mMainHandler: Handler
- mMediaDataSourceFactory: DataSource.Factory
- mEventLogger: EventLogger
+ abstract addUserInteractionView(): View
+ abstract onPlayerReady(): void
+ abstract updateResumePosition(): void
+ abstract isCaptionPreferenceEnable(): boolean
+ onCreate(Bundle): void
+ onStart(): void
+ onResume(): void
+ onPause(): void
+ onStop(): void
+ onNewIntent(Intent): void
+ onConfigurationChanged(Configuration): void
+ isActive(): boolean
- parseIntent(): void
- initLayout(): void
- setCaption(boolean): void
- setupExo(): void
- initMoviePlayer(): void
- releaseMoviePlayer(): void
- buildMediaSource(MediaModel): MediaSource
- buildDataSourceFactory(boolean): DataSource.Factory
+ getPlayerController(): TubiPlaybackControlInterface
}
Summary
`TubiPlayerActivity` serves as a robust and extensible foundation for video playback activities in the Tubi media app. Its design abstracts complex ExoPlayer setup and lifecycle management while empowering subclasses to customize UI and playback behavior. The class ensures smooth adaptive streaming, subtitle support, and resource-optimized playback lifecycle handling, making it a critical component in the media playback architecture.
Appendix: Activity Lifecycle Flowchart
flowchart TD
A[onCreate] --> B[parseIntent]
B --> C[initLayout]
C --> D[onStart / onResume]
D --> E[setupExo]
E --> F[initMoviePlayer]
F --> G[buildMediaSource]
G --> H[bind Player to UI]
H --> I[setCaption]
I --> J[onPlayerReady]
J --> K[Playback Active]
K --> L[onPause / onStop]
L --> M[releaseMoviePlayer]
M --> N[updateResumePosition]
N --> O[Playback Inactive]
If you need further details about related classes such as `TubiExoPlayerView` or `MediaModel`, or about the playback control interfaces, feel free to ask!