AndroidHDMI for Channels (ah4c): A virtual channel tuner using HDMI Encoder(s) + streaming stick(s)

Today's Test of the Day: Uploading m3u's thru webui

Copied my Osprey Deeplinks to my test m3u folder on Synology NAS. Renamed as as dtvstreamdeeplinks.m3u. On iPad, went to webui and selected Choose folder. There was no option to select a network folder. Jumped on Mac and the option was there. (This is probably just a limitation of the iPad). Uploaded m3u from Synology without issue. Checked m3u thru editor and it looked correct. Went to Channels DVR Sources, reload m3u, then did a delete and recreate database. After guide refreshed, some channels (locals) were not shown in their proper place. Checked guide on client and those spots were still populated with your locals but no guide data.
Deleted source from Channels and went back to ah4c webui. The m3u listed was still green showing it on Channels. Refreshed browser and still green. Selected the add to Channels DVR and it added it’s expected. Channels now showing correctly.

Observation:
I'm puzzled why your locals did not 100% disappear when I reloaded the m3u. They did go away when I deleted the source in Channels and reloaded thru ah4c.
We have an add to Channels DVR for the source. When you delete the source, ah4c still has it green and loaded. Maybe we need a delete source from the webui(??)

You have to click refresh m3u in Channels.

I did a couple of times. It's probably a Channels issue (artifact) as it only affected the replaced ABC, Fox, & NBC channels. They didn’t show in the channels web guide, only on the client. It would have probably cleared up in the next 24 hours anyway but my channels may have stayed out of order from the m3u.

Should be out soon with a test container that allows you to sort all of your channels in an M3U file and also renumber them quite nicely. I'm just working out a couple of bugs.

@bnhf I have two pull requests open related to this. I just broke them out because I wanted you to be able to read them easily. The only thing is, I'm just working out some bugs that I picked up on, so I just want to keep them in draft mode for now until we get some feedback.

I figured while I'm on the settings pass, I might as well make some things easier along the way. I feel like the goal, besides just settings, is just user friendliness. So, if we can make renumbering channels super easy for people, that would be awesome.

Hey everyone, the M3U editor is working freaking great. You should be able to sort channels by A through Z, renumber fairly easily while maintaining order, undo changes, preview them before you actually hit save, and push them directly to channels without having to refresh anything. I'm just quite pleased with this. So, if anyone wants to try it and try to find bugs or break it, please let me know. You can try my test build. mackid1993/ah4c either latest or beta both point at the same digest.

Edit: just making one more pass over these with Opus 5.5 since it just came out. I actually found a couple of minor nits that need to be fixed, very minor things.

Update: I actually found a bug relating to like when DirecTV has those 4,000 channels, the free ones. Renumbering those is kind of an issue when they're out of order.

So I'm looking into the best way to handle those. Trying to make the tool a bit more flexible.

Update 2: I believe I corrected this. If anyone wants to try, you should be able to edit channel numbers freeform now, and it'll warn you if there's a conflict.

For those dealing with the Cox Spectrum merger, I ported over my PyATV scripts and M3Us yesterday to use the Spectrum Apple TV app instead of the Cox Contour app. They actually are a lot simpler using deep links, which the contour app did not support.

Thank you @ChannelSam for the scripts , but I put in some minor tweaks to make clearer

bmitune:

#!/bin/bash
# Channels DVR invocation contract: bmitune.sh <channelId> <atvHost>
#   $1 = channelId (Gracenote/TMS station ID, from tvc-guide-stationid in M3U)
#   $2 = atvHost    (IP of the Apple TV assigned as this tuner)
channelId="$1"
atvHost="$2"

/usr/local/bin/atvremote --storage-filename /root/.android/.pyatv.conf \
  -s "$atvHost" launch_app="spectrumTV://watch.spectrum.net/livetv/${channelId}"

I had to add force quit logic to the stopbmitune to accommodate multiple tuners and avoid streaming limit errors from spectrum.

stopbmitine:

#!/bin/bash
set -e

# Channels DVR invocation contract: stopbmitune.sh <atvHost> <channelId>
#   $1 = atvHost    (IP of the Apple TV assigned as this tuner)
#   $2 = channelId  (Gracenote/TMS station ID, from tvc-guide-stationid in M3U)
# NOTE: argument order is REVERSED from bmitune.sh - this is the Channels DVR
# pre/stop contract, not a bug. Do not "align" this with bmitune.sh's order.
atvHost="$1"
channelId="$2"

pyatvCredentials="/root/.android/.pyatv.conf"
ATV_CMD="/usr/local/bin/atvremote --storage-filename ${pyatvCredentials} -s ${atvHost}"

# Tunable delays - measure per-ATV, don't assume Cox's timing applies here.
FC_SHORT_DELAY=0.6
SWIPE_PASSES=3   # start smaller than Cox's 5; raise only if one pass isn't enough

echo "📺 Force Quit Spectrum App on ${atvHost} (was tuned to ${channelId})"

