This guide covers installation, configuration, and usage of the SponsorBlock plugin for PeerTube instance administrators.
# Clone the repository
git clone https://github.com/jblemee/peertube-plugin-sponsorblock.git
# Install from the PeerTube directory
cd /var/www/peertube
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production \
npm run plugin:install -- --plugin-path /path/to/peertube-plugin-sponsorblock# Clone inside the container or mount the plugin directory, then:
docker exec -it <peertube_container> \
npm run plugin:install -- --plugin-path /path/to/peertube-plugin-sponsorblock
docker restart <peertube_container>Once the plugin is published to the npm registry, you will be able to install it directly:
cd /var/www/peertube
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production \
npm run plugin:install -- --npm-name peertube-plugin-sponsorblockAfter installation, go to Administration > Plugins/Themes and verify the plugin is listed and enabled.
Open Administration > Plugins/Themes > SponsorBlock > Settings.
| Setting | Default | Description |
|---|---|---|
| Operation mode | Skip segments (client-side) |
Skip: segments are skipped during playback in the browser. Remove: segments are also automatically cut from video files on import using FFmpeg. |
- Skip mode is safe and reversible. Recommended for most instances. You can still trigger permanent removal manually via the Process button in the dashboard.
- Remove mode automatically queues videos for FFmpeg processing on import. Irreversible. Only use with backups enabled. Requires
ffmpegandffprobein the systemPATH. - In both modes, segments are skipped in the player and the Process button is always available.
Each SponsorBlock category can be individually enabled or disabled. These settings only affect client-side skipping. Permanent removal (FFmpeg) always removes all segment types regardless of these settings.
| Category | Default | What it skips |
|---|---|---|
| Sponsors | On | Paid product placements |
| Self-promotion | On | Plugs for the creator's own products/channels |
| Interaction reminders | On | "Like and subscribe" prompts |
| Intros | Off | Opening animations or greetings |
| Outros | Off | End-of-video credits or cards |
| Previews/Recaps | Off | Previews of upcoming or recap of previous content |
| Off-topic music | Off | Music unrelated to the video topic |
| Filler content | Off | Tangential or filler content |
| Setting | Default | Description |
|---|---|---|
| SponsorBlock API URL | https://sponsor.ajay.app |
URL of the SponsorBlock server. Change only if using a self-hosted mirror. |
| Cache duration (hours) | 24 |
How long cached segments are considered fresh before a re-fetch. |
| Show skip notifications | On | Display a toast notification when a segment is skipped. |
| PeerTube storage path | /var/www/peertube/storage |
Absolute path to your PeerTube storage directory. Required for remove mode. |
| Periodic sync interval (hours) | 0 (disabled) |
When set to a positive number, the plugin automatically re-fetches segments for all mapped videos at this interval. Set to 0 to disable. |
When a video is imported from YouTube (via URL import or channel sync), the plugin:
- Extracts the YouTube video ID from the import URL
- Saves a mapping (PeerTube UUID <-> YouTube ID)
- Fetches sponsor segments from the SponsorBlock API
- Caches them locally in the database
No manual action is required for new imports.
When a viewer opens a video that has mapped segments:
- The player fetches segments from the plugin API
- Color-coded markers appear on the progress bar (each category has a distinct color)
- When playback enters a segment, the player automatically jumps to the end of it
- A notification briefly appears: "Skipped Sponsor (12.5s)"
Permanent segment removal can be triggered in two ways:
- Automatically (remove mode): on import, the video is queued for FFmpeg processing
- Manually (any mode): click the Process button in the admin dashboard
Important: Permanent removal always removes all SponsorBlock segment types (sponsors, intros, outros, etc.), regardless of the category checkboxes in the settings. Category settings only control client-side skipping.
When a video is queued:
- A background worker (polling every 30 seconds) picks up the job
- FFmpeg cuts the segments using
-c copy(no re-encoding, no quality loss) - All video file versions (web-videos, HLS, originals) are processed
- The original file is replaced with the cleaned version
- Once processed, the video is marked as such and the client no longer skips segments (they have already been removed)
- Up to 3 automatic retries on failure
The admin dashboard is embedded in the plugin settings page. Open Administration > Plugins/Themes > SponsorBlock > Settings and scroll down.
Four cards display at-a-glance metrics:
- Mapped Videos — total number of PeerTube videos linked to a YouTube ID
- Total Segments — total cached SponsorBlock segments across all videos
- Time Saved — cumulative duration of all segments (e.g.,
14m 32s) - Queue Pending — number of videos waiting for FFmpeg processing
| Button | What it does |
|---|---|
| Scan Imports | Scans the PeerTube videoImport table for YouTube URLs, creates mappings for any that don't already exist, and fetches their segments. Use this after installing the plugin on an instance with existing YouTube imports. |
| Sync All | Re-fetches segments from SponsorBlock for every mapped video. Runs in the background with 200ms rate limiting between API calls. |
| Process All | Queues every mapped video that has segments but has not yet been processed for FFmpeg removal. Works in any mode. |
Each row shows one mapped video:
| Column | Description |
|---|---|
| Video | Video title (link to watch page), or full UUID if video was deleted |
| YouTube ID | The 11-character YouTube video ID |
| Segments | Number of cached SponsorBlock segments |
| Time Saved | Total segment duration for this video |
| Last Sync | When segments were last fetched (relative time) |
| Queue | Processing queue status badge (Pending / Processing / Done / Error) |
| Actions | Per-row action buttons (see below) |
| Button | What it does |
|---|---|
| Sync | Re-fetches segments from SponsorBlock for this single video and updates the cache. |
| Process | Queues this video for FFmpeg segment removal. Works in any mode. |
| Delete | Removes the mapping. If no other video shares the same YouTube ID, the cached segments are also deleted. Asks for confirmation before proceeding. |
Admins and moderators see a SponsorBlock widget below the video player on the watch page.
- Click the SponsorBlock toggle to expand the widget
- Enter a YouTube video ID (e.g.,
dQw4w9WgXcQ) or a full YouTube URL - Click Link
- The plugin creates the mapping, fetches segments, and activates skipping immediately
This is useful for:
- Videos imported through methods that don't trigger the import hook
- Manually correcting a wrong mapping
- Linking a re-uploaded version of a YouTube video
On the video watch page, sponsor segments are displayed as colored overlays on the progress bar. Each category has a distinct color:
| Category | Color |
|---|---|
| Sponsor | Green |
| Self-promotion | Yellow |
| Interaction | Light blue |
| Intro | Cyan |
| Outro | Blue |
| Preview | Orange |
| Off-topic music | Magenta |
| Filler | Purple |
Hovering over a marker shows a tooltip with the category name and time range.
To keep segment data up to date (new community submissions, revised timestamps), configure the Periodic sync interval:
- Go to plugin settings
- Set Periodic sync interval (hours) to the desired value (e.g.,
24for daily) - Save
The plugin checks every 5 minutes whether the interval has elapsed. When it triggers, it iterates all mappings and re-fetches segments from SponsorBlock with 200ms rate limiting.
Set to 0 to disable periodic sync entirely.
All routes are prefixed with /plugins/sponsorblock/router.
| Method | Path | Description |
|---|---|---|
GET |
/segments/:videoUuid |
Returns cached segments for a video |
GET |
/mapping/:videoUuid |
Returns the YouTube mapping for a video |
| Method | Path | Description |
|---|---|---|
POST |
/mapping/:videoUuid |
Create or update a YouTube mapping |
POST |
/scan |
Scan imports and create new mappings |
POST |
/sync/:videoUuid |
Re-fetch segments for one video |
POST |
/process/:videoUuid |
Queue one video for FFmpeg processing |
POST |
/process-all |
Queue all unprocessed videos |
| Method | Path | Description |
|---|---|---|
GET |
/admin/stats |
Dashboard statistics |
GET |
/admin/mappings |
All mappings with segment counts and queue status |
DELETE |
/mapping/:videoUuid |
Delete a mapping and orphaned segments |
POST |
/sync-all |
Re-fetch segments for all mappings (background) |
All admin routes require an admin authentication token (Authorization: Bearer <token>).
If you install the plugin on an instance that already has YouTube-imported videos:
- Open the plugin settings page
- Click Scan Imports in the admin dashboard
- The plugin scans the
videoImporttable, finds YouTube URLs, creates mappings, and fetches segments
Alternatively, use the API:
curl -X POST http://your-instance/plugins/sponsorblock/router/scan \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"- Open the browser developer console (F12)
- Look for
[SponsorBlock]log messages - Verify segments are fetched: you should see
Found X segments to skip - Try a hard refresh (Ctrl+Shift+R) to clear cached scripts
- Check the API directly:
GET /plugins/sponsorblock/router/segments/<video-uuid>
- Markers only appear if segments exist for that video
- The video duration must be available (markers are added after
durationchange) - Check the console for
Added X progress bar markers
- Ensure you are logged in as an admin (role 0)
- Click Scan Imports if no mappings exist yet
- Check the PeerTube logs for SQL errors:
sudo journalctl -u peertube -f
- Verify FFmpeg is installed:
ffmpeg -version - Check
storage_pathpoints to the correct directory - Check PeerTube logs for the specific error message
- The worker retries up to 3 times before marking a job as
error - You can re-queue a failed video by clicking Process in the dashboard
- Check PeerTube version: the plugin requires >= 6.0.0
- Check logs:
sudo journalctl -u peertube -f | grep -i sponsorblock - Verify file permissions on the plugin directory
Via the PeerTube admin interface: Administration > Plugins/Themes > SponsorBlock > Uninstall.
Or via CLI:
cd /var/www/peertube
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production \
npm run plugin:uninstall -- --npm-name peertube-plugin-sponsorblockThe plugin's database tables (plugin_sponsorblock_mapping, plugin_sponsorblock_segments, plugin_sponsorblock_processing_queue) are not automatically dropped. To remove them manually:
DROP TABLE IF EXISTS plugin_sponsorblock_processing_queue;
DROP TABLE IF EXISTS plugin_sponsorblock_segments;
DROP TABLE IF EXISTS plugin_sponsorblock_mapping;