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

@bnhf

I just reread through the 3 releases pyatv has done in the last year and don't see anything that is needed right now...Especially since everything is currently working with 0.14.5 Quimby (2023-12-24). I vote to leave it as is and post to :appletv when your ready.

Thank you for the link to the CMDx information.
I don't know how I didn't see that with my topic/site search. I didn't see any mention of the TEECMD env variable mentioned in those posts.

That's for support of non-network encoder devices like Magewell or Hauppauge cards.

when inputting the local domain do i have to put the words "local domain" and then the name or just the name

The first post in this thread has the ah4c Docker Compose you need to copy and paste into Portainer-Stacks. Then in the Environment variables section, in Advanced mode, you can copy and paste the example env vars. Then one-by-one, change the sample values to ones that are correct for you.

In the case of the DOMAIN value, you'd be changing it to:

DOMAIN=attlocal.net

thank you

This is done as of this morning. You can now use the bnhf/ah4c:appletv image, as it's the same as bnhf/ah4c:appletv.test3. I'll wait a week or so, to be sure no issues materialize, but after that I'll delete whatever :apple.testx images there are on Docker Hub.

1 Like

Deco router doesnt have domain name

Can i still use this docker container?

Yes, but be sure to use IP addresses to identify everything on your LAN, hostnames typically won't work.

This also has broader implications for those using Tailscale with MagicDNS, as the DOMAIN env var supports multiple, space-separated domain names. One can then list both a local domain and a Tailnet, with each searched in sequence when resolving local hostnames.

1 Like

Big thanks i finally got this working :smiling_face_with_three_hearts:
Some questions:
Is there any setting for speeding up channel change with arrows?
I´m testing now with vlc and first channel always start fast and ok but if i zap to next there is some kind of delay in starting of the stream and vlc shows some error: " vlc cant open url" but video do play after some waiting time.

Equipment: Android sat-tuner , always on and tuning with numbers with your script from above.
I guess what i´m asking for is a4hc to release the stream faster without wait on channel change, im ok with seeing the gui from my android box changing the channel from a4hc.

I'm curious if part of this is because you're using VLC. Can you try tuning via a Channels client to compare? Also, I'm guessing you only have a single tuner setup at this point?

I dont have any channels server atm , but have tested both with vlc and Kodi/tvheadend and its the same.
Any log that would be of use? Let me know how to collect it if needed.
Edit added log with playback of 2 channels , its the last one that gives vlc error

