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

I don't mind hard coding the values for now as doing env variables in a stacks file kind of sucks. I'll add the ports but I cant make out the screenshot unfortunately. I tried zooming in but I just couldn't make it any bigger.

Go into advanced mode in the Environment variables section, and you can copy and paste. It's actually easier than hard coding values.

version: '3.9'
services:
  ah4c:
    image: bnhf/ah4c:${TAG}
    container_name: ah4c
    hostname: ah4c
    dns_search: ${DOMAIN} # Specify the name of your LAN's domain, usually local or localdomain
    ports:
      - ${ADBS_PORT}:5037 # Port used by adb-server
      - ${HOST_PORT}:7654 # Port used by this ah4c proxy
      - ${WSCR_PORT}:8000 # Port used by ws-scrcpy
    environment:
      - IPADDRESS=${IPADDRESS} # Hostname or IP address of this ah4c extension to be used in M3U file (also add port number if not in M3U)
      - NUMBER_TUNERS=${NUMBER_TUNERS} # Number of tuners you'd like defined 1, 2, 3 or 4 supported
      - TUNER1_IP=${TUNER1_IP} # Streaming device #1 with adb port in the form hostname:port or ip:port
      - TUNER2_IP=${TUNER2_IP} # Streaming device #2 with adb port in the form hostname:port or ip:port
      - TUNER3_IP=${TUNER3_IP} # Streaming device #3 with adb port in the form hostname:port or ip:port
      - TUNER4_IP=${TUNER4_IP} # Streaming device #4 with adb port in the form hostname:port or ip:port
      - ENCODER1_URL=${ENCODER1_URL} # Full URL for tuner #1 in the form http://hostname/stream or http://ip/stream
      - ENCODER2_URL=${ENCODER2_URL} # Full URL for tuner #2 in the form http://hostname/stream or http://ip/stream
      - ENCODER3_URL=${ENCODER3_URL} # Full URL for tuner #3 in the form http://hostname/stream or http://ip/stream
      - ENCODER4_URL=${ENCODER4_URL} # Full URL for tuner #4 in the form http://hostname/stream or http://ip/stream
      - STREAMER_APP=${STREAMER_APP} # Streaming device name and streaming app you're using in the form scripts/streamer/app (use lowercase with slashes between as shown)
      - CHANNELSIP=${CHANNELSIP} # Hostname or IP address of the Channels DVR server itself
      - ALERT_SMTP_SERVER=${ALERT_SMTP_SERVER} # The domainname:port of the SMTP server you'll be using like smtp.gmail.com:587. This is for sending ah4c alerts if tuning fails.
      - ALERT_AUTH_SERVER=${ALERT_AUTH_SERVER} # The auth server for the e-mail you'll be using like smtp.gmail.com
      - ALERT_EMAIL_FROM=${ALERT_EMAIL_FROM} # The e-mail address you'd like your ah4c failure alert e-mails to show as being from.
      - ALERT_EMAIL_PASS=${ALERT_EMAIL_PASS} # Gmail and Yahoo both support the creation of app-specific e-mail passwords, and this is the way to go! It's NOT recommended to use your everyday e-mail password.
      - ALERT_EMAIL_TO=${ALERT_EMAIL_TO} # The e-mail address you'd like your alert e-mails sent to.
      #- ALERT_WEBHOOK_URL=""
      - LIVETV_ATTEMPTS=${LIVETV_ATTEMPTS} # For FireTV Live Guide tuning only, set maximum number of attempts at finding the desired channel
      - CREATE_M3US=${CREATE_M3US} # Set to true to create device-specific M3Us for use with Amazon Prime Premium channels -- requires a FireTV device
      - UPDATE_SCRIPTS=${UPDATE_SCRIPTS} # Set to true if you'd like the sample scripts and STREAMER_APP scripts updated whether they exist or not
      - UPDATE_M3US=${UPDATE_M3US} # Set to true if you'd like the sample m3us updated whether they exist or not
      - TZ=${TZ} # Your local timezone in Linux "tz" format
    volumes:
      - ${HOST_DIR}/ah4c/scripts:/opt/scripts # pre/stop/bmitune.sh scripts will be stored in this bound host directory under streamer/app
      - ${HOST_DIR}/ah4c/m3u:/opt/m3u # m3u files will be stored here and hosted at http://<hostname or ip>:7654/m3u for use in Channels DVR - Custom Channels settings
      - ${HOST_DIR}/ah4c/adb:/root/.android # Persistent data directory for adb keys
    restart: unless-stopped
TAG=latest
DOMAIN=localdomain
ADBS_PORT=5037
HOST_PORT=7654
WSCR_PORT=7655
IPADDRESS=htpc6:7654
NUMBER_TUNERS=2
TUNER1_IP=firestick-rack1:5555
ENCODER1_URL=http://encoder_48007/0.ts
TUNER2_IP=firestick-rack2:5555
ENCODER2_URL=http://encoder_48007/4.ts
STREAMER_APP=scripts/firetv/directv
CHANNELSIP=media-server6
ALERT_SMTP_SERVER=smtp.gmail.com:587
ALERT_AUTH_SERVER=smtp.gmail.com
[email protected]
ALERT_EMAIL_PASS=xxxxxxxxxxxxxxxx
[email protected]
LIVETV_ATTEMPTS=45
CREATE_M3US=false
UPDATE_SCRIPTS=true
UPDATE_M3US=true
TZ=US/Mountain
HOST_DIR=/data

