# How SmartTube Renders SponsorBlock Segments on the Seek Bar: A Deep Dive into the Implementation

> Discover how SmartTube implements SponsorBlock markers on its seek bar. Learn about proportional SeekBarSegment objects and category-specific colors in this deep dive.

- Repository: [Yuriy L/SmartTube](https://github.com/yuliskov/SmartTube)
- Tags: deep-dive
- Published: 2026-09-14

---

**SmartTube converts SponsorBlock API data into proportional SeekBarSegment objects with category-specific colors, then renders them as colored rectangles on a custom SeekBar view.**

SmartTube is an open-source YouTube client for Android TV that integrates the SponsorBlock service to skip unwanted video segments. Understanding how SmartTube handles Seek Bar markers for SponsorBlock segments reveals a clean architecture that transforms temporal API data into visual UI elements using proportional positioning and dynamic color mapping according to the yuliskov/SmartTube source code.

## Architecture Overview: From API to Visual Markers

The implementation follows a four-stage pipeline that separates data retrieval from presentation. First, `SponsorBlockController` fetches segment data from the SponsorBlock API. Next, it converts raw timestamps into proportional progress values and assigns category-specific colors. Finally, the custom `SeekBar` view renders these as colored rectangles overlaid on the video progress bar.

This architecture ensures that the player UI remains decoupled from the SponsorBlock API, communicating instead through lightweight `SeekBarSegment` data transfer objects.

## Fetching and Converting SponsorBlock Data

The process begins in [`SponsorBlockController.java`](https://github.com/yuliskov/SmartTube/blob/main/SponsorBlockController.java) located at `common/src/main/java/com/liskovsoft/smartyoutubetv2/common/app/models/playback/controllers/`. This controller receives a list of `SponsorSegment` objects from the SponsorBlock API and transforms them into UI-ready objects.

The conversion happens in the `toSeekBarSegments()` method, which calculates proportional start and end positions by dividing segment timestamps by the total video duration:

```java
// Inside SponsorBlockController – converting raw SponsorSegment data
private List<SeekBarSegment> toSeekBarSegments(List<SponsorSegment> segments) {
    List<SeekBarSegment> result = new ArrayList<>();
    for (SponsorSegment s : segments) {
        SeekBarSegment seg = new SeekBarSegment();
        seg.startProgress = (float) s.getStartTimeMs() / videoDuration;
        seg.endProgress   = (float) s.getEndTimeMs()   / videoDuration;
        seg.color = sponsorBlockData.getColorRes(s.getCategory()); // colour mapping
        result.add(seg);
    }
    return result;
}

```

Each `SeekBarSegment` contains three critical fields: `startProgress` (float), `endProgress` (float), and `color` (int resource ID). These values represent the segment's position as a fraction of the total video length, ensuring markers remain accurate regardless of screen resolution or seek bar width.

## Category-Based Color Mapping

The color for each segment category is defined in [`SponsorBlockData.java`](https://github.com/yuliskov/SmartTube/blob/main/SponsorBlockData.java) at `common/src/main/java/com/liskovsoft/smartyoutubetv2/common/prefs/`. The constructor of this class builds a color map that associates each SponsorBlock category with a specific resource color. For example, **Sponsor** segments typically map to green, **Intro** segments to cyan, and other categories like **Outro** or **Self-promotion** receive distinct colors.

When `toSeekBarSegments()` calls `sponsorBlockData.getColorRes(s.getCategory())`, it retrieves the appropriate color resource ID for that segment type, ensuring users can visually distinguish between different kinds of skipped content at a glance.

## Integrating with the Player UI

Once converted, the list of `SeekBarSegment` objects travels to the player UI through the `Player.setSeekBarSegments()` interface method. This is implemented in UI glue classes such as `PlaybackFragment` and `MaxControlsVideoPlayerGlue`, located in `smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/playback/`.

These components act as intermediaries, receiving the segment list from the controller and forwarding it to the actual view component. This abstraction allows the controller to remain in the common module while the TV-specific UI handles the actual rendering implementation.

## Rendering Markers on the Custom SeekBar

The final rendering occurs in the custom `SeekBar` class at [`smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/mod/leanback/misc/SeekBar.java`](https://github.com/yuliskov/SmartTube/blob/main/smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/mod/leanback/misc/SeekBar.java). This view extends the standard Android SeekBar to support segmented overlays.

The view receives segments through `setSegments(List<SeekBarSegment>)`, creates a `SeekBarRectangle` for each segment, and invalidates the view to trigger a redraw:

```java
// SeekBar view – drawing the coloured markers
public void setSegments(List<SeekBarSegment> segments) {
    calculateSegments(segments);
    invalidate(); // triggers onDraw where each SeekBarRectangle is painted with its colour
}

```

During the `onDraw` canvas operation, the view iterates over the calculated rectangles and paints colored bars at the proportional positions defined by `startProgress` and `endProgress`, overlaying the standard seek bar track.

## Summary

- **Data Conversion**: `SponsorBlockController` transforms API timestamps into proportional `SeekBarSegment` objects with normalized start/end progress values.
- **Color Mapping**: `SponsorBlockData` maintains a category-to-color mapping (e.g., Sponsor → green, Intro → cyan) applied during segment conversion.
- **UI Decoupling**: The controller communicates with the player UI through the `Player.setSeekBarSegments()` interface, implemented by `PlaybackFragment` and glue classes.
- **Custom Rendering**: The modified `SeekBar` view in `smarttubetv` draws colored rectangles by creating `SeekBarRectangle` objects and painting them during the canvas draw cycle.

## Frequently Asked Questions

### How does SmartTube calculate the position of SponsorBlock markers on the seek bar?

SmartTube calculates positions by dividing the segment's start and end timestamps (in milliseconds) by the total video duration. This occurs in `SponsorBlockController.toSeekBarSegments()`, which stores the result as floating-point `startProgress` and `endProgress` values between 0.0 and 1.0 in the `SeekBarSegment` object.

### What colors does SmartTube use for different SponsorBlock categories?

The colors are defined in [`SponsorBlockData.java`](https://github.com/yuliskov/SmartTube/blob/main/SponsorBlockData.java) and mapped during segment conversion. While the exact hex values depend on the theme, typical mappings include green for **Sponsor** segments, cyan for **Intro**, and distinct colors for **Outro**, **Self-promotion**, and **Interaction Reminder** categories.

### Where is the SeekBar rendering logic implemented in SmartTube?

The custom rendering logic resides in [`smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/mod/leanback/misc/SeekBar.java`](https://github.com/yuliskov/SmartTube/blob/main/smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/mod/leanback/misc/SeekBar.java). This class extends the standard Android SeekBar, overrides the drawing methods, and handles `SeekBarSegment` objects to paint colored rectangles at the appropriate proportional positions.

### How does the SponsorBlockController communicate segment data to the UI?

The controller calls `player.setSeekBarSegments()`, which is implemented by player UI components like `PlaybackFragment` and `MaxControlsVideoPlayerGlue`. These glue classes forward the segment list to the custom `SeekBar` view, maintaining separation between the data layer (common module) and the presentation layer (TV module).