2025/01/24 10:40:29 Attempting network tune for device http://192.168.0.125:8090/stream0 192.168.0.138:5555 45
2025/01/24 10:40:29 [EXECUTE] Running [./scripts/android/allente/prebmitune.sh 192.168.0.138:5555 45]
2025/01/24 10:40:29 [EXECUTE] Stdout: 'Script not required
'
2025/01/24 10:40:29 [EXECUTE] Stderr: ''
2025/01/24 10:40:29 [EXECUTE] Finished running ./scripts/android/allente/prebmitune.sh in 110.662296ms
2025/01/24 10:40:29 [EXECUTE] Running [./scripts/android/allente/bmitune.sh 45 192.168.0.138:5555]
2025/01/24 10:40:31 [EXECUTE] Stdout: 'bmitune.sh is exiting for 192.168.0.138:5555 with exit code 0
'
2025/01/24 10:40:31 [EXECUTE] Stderr: '+ channelID=45
+ streamerIP=192.168.0.138:5555
+ adbTarget='adb -s 192.168.0.138:5555'
+ trap finish EXIT
+ main
+ tuneChannel
+ (( digit=0 ))
+ (( digit<2 ))
+ keypress=4
+ adb -s 192.168.0.138:5555 shell input keyevent KEYCODE_4
+ (( digit++ ))
+ (( digit<2 ))
+ keypress=5
+ adb -s 192.168.0.138:5555 shell input keyevent KEYCODE_5
+ (( digit++ ))
+ (( digit<2 ))
+ finish
+ echo 'bmitune.sh is exiting for 192.168.0.138:5555 with exit code 0'
'
2025/01/24 10:40:31 [EXECUTE] Finished running ./scripts/android/allente/bmitune.sh in 2.779024073s
2025/01/24 10:40:48 Tuner 0 is active - skipping
2025/01/24 10:40:48 [ERR] Failed to tune device(s) not available
2025/01/24 10:40:48 [GIN-debug] Request: 192.168.0.119 GET /play/tuner/121, latency: 459.704µs, status: 500
2025/01/24 10:40:48 [IO] io.Copy: write tcp 172.21.0.2:7654->192.168.0.119:56868: write: broken pipe
2025/01/24 10:40:48 [IOINFO] Successfully copied 26389972 bytes
2025/01/24 10:40:48 [IOINFO] Transfer speed: 10.803217068207019 Mbits/second
2025/01/24 10:40:48 Performing Close() for 192.168.0.138:5555
2025/01/24 10:40:48 Tuner 0 is active - skipping
2025/01/24 10:40:48 [EXECUTE] Running [./scripts/android/allente/stopbmitune.sh 192.168.0.138:5555 45]
2025/01/24 10:40:48 [ERR] Failed to tune device(s) not available
2025/01/24 10:40:48 [GIN-debug] Request: 192.168.0.119 GET /play/tuner/121, latency: 730.222µs, status: 500
2025/01/24 10:40:48 Tuner 0 is active - skipping
2025/01/24 10:40:48 [ERR] Failed to tune device(s) not available
2025/01/24 10:40:48 [GIN-debug] Request: 192.168.0.119 GET /play/tuner/122, latency: 359.111µs, status: 500
2025/01/24 10:40:48 Tuner 0 is active - skipping
2025/01/24 10:40:48 [ERR] Failed to tune device(s) not available
2025/01/24 10:40:48 [GIN-debug] Request: 192.168.0.119 GET /play/tuner/122, latency: 156.222µs, status: 500
2025/01/24 10:40:48 [EXECUTE] Stdout: 'Script not required
'
2025/01/24 10:40:48 [EXECUTE] Stderr: ''
2025/01/24 10:40:48 [EXECUTE] Finished running ./scripts/android/allente/stopbmitune.sh in 24.238407ms
2025/01/24 10:40:48 [GIN-debug] Request: 192.168.0.119 GET /play/tuner/45, latency: 19.681345137s, status: 200
2025/01/24 10:40:48 Attempting network tune for device http://192.168.0.125:8090/stream0 192.168.0.138:5555 123
2025/01/24 10:40:48 [EXECUTE] Running [./scripts/android/allente/prebmitune.sh 192.168.0.138:5555 123]
2025/01/24 10:40:48 [EXECUTE] Stdout: 'Script not required
'
2025/01/24 10:40:48 [EXECUTE] Stderr: ''
2025/01/24 10:40:48 [EXECUTE] Finished running ./scripts/android/allente/prebmitune.sh in 5.073592ms
2025/01/24 10:40:48 [EXECUTE] Running [./scripts/android/allente/bmitune.sh 123 192.168.0.138:5555]
2025/01/24 10:40:51 [EXECUTE] Stdout: 'bmitune.sh is exiting for 192.168.0.138:5555 with exit code 0
'
2025/01/24 10:40:51 [EXECUTE] Stderr: '+ channelID=123
+ streamerIP=192.168.0.138:5555
+ adbTarget='adb -s 192.168.0.138:5555'
+ trap finish EXIT
+ main
+ tuneChannel
+ (( digit=0 ))
+ (( digit<3 ))
+ keypress=1
+ adb -s 192.168.0.138:5555 shell input keyevent KEYCODE_1
+ (( digit++ ))
+ (( digit<3 ))
+ keypress=2
+ adb -s 192.168.0.138:5555 shell input keyevent KEYCODE_2
+ (( digit++ ))
+ (( digit<3 ))
+ keypress=3
+ adb -s 192.168.0.138:5555 shell input keyevent KEYCODE_3
+ (( digit++ ))
+ (( digit<3 ))
+ finish
+ echo 'bmitune.sh is exiting for 192.168.0.138:5555 with exit code 0'
'
2025/01/24 10:40:51 [EXECUTE] Finished running ./scripts/android/allente/bmitune.sh in 2.32242948s
2025/01/24 10:41:03 [IO] io.Copy: write tcp 172.21.0.2:7654->192.168.0.119:56873: write: broken pipe
2025/01/24 10:41:03 [IOINFO] Successfully copied 21532628 bytes
2025/01/24 10:41:03 [IOINFO] Transfer speed: 11.4748692250848 Mbits/second
2025/01/24 10:41:03 Performing Close() for 192.168.0.138:5555
2025/01/24 10:41:03 [EXECUTE] Running [./scripts/android/allente/stopbmitune.sh 192.168.0.138:5555 123]
2025/01/24 10:41:03 [EXECUTE] Stdout: 'Script not required
'
2025/01/24 10:41:03 [EXECUTE] Stderr: ''
2025/01/24 10:41:03 [EXECUTE] Finished running ./scripts/android/allente/stopbmitune.sh in 5.340777ms
2025/01/24 10:41:03 [GIN-debug] Request: 192.168.0.119 GET /play/tuner/123, latency: 15.025861436s, status: 200
2025/01/24 10:42:38 [GIN-debug] Request: 192.168.0.124 GET /m3u/allente.m3u, latency: 66.773148ms, status: 200