looks like the only thing I was missing was the port on the end of the ah4c IP. I changed that and restarted the container with the same result. I tried it from curl on the Channels server and same failure.

seth@channelsdvr:~$ curl http://192.168.12.18:8000/play/tuner/17153
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /play/tuner/17153</pre>
</body>
</html>

Unless you added env vars, you don't have any of your ports defined. As you know, the port number you're using on the docker host side is to the left of the colon.

Also, once you get your host side port assignments sorted out, port 8000 is the ws-scrcpy port. ah4c is on 7654.

So what would it look like then?

 ports:
      - 5037:5037 # Port used by adb-server
      - 7654:7654 # Port used by this ah4c proxy
      - 8000:8000 # Port used by ws-scrcpy

That would be correct if you're hard coding values.

same error. I dont want you to have to waste any more time. I seem to be the only one having issues getting this to work so the issue has to be me.

Are you sure you're using the right port with curl? Did you miss this post:

I just tried it on my system and I see:

root@htpc6:~# curl http://htpc6:7654/play/tuner/212
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.

Which seems about right for output, though I haven't ever tried using curl on an ah4c port before.

@slampman

Can you post your Portainer log output from container spin-up until it shows as ready?

sure

connected to 192.168.12.177:5555
Existing ./scripts/firetv/directv/prebmitune.sh found, and will be preserved
Existing ./scripts/firetv/directv/bmitune.sh found, and will be preserved
Existing ./scripts/firetv/directv/stopbmitune.sh found, and will be preserved
No existing directv.m3u found or UPDATE_M3US set to true
No existing dtvdeeplinks.m3u found or UPDATE_M3US set to true
No existing dtvosprey.m3u found or UPDATE_M3US set to true
No existing dtvstream.m3u found or UPDATE_M3US set to true
No existing dtvstreamdeeplinks.m3u found or UPDATE_M3US set to true
No existing foo-fighters.m3u found or UPDATE_M3US set to true
No existing fubo.m3u found or UPDATE_M3US set to true
No existing hulu.m3u found or UPDATE_M3US set to true
No existing livetv.m3u found or UPDATE_M3US set to true
No existing nbc.m3u found or UPDATE_M3US set to true
No existing npo.m3u found or UPDATE_M3US set to true
No existing pbs-seatac.m3u found or UPDATE_M3US set to true
No existing pbs-worcester.m3u found or UPDATE_M3US set to true
No existing silicondust.m3u found or UPDATE_M3US set to true
No existing sling.m3u found or UPDATE_M3US set to true
No existing spectrum.m3u found or UPDATE_M3US set to true
No existing xfinity.m3u found or UPDATE_M3US set to true
No existing youtubetv_shield.m3u found or UPDATE_M3US set to true
No existing youtubetv.m3u found or UPDATE_M3US set to true
[START] ah4c is starting
[ENV] Not loading env
[ENV] IPADDRESS                  192.168.12.18:7654
[ENV] ALERT_SMTP_SERVER          
[ENV] ALERT_AUTH_SERVER          
[ENV] ALERT_EMAIL_FROM           
[ENV] ALERT_EMAIL_PASS           
[ENV] ALERT_EMAIL_TO             
[ENV] ALERT_WEBHOOK_URL          
[ENV] ALLOW_DEBUG_VIDEO_PREVIEW  
[ENV] Creating tuner             1
[ENV] ENCODER1_URL               http://192.168.12.16:8090/stream0
[ENV] TUNER1_IP                  192.168.12.177:5555
[ENV] CMD1                       
[ENV] TEECMD1                    
[ENV] PRE SCRIPT                 ./scripts/firetv/bbc/prebmitune.sh
[ENV] START SCRIPT               ./scripts/firetv/bbc/bmitune.sh
[ENV] STOP SCRIPT                ./scripts/firetv/bbc/stopbmitune.sh
[ENV] REBOOT SCRIPT              ./scripts/firetv/bbc/reboot.sh
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET    /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] HEAD   /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] Loaded HTML Templates (11): 
	- index.html
	- routes.html
	- status.html
	- stream.html
	- 
      
	- edit.html
      
	- logs.html
      
	- m3us.html
	- status_and_logs.html
	- config.html
	- editm3u.html
