Coax: a simple IPTV/M3U Manager appliance for Channels DVR

I started using IPTV with Channels DVR a couple of weeks ago, and the streams kept freezing, drifting out of sync and dropping. So I built coax to sit between the provider and Channels and smooth that out. I started with a couple of tools I built for Dispatcharr including some very complex Python-based profiles. Due to the complexity of that and how well it was working, I thought it might be helpful to just own the entire stack to prevent breakage in the future. The idea of coax is it is an appliance. It is meant to be set and forget. It is not meant to be frequently updated or changed unless there's some severe security issue. It has no authentication. It sits on your LAN and does its thing. There's no database component. Everything is handled through a JSON file. It lives in Docker on one's server or NAS and simply accepts a feed from wherever you may choose and will smooth over any rough edges and pass that off to Channels. Most importantly, rather than relying on poor quality XMLTV guide data, it queries Channels and tries to match proper Gracenote values. Additionally, it will look for similar feeds in one's provider and map those pretty seamlessly as backup feeds just in case something were to go down and a fallover is needed. This is done as automated as possible with the ability to manually check things over to make sure nothing was matched incorrectly. I found it to be incredibly smooth and quick to go through about 200 channels and get them all matched and sorted up. One can also just click a button; it adds a playlist right to Channels DVR. And additionally, when changes are made to a channel or a Gracenote ID or something else, for example, the playlist in Channels DVR is refreshed and the guide data is refreshed as well. So one doesn't have to go and click around.

How it handles bad streams

  • Reserve buffer. coax plays about a minute behind live. When the provider stalls, Channels keeps playing from the reserve, so you don't see it.

  • Invisible refill. When the reserve runs low, coax plays video and audio 3% slower until it's back up. You can't notice it, and there's no rebuffering.

  • Keeps the connection open. If the provider stops sending video, coax sends keepalive packets so Channels doesn't give up on the tuner while the stream recovers.

  • Placeholder detection. When a provider swaps in an "offline" or "unavailable" screen, coax treats it as a dead stream instead of recording it.

  • Failover. If a stream dies, coax switches to your backup streams in the order you set, and the player keeps going without restarting.

  • A/V sync. It holds audio and video together across restarts and stream switches, so you don't end up with drift.

  • Tuner sharing. When Channels DVR shares a tuner between viewers, coax gives the new viewer a short head start so it doesn't stall right away.

The Status page shows each live channel's reserve, whether it's running in real time or refilling, whether transcoding is on, and a timeline of every correction coax made, like "switched to backup stream 2" or "video back after 2.2s."

Setup

  • Add your provider

  • Pick channels from the catalog by group. Prefixes are cleaned up automatically.

  • Auto-match finds Gracenote station IDs and backup streams in one pass. Anything it isn't sure about lands in Needs attention, with search as you type for Gracenote and your provider's XMLTV guide.

  • Group channels into lineups, each using Gracenote, XMLTV or both. Add a lineup to Channels DVR in one click, and changes sync on their own.

  • Your config backs up daily, with one-click restore.

It also transcodes on the GPU (Intel, AMD or NVIDIA) with the whole chain on the GPU, so CPU use stays low. An optional Gluetun VPN is supported. In order for most of the corrective features to work, transcoding is required to keep things smooth. So it is very important to pass some sort of graphics through in order for that to function. There are various transcoding profiles to choose from. So if one does have to transcode on CPU, one can use a weaker profile.

The streaming design follows ah4c for reliability's sake.

It's provided as is. Feel free to fork it and make it your own.

Image: ghcr.io/mackid1993/coax:latest (amd64). The README has the compose files.

Finally, please no discussion of any illicit activity or providers in this thread. Of course, that goes against forum rules, and this post is not intended to violate any forum rules. It is intended to discuss a tool that can be used for any such purpose that involves pulling in M3U feeds.

