User Interaction Controller

Purpose

The User Interaction Controller manages the interface between the user’s input and the media playback engine within the player UI. It addresses the need for responsive, intuitive control over video playback, seeking, subtitle toggling, and ad interaction. By maintaining observable playback state data, it enables dynamic UI updates that reflect current playback status and media metadata.

This controller solves the problem of bridging complex playback states—including transitions between ads and content—and user actions, ensuring that UI elements such as play/pause buttons, seek bars, subtitles toggles, and ad metadata stay synchronized with the underlying media player.

Functionality

Key Workflow Example

When the user drags the seek bar:

  1. onStartTrackingTouch sets isDraggingSeekBar to true to pause automatic UI updates.

  2. As progress changes, onProgressChanged updates the displayed time values in real-time.

  3. On releasing the seek bar (onStopTrackingTouch), the controller seeks the player to the new position and clears the dragging flag.

  4. Playback progress updates resume only when the user is not interacting.

Relationship to Parent Topic and Other Subtopics

This controller is a core part of the **Media Playback and UI Controls** parent topic, specializing in bridging user input with the adaptive streaming playback managed by ExoPlayer. Unlike the **Player UI Controller** which focuses primarily on managing UI component visibility and resume states, or the **Custom Player View** which integrates video rendering and subtitles, the User Interaction Controller encapsulates the logic for interpreting and acting on user commands, while maintaining observable state for UI binding.

It complements the **Playback Activity Base** by providing a reusable, lifecycle-aware interface for controlling playback that activities can instantiate and bind to UI components such as `UIControllerView`. It also interacts indirectly with the FSM layer via callbacks to synchronize user actions with playback state transitions, ensuring smooth coordination between user input, UI feedback, and underlying media state.

Introducing New Behavior Not Covered Elsewhere

Code Snippet Highlight

The controller’s operation on user seeking demonstrates its integration of UI events with playback control:

@Override
public void onStopTrackingTouch(final SeekBar seekBar) {
    if (mPlayer != null) {
        seekTo(Utils.progressToMilli(mPlayer.getDuration(), seekBar));
    }
    isDraggingSeekBar.set(false);
}

@Override
public void seekTo(final long millisecond) {
    if (mPlaybackActionCallback != null && mPlaybackActionCallback.isActive()) {
        long currentProgress = mPlayer != null ? mPlayer.getCurrentPosition() : 0;
        mPlaybackActionCallback.onSeek(mMediaModel, currentProgress, millisecond);
    }
    seekToPosition(millisecond);
}

private void seekToPosition(long positionMs) {
    if (mPlayer != null) {
        mPlayer.seekTo(mPlayer.getCurrentWindowIndex(), positionMs);
    }
}

This snippet shows how user input triggers a seek operation both in the ExoPlayer instance and notifies external callbacks for further processing or analytics.

Diagram

flowchart TD
    User[User Input]
    UI[UI Components (e.g. SeekBar, Buttons)]
    Controller[User Interaction Controller]
    Player[ExoPlayer Instance]
    Callbacks[PlaybackActionCallback]
    SubtitleView[Subtitle View]

    User --> UI
    UI --> Controller
    Controller --> Player
    Controller --> Callbacks
    Controller --> SubtitleView
    Player --> Controller
    Callbacks --> Controller

**Diagram Explanation:** User input through UI components (like buttons or seek bars) is routed to the User Interaction Controller, which translates these actions into playback commands on the ExoPlayer instance and updates UI observables. It also notifies registered playback callbacks for state synchronization. The controller directly manipulates subtitle visibility through the subtitle view and listens for player events to update UI accordingly.


This design ensures a seamless, reactive user experience tightly coupled with the underlying playback engine and higher-level state management.