[GIN-debug] GET    /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] HEAD   /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] GET    /                         --> main.run.func1 (2 handlers)
[GIN-debug] GET    /routes                   --> main.run.func2 (2 handlers)
[GIN-debug] GET    /play/tuner:tuner/:channel --> main.run.func3 (2 handlers)
[GIN-debug] GET    /m3u/:channel             --> main.run.func4 (2 handlers)
[GIN-debug] GET    /env                      --> main.run.func5 (2 handlers)
[GIN-debug] GET    /logs/text                --> main.run.func6 (2 handlers)
[GIN-debug] GET    /logs                     --> main.run.func7 (2 handlers)
[GIN-debug] GET    /status/andlogs           --> main.run.func8 (2 handlers)
[GIN-debug] GET    /logs/json                --> main.run.func9 (2 handlers)
[GIN-debug] GET    /video                    --> main.run.func10 (2 handlers)
[GIN-debug] GET    /status                   --> main.statusPageHandler (2 handlers)
[GIN-debug] GET    /api/status               --> main.apiStatusHandler (2 handlers)
[GIN-debug] GET    /stream                   --> main.run.func11 (2 handlers)
[GIN-debug] GET    /test/webhook             --> main.run.func12 (2 handlers)
[GIN-debug] GET    /test/email               --> main.run.func13 (2 handlers)
[GIN-debug] GET    /status/channelsactivity  --> main.run.func14 (2 handlers)
[GIN-debug] GET    /edit                     --> main.run.func15 (2 handlers)
[GIN-debug] POST   /save                     --> main.run.func16 (2 handlers)
[GIN-debug] POST   /m3usave/:file            --> main.run.func17 (2 handlers)
[GIN-debug] GET    /m3us                     --> main.run.func18 (2 handlers)
[GIN-debug] GET    /editm3u/:file            --> main.run.func19 (2 handlers)
[GIN-debug] GET    /config                   --> main.run.func20 (2 handlers)
[GIN-debug] POST   /configsave               --> main.run.func21 (2 handlers)
[START] ah4c is ready
[GIN-debug] Listening and serving HTTP on :7654
> [email protected] start
> node ./index.js
Listening on:
	http://ah4c:8000 http://localhost:8000
	http://127.0.0.1:8000 http://192.168.12.18:8000
	http://[::1]:8000
[GIN-debug] Request: 172.16.1.11 GET /status/andlogs, latency: 4.11206ms, status: 200
[GIN-debug] Request: 172.16.1.11 GET /favicon.ico, latency: 824.386µs, status: 200
[GIN-debug] Request: 172.16.1.11 GET /logs?notime, latency: 2.421034ms, status: 200
[GIN-debug] Request: 172.16.1.11 GET /status, latency: 4.255339ms, status: 200

You're missing about the first dozen lines of the log, which is part of what I wanted to see.

Regarding what you're trying to do with curl, are you just trying to confirm the port is open?

How about using netcat:

root@htpc6:~# nc -zv htpc6 7654
htpc6.tailxxxxx.ts.net [192.168.110.111] 7654 (?) open

EDIT: If you go to http://192.168.12.18:7654 in your browser you should see this:

And, if you go to http://192.168.12.18:8000 you should see this:

No i was just trying to test the script to see if it would turn the channel properly is that my issue? Its not able to bet tested in that way?

Here are the logs after a reboot:

127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
192.168.12.18	ah4c
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
connected to 192.168.12.177:5555
Existing ./scripts/firetv/directv/prebmitune.sh found, and will be preserved
Existing ./scripts/firetv/directv/bmitune.sh found, and will be preserved
Existing ./scripts/firetv/directv/stopbmitune.sh found, and will be preserved
No existing directv.m3u found or UPDATE_M3US set to true
No existing dtvdeeplinks.m3u found or UPDATE_M3US set to true
No existing dtvosprey.m3u found or UPDATE_M3US set to true
No existing dtvstream.m3u found or UPDATE_M3US set to true
No existing dtvstreamdeeplinks.m3u found or UPDATE_M3US set to true
No existing foo-fighters.m3u found or UPDATE_M3US set to true
No existing fubo.m3u found or UPDATE_M3US set to true
No existing hulu.m3u found or UPDATE_M3US set to true
No existing livetv.m3u found or UPDATE_M3US set to true
No existing nbc.m3u found or UPDATE_M3US set to true
No existing npo.m3u found or UPDATE_M3US set to true
No existing pbs-seatac.m3u found or UPDATE_M3US set to true
No existing pbs-worcester.m3u found or UPDATE_M3US set to true
No existing silicondust.m3u found or UPDATE_M3US set to true
No existing sling.m3u found or UPDATE_M3US set to true
No existing spectrum.m3u found or UPDATE_M3US set to true
No existing xfinity.m3u found or UPDATE_M3US set to true
No existing youtubetv_shield.m3u found or UPDATE_M3US set to true
No existing youtubetv.m3u found or UPDATE_M3US set to true
[START] ah4c is starting
[ENV] Not loading env
[ENV] IPADDRESS                  192.168.12.18:7654
[ENV] ALERT_SMTP_SERVER          
[ENV] ALERT_AUTH_SERVER          
[ENV] ALERT_EMAIL_FROM           
[ENV] ALERT_EMAIL_PASS           
[ENV] ALERT_EMAIL_TO             
[ENV] ALERT_WEBHOOK_URL          
[ENV] ALLOW_DEBUG_VIDEO_PREVIEW  
[ENV] Creating tuner             1
[ENV] ENCODER1_URL               http://192.168.12.16:8090/stream0
[ENV] TUNER1_IP                  192.168.12.177:5555
[ENV] CMD1                       
[ENV] TEECMD1                    
[ENV] PRE SCRIPT                 ./scripts/firetv/bbc/prebmitune.sh
[ENV] START SCRIPT               ./scripts/firetv/bbc/bmitune.sh
[ENV] STOP SCRIPT                ./scripts/firetv/bbc/stopbmitune.sh
[ENV] REBOOT SCRIPT              ./scripts/firetv/bbc/reboot.sh
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET    /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] HEAD   /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] Loaded HTML Templates (11): 
	- index.html
	- routes.html
	- status.html
	- stream.html
	- 
      
	- edit.html
      
	- logs.html
      
	- m3us.html
	- status_and_logs.html
	- config.html
	- editm3u.html
