DemoActivity.java
Overview
`DemoActivity.java` defines the `DemoActivity` class, which is a specialized Android activity extending from `TubiPlayerActivity`. This activity acts as a demo player for media content, leveraging the ExoPlayer media playback framework within the Tubi ecosystem. Its primary responsibility is to initialize media playback, manage user interactions with the media player (such as play/pause toggling, seeking, subtitle toggling, and quality selection), and handle ad insertion by concatenating advertisement media sources with the main media.
This file demonstrates how to extend and customize the playback experience by overriding player lifecycle callbacks and event handlers. It includes logic to create a concatenated media source combining ads and main content, as well as handling user actions like "Learn More" clicks on media ads.
Classes and Methods
DemoActivity
Extends `TubiPlayerActivity` and overrides several lifecycle and event callback methods to customize media playback behavior.
Constants
TAG(String): A tag for logging purposes, initialized to the class simple name (DemoActivity).
Lifecycle Methods
protected void onCreate(Bundle savedInstanceState)Description: Android lifecycle method called when the activity is created. Here it calls the superclass implementation.
Parameters:
savedInstanceState(Bundle): If non-null, this activity is being re-initialized after previously being shut down.
Return: None.
Usage: Standard Android activity creation; no additional initialization in this override.
Player Lifecycle and Event Callbacks
protected void onPlayerReady()Description: Called when the player is ready for playback. This method creates a media source and starts playback.
Parameters: None.
Return: None.
Usage Example:
@Override protected void onPlayerReady() { MediaSource mediaSource = createMediaSource(); playMedia(mediaSource); }Implementation Details: Calls
createMediaSource()to build a concatenated media source with ads and media, then uses the inheritedplayMedia()method to start playback.
public void onProgress(@Nullable MediaModel mediaModel, long milliseconds, long durationMillis)Description: Callback for playback progress updates.
Parameters:
mediaModel(MediaModel| nullable): The media currently playing.milliseconds(long): Current playback position in milliseconds.durationMillis(long): Total duration of the media in milliseconds.
Return: None.
Usage: Currently commented-out debug logging and an example of restarting playback after 15 seconds.
public void onSeek(@Nullable MediaModel mediaModel, long oldPositionMillis, long newPositionMillis)Description: Callback for when the user seeks to a new playback position.
Parameters:
mediaModel(MediaModel| nullable): The media currently playing.oldPositionMillis(long): The previous playback position.newPositionMillis(long): The new playback position after seeking.
Return: None.
Usage: Currently commented-out debug logging.
public void onPlayToggle(@Nullable MediaModel mediaModel, boolean playing)Description: Callback when playback is toggled (play/pause).
Parameters:
mediaModel(MediaModel| nullable): The media currently playing.playing(boolean): True if playback started, false if paused.
Return: None.
Usage: Logs the current playing state.
public void onLearnMoreClick(@NonNull MediaModel mediaModel)Description: Callback when the user clicks the "Learn More" button on a media item.
Parameters:
mediaModel(MediaModel): The media item clicked.
Return: None.
Usage: Opens the media's click-through URL in a browser if available.
Implementation Example:
@Override public void onLearnMoreClick(@NonNull MediaModel mediaModel) { if (mediaModel.getClickThroughUrl() != null) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mediaModel.getClickThroughUrl())); startActivity(intent); } }
public void onSubtitles(@Nullable MediaModel mediaModel, boolean enabled)Description: Callback when subtitles are enabled or disabled.
Parameters:
mediaModel(MediaModel| nullable): The media currently playing.enabled(boolean): True if subtitles are enabled.
Return: None.
Usage: Logs the subtitle enabled state.
public void onQuality(@Nullable MediaModel mediaModel)Description: Callback when quality selection is triggered.
Parameters:
mediaModel(MediaModel| nullable): The media currently playing.
Return: None.
Usage: Logs a quality event placeholder (no further implementation).
public void onCuePointReceived(long[] cuePoints)Description: Callback when cue points are received during playback.
Parameters:
cuePoints(long[]): Array of cue points in milliseconds.
Return: None.
Usage: Empty implementation; can be used to trigger actions based on cue points.
Protected Helper Methods
protected MediaSource createMediaSource()Description: Constructs a concatenated media source combining the main media and two advertisement media sources.
Parameters: None.
Return:
MediaSource- a concatenation of ad1, ad2, and the main media sources.Implementation Details:
Sets the media source for the main
mediaModelby callingbuildMediaSource(mediaModel).Creates two ad
MediaModelinstances using static URLs and builds their media sources.Uses
MediaHelper.create(ad1, ad2, mediaModel).getConcatenatedMedia()to concatenate these media sources for playback.
Usage Example:
protected MediaSource createMediaSource() { mediaModel.setMediaSource(buildMediaSource(mediaModel)); MediaModel ad1 = MediaModel.ad("http://c11.adrise.tv/ads/...", null, false); ad1.setMediaSource(buildMediaSource(ad1)); MediaModel ad2 = MediaModel.ad("http://c13.adrise.tv/ads/...", "https://github.com/stoyand", false); ad2.setMediaSource(buildMediaSource(ad2)); return MediaHelper.create(ad1, ad2, mediaModel).getConcatenatedMedia(); }Note:
mediaModelis presumably a field inherited or initialized inTubiPlayerActivity(not shown in this snippet).
Important Implementation Details and Algorithms
Ad Insertion via Concatenated MediaSource:
The
createMediaSource()method builds a singleMediaSourcethat concatenates two advertisements followed by the main media content. This is achieved through theMediaHelper.create(...).getConcatenatedMedia()utility, which likely returns aConcatenatingMediaSourcefrom ExoPlayer. This approach allows seamless playback of multiple media items in sequence, including ads.User Interaction Handling:
The class overrides multiple event callbacks to respond to user actions such as toggling playback, seeking, enabling subtitles, or clicking "Learn More." Although most callbacks currently log events or have minimal implementation, the structure is prepared for further customization.
Intent-based External Navigation:
On "Learn More" clicks, the activity launches an external browser intent pointing to the media's click-through URL, enhancing interactivity with ad content.
Interaction with Other Parts of the System
Inheritance from
TubiPlayerActivity:DemoActivityextendsTubiPlayerActivity, inheriting media player lifecycle methods, playback control (playMedia()), and possibly themediaModelfield representing the current media.Usage of ExoPlayer:
The activity uses ExoPlayer's
MediaSourceabstraction for media playback. Building media sources is delegated tobuildMediaSource()(likely defined in the superclass or elsewhere), and media concatenation utilities come fromMediaHelper.Model Layer:
MediaModelrepresents media items including advertisements. It encapsulates media URLs, click-through URLs, and playback states.Android Framework:
The activity makes use of standard Android components such as
Intent,Bundle, and lifecycle callbacks.
Example Usage
// Starting the DemoActivity from another Activity or Context:
Intent intent = new Intent(context, DemoActivity.class);
context.startActivity(intent);
Once started, `DemoActivity` will prepare the media player, load the ads and main content, and start playback automatically when the player is ready.
Mermaid Class Diagram
classDiagram
class DemoActivity {
+static TAG: String
+onCreate(savedInstanceState: Bundle)
+onPlayerReady()
+onProgress(mediaModel: MediaModel?, milliseconds: long, durationMillis: long)
+onSeek(mediaModel: MediaModel?, oldPositionMillis: long, newPositionMillis: long)
+onPlayToggle(mediaModel: MediaModel?, playing: boolean)
+onLearnMoreClick(mediaModel: MediaModel)
+onSubtitles(mediaModel: MediaModel?, enabled: boolean)
+onQuality(mediaModel: MediaModel?)
+onCuePointReceived(cuePoints: long[])
#createMediaSource(): MediaSource
}
DemoActivity --|> TubiPlayerActivity
Summary
`DemoActivity.java` is a demonstration subclass of `TubiPlayerActivity` that exemplifies how to play media with ads using ExoPlayer in the Tubi media framework. It overrides key lifecycle and event callbacks to manage playback, user interactions, and ad insertion via concatenated media sources. This file serves as a customizable template for implementing media playback activities with integrated ad content and user engagement features within an Android application.