FsmPlayer.java
Overview
`FsmPlayer` is an **abstract class** that implements a Finite State Machine (FSM) to manage media playback within a video player system, particularly focusing on orchestrating **content playback**, **ad playback**, and **state transitions** in response to playback events and ad retrieval results.
This class serves as the **core controller** that:
Maintains the current playback state.
Coordinates with UI and ad logic controllers.
Handles asynchronous callbacks from ad retrieval processes.
Manages media models for main content and ads.
Drives state transitions based on inputs and lifecycle events.
Supports special ad formats such as VPAID.
Ensures smooth integration of ads (preroll, midroll, etc.) with content playback.
`FsmPlayer` acts as the backbone for playback logic, offering a robust, extensible framework to handle complex playback workflows in a modular, maintainable way.
Detailed Description of Classes and Interfaces
Class: FsmPlayer
Package
`com.tubitv.media.fsm.state_machine`
Implements
Fsm(Finite State Machine interface)RetrieveAdCallback(for ad retrieval results)FsmAdController(ad playback control interface)
Key Responsibilities
Hold and update the current playback
State.Manage transitions triggered by
Inputevents.Interact with ad server interfaces and cue points retrievers.
Control ExoPlayer instances via UI and logic controllers.
Handle ad playback lifecycle, including VPAID ads.
Maintain playback resume positions for content.
Respect Android lifecycle to avoid invalid transitions.
Provide callback methods for ad retrieval results.
Fields and Properties
Field | Type | Description |
|---|---|---|
`playerComponentController` | `PlayerAdLogicController` | Wrapper for player logic related components (e.g., ad player, content player logic). |
`controller` | `PlayerUIController` | Wrapper for UI components managing video playback UI and ExoPlayer instances. |
`adServerInterface` | `AdInterface` | Interface to interact with ad network servers for fetching ads. |
`adRetriever` | `AdRetriever` | Contains information to retrieve ads from the server. |
`cuePointsRetriever` | `CuePointsRetriever` | Contains information to retrieve cue points from the server, which trigger midroll ads. |
`movieMedia` | `MediaModel` | The main content media being played. |
`adMedia` | `AdMediaModel` | The current ad media being played. |
`currentState` | `State` | The current FSM playback state representing the player's status. |
`factory` | `StateFactory` | Factory class to create and cache state instances for transitions. |
`VPAID_END_POINT` | `String` | URL endpoint for VPAID ads (default is example URL). |
`isInitialized` | `boolean` | Flag indicating whether the FSM player has been initialized. |
`mLifecycle` | `Lifecycle` | Android lifecycle to avoid transitions when the UI is inactive (e.g., stopped). |
Constructor
public FsmPlayer(StateFactory factory)
Parameters:
factory: AStateFactoryinstance to create FSM state objects.
Description:
Initializes the FSM player with a givenStateFactoryused for generating states during transitions.
Public Methods
static void updateMovieResumePosition(PlayerUIController controller)
Description:
Updates the resume position of the main video content in the controller, storing the current playback window index and position.Parameters:
controller: ThePlayerUIControllerinstance managing UI and ExoPlayer.
Usage:
Called to save playback progress so it can resume from the same point later.
boolean isInitialized()
Description:
Returns whether the FSM player has been initialized.Returns:
trueif initialized, elsefalse.
Getters and Setters for Media and Controllers
MediaModel getMovieMedia()void setMovieMedia(MediaModel movieMedia)AdMediaModel getAdMedia()void setAdMedia(AdMediaModel adMedia)AdInterface getAdServerInterface()void setAdServerInterface(@NonNull AdInterface adServerInterface)AdRetriever getAdRetriever()void setAdRetriever(@NonNull AdRetriever adRetriever)Lifecycle getLifecycle()void setLifecycle(Lifecycle mLifecycle)PlayerUIController getController()void setController(@NonNull PlayerUIController controller)PlayerAdLogicController getPlayerComponentController()void setPlayerComponentController(PlayerAdLogicController playerComponentController)CuePointsRetriever getCuePointsRetriever()void setCuePointsRetriever(CuePointsRetriever cuePointsRetriever)String getVPAID_END_POINT()void setVPAID_END_POINT(String VPAID_END_POINT)
boolean hasAdToPlay()
Description:
Checks if there are any ads available to play.Returns:
trueifadMediaexists and contains at least one ad;falseotherwise.
MediaModel getNextAdd()
Description:
Retrieves the next ad to be played from theadMedia.Returns:
The nextMediaModelrepresenting an ad, or null if none available.
void updateCuePointForRetriever(long cuepoint)
Description:
Updates the cue point value in theAdRetrieverfor fetching ads at a specific playback position.Parameters:
cuepoint: The cue point timestamp in milliseconds.
FSM Interface Methods
State getCurrentState()
Returns the current playback FSM state.
void restart()
Description:
Stops playback, clears resume info, resets the current state, prepares the main content media source again, and triggers an FSM transition withInput.INITIALIZE.Usage:
Used to restart the player and FSM playback lifecycle.
void transit(Input input)
Description:
Drives the FSM to transition to a new state based on the current state and anInputevent.Parameters:
input: TheInputenum representing an event such asINITIALIZE,AD_RECEIVED,AD_FINISH,ERROR, etc.
Implementation Details:
Checks Android lifecycle state; skips transition if the lifecycle is not at least
STARTED.Uses the current state's
transformToState(input, factory)method to determine the next state.If no valid next state is returned, defaults to
MoviePlayingState.Updates the resume position if applicable.
Calls the new state's
performWorkAndUpdatePlayerUI(this)to execute state behavior.
Example Usage:
fsmPlayer.transit(Input.INITIALIZE);
Triggers FSM initialization and state transition.
Ad Playback Control Methods (FsmAdController)
void removePlayedAdAndTransitToNextState()
Description:
Removes the ad that was just played from theadMedialist.Behavior:
If there are more ads to play, transitions to either
VPAID_MANIFESTorNEXT_ADinput depending on ad type.If no more ads remain, transitions to
VPAID_FINISHorAD_FINISHdepending on current state.
Usage:
Called after an ad finishes playing to move FSM forward.
void adPlayerError()
Description:
Transitions FSM to theERRORstate upon an ad player error.
Callback Methods (RetrieveAdCallback)
void onReceiveAd(AdMediaModel mediaModels)
Description:
Called when ad data is successfully retrieved from the ad server.Parameters:
mediaModels: TheAdMediaModelcontaining the ads fetched.
Behavior:
Updates
adMedia.Prepares ads via
playerComponentController.Triggers FSM transition based on current state (
AD_RECEIVEDorPRE_ROLL_AD_RECEIVED).
void onError()
Description:
Called when ad retrieval fails.Behavior:
Logs the failure.
Triggers FSM transition to
ERROR.
void onEmptyAdReceived()
Description:
Called when ad retrieval succeeds but returns no ads.Behavior:
Triggers FSM transition to
EMPTY_AD.
Other Methods
void updateSelf()
Description:
Invokes the current state'sperformWorkAndUpdatePlayerUI()to update playback behavior and UI.Use Case:
Called to refresh the FSM's current state logic.
Important Implementation Details and Algorithms
State Transition Logic:
The FSM transitions based on the currentState'stransformToState()method, which takes anInputand produces the nextState. If no valid transition exists, it defaults toMoviePlayingStateto maintain playback continuity.Lifecycle Awareness:
Transitions are guarded by Android lifecycle state. If the UI is not active (e.g., stopped), transitions are skipped to prevent illegal state changes during lifecycle pauses.Ad Playback Handling:
Ads are queued inadMedia, and the FSM manages their lifecycle by popping played ads and transitioning to the next ad or content playback.VPAID Ads Integration:
Special handling is provided for VPAID ads to pause the content and ad players and route playback through a WebView interface.Resume Position Management:
updateMovieResumePosition()saves the current playback position and window index during state changes to allow seamless resuming.Use of Factory Pattern:
StateFactorycreates and caches state instances to optimize performance and ensure consistent state objects.Separation of Concerns:
Playback logic (FsmPlayer) is separated from UI (PlayerUIController), ad logic (PlayerAdLogicController), and ad retrieval (AdRetriever,AdInterface).
Interaction with Other System Components
PlayerUIController:
Manages the ExoPlayer instances for content and ads, UI updates, and resume info storage.PlayerAdLogicController:
Controls additional player logic, such as dual players for ad/content and handles ad preparation.AdInterface and AdRetriever:
Interface and data class used for fetching ads asynchronously from ad servers.CuePointsRetriever:
Retrieves cue points indicating when midroll ads should play.StateFactory:
Generates state instances for FSM transitions.States (from package
com.tubitv.media.fsm.concrete):
Concrete implementations of playback states likeMoviePlayingState,MakingAdCallState,VpaidState, etc., encapsulating playback behavior and transition logic.Android Lifecycle:
Ensures FSM transitions respect activity lifecycle to avoid playback issues when the app is in the background.
Usage Example
// Initialize FSM Player with a StateFactory
StateFactory factory = new StateFactory();
FsmPlayer fsmPlayer = new ConcreteFsmPlayer(factory);
// Set controllers
fsmPlayer.setController(playerUIController);
fsmPlayer.setPlayerComponentController(playerAdLogicController);
// Set media and ad retrieval info
fsmPlayer.setMovieMedia(movieMediaModel);
fsmPlayer.setAdRetriever(adRetriever);
fsmPlayer.setAdServerInterface(adInterface);
// Start playback FSM
fsmPlayer.transit(Input.INITIALIZE);
// Later, on receiving ads:
fsmPlayer.onReceiveAd(adMediaModel);
// On ad playback completion:
fsmPlayer.removePlayedAdAndTransitToNextState();
Visual Diagram: Class Structure of FsmPlayer.java
classDiagram
class FsmPlayer {
-PlayerAdLogicController playerComponentController
-PlayerUIController controller
-AdInterface adServerInterface
-AdRetriever adRetriever
-CuePointsRetriever cuePointsRetriever
-MediaModel movieMedia
-AdMediaModel adMedia
-State currentState
-StateFactory factory
-String VPAID_END_POINT
-boolean isInitialized
-Lifecycle mLifecycle
+FsmPlayer(StateFactory factory)
+static void updateMovieResumePosition(PlayerUIController controller)
+boolean isInitialized()
+MediaModel getMovieMedia()
+void setMovieMedia(MediaModel)
+AdMediaModel getAdMedia()
+void setAdMedia(AdMediaModel)
+AdInterface getAdServerInterface()
+void setAdServerInterface(AdInterface)
+AdRetriever getAdRetriever()
+void setAdRetriever(AdRetriever)
+Lifecycle getLifecycle()
+void setLifecycle(Lifecycle)
+boolean hasAdToPlay()
+String getVPAID_END_POINT()
+void setVPAID_END_POINT(String)
+MediaModel getNextAdd()
+PlayerUIController getController()
+void setController(PlayerUIController)
+PlayerAdLogicController getPlayerComponentController()
+void setPlayerComponentController(PlayerAdLogicController)
+CuePointsRetriever getCuePointsRetriever()
+void setCuePointsRetriever(CuePointsRetriever)
+void updateCuePointForRetriever(long)
+State getCurrentState()
+void restart()
+void transit(Input)
+void removePlayedAdAndTransitToNextState()
+void adPlayerError()
+void updateSelf()
+void onReceiveAd(AdMediaModel)
+void onError()
+void onEmptyAdReceived()
}
FsmPlayer ..|> Fsm
FsmPlayer ..|> RetrieveAdCallback
FsmPlayer ..|> FsmAdController
Summary
`FsmPlayer` is an abstract finite state machine controller for a media player that elegantly manages the complex interplay between content playback and ad insertion. It coordinates playback states, handles asynchronous ad fetching callbacks, manages lifecycle-aware transitions, and supports special ad formats like VPAID. Its design promotes modularity, extensibility, and robustness, making it a foundational component of the media playback system.