I did a bit of testing on my setup, and one big difference is that with a multi-port encoder combined with Channels, channel changes via the Quick Guide or channel up/down buttons are begun immediately on the next available tuner. This allows channel changes to a quick as possible based on whatever your setup's capabilities.

Also looking in the log, it appears Channels actually closes the connection, and I see that when I monitor the output from the encoder -- the stick is sent the adb commands and begins sleeping promptly:

2025/01/24 06:55:33.147484 [TNR] Closed connection to M3U-FireTVDirecTV for ch504 HBO West HD
2025/01/24 06:55:34.416479 [TNR] Opened connection to M3U-FireTVDirecTV for ch505 HBO2 West HD

Based, on what you're describing, and given you're using this project with something other than Channels DVR -- I believe the best outcome would be with adding a second encoder, or changing to a multi-port unit.

1 Like

Can i split hdmi from one android box to 2 streamers or would i need 2 ”tuners” also to make this work?

Multiple single-port encoders or a single multi-port encoder, with a streaming stick or other Android adb-controllable device connected to each encoder port you want to use. It's one-to-one between encoder ports and Android devices, with each pair creating one virtual tuner.

Tested and with 2 tuners and it´s working, thanks again :pray:

2 Likes

If i want to expand my setup with a new streamer tied to a new different script than above is that possible or should i make a second docker stack with different ports?

The easiest path would be to spin-up a second ah4c container with a different container name, hostname and ports. I've had as many as three running at the same time, but each needs to be using a dedicated set of encoder ports and streaming sticks. I.E., you can't "share" a virtual tuning pair with more than one container.

It's technically possible to have an M3U and a set of scripts that would work with different apps, but it's a project that would take some time to develop, and I've never been motivated to do it for my personal needs.

1 Like

Yep, I run two instances as well because I have two different streaming sources. Way easier that way even if you have some script duplication, once you get it set up you don't really need to touch it after that.

2 Likes

Can i reset adb in a4hc? Suddenly a4hc has stoped tuning on tuner 2. I have already disable/enable rewoked adb on the tvbox but nothing helps. Any other ide what could be wrong?

EDIT hdmi encoder stuck. Fixed with reboot of encoder (not ah4c container). Sorry for the noise

Can you post the Portainer log from when a tuning attempt starts to when it completes on that tuner?

Be sure to use 3 backticks before and after the log text so that it ends up in a "code block" for better readability.

1 Like