[GIN-debug] GET    /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] HEAD   /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] GET    /                         --> main.run.func1 (2 handlers)
[GIN-debug] GET    /routes                   --> main.run.func2 (2 handlers)
[GIN-debug] GET    /play/tuner:tuner/:channel --> main.run.func3 (2 handlers)
[GIN-debug] GET    /m3u/:channel             --> main.run.func4 (2 handlers)
[GIN-debug] GET    /env                      --> main.run.func5 (2 handlers)
[GIN-debug] GET    /logs/text                --> main.run.func6 (2 handlers)
[GIN-debug] GET    /logs                     --> main.run.func7 (2 handlers)
[GIN-debug] GET    /status/andlogs           --> main.run.func8 (2 handlers)
[GIN-debug] GET    /logs/json                --> main.run.func9 (2 handlers)
[GIN-debug] GET    /video                    --> main.run.func10 (2 handlers)
[GIN-debug] GET    /status                   --> main.statusPageHandler (2 handlers)
[GIN-debug] GET    /api/status               --> main.apiStatusHandler (2 handlers)
[GIN-debug] GET    /stream                   --> main.run.func11 (2 handlers)
[GIN-debug] GET    /test/webhook             --> main.run.func12 (2 handlers)
[GIN-debug] GET    /test/email               --> main.run.func13 (2 handlers)
[GIN-debug] GET    /status/channelsactivity  --> main.run.func14 (2 handlers)
[GIN-debug] GET    /edit                     --> main.run.func15 (2 handlers)
[GIN-debug] POST   /save                     --> main.run.func16 (2 handlers)
[GIN-debug] POST   /m3usave/:file            --> main.run.func17 (2 handlers)
[GIN-debug] GET    /m3us                     --> main.run.func18 (2 handlers)
[GIN-debug] GET    /editm3u/:file            --> main.run.func19 (2 handlers)
[GIN-debug] GET    /config                   --> main.run.func20 (2 handlers)
[GIN-debug] POST   /configsave               --> main.run.func21 (2 handlers)
[START] ah4c is ready
[GIN-debug] Listening and serving HTTP on :7654
> [email protected] start
> node ./index.js
Listening on:
	http://ah4c:8000 http://localhost:8000
	http://127.0.0.1:8000 http://192.168.12.18:8000
	http://[::1]:8000
