Media Models and Helpers

This module defines the core data models representing media and advertisement content, as well as utility helpers that facilitate media source creation and device-specific playback behavior. It encapsulates the representation of media items, advertisement breaks, and provides supportive utilities to manage media playback characteristics efficiently.


Media and Ad Models

MediaModel

The `MediaModel` class represents an individual media item, which can be either a piece of video content or an advertisement. It serves as the foundational data structure carrying all necessary metadata and playback information required throughout the playback lifecycle.

**Purpose and Problem Solved:** `MediaModel` abstracts the various attributes associated with media playback into a single, serializable object. This encapsulation allows the playback system and UI components to uniformly handle both content and ads without duplicating logic or data structures.

**Key Attributes:**

**Key Functionalities:**

**Example Usage:**

// Creating a video media model
MediaModel content = MediaModel.video("Example Video", "http://example.com/video.m3u8", "http://example.com/artwork.jpg", null);

// Creating an ad media model
MediaModel ad = MediaModel.ad("http://example.com/ad.m3u8", "http://advertiser.com", false);

AdMediaModel

`AdMediaModel` acts as a container for a list of `MediaModel` instances representing a sequence of ads grouped into an ad break. It abstracts the concept of an ad break containing multiple ads and provides utility methods for managing this list.

**Core Purpose:** It simplifies ad break management by encapsulating multiple ads and providing methods to retrieve and consume ads one by one during playback.

**Key Functionalities:**

**Usage Context:** During ad playback, the FSM or ad playback controllers use this model to access the current ad to play, cycle through ads in an ad break, and determine when the ad break is complete.


Media Helper Utilities

MediaHelper

The `MediaHelper` class provides static utility methods to support media playback infrastructure, primarily focusing on the construction of data source factories required by the underlying media player.

**Purpose:** It centralizes and standardizes the creation of data source factories, which are essential for ExoPlayer to fetch media streams over HTTP with bandwidth measurement and user-agent headers.

**Key Functionalities:**

**Why This Matters:** Proper construction of these factories ensures efficient media loading, adaptive bitrate streaming, and consistency in network requests, which are fundamental for smooth playback experiences.

**Code Snippet Reference:**

public static @NonNull DataSource.Factory buildDataSourceFactory(@NonNull Context context,
        @Nullable DefaultBandwidthMeter bandwidthMeter) {
    return new DefaultDataSourceFactory(context, bandwidthMeter,
            buildHttpDataSourceFactory(context, bandwidthMeter));
}

Device Playback Utilities

PlayerDeviceUtils

This utility class provides methods to detect device characteristics influencing playback strategies, mainly whether the current device is a TV or has known limitations with multiple player instances.

**Core Problem Addressed:** Certain devices, especially TV sets or specific hardware like the Xiaomi Mi Box, have limited resources or platform quirks that require adapting the playback architecture, such as using a single player instance rather than multiple.

**Key Methods:**

**Impact on Playback Design:** These utilities enable the player implementation to conditionally configure itself for optimal performance and stability on different hardware configurations.

**Example Logic Reference:**

public static boolean useSinglePlayer() {
    if (sIsTVDevice) {
        return true;
    }
    if (XIAOMI_MANUFACTURER.equals(Util.MANUFACTURER) && MI_BOX_DEVICE.equals(Util.DEVICE)) {
        return true;
    }
    return false;
}

Seek Calculation Utility

SeekCalculator

`SeekCalculator` provides logic to compute dynamic seek intervals based on how long the user has been seeking and the frequency of seek requests.

**Why It Exists:** To enhance user experience during fast-forward or rewind operations, seeking speed should increase progressively the longer the user holds the seek control, allowing both fine-grained and rapid navigation.

**Key Concepts:**

**Workflow:**

**Example Behavior:**

long seekRate = SeekCalculator.getSeekRate(seekStartTime, currentTime);
if (seekRate > 0) {
    long newPosition = currentPosition + (seekRate * direction);
    player.seekTo(newPosition);
}

Interaction and Integration


Summary Diagram: Media Models and Helpers Overview

classDiagram
    class MediaModel {
        - String videoUrl
        - String mediaName
        - String artworkUrl
        - String subtitlesUrl
        - String clickThroughUrl
        - boolean isAd
        - boolean isVpaid
        - MediaSource mediaSource
        + video()
        + ad()
        + getMediaSource()
        + setMediaSource()
    }

    class AdMediaModel {
        - List~MediaModel~ listOfAds
        + nextAD()
        + popFirstAd()
        + nubmerOfAd()
    }

    class MediaHelper {
        + buildDataSourceFactory(context, bandwidthMeter)
        + buildHttpDataSourceFactory(context, bandwidthMeter)
    }

    class PlayerDeviceUtils {
        + isTVDevice(context)
        + useSinglePlayer()
    }

    class SeekCalculator {
        + getSeekRate(startTime, currentTime)
    }

    MediaModel "1" --o "1" AdMediaModel : contains >
    MediaHelper ..> MediaModel : builds data sources for
    PlayerDeviceUtils ..> MediaModel : influences player config
    SeekCalculator ..> MediaModel : used for playback seeking

This documentation exposes the foundational media data representations and playback utility functions critical for the system’s media playback, ad management, and user interaction features. Understanding these models and helpers is essential for working with media preparation, playback logic, and adapting to device-specific constraints.