Lastly, to maintain compliance with forum rules, I have posted screenshots on GitHub rather than sharing them directly here, just in case I don't want to put any liability on Fancy Bits. Keep in mind this tool is meant for legitimate use only, and nothing illegitimate should be done with it. What you do with it is your business, in my opinion. This project has no affiliation with Channels DVR, Fancy Bits, or anything else of that sort. Please do not contact their team for support at all. This project is also not open to pull requests, issues, or anything of that sort. It is a project meant for me that I am sharing, and I really don't have the energy or time to implement features or suggestions. However, I am happy to share. That being said, if anyone finds a bug, particularly a really major bug, please do share it here, and I'll be happy to take a look when I have time. And if anyone wants to discuss, this is a great place to do that. I hope this is helpful to some people. I have found it to work pretty well for me so far. And if I do find any issues in my initial testing since I have built this today, based off of work that I have validated over the course of about two weeks, I will post an update here noting that I have made revisions.


Changelog

  • 1.0.0 - Initial Release - 10/27/2026
  • 1.0.1 - 10/27/2026
    • The big change: coax no longer gives up on a stream. As long as Channels DVR is connected, it keeps retrying until the stream comes back, so a recording keeps going instead of ending.
    • Frozen stream recovery. If the engine sends nothing for 25 seconds, coax restarts it on the same line without dropping the connection to Channels.
    • No video recovery. If there's no real video for 90 seconds, coax retunes with a fresh connection. Every second retune in a row moves to another free line on the same provider, if you have one.
    • Holds the connection open. Between retries, coax sends filler packets so Channels doesn't drop the tuner. Retries back off up to 15 seconds apart and never stop.
    • Smarter restarts. After a restart, coax picks up where it left off instead of starting over with an empty reserve.
    • Remembers bad streams. A stream that failed recently is tried last, for every channel, when tuning and during failover.
    • Failover across providers counts the right line. Switching to a backup on another provider now reserves that provider's line, so a new tune can't overload it.
    • Line cooldown. A line that was just released is used last, so the provider has time to drop the old connection.
    • Stream health history. Each channel's 10-minute health reports are saved in data/cache/history/.
    • "Unsteady feed" badge on the Status page when the last 10 minutes had repeated failovers or long gaps without video.
  • 1.0.2 - 10/27/2026
    • Smart Standby: coax now decides which of a channel's streams plays, and keeps bad feeds away from your TV.
    • Checks backups before switching (HLS). At the first real trouble on a stream, coax checks every backup by picture and sound against what you were just watching, while the reserve keeps playing. It switches only to a backup that's in sync. A backup with its sound off its picture (some feeds are built that way) is blocked and never shown.
    • Tries backups best first. Every stream is scored on its last day: sound off its picture counts worst, then offline slates, dead streams, no video and freezes. Clean playback counts in its favor.
    • Blocks bad streams, never deletes them. A stream that misbehaves sits out for 12 hours, 24 hours or 3 days, depending on how bad and how often. It comes back on its own.
    • Promotes the stable stream. After trouble, the stream that held up moves ahead of the one that failed, becoming the main stream if needed. It stays there until the next real trouble, so channels don't flip back and forth.
    • Ignores normal IPTV wobble. Stalls and refills the reserve absorbs don't count against a stream.
    • MPEG-TS: coax switches to the best-ranked backup and checks it while it plays, then leaves it if it's bad, so you see a bad backup briefly. Use HLS if your source offers it.
    • Notifications bell: every block and every new main stream shows up under a bell in the sidebar, with Undo, an X to dismiss and Clear all.
    • Fixes and polish:
      • Audio stays in sync when switching streams with transcoding on.
      • The Status page shows the live reserve on every stream, right from the start.
      • The Status timeline lists real corrections only, no startup noise.
      • Daily cleanup of old cache and state files.
      • XMLTV search matches by words and finds every channel name in your guide.
      • Clearer error messages, autosave for Auto-match, and a smoother drag-to-reorder for backups.
  • 1.0.3 - 10/27/2026
    • Bug fixes after a code review.
    • Backups are now a tarball rather than a single JSON due to there being several files to snapshot now.
3 Likes

This comment is reserved.