Wanted to share something I've been building called FastChannels — a self-hosted FAST channel aggregator that scrapes free ad-supported streaming services and delivers unified M3U playlists and XMLTV EPG guides for Channels DVR (and any other IPTV client).
Why FastChannels?
The problem it solves: Pluto TV, Tubi, Roku Channel, Samsung TV Plus, Xumo, Plex, DistroTV and others each have hundreds of free live channels —but they're siloed. Getting them all into Channels DVR meant maintaining separate sources, dealing with stale stream URLs, and having no way to
easily deduplicate channels that appear on multiple services. FastChannels solves all of that in one place. It was designed with end user ease of use and maintainence first and foremost.
What it does:
- Multi-source aggregation — Currently scrapes Pluto TV, Tubi, The Roku Channel, Samsung TV Plus, Xumo Play, Plex, DistroTV, Sling Freestream, and FreeLiveSports. All channels and EPG unified into a single M3U + XMLTV output.
- Always-fresh stream URLs — Streams are resolved at playback time, not at scrape time. Tokens, JWTs, and session cookies are refreshed automatically so URLs never go stale.
- Named Feeds — Create persistent filtered sub-feeds (Sports, News, Spanish, etc.) with their own /m3u and /epg.xml URLs. Each feed can have its own channel number range and filter by source, category, or language.
- Image proxy — Channel logos and program artwork are cached locally and served through FastChannels. Eliminates CDN 403s and logo loading issues in Channels DVR (looking at you, Roku).
- Stream Audit — Health-checks every channel's stream and automatically marks dead or DRM-only channels inactive so they disappear from your lineup.
- Duplicate resolution helper — When multiple services carry the same channel (CBS News 24/7 shows up everywhere), a one-click resolver picks the best copy based on source priority and disables the rest.
- Admin UI — Web dashboard to manage sources, browse and enable/disable individual channels, create feeds, and monitor scrape status. No config files.
- Docker deployment — Single container, single volume mount. Runs alongside your existing stack.
Channels DVR integration
Add the M3U and EPG URLs directly as a Custom Channels source. FastChannels also supports Gracenote-matched output as a separate M3U variant so you can mix XMLTV and Gracenote EPG sources cleanly.
How to Install
- DOCKER
Get Docker! If you're new to this, I promise Docker isn't as complicated as you think. Tons of guides online to walk you through it, or ask your favorite chatbot for help. No env variables required.
One liner install once Docker installed:
docker run -d --name fastchannels --restart unless-stopped -p 5523:5523 -v fastchannels_data:/data ghcr.io/kineticman/fastchannels:latest
-
*PORTAINER - Instructions on GitHub -- GitHub - kineticman/FastChannels: Aggregrator of FastChannel services with admin console that exports M3U/XML · GitHub
-
PROJECT ONE CLICK - @bnhf will add instructions below
Once installed -- open a browser (preferably on a PC, but I do have mobile-friendly pages) and go to
http://YOUR-SERVER:5523/admin. Go grab a cup of coffee and let the scrapers do their thing. Then, once you've had your drink, a few things should be set for the best user experience. Go to Settings and set the local IP your FastChannels server is on (there are clear instructions on the page) and set your CDVR address as well. Then go over to Sources and set a password if you want to use Pluto. Everything else should work out of the box. This is where you enable/disable sources.
Stream Audit - Find DRM and Dead Channels
Once your sources have scraped, I highly recommend running a Stream Audit on each source. This checks every channel's stream for dead links, VOD-only content, and DRM encryption — and automatically disables any channels that won't play back properly.
To run it, go to Sources, find a source card, and click the
Stream Audit button. You'll see a live progress bar showing how many channels have been checked and a running count of DRM and dead channels found. It may take several minutes depending on how many channels the source has.
Which sources tend to have the most DRM? Generally The Roku Channel is the most common offenders. Tubi, Samsung TV Plus, and Plex tend to be cleaner. Running the audit on all your sources is the best way to know for sure — results vary by region.
After the audit completes, the disabled channels are hidden from your feeds automatically. You don't need to do anything else.
The Channels Page
The Channels page is your command center for everything channel-related. Once your sources have scraped (and ideally after you've run Stream Audits), this is where you'll spend most of your time fine-tuning your lineup.
What you're looking at: Every channel from every enabled source — name, logo, source, category, language, channel number, Gracenote ID, and stream health flags. Channels marked DRM or Dead from a Stream Audit show a badge; you can re-enable any of them individually if you think the audit got it wrong.
Filtering and searching: Seven ways to slice the list:
- Free-text search by channel name
- Filter by source, category, or language
- Show only Enabled, Disabled, or All
- Filter by stream health (DRM only, Dead only, clean only)
- Filter by Gracenote coverage (has it / missing it)
- Duplicates only — shows channels whose name appears in more than one source
The Duplicates filter is worth a dedicated mention. If you have Pluto, Roku, and Plex all scraped, you'll have a lot of the same channels appearing multiple times in your M3U. Use the "Duplicates only" filter to find them, then hit
Resolve Duplicates to sort it out in bulk. That tool lets you drag-to-reorder your sources by priority (and recommends the one with the best Gracenote coverage) — then disables all the lower-priority duplicates at once. Clean lineup in seconds. You can always go back and enable/disable any channel you want after.
Per-channel actions:
- Enable/Disable toggle — removes a channel from your M3U/EPG output without deleting it
- Gracenote ID — click any Gracenote field to edit it inline; auto-saves when you tab out. Useful if a channel is missing guide data and you know its ID. Some are pre-loaded from source/community knowledge.
- Preview (eye icon) — shows current/next program info and an in-browser stream preview
- Inspector (magnifying glass) — does a live real-time check of that one channel's stream: confirms it's Live, or tells you it's DRM, Dead, VOD, or just not sending data. Useful for spot-checking a channel without running a full audit.
Bulk actions: Check the box on any rows (or use "select all") and a bulk bar appears at the bottom — enable or disable everything selected at once. Great for quickly culling a category or language you don't want.
Sorting: Click any column header to sort. The # column sorts by approximate M3U channel number order, which is handy for visualizing how your lineup will look in your DVR.
How to Setup Your Feeds
Feeds are how you control what channels get served to your DVR or media player. There's always a Default feed that includes everything, but you can create custom feeds to slice and dice the channel list however you like — by source, category, language, or even a hand-picked list of specific channels (my favorite feature). I challenge you to think differently how you setup custom sources before with just adding a whole new service - think of this as more custom channel groups.
Go to Admin → Feeds and click + New Feed. Give it a name (the URL slug is auto-generated), then use the filter options to define what goes in it:
- Sources — only include channels from specific sources (e.g., Roku, Pluto, Plex)
- Categories — filter by genre like News, Sports, or Movies
- Languages — filter by language code (e.g., en, es)
- Gracenote — only channels that have guide data matched, great for a "clean EPG" feed
- Manual selection — pick specific channels by hand if you want full control
As you set filters, the feed modal shows a live count of how many channels will be included. If you're adding the feed to Channels DVR, try to keep it under 750 channels — DVR performance degrades above that.
If you've already set your CDVR address in Settings, there's an Add to Channels DVR button right on the feed card that registers it automatically — no copy/paste needed.
A few example feeds to get you started:
- Sports Only — filter categories: Sports
- English Channels — filter languages: en
- Guide-Ready — filter gracenote: has (these channels all have matched EPG data)
- Pluto Everything — filter sources: Pluto TV
- Anime
- Movies
**Caveats-
-
Roku. They are very CloudFare sensitive and sometimes, the scraper/tuner gets 403'ed (too much activity at once). You may have to re-force a scrape to get it setup and sometimes a stream will fail loading on CDVR. Do not hammer it- it'll only make it worse. Get another cup of coffee, then come back and try again later. I did everything I could to minimize this with caching, but out of my full control..
-
Amazon and Sling as listed as sources, but they are 100% DRM. I kept them in case of future developments and for EPG enrichment, but not a ton of value in turning them on at this time.
-
EPG/XML data is only as good as the source. I made best effort to do categories/language but it's not perfect.
Big thanks to @bnhf, @babsonnexus , @matthuisman, and this whole community.
