ESPN+ with Custom Channels via ADBTuner

In your CDVR Custom Channels Source settings, I would think you could just override the starting channel number, and then match the virtual channels to their guide data with Manage Lineup.

Trying to install and getting this error when installing via portainer stack method:

Failed to deploy a stack: compose up operation failed: Error response from daemon: Bind mount failed: '/data/compose/43/data' does not exist

Here's the YAML I inserted:

services:
  espn4cc4c:
    image: ghcr.io/kineticman/espn4cc4c:${TAG:-latest}
    container_name: espn4cc4c
    init: true
    stop_grace_period: 20s

    ports:
      - ${PORT:-8094}:${PORT:-8094}

    environment:
      - TZ=${TZ:-America/New_York}
      - VC_RESOLVER_BASE_URL=${VC_RESOLVER_BASE_URL:-http://192.0.2.10:8094}
      - CC_HOST=${CC_HOST:-192.0.2.10}
      - CC_PORT=${CC_PORT:-5589}
      # Optional: Channels-4-Chrome (CH4C) bridge for http:// playlists
      - CH4C_HOST=${CH4C_HOST:-127.0.0.1}
      - CH4C_PORT=${CH4C_PORT:-2442}
      - PORT=${PORT:-8094}
      - APP_MODULE=${APP_MODULE:-bin.vc_resolver:app}
      - VALID_HOURS=${VALID_HOURS:-72}
      - LANES=${LANES:-40}
      - ALIGN=${ALIGN:-30}
      - MIN_GAP_MINS=${MIN_GAP_MINS:-30}
      - M3U_GROUP_TITLE=${M3U_GROUP_TITLE:-ESPN+ VC}
      - VC_M3U_PATH=${VC_M3U_PATH:-/app/out/playlist.m3u}
      - WATCH_API_KEY=${WATCH_API_KEY:-0dbf88e8-cc6d-41da-aa83-18b5c630bc5c}
      # Optional: Event filtering (see Filtering section below)
      # - FILTER_EXCLUDE_NETWORKS=ACCN,ESPN,ESPN2,ESPNDeportes,ESPNU
      # - FILTER_REQUIRE_ESPN_PLUS=true
      # - FILTER_EXCLUDE_PPV=true
      # - FILTER_EXCLUDE_REAIR=true

    volumes:
      - ${HOST_DIR:-.}/data:/app/data
      - ${HOST_DIR:-.}/out:/app/out
      - ${HOST_DIR:-.}/logs:/app/logs

    # Optional: helps suffix matching only; actual name resolution must work in your LAN/Tailscale DNS.
    dns_search:
      - ${DOMAIN:-localdomain}
      - ${TAILNET:-tailxxxxx.ts.net}

    healthcheck:
      test: ["CMD-SHELL", "curl -fsS http://localhost:${PORT:-8094}/health >/dev/null"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

    restart: unless-stopped

This is on a Synology NAS (x64). Any insight into what may be causing this?

Thanks.

On Synology, I would think you'd either need to use Docker Volumes for each bind mount, or create the needed directories in advance under /volume1/docker.

You'd need:

/volume1/docker/espn4cc4c/data
/volume1/docker/espn4cc4c/out
/volume1/docker/espn4cc4c/logs

And then set:

HOST_DIR=/volume1/docker/espn4cc4c

Thanks, added the folders and changed the Host_Dir to the following:

    volumes:
      - ${HOST_DIR:-.}/volume1/espn4cc4c/data:/app/data
      - ${HOST_DIR:-.}/volume1/espn4cc4c/out:/app/out
      - ${HOST_DIR:-.}/volume1/espn4cc4c/logs:/app/logs

But got this error:

Failed to deploy a stack: compose up operation failed: Error response from daemon: Bind mount failed: '/data/compose/44/volume1/espn4cc4c/data' does not exist

Should I have done that through an environmental variable section (didn't see that in the directions on the Github page).

EDIT - Tried using the environmental variable section and that worked, thanks.

Put the above section back the way it was. You'll want to set your env vars in the section of the Portainer-Stacks Editor designed for this purpose:

New bnhf/olivetin:latest (aka bnhf/olivetin:2025.11.23) pushed today with support for both spinning-up an ESPN4cc4c stack, and also adding however many ADBTuner ESPN virtual channels (aka lanes) desired. Both cc4c and ch4c are supported, and can be run side-by-side.

The Action that creates x number of ESPN+ lanes in ADBTuner (which needs to match the number of lanes configured in the ESPN4cc4c stack), will also create an espn4adbt CDVR Custom Channels Source.

Plus, the Action will delete any pre-existing virtual channels with a provider name of ESPN, if desired. And finally, it'll add the required ADBTuner Custom Configuration if one doesn't exist with its UUID.

The ESPN4cc4c One-Click (this needs to be run first, even if you're only going to use it with ADBTuner):

The ESPN4adbt One-Click (be sure you're using ADBTuner 20251114-2 or newer):

1 Like

I believe I have all guide-matching related issues sorted out in the latest Project One-Click for this hybrid project. Using the new ADBTuner API, the Action will automatically create as many virtual channels in ADBTuner as desired. It'll also delete any existing channels with a provider name of ESPN -- to clear the decks.

I have all three variations (using cc4c, ch4c or ADBTuner) running simultaneously, each using a custom channel number range:

More details on the new ESPN4cc4c ADBTuner Project One-Click Action:

Think the "mac hack" for DOCKER_GATEWAY might be missing/broken from the 1-click:

root@37c27cfbad99:/app# curl http://host.docker.internal/whatson/1
curl: (7) Failed to connect to host.docker.internal port 80 after 4 ms: Could not connect to server
root@37c27cfbad99:/app# curl http://host.docker.internal:8094/whatson/1
{"ok":true,"lane":1,"event_uid":"fea9692a-dacb-468f-92ec-5f051a27244f:3b6f1bb815fc2b44153dfcd0285e2c05","at":"2025-11-24T11:51:50+00:00","deeplink_url":null}root@37c27cfbad99:/app#

I added it manually as an env var, but still no dice.

The One-Click Action is now building the channels for ADBTuner using your actual host:port or ip:port for ESPN4cc4c embedded in the custom channel's URL. I.E., host.docker.internal is no longer being used, since we don't need it to be one-size-fits-all -- and any number of channels is possible:

Did you run both Project One-Click Actions?

The second one fails because dvr:8094 isn't working, similar to earlier tries before that fix.

{"detail":"Not Found"}

Are you expecting dvr to be resolved by your local DNS server, or are you using Tailscale's MagicDNS?

Pretty much either way, the search domains you specified in OliveTin need to be correct:

You can always use your Mac's IP if needed.

Note that localdomain is the correct search domain on my LAN, but yours could be local, lan or whatever your DNS server expects.

@KineticMan

Could you add another copy block to /setupfilters that would be suitable for use in Portainer's Environment variables section of the Stacks-Editor?

Currently you're offering this:

environment:
  - FILTER_EXCLUDE_NETWORKS=ESPN Deportes
  - FILTER_EXCLUDE_LEAGUES=NBA G League
  - FILTER_EXCLUDE_SPORTS=Wrestling
  - FILTER_EXCLUDE_EVENT_TYPES=OVER
  - FILTER_EXCLUDE_LANGUAGES=es
  - FILTER_EXCLUDE_REAIR=true
  - FILTER_CASE_INSENSITIVE=true
  - FILTER_PARTIAL_LEAGUE_MATCH=true
  - FILTER_REQUIRE_ESPN_PLUS=false

but I'm hoping you can set this up as an alternative:

FILTER_EXCLUDE_NETWORKS=ESPN Deportes
FILTER_EXCLUDE_LEAGUES=NBA G League
FILTER_EXCLUDE_SPORTS=Wrestling
FILTER_EXCLUDE_EVENT_TYPES=OVER
FILTER_EXCLUDE_LANGUAGES=es
FILTER_EXCLUDE_REAIR=true
FILTER_CASE_INSENSITIVE=true
FILTER_PARTIAL_LEAGUE_MATCH=true
FILTER_REQUIRE_ESPN_PLUS=false

That way, when the environment: section of the compose looks like this:

    environment:
      - TZ=${TZ:-America/New_York}
      - VC_RESOLVER_BASE_URL=${VC_RESOLVER_BASE_URL:-http://192.168.86.72:8094}
      - CC_HOST=${CC_HOST:-192.168.86.72}
      - CC_PORT=${CC_PORT:-5589}
      - CH4C_HOST=${CH4C_HOST:-127.0.0.1}
      - CH4C_PORT=${CH4C_PORT:-2442}
      - PORT=${PORT:-8094}
      - APP_MODULE=${APP_MODULE:-bin.vc_resolver:app}
      - VALID_HOURS=${VALID_HOURS:-72}
      - LANES=${LANES:-40}
      - ALIGN=${ALIGN:-30}
      - MIN_GAP_MINS=${MIN_GAP_MINS:-30}
      - M3U_GROUP_TITLE=${M3U_GROUP_TITLE:-ESPN+ VC}
      - VC_M3U_PATH=${VC_M3U_PATH:-/app/out/playlist.m3u}
      - WATCH_API_KEY=${WATCH_API_KEY:-0dbf88e8-cc6d-41da-aa83-18b5c630bc5c}
      - FILTER_ENABLED_NETWORKS=${FILTER_ENABLED_NETWORKS:-*}
      - FILTER_EXCLUDE_NETWORKS=${FILTER_EXCLUDE_NETWORKS:-}
      - FILTER_ENABLED_SPORTS=${FILTER_ENABLED_SPORTS:-*}
      - FILTER_EXCLUDE_SPORTS=${FILTER_EXCLUDE_SPORTS:-}
      - FILTER_ENABLED_LEAGUES=${FILTER_ENABLED_LEAGUES:-*}
      - FILTER_EXCLUDE_LEAGUES=${FILTER_EXCLUDE_LEAGUES:-}
      - FILTER_ENABLED_EVENT_TYPES=${FILTER_ENABLED_EVENT_TYPES:-*}
      - FILTER_EXCLUDE_EVENT_TYPES=${FILTER_EXCLUDE_EVENT_TYPES:-}
      - FILTER_ENABLED_LANGUAGES=${FILTER_ENABLED_LANGUAGES:-*}
      - FILTER_EXCLUDE_LANGUAGES=${FILTER_EXCLUDE_LANGUAGES:-}
      - FILTER_REQUIRE_ESPN_PLUS=${FILTER_REQUIRE_ESPN_PLUS:-}
      - FILTER_EXCLUDE_PPV=${FILTER_EXCLUDE_PPV:-false}
      - FILTER_EXCLUDE_REAIR=${FILTER_EXCLUDE_REAIR:-false}
      - FILTER_EXCLUDE_NO_SPORT=${FILTER_EXCLUDE_NO_SPORT:-false}
      - FILTER_CASE_INSENSITIVE=${FILTER_CASE_INSENSITIVE:-true}
      - FILTER_PARTIAL_LEAGUE_MATCH=${FILTER_PARTIAL_LEAGUE_MATCH:-true}

Those values, in that form, can just be pasted in as overrides here:

This way, one knows at a glance which values are not the defaults, and are specific to an individual installation.

@hancox

What do you see here for your Search Domains value?:

local , which is what i also have in my env vars.

It's def. resolving, else i wouldn't get that error message on browser when hitting it.

Exec into the olivetin container, and see what happens when you ping dvr...

Works fine (removed hostname)

64 bytes from (192.168.50.95): icmp_seq=1 ttl=63 time=1.09 ms
64 bytes from (192.168.50.95): icmp_seq=2 ttl=63 time=1.43 ms
64 bytes from (192.168.50.95): icmp_seq=3 ttl=63 time=1.42 ms
64 bytes from (192.168.50.95): icmp_seq=4 ttl=63 time=1.55 ms

And, if you exec into the adbtuner container can you do the same?

Weird - no ping in container, and install fails getting out, from the looks of it

root@84cd6e28727a:/app# apt update
Ign:1 http://deb.debian.org/debian buster InRelease
Ign:2 http://deb.debian.org/debian-security buster/updates InRelease
Ign:3 http://deb.debian.org/debian buster-updates InRelease
Err:4 http://deb.debian.org/debian buster Release
  404  Not Found [IP: 151.101.46.132 80]
Err:5 http://deb.debian.org/debian-security buster/updates Release
  404  Not Found [IP: 151.101.46.132 80]
Err:6 http://deb.debian.org/debian buster-updates Release
  404  Not Found [IP: 151.101.46.132 80]
Reading package lists... Done
root@84cd6e28727a:/app# apt install inetutils-ping
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libidn11
The following NEW packages will be installed:
  inetutils-ping libidn11
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 337 kB of archives.
After this operation, 655 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Err:1 http://deb.debian.org/debian buster/main arm64 libidn11 arm64 1.33-2.2
  404  Not Found [IP: 151.101.46.132 80]
Err:2 http://deb.debian.org/debian-security buster/updates/main arm64 inetutils-ping arm64 2:1.9.4-7+deb10u3
  404  Not Found [IP: 151.101.46.132 80]