# How SmartTube Integrates with SponsorBlock: A Technical Deep Dive

> Discover how SmartTube integrates with SponsorBlock. Learn about the controller, API fetching, and automatic segment skipping for an enhanced viewing experience.

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

---

**SmartTube integrates SponsorBlock through a dedicated controller that fetches crowd-sourced segment data from the SponsorBlock API and automatically skips, notifies, or prompts users about unwanted video segments based on configurable preferences stored in SponsorBlockData.**

SmartTube, the popular open-source YouTube client for Android TV maintained by yuliskov/SmartTube, seamlessly removes sponsored content and other unwanted segments through native SponsorBlock integration. This feature allows users to automatically skip advertisements, intros, outros, and other crowd-sourced categories without manual intervention. Understanding how SmartTube integrates with SponsorBlock requires examining the Java-based controller architecture that bridges the SponsorBlock API with the video playback pipeline.

## Architecture Overview

The SmartTube SponsorBlock integration consists of four primary components that work together to filter video segments during playback. These components handle everything from user preference storage to real-time segment skipping.

The data flow follows this pattern:

```text
PlaybackPresenter → registers SponsorBlockController
SponsorBlockController
   │
   ├─ reads preferences from SponsorBlockData
   ├─ contacts SponsorBlock API → receives List<SponsorSegment>
   ├─ filters segments according to enabled categories & excluded channels
   └─ executes the configured SegmentAction while the player runs

```

## Core Components

### SponsorBlockData (Preference Storage)