echo "🔁 Opening app switcher..."
eval "$ATV_CMD home home" >/dev/null 2>&1 || true
sleep "$FC_SHORT_DELAY"

# NOTE: no "left" press here - Spectrum should already be the frontmost,
# focused card since it's the most-recently-used app on this ATV. If testing
# shows the wrong app gets swiped, that's the signal to add navigation back.

i=1
while [ "$i" -le "$SWIPE_PASSES" ]; do
  echo "🧹 Swiping up to force-quit the app... (Pass $i)"
  eval "$ATV_CMD up up" >/dev/null 2>&1 || true
  sleep "$FC_SHORT_DELAY"
  i=$((i + 1))
done

echo "🏡 Returning to Home Screen..."
eval "$ATV_CMD home" >/dev/null 2>&1 || true
sleep "$FC_SHORT_DELAY"

echo "✅ Spectrum app force-quit, ATV in idle state"

Heres a sample M3U:

#EXTM3U


#EXTINF:-1 channel-id="56905" channel-number="3024" tvg-name="DSCHD" tvc-guide-stationid="56905",Discovery
http://{{ .IPADDRESS }}/play/tuner/56905

#EXTINF:-1 channel-id="59337" channel-number="3025" tvg-name="AMCHD" tvc-guide-stationid="59337",AMC
http://{{ .IPADDRESS }}/play/tuner/59337

#EXTINF:-1 channel-id="59186" channel-number="3026" tvg-name="PARHD" tvc-guide-stationid="59186",Paramount
http://{{ .IPADDRESS }}/play/tuner/59186

#EXTINF:-1 channel-id="58623" channel-number="3032" tvg-name="SYFYHD" tvc-guide-stationid="58623",SYFY
http://{{ .IPADDRESS }}/play/tuner/58623

#EXTINF:-1 channel-id="57708" channel-number="3041" tvg-name="HSTRYHD" tvc-guide-stationid="57708",History
http://{{ .IPADDRESS }}/play/tuner/57708

#EXTINF:-1 channel-id="49788" channel-number="3044" tvg-name="HGTVD" tvc-guide-stationid="49788",HGTV
http://{{ .IPADDRESS }}/play/tuner/49788

#EXTINF:-1 channel-id="60179" channel-number="3046" tvg-name="FNCHD" tvc-guide-stationid="60179",Fox_News
http://{{ .IPADDRESS }}/play/tuner/60179

#EXTINF:-1 channel-id="64241" channel-number="3047" tvg-name="MSNBC" tvc-guide-stationid="16300",MSNOW
http://{{ .IPADDRESS }}/play/tuner/64241

#EXTINF:-1 channel-id="58646" channel-number="3049" tvg-name="CNNHD" tvc-guide-stationid="58646",CNN
http://{{ .IPADDRESS }}/play/tuner/58646

#EXTINF:-1 channel-id="58812" channel-number="3051" tvg-name="WEATHHD" tvc-guide-stationid="58812",The_Weather_Channel
http://{{ .IPADDRESS }}/play/tuner/58812

#EXTINF:-1 channel-id="58574" channel-number="3053" tvg-name="FXHD" tvc-guide-stationid="58574",FX
http://{{ .IPADDRESS }}/play/tuner/58574

#EXTINF:-1 channel-id="62420" channel-number="3058" tvg-name="CCHD" tvc-guide-stationid="62420",Comedy_Central
http://{{ .IPADDRESS }}/play/tuner/62420

#EXTINF:-1 channel-id="68344" channel-number="3076" tvg-name="CSPANHD" tvc-guide-stationid="68344",C-SPAN
http://{{ .IPADDRESS }}/play/tuner/68344

#EXTINF:-1 channel-id="49438" channel-number="3083" tvg-name="NGCHD" tvc-guide-stationid="49438",National_Geographic
http://{{ .IPADDRESS }}/play/tuner/49438

#EXTINF:-1 channel-id="66268" channel-number="3090" tvg-name="HALLHD" tvc-guide-stationid="66268",HALLMARK
http://{{ .IPADDRESS }}/play/tuner/66268

#EXTINF:-1 channel-id="46710" channel-number="3091" tvg-name="HMMHD" tvc-guide-stationid="46710",Hallmark_Movies_Mysteries
http://{{ .IPADDRESS }}/play/tuner/46710

#EXTINF:-1 channel-id="57390" channel-number="3100" tvg-name="SCIHD" tvc-guide-stationid="57390",Science
http://{{ .IPADDRESS }}/play/tuner/57390

#EXTINF:-1 channel-id="64492" channel-number="3158" tvg-name="BBCAHD" tvc-guide-stationid="64492",BBC_America
http://{{ .IPADDRESS }}/play/tuner/64492

@bnhf just flagging you in case you want to add these tweaks for these scripts into the latest repo.

Im going to built a completely new container from scratch and test the appletv pairing and script deployment using fastchannels , etc within a day or two, Can we push these latest scripts into the repo? Then Ill test everything with a totally new host directory and keep my old "production" tuner suspended while I test all the new changes.