[GIN-debug] Request: 172.16.1.11 GET /status/andlogs, latency: 4.11206ms, status: 200
[GIN-debug] Request: 172.16.1.11 GET /favicon.ico, latency: 824.386µs, status: 200
[GIN-debug] Request: 172.16.1.11 GET /logs?notime, latency: 2.421034ms, status: 200
[GIN-debug] Request: 172.16.1.11 GET /status, latency: 4.255339ms, status: 200
[STATS] CPU usage: 8.161495702290626%
[STATS] Alloc = 2 MiB
[STATS] TotalAlloc = 47 MiB
[STATS] Sys = 20 MiB
[STATS] NumGC = 39
[STATS] Total memory: 31941 MiB
[STATS] Memory used: 10742 MiB
[STATS] Memory used percent: 33.63025935246027%
[STATS] CPU usage: 6.836631615675354%
[STATS] Alloc = 2 MiB
[STATS] TotalAlloc = 47 MiB
[STATS] Sys = 20 MiB
[STATS] NumGC = 54
[STATS] Total memory: 31941 MiB
[STATS] Memory used: 10810 MiB
[STATS] Memory used percent: 33.842338300961565%
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
192.168.12.18	ah4c
* daemon not running; starting now at tcp:5037
List of devices attached
* daemon started successfully
connected to 192.168.12.177:5555
Existing ./scripts/firetv/directv/prebmitune.sh found, and will be preserved
Existing ./scripts/firetv/directv/bmitune.sh found, and will be preserved
Existing ./scripts/firetv/directv/stopbmitune.sh found, and will be preserved
No existing directv.m3u found or UPDATE_M3US set to true
No existing dtvdeeplinks.m3u found or UPDATE_M3US set to true
No existing dtvosprey.m3u found or UPDATE_M3US set to true
No existing dtvstream.m3u found or UPDATE_M3US set to true
No existing dtvstreamdeeplinks.m3u found or UPDATE_M3US set to true
No existing foo-fighters.m3u found or UPDATE_M3US set to true
No existing fubo.m3u found or UPDATE_M3US set to true
No existing hulu.m3u found or UPDATE_M3US set to true
No existing livetv.m3u found or UPDATE_M3US set to true
No existing nbc.m3u found or UPDATE_M3US set to true
No existing npo.m3u found or UPDATE_M3US set to true
No existing pbs-seatac.m3u found or UPDATE_M3US set to true
No existing pbs-worcester.m3u found or UPDATE_M3US set to true
No existing silicondust.m3u found or UPDATE_M3US set to true
No existing sling.m3u found or UPDATE_M3US set to true
No existing spectrum.m3u found or UPDATE_M3US set to true
No existing xfinity.m3u found or UPDATE_M3US set to true
No existing youtubetv_shield.m3u found or UPDATE_M3US set to true
No existing youtubetv.m3u found or UPDATE_M3US set to true
[START] ah4c is starting
[ENV] Not loading env
[ENV] IPADDRESS                  192.168.12.18:7654
[ENV] ALERT_SMTP_SERVER          
[ENV] ALERT_AUTH_SERVER          
[ENV] ALERT_EMAIL_FROM           
[ENV] ALERT_EMAIL_PASS           
[ENV] ALERT_EMAIL_TO             
[ENV] ALERT_WEBHOOK_URL          
[ENV] ALLOW_DEBUG_VIDEO_PREVIEW  
[ENV] Creating tuner             1
[ENV] ENCODER1_URL               http://192.168.12.16:8090/stream0
[ENV] TUNER1_IP                  192.168.12.177:5555
[ENV] CMD1                       
[ENV] TEECMD1                    
[ENV] PRE SCRIPT                 ./scripts/firetv/bbc/prebmitune.sh
[ENV] START SCRIPT               ./scripts/firetv/bbc/bmitune.sh
[ENV] STOP SCRIPT                ./scripts/firetv/bbc/stopbmitune.sh
[ENV] REBOOT SCRIPT              ./scripts/firetv/bbc/reboot.sh
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET    /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] HEAD   /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] Loaded HTML Templates (11): 
	- 
	- editm3u.html
	- index.html
	- routes.html
	- status_and_logs.html
	- stream.html
	- config.html
      
	- edit.html
      
	- logs.html
      
	- m3us.html
	- status.html
[GIN-debug] GET    /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] HEAD   /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] GET    /                         --> main.run.func1 (2 handlers)
[GIN-debug] GET    /routes                   --> main.run.func2 (2 handlers)
[GIN-debug] GET    /play/tuner:tuner/:channel --> main.run.func3 (2 handlers)
[GIN-debug] GET    /m3u/:channel             --> main.run.func4 (2 handlers)
[GIN-debug] GET    /env                      --> main.run.func5 (2 handlers)
[GIN-debug] GET    /logs/text                --> main.run.func6 (2 handlers)
[GIN-debug] GET    /logs                     --> main.run.func7 (2 handlers)
[GIN-debug] GET    /status/andlogs           --> main.run.func8 (2 handlers)
[GIN-debug] GET    /logs/json                --> main.run.func9 (2 handlers)
[GIN-debug] GET    /video                    --> main.run.func10 (2 handlers)
[GIN-debug] GET    /status                   --> main.statusPageHandler (2 handlers)
[GIN-debug] GET    /api/status               --> main.apiStatusHandler (2 handlers)
[GIN-debug] GET    /stream                   --> main.run.func11 (2 handlers)
[GIN-debug] GET    /test/webhook             --> main.run.func12 (2 handlers)
[GIN-debug] GET    /test/email               --> main.run.func13 (2 handlers)
[GIN-debug] GET    /status/channelsactivity  --> main.run.func14 (2 handlers)
[GIN-debug] GET    /edit                     --> main.run.func15 (2 handlers)
[GIN-debug] POST   /save                     --> main.run.func16 (2 handlers)
[GIN-debug] POST   /m3usave/:file            --> main.run.func17 (2 handlers)
[GIN-debug] GET    /m3us                     --> main.run.func18 (2 handlers)
[GIN-debug] GET    /editm3u/:file            --> main.run.func19 (2 handlers)
[GIN-debug] GET    /config                   --> main.run.func20 (2 handlers)
[GIN-debug] POST   /configsave               --> main.run.func21 (2 handlers)
[START] ah4c is ready
[GIN-debug] Listening and serving HTTP on :7654
> [email protected] start
> node ./index.js
Listening on:
	http://ah4c:8000 http://localhost:8000
	http://127.0.0.1:8000 http://192.168.12.18:8000
	http://[::1]:8000

I've never done it that way, and as I posted earlier, when I tried it I got an error regarding binary output to the terminal. Testing with VLC would be much more useful.

@slampman

Why don't you try these for scripts:

prebmitune.sh:

#!/bin/bash
#prebmitune.sh for firetv/bbc

#Debug on if uncommented
set -x

streamerIP="$1"
streamerNoPort="${streamerIP%%:*}"
adbTarget="adb -s $streamerIP"

mkdir -p $streamerNoPort

#Trap end of script run
finish() {
  echo "prebmitune.sh is exiting for $streamerIP with exit code $?"
}

trap finish EXIT

