FruitDeepLinks — Universal Sports Aggregator for Channels DVR

Could a potential solution be a redirect link in the m3u and have a backend running to change where that link redirects too?

1 Like

Yup, that's the idea!

1 Like

one wild idea I had and actually kind of works, but again not pretty and hacky.

  1. Create say 30 "lanes" streamlinks as videos in video collection (example below)
brad@bradmini:/media/brad/DVR/Imports/Videos$ ls
lane1.strmlnk  lane2.strmlnk

brad@bradmini:/media/brad/DVR/Imports/Videos$ cat lane1.strmlnk
sportscenter://x-callback-url/showWatchStream?playID=8aac40e6-a4a3-472c-b90d-a351f3c0961c

Then, have each Channel in the M3U call a proxy server that in turn calls a curl command to the Channels client DVR:

curl -X POST http://192.168.86.58:57000/api/play/recording/1533

Then, Channels client opens the streamlink'ed app.... this app could in theory just keep updating those files and keep the URL updated with the now playing link.

yeaaaaa not pretty, but def a workaround... i know @tmm1 loves a good hack, but this one is a little hairy.. maybe it'd be simplier if he'd make a Streamlink API call for us? not sure how we'd determine what client is calling for the streamlink though....

3 Likes

Would like to see the WNBA in there under Speciality/league/OTT services. Thanks!

1 Like

This might be a dumb question, but I currently use mlbserver and eplustv with ADBTuner, is this going to be in addition to those things, or an eventual replacement?

think MLB still provides non-DRM streams, so you can stay with that. Until of course they introduce DRM then we can find a way to grab the deep link schedule someday.

EPlusTV — maybe?

My goal is just to have a simple catch-all app for all the sports Streamlinke apps that have deep link access. I’m not an expert by any means on ADBTuner, but I think once the dust settles, my man @bnhf will take a look and see if he can make ADBTuner work with more of these apps. I suspect some may be too complex, but he’s pretty crafty!

2 Likes

just thought i'd share results of latest scrape:

App / TV services

  • ESPN (sportscenter) – 646 playables
  • Prime Video (aiv) – 627 playables
  • Paramount+ (pplus) – 183 playables
  • NFL+ (nflctv) – 25 playables
  • Max (max) – 19 playables
  • DAZN (open.dazn.com) – 15 playables
  • CBS Sports (cbssportsapp) – 13 playables
  • NBC Sports (nbcsportstve) – 8 playables
  • FOX Sports (fsapp) – 7 playables
  • ViX (vixapp) – 4 playables
  • F1 TV (f1tv) – 3 playables
  • Apple MLS Season Pass (apple_mls) – 2 playables
  • CBS (cbstve) – 1 playable
  • truTV (watchtru) – 1 playable
  • Prime Video TNF (gametime) – 1 playable

Total app/TV playables: 1,531

Web-based playables (direct browser links--will work on AppleTV not sure about Android/firesticks)

  • Peacock (Web) – 36 playables (60.0%)
  • Max – 19 playables (31.7%)
  • F1 TV – 3 playables (5.0%)
  • Apple MLS – 2 playables (3.3%)

Total web playables: 60

Grand total across all providers: 1,591 playables.

4 Likes

I realize you probably mean Q1 2026...
I am really looking forward to experimenting with this. :slight_smile:
Should be a FANTASTIC addition to the Cannels Add-On Eco System! :clap:

:rofl:. I’m actually pretty close to a beta version I could put out for brave souls.

It’d be limited to direct M3U (so like right now it looks for all events with +24 hours and created about 350 channels). XML looking great too. It does create lanes like ESPN4CC4C but kinda useless without some sort of ADBTuner as haven’t figured out a workaround for dynamic streamlinks.

And honestly I don’t even subscribe to most of these services so those with the services would be helpful!

4 Likes

I'm here, man. I'll test it out

[BETA] FruitDeepLinks – Apple Sports → Channels DVR (looking for Fire TV / Android testers)

I’ve opened up a public beta of FruitDeepLinks, a Docker app that scrapes Apple’s Sports aggregation and builds a unified sports EPG for Channels DVR, with deep links out to the various streaming apps.

Right now, Apple TV should handle all deeplinks correctly. I’m specifically looking for feedback from Fire TV / Android TV users about what works, what doesn’t, and which providers misbehave.

What’s working best today

The most stable feature is:

  • Direct channels (recommended)
    • M3U: http://YOUR-SERVER-IP:6655/direct.m3u
    • XMLTV: http://YOUR-SERVER-IP:6655/direct.xml
    • Add as a Custom Channels source in Channels DVR, and set Stream Format = STRMLINK in that source.

This creates a bunch of “one channel per event” entries in Channels – great for browsing specific games.

Lanes & ADB lanes are BETA / experimental – You can safely ignore multisource_lanes* and the ADB provider outputs for now. They’re coming later once the core behavior is solid.

Install (Docker / Portainer)

Repo: https://github.com/kineticman/FruitDeepLinks

Simplest path (Portainer, Git stack):

  1. Add a new stack from repository:
  • Repository URL: https://github.com/kineticman/FruitDeepLinks.git
  • Reference: main
  • Compose path: docker-compose.yml
  1. Set these env vars in the stack:
SERVER_URL=http://YOUR-SERVER-IP:6655
FRUIT_HOST_PORT=6655
TZ=Your/Timezone

(Optional but nice for auto-refresh: CHANNELS_DVR_IP and CHANNELS_SOURCE_NAME=fruitdeeplinks.)
3. Deploy the stack and open the web UI at
http://YOUR-SERVER-IP:6655.

From there you can tweak service filters and run a manual refresh.