Located at [`common/src/main/java/com/liskovsoft/smartyoutubetv2/common/prefs/SponsorBlockData.java`](https://github.com/yuliskov/SmartTube/blob/main/common/src/main/java/com/liskovsoft/smartyoutubetv2/common/prefs/SponsorBlockData.java), this singleton class serves as the central repository for all SponsorBlock-related settings. It stores the global enabled flag, per-category actions, channel exclusion lists, and alternate server configurations.

Key responsibilities include:

- Managing the `isSponsorBlockEnabled()` state
- Mapping segment categories to `SegmentAction` values
- Maintaining the excluded channels list via `excludeChannel()`

### SponsorBlockSettingsPresenter (User Interface)

The `SponsorBlockSettingsPresenter` class in [`common/src/main/java/com/liskovsoft/smartyoutubetv2/common/app/presenters/settings/SponsorBlockSettingsPresenter.java`](https://github.com/yuliskov/SmartTube/blob/main/common/src/main/java/com/liskovsoft/smartyoutubetv2/common/app/presenters/settings/SponsorBlockSettingsPresenter.java) provides the settings interface accessible through *Settings → Content Block → SponsorBlock*. This presenter manipulates `SponsorBlockData` to persist user choices.

Users can configure:

- Global enable/disable toggle
- Per-category actions: *Do nothing*, *Skip only*, *Skip + toast*, or *Show dialog*
- Channel exclusions to disable SponsorBlock for specific creators
- Alternate server endpoints

### SponsorBlockController (Playback Integration)

The `SponsorBlockController` at [`common/src/main/java/com/liskovsoft/smartyoutubetv2/common/app/models/playback/controllers/SponsorBlockController.java`](https://github.com/yuliskov/SmartTube/blob/main/common/src/main/java/com/liskovsoft/smartyoutubetv2/common/app/models/playback/controllers/SponsorBlockController.java) is the core engine that monitors playback position and executes segment actions. As a subclass of `BasePlayerController`, it receives callbacks during video playback.

The controller implements the primary logic in `onPlayerStateChanged()`:

```java
@Override
public void onPlayerStateChanged(PlayerState state) {
    if (!mPrefs.isSponsorBlockEnabled() || !checkVideo(getVideo())) return;

    // Load cached segments or request fresh ones from SponsorBlock API
    mOriginalSegments = fetchSegmentsFromApi(getVideo().videoId);
    mActiveSegments = filterSegments(mOriginalSegments);

    // Check if current playback position intersects with any segment
    List<SponsorSegment> hit = findMatchedSegments(
            getPlayer().getPositionMs(), mActiveSegments, true);

    // Apply the user-chosen action for each matched segment
    for (SponsorSegment seg : hit) {
        SegmentAction action = mPrefs.getAction(seg.category);
        performAction(action, seg);
    }
}

```

### PlaybackPresenter (Controller Registration)

The `PlaybackPresenter` class registers `SponsorBlockController` into the playback pipeline, ensuring the controller receives video metadata and position updates. This registration happens during playback initialization in [`common/src/main/java/com/liskovsoft/smartyoutubetv2/common/app/presenters/PlaybackPresenter.java`](https://github.com/yuliskov/SmartTube/blob/main/common/src/main/java/com/liskovsoft/smartyoutubetv2/common/app/presenters/PlaybackPresenter.java).

## Data Flow and API Integration

### Fetching Segment Data

When a video loads, `fetchSegmentsFromApi()` contacts the SponsorBlock API at `https://sponsor.ajay.app/api/...` (or an alternate server if configured). The API returns a `List<SponsorSegment>` containing start times, end times, and categories for crowd-sourced segments.

### Filtering Logic

The `filterSegments()` method applies user preferences to the raw API response:

- Removes segments from excluded channels
- Filters out disabled categories
- Validates segment boundaries against video duration

### Executing Actions

The `performAction()` method implements four distinct behaviors based on `SponsorBlockData` preferences:

- **Skip only**: Seeks playback to `seg.endTimeMs` immediately
- **Skip + toast**: Jumps to the end time and displays a brief notification
- **Show dialog**: Pauses playback and invokes `AppDialogUtil` to present skip/keep options
- **Do nothing**: Allows the segment to play normally

## Configuration Examples

### Enabling SponsorBlock Programmatically

To enable SponsorBlock and configure the "Skip + toast" action for sponsor segments:

```java
Context ctx = // Android context
SponsorBlockData prefs = SponsorBlockData.instance(ctx);

// Enable the feature globally
prefs.setSponsorBlockEnabled(true);

// Set action for sponsor category
prefs.setAction(
    SponsorSegment.CATEGORY_SPONSOR,
    SponsorBlockData.ACTION_SKIP_WITH_TOAST
);

```

### Excluding Specific Channels

To prevent SponsorBlock from activating on specific channels:

```java
String channelId = "UCabcd1234EFGH";
SponsorBlockData.instance(ctx).excludeChannel(channelId);

```

### Manual Segment Skipping

While the controller handles skipping automatically, manual intervention is possible:

```java
SponsorBlockController controller = new SponsorBlockController();
controller.skipCurrentSegment(); // Jumps to end of active segment

```

## Summary

- **SmartTube SponsorBlock integration** relies on four core components: `SponsorBlockData` for preferences, `SponsorBlockSettingsPresenter` for UI, `SponsorBlockController` for playback logic, and `PlaybackPresenter` for registration.
- The system fetches crowd-sourced segment data from the SponsorBlock API and filters it according to user preferences before playback begins.
- Users can configure distinct actions for each segment category, including automatic skipping, toast notifications, or interactive dialogs.
- Channel-specific exclusions allow creators to be whitelisted, preventing their content from being filtered.
- All configuration persists through `SponsorBlockData`, with changes taking effect immediately on the next video playback.

## Frequently Asked Questions

### How does SmartTube fetch SponsorBlock segment data?

SmartTube contacts the SponsorBlock API (defaulting to `https://sponsor.ajay.app/`) during video initialization. The `SponsorBlockController` calls `fetchSegmentsFromApi()` with the current video ID, receiving a list of segments containing start times, end times, and categories. This data is cached and filtered against user preferences before the video begins playing.

### Can I disable SponsorBlock for specific YouTube channels?

Yes. The `SponsorBlockData` class maintains an exclusion list accessible through the settings UI or programmatically via `excludeChannel(channelId)`. When segments are loaded, `filterSegments()` removes any entries belonging to channels in this exclusion list, allowing those creators' content to play without interruption.

### What actions can SmartTube take when it encounters a sponsor segment?

SmartTube supports four actions configurable per category: *Do nothing* (play normally), *Skip only* (auto-seek past the segment), *Skip + toast* (skip with a notification), and *Show dialog* (pause and prompt the user). These are implemented in `performAction()` within [`SponsorBlockController.java`](https://github.com/yuliskov/SmartTube/blob/main/SponsorBlockController.java), with the dialog option utilizing `AppDialogUtil` for the UI.

### Is it possible to use a custom SponsorBlock server instead of the default?

Yes. `SponsorBlockData` includes support for alternate servers through its preferences system. Users can enable the "Alt server" option in the SponsorBlock settings, which redirects API requests from the default `sponsor.ajay.app` endpoint to the configured mirror, useful for privacy or reliability concerns.