adbConnect() {
  adb connect $streamerIP

  local -i adbMaxRetries=3
  local -i adbCounter=0

  while true; do
    $adbTarget shell input keyevent KEYCODE_WAKEUP
    local adbEventSuccess=$?

    if [[ $adbEventSuccess -eq 0 ]]; then
      break
    fi

    if (($adbCounter > $adbMaxRetries)); then
      touch $streamerNoPort/adbCommunicationFail
      echo "Communication with $streamerIP failed after $adbMaxRetries retries"
      exit 1
    fi

    sleep 1
    ((adbCounter++))
  done
}

adbWake() {
  packageLaunch="com.clientapp.MainActivity"
  packageName="uk.co.bbc.iplayer"
  packagePID=$($adbTarget shell pidof $packageName)
  
  if [ ! -z $packagePID ]; then
    $adbTarget shell input keyevent KEYCODE_WAKEUP
    $adbTarget shell am start -n $packageName/$packageLaunch
    echo "Waking $streamerIP"
    touch $streamerNoPort/adbAppRunning
  else
    $adbTarget shell input keyevent KEYCODE_WAKEUP
    $adbTarget shell am start -n $packageName/$packageLaunch
    echo "Starting $packageName on $streamerIP"
  fi
}

main() {
  adbConnect
  adbWake
}

main

bmitune.sh:

#!/bin/bash
#bmitune.sh for firetv/bbc

#Debug on if uncommented
set -x

#Global
channelID=\""$1\""
specialID="$1"
streamerIP="$2"
streamerNoPort="${streamerIP%%:*}"
adbTarget="adb -s $streamerIP"
packageName=uk.co.bbc.iplayer
m3uName="${STREAMER_APP#*/*/}.m3u"

#Trap end of script run
finish() {
  echo "bmitune.sh is exiting for $streamerIP with exit code $?"
}

trap finish EXIT

updateReferenceFiles() {

  # Handle cases where stream_stopped or last_channel don't exist
  mkdir -p $streamerNoPort
  [[ -f "$streamerNoPort/stream_stopped" ]] || echo 0 > "$streamerNoPort/stream_stopped"
  [[ -f "$streamerNoPort/last_channel" ]] || echo 0 > "$streamerNoPort/last_channel"

  # Write PID for this script to bmitune_pid for use in stopbmitune.sh
  echo $$ > "$streamerNoPort/bmitune_pid"
  echo "Current PID for this script is $$"
}

#Set encoderURL based on the value of streamerIP
matchEncoderURL() {

  case "$streamerIP" in
    "$TUNER1_IP")
      encoderURL=$ENCODER1_URL
      ;;
    "$TUNER2_IP")
      encoderURL=$ENCODER2_URL
      ;;
    "$TUNER3_IP")
      encoderURL=$ENCODER3_URL
      ;;
    "$TUNER4_IP")
      encoderURL=$ENCODER4_URL
      ;;
    *)
      exit 1
      ;;
  esac
}

#Check for active audio stream with maxDuration, preTuneAudioCheck, sleepBeforeAudioCheck and sleepAfterAudioCheck as arguments
activeAudioCheck() {
  local startTime=$(date +%s)
  local maxDuration=$1
  local minimumLoudness=-50
  local sleepBeforeAudioCheck=$3
  local sleepAfterAudioCheck=$4
  local preTuneAudioCheck=$2
  
  while true; do
    sleep $sleepBeforeAudioCheck
    checkLoudness=$(ffmpeg -t 1 -i $encoderURL -filter:a ebur128 -map 0:a -f null -hide_banner - 2>&1 | awk '/I:        /{print $2}')

    if (( $(date +%s) - $startTime > $maxDuration )); then
      echo "Active audio stream not detected in $maxDuration seconds."
      if [ $preTuneAudioCheck = "false" ]; then
        echo "Active audio stream not detected after tuning completed"
        case "$specialID" in
          "212")
            echo "Possible sports event blackout on NFL Network, so bumping channel up"
            $adbTarget shell input keyevent KEYCODE_DPAD_LEFT
            echo 0 > "$streamerNoPort/last_channel"
            exit 1
            ;; 
          "213")
            echo "Possible sports event blackout on MLB Network, so bumping channel down"
            $adbTarget shell input keyevent KEYCODE_DPAD_RIGHT
            echo 0 > "$streamerNoPort/last_channel"
            exit 1
            ;; 
          *)
            echo "Possible sports event blackout, so bumping channel down"
            $adbTarget shell input keyevent KEYCODE_DPAD_RIGHT
            echo 0 > "$streamerNoPort/last_channel"
            exit 1
            ;;
        esac
      else
        exit 1
      fi
    fi

    if (( $(echo "$checkLoudness > $minimumLoudness" | bc -l) )); then
      echo "Active audio stream detected with $checkLoudness LUF."
      break
    fi

    echo "Active audio stream not yet detected -- loudness is $checkLoudness LUF. Continuing..."
    sleep $sleepAfterAudioCheck
  done
}