What I’d love feedback on

Especially from Fire TV / Android TV users:

  • Which apps open correctly (ESPN+, Prime Video, Peacock, Paramount+, etc)?
  • Any apps that don’t honor the deeplink or drop you in a weird place?
  • Any crashes / hangs when launching from Channels?

Feel free to post:

  • Your device (Firestick model / Android TV box).
  • Example event that failed (league + teams + provider).
  • What you expected vs what actually happened.

This is still early beta, but the direct channels path is pretty solid, and I’d love to tighten up cross-device behavior before turning on more advanced features like lanes and ADB provider feeds.

2 Likes

I should note-- scrape takes about ~10 minutes. Be patient.

I am hoping to be able to look at this sometime late this weekend or early next week. Family commitments always get in the way of fun. :man_shrugging: :joy:

I understand that you will need the subscriptions for each service in order to view them but I would like to understand what is needed to actually just scrape for all the "channels"

Does it require an AppleTV and/or Android box as a "proxy" with all the desired apps installed on it or does it just scrape the web for the "feeds" inside the docker container?

If I am understanding everything else right...when selecting a stream it will then send the the command to open the App/Deeplink on the desired AppleTV and/or Android box...

The program simply scrapes the fruit company's public website/api and grabs the associated deeplinks/scheduling data. For those with tvOS device, the information is right on their TV app already. This simply grabs all that and puts it nicely into Channels. You don't even need to subscribe to all these services to see the schedule, but obviously to view their stream, you would. And yes, if you setup the Custom Source as STRMLINK, once you click the event, it'll then open the corresponding app/stream.

I despise having to look in other apps for sporting events. This puts it all in Channels for using their beautiful guide. It does not use Gracenote, so the XML isn't as rich, but I pulled as many categories and images in as possible so it should be a close enough experience for most.

Long term goal - keep adding more providers as I/we find out there, get their associated deeplinks, and tie into ADBTuner/Chrome Capture so you never have to leave Channels app. But, first step is just testing what we have now and getting to work with as many devices as possible. Then the fun stuff next!

1 Like

@KineticMan

Having some issues trying to get the stack deployed.

Getting the following error:
Failed to deploy a stack: compose up operation failed: Error response from daemon: Bind mount failed: '/data/compose/33/out' does not exist

Synology NAS using Portainer (Repository)

Env Variables:
SERVER_URL=http://10.0.1.65:6655
FRUIT_HOST_PORT=6655
TZ=America/Chicago
CHANNELS_DVR_IP=10.0.1.65
HOST_DIR=/volume1/data

Got any recommendations on what I need to fix that

On a Synology NAS, any volumes mapped in docker have to already exists on the Synology.
The Synology docker daemon will NOT create host directories on the Synology.
Recommendation is to use HOST_DIR=/volume1/docker
That avoids any permission issues on a Synology.

Ive been trying different things but its the same result. Im going to try with host_dir and see if it helps

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

Tried without Host_Dir and get the same error. I have both docker and data folders already. I just dont know what else I should add

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

1 Like

I've installed it in Windows Docker using Portainer in repository method; it failed to install the1st time because it couldn't find the "main" reference. If I leave that field blank, it installed fine.

Quick observations, Peacock and Paramount opened up on my Android phone without a problem. It hasn't been able to open the ESPN app though.

Edit: Two other things, I had to use /out/direct.m3u and /out/direct.xml in Channels source. Also, the app didn't honor my start channel preference ( I entered 900 as start channel, but most channels are in 1000 or over).

Sorry I’m not familiar with NAS setups. I tested it with Ubuntu and Windows.

I did punch your question into ChatGPT and it said essentially what @chDVRuser said. See attached.

Fixing Portainer/Synology “Bind mount failed: '/data/compose/33/out' does not exist”

This is a host path does not exist error.

On Synology + Portainer, /data/compose/33/... is Portainer’s internal stack working directory.
It usually appears when your compose file uses relative mounts like ./out:/app/out. Portainer resolves ./out to something like /data/compose/33/out, which doesn’t exist.


Recommended fix (use absolute Synology paths)

1) Create the folders on the NAS (SSH or File Station)

mkdir -p /volume1/data/FruitDeepLinks/{out,data,logs,config}

2) Update your stack’s volumes: to mount those absolute paths

Using your env var HOST_DIR=/volume1/data:

services:
  fruitdeeplinks:
    volumes:
      - ${HOST_DIR}/FruitDeepLinks/out:/app/out
      - ${HOST_DIR}/FruitDeepLinks/data:/app/data
      - ${HOST_DIR}/FruitDeepLinks/logs:/app/logs
      - ${HOST_DIR}/FruitDeepLinks/config:/app/config

This avoids Portainer’s /data/compose/... paths entirely.


Alternative (not recommended): keep relative paths

If you keep ./out:/app/out, you must ensure out/ exists inside Portainer’s stack context (often /data/compose/<stack-id>/out). With “Repository” stacks, this is typically confusing, so absolute NAS paths are better.


Common Synology gotchas

  • Permissions: Docker must be able to read/write the mounted folder.
  • Exact paths: /volume1/data must match the real share path and casing.
  • SERVER_URL: should match how clients reach the container (your http://10.0.1.65:6655 is fine if that port is published).

Quick checklist

  1. Create: /volume1/data/FruitDeepLinks/out
  2. Create: /volume1/data/FruitDeepLinks/data
  3. Create: /volume1/data/FruitDeepLinks/logs
  4. Create: /volume1/data/FruitDeepLinks/config
  5. Update compose mounts to ${HOST_DIR}/FruitDeepLinks/...
  6. Redeploy stack