PlayerUIController.java
Overview
`PlayerUIController` is a Java class designed to manage multiple ExoPlayer instances and related UI components involved in media playback within an Android application. Its primary role is to coordinate playback between content videos and advertisements, including support for VPAID ads via a WebView, and to maintain playback resume state information for both content and ads.
This controller abstracts the complexity of handling separate players for content and ads (or reusing a single player instance depending on device capabilities), tracks playback positions to enable seamless resumption, and maintains user playback history. It acts as a bridge between the underlying media playback engines and the user interface layer, facilitating smooth transitions and consistent UI state during playback sessions.
Detailed Breakdown
Class: PlayerUIController
Purpose
Manage references to
SimpleExoPlayerinstances for both content and ads.Handle a
WebViewfor VPAID ads.Maintain the view that renders the player UI.
Track resume positions and windows for content and ads.
Manage playback history for resuming from a saved position.
Provide accessor and mutator methods for these properties.
Adapt behavior based on device-specific constraints (e.g., single player reuse).
Fields
Field Name | Type | Description |
|---|---|---|
`isPlayingAds` | `boolean` | Indicates whether ads are currently playing. |
`contentPlayer` | `SimpleExoPlayer` | The ExoPlayer instance used to play main content videos. |
`adPlayer` | `SimpleExoPlayer` | The ExoPlayer instance used to play advertisements (may be null or same as contentPlayer). |
`vpaidWebView` | `WebView` | A WebView used to display VPAID ads (video ads rendered via HTML/JS). |
`exoPlayerView` | `View` | The UI View associated with the ExoPlayer instances (player UI surface). |
`adResumeWindow` | `int` | The resume window index for ad playback; `C.INDEX_UNSET` if unset. |
`adResumePosition` | `long` | The resume position (in milliseconds) within the ad window; `C.TIME_UNSET` if unset. |
`movieResumeWindow` | `int` | The resume window index for content playback; `C.INDEX_UNSET` if unset. |
`movieResumePosition` | `long` | The resume position (in milliseconds) within the movie window; `C.TIME_UNSET` if unset. |
`hasHistory` | `boolean` | Flag indicating if there is a playback history to resume from. |
`historyPosition` | `long` | The playback position to resume from history; `C.TIME_UNSET` if unset. |
Constructors
PlayerUIController()
Default constructor initializing an empty controller with no players or views set.
PlayerUIController(@Nullable SimpleExoPlayer contentPlayer, @Nullable SimpleExoPlayer adPlayer, @Nullable WebView vpaidWebView, @Nullable View exoPlayerView)
Parameterized constructor for initializing all the main components at once.
Parameters:
contentPlayer: ExoPlayer instance for content playback.adPlayer: ExoPlayer instance for ad playback.vpaidWebView: WebView for VPAID ads.exoPlayerView: View associated with ExoPlayer rendering.
**Usage example:**
SimpleExoPlayer contentPlayer = ...; // Initialized elsewhere
SimpleExoPlayer adPlayer = ...; // Optional; could be null
WebView vpaidWebView = ...; // Optional
View playerView = ...; // ExoPlayer UI view
PlayerUIController controller = new PlayerUIController(contentPlayer, adPlayer, vpaidWebView, playerView);
Methods
Player Accessors and Mutators
SimpleExoPlayer getContentPlayer()Returns the ExoPlayer instance used for content video playback.
void setContentPlayer(SimpleExoPlayer contentPlayer)Sets the content player instance.
SimpleExoPlayer getAdPlayer()Returns the ExoPlayer instance used for ad playback.
Important: If the device uses a single player setup (
PlayerDeviceUtils.useSinglePlayer()returns true), the content player instance is reused for ads.This abstraction allows optimized resource usage depending on device capabilities.
void setAdPlayer(SimpleExoPlayer adPlayer)Sets the ad player instance.
WebView getVpaidWebView()Returns the WebView used for VPAID ads.
void setVpaidWebView(WebView vpaidWebView)Sets the VPAID WebView.
View getExoPlayerView()Returns the view associated with the ExoPlayer UI.
void setExoPlayerView(View exoPlayerView)Sets the ExoPlayer UI view.
Playback History Management
void setPlayFromHistory(long pos)Marks that playback should resume from a saved position.
Sets
hasHistoryto true and stores thehistoryPosition.
boolean hasHistory()Returns true if there is playback history to resume from.
long getHistoryPosition()Returns the saved playback position for resuming.
void clearHistoryRecord()Clears the playback history flag and resets position.
Resume Information for Ads and Content
void setAdResumeInfo(int window, long position)Saves the resume window index and position for ad playback.
void clearAdResumeInfo()Resets ad resume info to unset values.
void setMovieResumeInfo(int window, long position)Saves the resume window index and position for content playback.
void clearMovieResumeInfo()Resets movie resume info to unset values.
int getAdResumeWindow()Gets the ad resume window index.
long getAdResumePosition()Gets the ad resume position.
int getMovieResumeWindow()Gets the movie resume window index.
long getMovieResumePosition()Gets the movie resume position.
Nested Class: PlayerUIController.Builder
A builder class to facilitate flexible and readable construction of `PlayerUIController` instances.
Builder Methods
Builder setContentPlayer(SimpleExoPlayer contentPlayer)Builder setAdPlayer(SimpleExoPlayer adPlayer)Builder setVpaidWebView(WebView vpaidWebView)Builder setExoPlayerView(View exoPlayerView)PlayerUIController build()
**Usage example:**
PlayerUIController controller = new PlayerUIController.Builder()
.setContentPlayer(contentPlayer)
.setAdPlayer(adPlayer)
.setVpaidWebView(vpaidWebView)
.setExoPlayerView(playerView)
.build();
Important Implementation Details
Single Player Optimization:
The methodgetAdPlayer()consultsPlayerDeviceUtils.useSinglePlayer()to decide whether to reuse the content player for ads or use a separate ad player instance. This optimization reduces resource usage on devices that perform better with a single player.Resume Window and Position:
Playback is tracked not just by position in milliseconds but also by the window index (adResumeWindowandmovieResumeWindow). This is important in playlists or multi-window media sources where playback can span multiple media items.Playback History Flag:
ThehasHistoryboolean andhistoryPositionallow the application to know if the user wants to resume playback from a previous session and at what position.VPAID Support:
The inclusion of aWebViewfield for VPAID (Video Player-Ad Interface Definition) ads indicates support for interactive HTML5-based video ads, which are not played via ExoPlayer and require a dedicated WebView.
Interaction with Other System Components
Content and Ad Players:
PlayerUIControllermanages the two main ExoPlayer instances used throughout the app for playing content and ads, possibly switching between them or reusing one.Player UI View:
TheexoPlayerViewfield holds the UI element that displays video and controls. This view is updated or controlled based on the active player instance.PlayerDeviceUtils:
Utility class used to determine device capabilities and adjust player reuse behavior.Playback Control Layer:
Other components, such as user interaction controllers or playback state machines, interact with this controller to query or set playback state, retrieve players, or manage playback resume logic.Ad Integration Layer:
The WebView for VPAID ads enables integration with interactive ads that require a different rendering pathway than typical video playback.
Example Usage Scenario
The application initializes
PlayerUIControllervia theBuilderpattern, providing the content player, the ad player, the VPAID WebView, and the player view.When an ad is about to play, the system requests the ad player via
getAdPlayer(). Depending on the device, this might be the content player or a dedicated ad player.The system saves the current playback position of the content (movie) before switching to ads by calling
setMovieResumeInfo(...).After ad playback, resume info for ads and movie is used to seamlessly return playback to the correct content position.
If the user had previously watched part of the movie,
setPlayFromHistory(pos)is called to resume from that position.
Mermaid Class Diagram
classDiagram
class PlayerUIController {
- boolean isPlayingAds
- SimpleExoPlayer contentPlayer
- SimpleExoPlayer adPlayer
- WebView vpaidWebView
- View exoPlayerView
- int adResumeWindow
- long adResumePosition
- int movieResumeWindow
- long movieResumePosition
- boolean hasHistory
- long historyPosition
+ PlayerUIController()
+ PlayerUIController(contentPlayer, adPlayer, vpaidWebView, exoPlayerView)
+ getContentPlayer()
+ setContentPlayer(contentPlayer)
+ getAdPlayer()
+ setAdPlayer(adPlayer)
+ getVpaidWebView()
+ setVpaidWebView(vpaidWebView)
+ getExoPlayerView()
+ setExoPlayerView(exoPlayerView)
+ setPlayFromHistory(pos)
+ hasHistory()
+ getHistoryPosition()
+ clearHistoryRecord()
+ setAdResumeInfo(window, position)
+ clearAdResumeInfo()
+ setMovieResumeInfo(window, position)
+ clearMovieResumeInfo()
+ getAdResumeWindow()
+ getAdResumePosition()
+ getMovieResumeWindow()
+ getMovieResumePosition()
}
class PlayerDeviceUtils {
+ useSinglePlayer()
}
PlayerUIController --> PlayerDeviceUtils : uses
class Builder {
- SimpleExoPlayer contentPlayer
- SimpleExoPlayer adPlayer
- WebView vpaidWebView
- View exoPlayerView
+ setContentPlayer(contentPlayer)
+ setAdPlayer(adPlayer)
+ setVpaidWebView(vpaidWebView)
+ setExoPlayerView(exoPlayerView)
+ build()
}
PlayerUIController ..> Builder : creates
Summary
`PlayerUIController` is a central component managing multiple playback instances and related UI elements for a media playback Android app. It elegantly handles the complexities of ad playback vs. content playback, resume positions, and VPAID ad integration via a WebView, providing a flexible interface for other components to interact with playback sessions. The inclusion of a builder pattern enhances configurability and clarity during instantiation.
This controller is crucial for maintaining a seamless viewing experience where playback can pause, resume, switch between content and ads, and support advanced ad formats without disrupting the user interface or playback flow.