Now, you can just upload the scripts to your local storage in browser. You can do it inside of AH4C without having to go and deal with any command line or SFTP or anything like that. So also if you pull my tag that I mentioned above, it has a full M3U editor with the ability to change channel numbers, sort, etc. Really need that stress test before @bnhf merges it into everything so.

I actually just now made a slight update to some wording, very minor, but should make it easier to understand. If you find that you need to make modifications, it should make it a little bit nicer. I also absolutely need your feedback on the Apple TV pairing. If you would also like to play with the M3U editor, I would love for someone to try to break it.

Actually, the latest scripts/atv/spectrum in the repo are only from August, and were from @PSPS as shown here:

@PSPS reported these scripts were working well for him at the time, so maybe we can get some quick coordination on this? I hate to replace working scripts, unless there's a proven reason.

1 Like

First off, I think emojis in scripts should be banned. Could cause parsing issues.

Blame uncle Claude!!! :rofl:

2 Likes

I've actually been using a mixture of Uncle Claude and Grandpa Codex to work on this latest update. Although I'm kind of reverting back to Uncle Claude, given that Opus 5.5 is freaking amazing. I also just genuinely prefer the terminal client that they have. It's just so much better than anything else.

Thanks for pointing this out. I was using a old spectrum scripts that were hanging around on my system since June of 2025 and had to tweak them. I'll take a look at the @PSPS scripts. Hopefully they dont have any emojis @mackid1993

I will test this with the new container deployment in a totally new HOSTDIR area on my machine I can test up to beta4 release easily in my portainer/docker Mac environment within the next few days. Happy to stress test everything.

Are there significant changes pending? I dont have the whole repo cloned here, Ive been using the docker/portainer method to deploy. I can start looking into cloning the repo and all that but am stretched thin here for the next few days and defiantly dont want to break my working production tuners..... Is there a workaround within portainer/docker to deploy what @mackid1993 has released that is after beta4

Otherwise I have a learning curve with uncle Claude on how to grab the full repo locally here without portainer - which has made life incredibly easy, but Id prefer not to have Claude drag me down into a rabbit hole and break my production tuners (lol) . No emoji.

All you have to do is just type mackid1993/ah4c and swap the tag to :beta. Just that simple. And then, when it gets rolled in, you just swap it bnhf/ah4c:whatevertag.

I would just like someone who's messing with M3Us to kind of exercise that since I made some pretty significant changes and could really use the feedback because I've been noticing just minor little things and patching them as I've gone on today.

This is my last little bit of work, and I'm calling it done unless people find bugs.

I think we've basically made this tool as friendly as possible for right now. I'm open to suggestions as to how we can make it even more friendly down the line. :slightly_smiling_face:

I spent a number of hours trying to figure out a way to make the View & control feature work with "virtual encoders" (Capture Cards with a CDVR Custom Source transcoding their streams), but was unable to make any meaningful progress.

For some reason the viewer starts displaying the virtual encoder output, but then quickly decides it's no good and grays it out, followed by a spinning circle.

It's not a huge deal for me, but as more people discover just how fab the FastChannels ah4c bridge is, I think we'll see more new users wanting to manage multiple Capture Card solutions using ah4c.

Anyway, if you're up for yet another challenge :slight_smile:, it'd be great if you could take a look at this -- as I'm sure it'll come-up as an issue in the future otherwise.

I could use a little bit of rest after this one, but I'll look into that. I just don't have a virtual encoder to test with, that's the problem.

You mean like a cheap USB capture card? Like one of those ten dollar ones? I have one of those really cheap ones.

If fhat's the case, I can try that. I just would need to know how it's configured. If you can give me, like, you know, just a basic rundown of how you configure it, maybe over a DM, I can get that running on my test rig that I plan on setting up this evening.

Oh! Quick Q: I was messing around with the Fast Channels bridge. How do I get the correct channel numbers for DTV? That will drive me crazy lol.

You could use a $10 one, or if you DM me your shipping address, I'll have Amazon ship a slightly nicer $25 one to you -- the same one I'm using. I'm passing a couple of these through to a Channels DVR LXC, so they play nice with Linux:

https://www.amazon.com/dp/B097DKNS1M

And, I can walk you through the process either for Windows or Linux. In fact, my Proxmox write-up on installing these would probably be close to what you'd need:

No worries. I appreciate it, the one I have should be fine for testing!

I know right? FastChannels is a no-go for using sub-channels, so I've been living with not having DTV numbering. My current plan is try the @babsonnexus Playlist Manager, as I believe that would work well for getting the channel numbers as we'd like them, plus allowing for seamless multiple source fallback.

Yeah, there should be like an option in that to preserve source provider numbering or something if it's an option. Like, DirecTV actually exposes that. So, like, maybe like that could just be like a feature. Like an override or something. Like some providers, most of them don't expose channel numbers. It's not important, but DirecTV actively does and actively uses them.