#Special channels to kill DirecTV app or reboot FireStick
specialChannels() {

    if [ $specialID = "exit" ]; then
      echo "Exit $packageName requested on $streamerIP"
      rm $streamerNoPort/last_channel $streamerNoPort/adbAppRunning
      $adbTarget shell am force-stop $packageName
      exit 0
    elif [ $specialID = "reboot" ]; then
      echo "Reboot $streamerIP requested"
      rm $streamerNoPort/last_channel $streamerNoPort/adbAppRunning
      $adbTarget reboot
      exit 0
    elif [[ -f $streamerNoPort/adbCommunicationFail ]]; then
      rm $streamerNoPort/adbCommunicationFail
      exit 1
    else
      echo "Not a special channel (exit nor reboot)"
      appFocus=$($adbTarget shell dumpsys window windows | grep -E 'mCurrentFocus' | cut -d '/' -f1 | sed 's/.* //g')
      echo "Current app in focus is $appFocus" 
    fi
}

#Variable delay based on whether app was running or needed to be launched
#and whether less than maxTime seconds (maxTime/3600 for hours) has passed while sleeping
launchDelay() {
  local lastChannel
  local lastAwake
  local timeNow
  local timeElapsed
  local maxTime=14400

  lastChannel=$(<"$streamerNoPort/last_channel")
  lastAwake=$(<"$streamerNoPort/stream_stopped")
  timeNow=$(date +%s)
  timeElapsed=$(($timeNow - $lastAwake))

  if (( $lastChannel == $specialID )) && (( $timeElapsed < $maxTime )); then
    echo "Last channel selected on this tuner, no channel change required"
    activeAudioCheck 42 true 0 1 # (maxDuration, preTuneAudioCheck, sleepBeforeAudioCheck, sleepAfterAudioCheck)
    $adbTarget shell input keyevent KEYCODE_MENU; sleep 2
    $adbTarget shell input keyevent KEYCODE_DPAD_CENTER
    exit 0
  elif [ -f $streamerNoPort/adbAppRunning ] && (( $timeElapsed < $maxTime )); then
    activeAudioCheck 42 true 0 1 # (maxDuration, preTuneAudioCheck, sleepBeforeAudioCheck, sleepAfterAudioCheck)
    #sleep 14
    rm $streamerNoPort/adbAppRunning
    echo $specialID > "$streamerNoPort/last_channel"
  else
    activeAudioCheck 42 true 0 1 # (maxDuration, preTuneAudioCheck, sleepBeforeAudioCheck, sleepAfterAudioCheck)
    #sleep 32
    echo $specialID > "$streamerNoPort/last_channel"
  fi
}

#Tuning is based on channel name values from $m3uName.
tuneChannel() {
  case "$specialID" in
    "17153")
      echo "Tune BBC1"
      $adbTarget shell input keyevent KEYCODE_DPAD_CENTER
      sleep 3
      $adbTarget shell input keyevent KEYCODE_DPAD_LEFT
      sleep 1
      $adbTarget shell input keyevent KEYCODE_DPAD_DOWN
      sleep 1
      $adbTarget shell input keyevent KEYCODE_DPAD_CENTER
      sleep 1
      $adbTarget shell input keyevent KEYCODE_DPAD_CENTER
      sleep 1
      $adbTarget shell input keyevent KEYCODE_DPAD_CENTER
      ;;
    *)
      echo "Invalid channel"
      exit 1
      ;;  
  esac
}

main() {
  updateReferenceFiles
  matchEncoderURL
  #specialChannels
  #launchDelay
  #activeAudioCheck 42 true 0 1 # (maxDuration, preTuneAudioCheck, sleepBeforeAudioCheck, sleepAfterAudioCheck)
  tuneChannel
  #activeAudioCheck 24 false 5 1 # (maxDuration, preTuneAudioCheck, sleepBeforeAudioCheck, sleepAfterAudioCheck)
}

main

stopbmitune.sh:

#!/bin/bash
#stopbmitune.sh for firetv/bbc

#Debug on if uncommented
set -x

streamerIP="$1"
streamerNoPort="${streamerIP%%:*}"
adbTarget="adb -s $streamerIP"
packageName=uk.co.bbc.iplayer

#Check if bmitune.sh is done running
bmituneDone() {
  bmitunePID=$(<"$streamerNoPort/bmitune_pid")

  while ps -p $bmitunePID > /dev/null; do
    echo "Waiting for bmitune.sh to complete..."
    sleep 2
  done
}

#Stop stream
adbStop() {
  #stop="input keyevent KEYCODE_HOME"
  stop="am force-stop $packageName"

  $adbTarget shell $stop; sleep 2
  echo "Streaming stopped for $streamerIP"
}

#Device sleep
adbSleep() {
  sleep="input keyevent KEYCODE_SLEEP"

  $adbTarget shell $sleep
  echo "Sleep initiated for $streamerIP"
  date +%s > $streamerNoPort/stream_stopped
  echo "$streamerNoPort/stream_stopped written with epoch stop time"
}

main() {
  bmituneDone
  adbStop
  adbSleep
}

main

thanks for doing that. I did try but unfortunately I get the same result. I hate for you to have to spend any more time on this. I'm ok if this just isn't for me. For some reason this is kicking my butt and I still don't have a solid grasp on the inter-workings of this process...

Channels error

2024/09/10 19:51:25.472396 [ERR] Failed to start stream for ch11336: M3U: GET: http://192.168.12.18:8000/play/tuner/17153: 404 Not Found

Logs

[ENV] Creating tuner             1
[ENV] ENCODER1_URL               http://192.168.12.16:8090/stream0
[ENV] TUNER1_IP                  192.168.12.177:5555
[ENV] CMD1                       
[ENV] TEECMD1                    
[ENV] PRE SCRIPT                 ./scripts/firetv/bbc/prebmitune.sh
[ENV] START SCRIPT               ./scripts/firetv/bbc/bmitune.sh
[ENV] STOP SCRIPT                ./scripts/firetv/bbc/stopbmitune.sh
[ENV] REBOOT SCRIPT              ./scripts/firetv/bbc/reboot.sh
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET    /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] HEAD   /favicon.ico              --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (2 handlers)
[GIN-debug] Loaded HTML Templates (11): 
	- status.html
	- stream.html
	- config.html

	- edit.html
	- editm3u.html
	- index.html

	- m3us.html
	- 

	- logs.html
	- routes.html
	- status_and_logs.html
[GIN-debug] GET    /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] HEAD   /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (2 handlers)
[GIN-debug] GET    /                         --> main.run.func1 (2 handlers)
[GIN-debug] GET    /routes                   --> main.run.func2 (2 handlers)
[GIN-debug] GET    /play/tuner:tuner/:channel --> main.run.func3 (2 handlers)
[GIN-debug] GET    /m3u/:channel             --> main.run.func4 (2 handlers)
[GIN-debug] GET    /env                      --> main.run.func5 (2 handlers)
[GIN-debug] GET    /logs/text                --> main.run.func6 (2 handlers)
[GIN-debug] GET    /logs                     --> main.run.func7 (2 handlers)
[GIN-debug] GET    /status/andlogs           --> main.run.func8 (2 handlers)
[GIN-debug] GET    /logs/json                --> main.run.func9 (2 handlers)
[GIN-debug] GET    /video                    --> main.run.func10 (2 handlers)
[GIN-debug] GET    /status                   --> main.statusPageHandler (2 handlers)
[GIN-debug] GET    /api/status               --> main.apiStatusHandler (2 handlers)
[GIN-debug] GET    /stream                   --> main.run.func11 (2 handlers)
[GIN-debug] GET    /test/webhook             --> main.run.func12 (2 handlers)
[GIN-debug] GET    /test/email               --> main.run.func13 (2 handlers)
[GIN-debug] GET    /status/channelsactivity  --> main.run.func14 (2 handlers)
[GIN-debug] GET    /edit                     --> main.run.func15 (2 handlers)
[GIN-debug] POST   /save                     --> main.run.func16 (2 handlers)
[GIN-debug] POST   /m3usave/:file            --> main.run.func17 (2 handlers)
[GIN-debug] GET    /m3us                     --> main.run.func18 (2 handlers)
[GIN-debug] GET    /editm3u/:file            --> main.run.func19 (2 handlers)
[GIN-debug] GET    /config                   --> main.run.func20 (2 handlers)
[GIN-debug] POST   /configsave               --> main.run.func21 (2 handlers)
[START] ah4c is ready
[GIN-debug] Listening and serving HTTP on :7654
> [email protected] start
> node ./index.js
Listening on:
	http://ah4c:8000 http://localhost:8000
	http://127.0.0.1:8000 http://192.168.12.18:8000
	http://[::1]:8000
[GIN-debug] Loaded HTML Templates (21): 
	- xfinity.m3u
	- 
	- dtvstreamdeeplinks.m3u
	- npo.m3u
	- pbs-seatac.m3u
	- youtubetv_shield.m3u
	- bbc.m3u
	- dtvosprey.m3u
	- fubo.m3u
	- youtubetv.m3u
	- silicondust.m3u
	- spectrum.m3u
	- directv.m3u
	- hulu.m3u
	- livetv.m3u
	- pbs-worcester.m3u

	- sling.m3u
	- dtvdeeplinks.m3u
	- dtvstream.m3u
	- foo-fighters.m3u
	- nbc.m3u
[GIN-debug] Loaded HTML Templates (11): 
	- 
	- config.html

	- edit.html

	- logs.html

	- m3us.html
	- status_and_logs.html
	- editm3u.html
	- index.html
	- routes.html
	- status.html
	- stream.html
[GIN-debug] Request: 192.168.254.228 GET /m3u/bbc.m3u, latency: 9.653718ms, status: 200

not following closely, but based on your log the 404 is because the url doesn't match any of the GIN-debug lines. it should be /tuner0/ instead of /tuner/

Still no joy

Failed to start stream for ch11336: M3U: GET: http://192.168.12.18:8000/play/tuner0/17153: 404 Not Found

Then it kinda sounds like you're connecting to something else that's running on 8000

1 Like

Ok...just got my linkpi so I should be set to rock and roll. If I'm able to get sling working, I should be able to share to the class one of my m3us for it

2 Likes