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

We have a new beta (bnhf/ah4c:beta), for anyone to try who's interested. This is another excellent effort by @mackid1993, including a new in-app settings option (env vars continue to work, and take precedence), along with lots of other new features through the WebUI.

If you'd like to continue to use the "full" Docker Compose (which will require no new configuration on your part), here's the updated version:

services:
  # 2026.09.16
  # GitHub home for this project with setup instructions: https://github.com/sullrich/ah4c
  # Docker Hub home for this project: https://hub.docker.com/repository/docker/bnhf/ah4c
  ah4c: # This docker-compose typically requires no editing. Use the Environment variables section of Portainer to set your values.
    image: bnhf/ah4c:${TAG:-latest}
    container_name: ${CONTAINER_NAME:-ah4c}
    hostname: ${HOSTNAME:-ah4c}
    dns_search: ${DOMAIN:-localdomain} # Specify the name of your LAN's domain, usually local or localdomain
    runtime: ${DOCKER_RUNTIME:-runc} # Closed captions only. Set DOCKER_RUNTIME=nvidia for an NVIDIA GPU with the CUDA engine build. Requires the NVIDIA container toolkit.
    devices:
      - ${GPU_DEVICE:-/dev/null} # Closed captions only. Set GPU_DEVICE=/dev/dri to let the Vulkan engine build use an Intel or AMD GPU. Left at the default it passes /dev/null, which always exists and does nothing.
    ports:
      - ${HOST_PORT:-7654}:7654 # Port used by this ah4c proxy
    environment:
      - AH4C_COMPOSE=2026.09.16 # Compose file date stamp - do not change. The startup log flags it when out of date.
      # ── Proxy identity ──────────────────────────────────────────────────────
      - IPADDRESS=${IPADDRESS} # Hostname or IP address of this ah4c extension to be used in M3U file (also add port number if not in M3U)
      - SETUP_WIZARD=${SETUP_WIZARD:-false} # Full environment-managed installs skip the web setup wizard. Set to true to allow it.
      # ── Tuners ──────────────────────────────────────────────────────────────
      # One trio per tuner: TUNERn_IP is the box to tune; video comes from CMDn if set, otherwise ENCODERn_URL.
      - NUMBER_TUNERS=${NUMBER_TUNERS} # Number of tuners you'd like defined - add a matching TUNERn_IP, ENCODERn_URL and CMDn trio below for each beyond 9
      - TUNER1_IP=${TUNER1_IP} # Streaming device #1 with adb port in the form hostname:port or ip:port
      - ENCODER1_URL=${ENCODER1_URL} # Tuner #1 source URL (http://hostname/stream). Streamed directly when CMD1 is blank; otherwise referenced by CMD1 as ${ENCODER1_URL}.
      - CMD1=${CMD1} # Optional tuner #1 command; ah4c streams its stdout (end it with "-f mpegts -") instead of fetching ENCODER1_URL. No shell.
      - TUNER2_IP=${TUNER2_IP} # Streaming device #2 with adb port in the form hostname:port or ip:port
      - ENCODER2_URL=${ENCODER2_URL} # Tuner #2 source URL. Streamed directly when CMD2 is blank; otherwise referenced by CMD2 as ${ENCODER2_URL}.
      - CMD2=${CMD2} # Optional tuner #2 command; ah4c streams its stdout instead of fetching ENCODER2_URL. See CMD1.
      - TUNER3_IP=${TUNER3_IP} # Streaming device #3 with adb port in the form hostname:port or ip:port
      - ENCODER3_URL=${ENCODER3_URL} # Tuner #3 source URL. Streamed directly when CMD3 is blank; otherwise referenced by CMD3 as ${ENCODER3_URL}.
      - CMD3=${CMD3} # Optional tuner #3 command; ah4c streams its stdout instead of fetching ENCODER3_URL. See CMD1.
      - TUNER4_IP=${TUNER4_IP} # Streaming device #4 with adb port in the form hostname:port or ip:port
      - ENCODER4_URL=${ENCODER4_URL} # Tuner #4 source URL. Streamed directly when CMD4 is blank; otherwise referenced by CMD4 as ${ENCODER4_URL}.
      - CMD4=${CMD4} # Optional tuner #4 command; ah4c streams its stdout instead of fetching ENCODER4_URL. See CMD1.
      - TUNER5_IP=${TUNER5_IP} # Streaming device #5 with adb port in the form hostname:port or ip:port
      - ENCODER5_URL=${ENCODER5_URL} # Tuner #5 source URL. Streamed directly when CMD5 is blank; otherwise referenced by CMD5 as ${ENCODER5_URL}.
      - CMD5=${CMD5} # Optional tuner #5 command; ah4c streams its stdout instead of fetching ENCODER5_URL. See CMD1.
      - TUNER6_IP=${TUNER6_IP} # Streaming device #6 with adb port in the form hostname:port or ip:port
      - ENCODER6_URL=${ENCODER6_URL} # Tuner #6 source URL. Streamed directly when CMD6 is blank; otherwise referenced by CMD6 as ${ENCODER6_URL}.
      - CMD6=${CMD6} # Optional tuner #6 command; ah4c streams its stdout instead of fetching ENCODER6_URL. See CMD1.
      - TUNER7_IP=${TUNER7_IP} # Streaming device #7 with adb port in the form hostname:port or ip:port
      - ENCODER7_URL=${ENCODER7_URL} # Tuner #7 source URL. Streamed directly when CMD7 is blank; otherwise referenced by CMD7 as ${ENCODER7_URL}.
      - CMD7=${CMD7} # Optional tuner #7 command; ah4c streams its stdout instead of fetching ENCODER7_URL. See CMD1.
      - TUNER8_IP=${TUNER8_IP} # Streaming device #8 with adb port in the form hostname:port or ip:port
      - ENCODER8_URL=${ENCODER8_URL} # Tuner #8 source URL. Streamed directly when CMD8 is blank; otherwise referenced by CMD8 as ${ENCODER8_URL}.
      - CMD8=${CMD8} # Optional tuner #8 command; ah4c streams its stdout instead of fetching ENCODER8_URL. See CMD1.
      - TUNER9_IP=${TUNER9_IP} # Streaming device #9 with adb port in the form hostname:port or ip:port
      - ENCODER9_URL=${ENCODER9_URL} # Tuner #9 source URL. Streamed directly when CMD9 is blank; otherwise referenced by CMD9 as ${ENCODER9_URL}.
      - CMD9=${CMD9} # Optional tuner #9 command; ah4c streams its stdout instead of fetching ENCODER9_URL. See CMD1.
      # ── Streaming app and DVR ───────────────────────────────────────────────
      - 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)
      - PYATV=${PYATV:-false} # Set to TRUE to run docker-start-pyatv.sh at container start for Apple TV tuners via pyatv, instead of the default docker-start.sh used for adb-based tuners. Case-insensitive; anything else runs the default.
      - CHANNELSIP=${CHANNELSIP} # Hostname or IP address of the Channels DVR server itself
      - FASTCHANNELS_URL=${FASTCHANNELS_URL} # Base URL of your FastChannels container, so the firetv/fastchannels scripts can use its built-in ah4c integration to tune. A URL pre-filled into an exported script overrides this.
      # ── Failure alerts ──────────────────────────────────────────────────────
      # Email via SMTP and/or a webhook GET, sent when a tune fails. Leave blank to disable.
      - 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=${ALERT_WEBHOOK_URL} # URL to GET when an alert fires (same failures that trigger the e-mail); put $reason in the URL and it's replaced with the URL-encoded message. Blank disables it.
      # ── Guide tuning and content updates ────────────────────────────────────
      - LIVETV_ATTEMPTS=${LIVETV_ATTEMPTS} # For FireTV Live Guide tuning only, set maximum number of attempts at finding the desired channel
      - CREATE_M3US=${CREATE_M3US:-false} # Set to true to create device-specific M3Us for use with Amazon Prime Premium channels -- requires a FireTV device
      - UPDATE_SCRIPTS=${UPDATE_SCRIPTS:-true} # Set to true if you'd like the sample scripts and STREAMER_APP scripts updated whether they exist or not
      - UPDATE_M3US=${UPDATE_M3US:-true} # Set to true if you'd like the sample m3us updated whether they exist or not
      # ── Timezone and session handling ───────────────────────────────────────
      - TZ=${TZ} # Your local timezone in Linux "tz" format
      - SPEED_MODE=${SPEED_MODE:-false} # Set to false if you'd like the target streaming app to be closed after each tuning cycle (limited script support).
      - KEEP_WATCHING=${KEEP_WATCHING} # In supported scripts, set the delay before resending a tuning deeplink to prevent "Are you still watching?" type messages. Examples: Use 4h for 4 hours or 240m for 240 minutes.
      # ── Autocrop (LinkPi encoders only) ─────────────────────────────────────
      - AUTOCROP_CHANNELS=${AUTOCROP_CHANNELS} # Space separated list of channels (by number) with black borders on 4 sides to autocrop while maintaining aspect ratio. Requires LinkPi Encoder!
      - LINKPI_HOSTNAME=${LINKPI_HOSTNAME} # Hostname or IP of the LinkPi Encoder's web API. Required for AUTOCROP_CHANNELS.
      - LINKPI_USERNAME=${LINKPI_USERNAME} # Username for the LinkPi Encoder's web API. Required for AUTOCROP_CHANNELS.
      - LINKPI_PASSWORD=${LINKPI_PASSWORD} # Password for the LinkPi Encoder's web API. Required for AUTOCROP_CHANNELS; not currently read by the bundled scripts, which log in with the LinkPi default password instead.
      # ── Custom startup script ───────────────────────────────────────────────
      - USER_SCRIPT=${USER_SCRIPT} # Path to a custom script to run alongside ah4c at container startup. Blank runs nothing extra.
      # ── Recording continuity and playback timing ────────────────────────────
      # Keep recordings starting on the program and free of gaps within the DVR's 30s tune window.
      - NULL_FRAME_INSERTION=${NULL_FRAME_INSERTION:-false} # Set to TRUE to fill encoder stalls with MPEG-TS NULL packets (PID 0x1FFF) so the DVR never sees a zero-byte gap mid-recording. Case-insensitive (true/True/TRUE all work); anything else, including 1/yes, leaves the feature off.
      - PLAYBACK_DETECTION=${PLAYBACK_DETECTION:-false} # Set to TRUE to hold the stream until the device reports audio playing and the picture moving, then start on a keyframe, so recording begins on the program, not the loading screen. Requires adb; network tuners only. Case-insensitive; anything but true leaves it off.
      - PLAYBACK_STATIC_TIMEOUT=${PLAYBACK_STATIC_TIMEOUT} # Only used with PLAYBACK_DETECTION=TRUE. Seconds the box may keep its prior player/session before the check falls back to gating on motion alone. Default 2 suits Ospreys; apps like DirecTV that hold one player across channel changes need more. 0 or unset uses the default.
      - PLAYBACK_DELAY=${PLAYBACK_DELAY} # Hold every tune this long before handing the DVR the program, so a slow-starting app still records within the DVR's 30s window. Black or a mounted pre-roll fills the wait; the box's own video is never passed through. Accepts a bare number (seconds) or a duration like 30s/1m, capped at 10m. Network tuners only. Empty or 0 disables it.
      - ENCODER_CODEC=${ENCODER_CODEC:-h264} # The video codec your encoder outputs: h264 (default) or h265. Filler black/pre-roll must match it, or playback won't cross to the program at hand-off. Pre-roll video is converted to match; an existing H.265 stream is copied. Leave at h264 unless your encoder is H.265. Case-insensitive; h265/hevc both work.
      - HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-180} # In supported scripts (currently osprey), seconds between keepalive keyevents sent during playback to stop the app's UI inactivity timer from resetting the stream. Default 180; set to 0 to disable.
      # ── NVIDIA GPU ──────────────────────────────────────────────────────────
      # Used by the CUDA caption engine and any CMDn calling h264_nvenc/hevc_nvenc. Needs the NVIDIA container toolkit.
      - NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES} # For the CUDA caption engine and/or an NVENC CMDn. Set to all alongside DOCKER_RUNTIME=nvidia to expose an NVIDIA GPU. Empty means no GPU and is the default.
      - NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES} # Set to compute,utility for the CUDA caption engine. A CMDn using h264_nvenc/hevc_nvenc also needs video - use compute,utility,video (or all).
    volumes:
      - ${HOST_DIR:-/data}/ah4c/config:/opt/config # Settings saved from the web interface
      - ${HOST_DIR:-/data}/ah4c/scripts:/opt/scripts # pre/stop/bmitune.sh scripts will be stored in this bound host directory under streamer/app
      - ${HOST_DIR:-/data}/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:-/data}/ah4c/adb:/root/.android # Persistent data directory for adb keys
      - ${HOST_DIR:-/data}/ah4c/captions:/opt/captions # Closed caption settings, and the speech model, engine and any GPU driver downloaded from the Closed Captions page. Stays empty unless you turn captions on
      - ${PREROLL_FILE:-${HOST_DIR:-/data}/ah4c/preroll}:/opt/preroll # A video or still image shown to the DVR instead of NULL packets, during a PLAYBACK_DELAY/PLAYBACK_DETECTION hold or a NULL_FRAME_INSERTION stall. Set PREROLL_FILE to a host path, or drop the file into this directory. Anything ffmpeg reads; prepared once at startup, loops until the real stream is ready
    restart: unless-stopped

If you'd like to have as many options exposed as possible through the new Settings page, then you're going to want to use a more minimal Docker Compose (going this route will require you to set things up through the WebUI that were previously done through env vars).

Here's a recommended Docker Compose for that new minimal route. The Compose itself still requires no editing, but it has a much smaller set of potential env var overrides:

services:
  # 2026.09.16
  # GitHub home for this project with setup instructions: https://github.com/sullrich/ah4c
  # Docker Hub home for this project: https://hub.docker.com/repository/docker/bnhf/ah4c
  ah4c: # This docker-compose typically requires no editing. Use the Environment variables section of Portainer to set your values.
    image: bnhf/ah4c:${TAG:-latest}
    container_name: ${CONTAINER_NAME:-ah4c}
    hostname: ${HOSTNAME:-ah4c}
    dns_search: ${DOMAIN:-localdomain} # Specify the name of your LAN's domain, usually local or localdomain
    runtime: ${DOCKER_RUNTIME:-runc} # Closed captions only. Set DOCKER_RUNTIME=nvidia for an NVIDIA GPU with the CUDA engine build. Requires the NVIDIA container toolkit.
    devices:
      - ${GPU_DEVICE:-/dev/null} # Closed captions only. Set GPU_DEVICE=/dev/dri to let the Vulkan engine build use an Intel or AMD GPU. Left at the default it passes /dev/null, which always exists and does nothing.
    ports:
      - ${HOST_PORT:-7654}:7654 # Port used by this ah4c proxy
    environment:
      - AH4C_COMPOSE=2026.09.16 # Compose file date stamp - do not change. The startup log flags it when out of date.
      - NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES} # For the CUDA caption engine and/or an NVENC CMDn. Set to all alongside DOCKER_RUNTIME=nvidia to expose an NVIDIA GPU. Empty means no GPU and is the default.
      - NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES} # Set to compute,utility for the CUDA caption engine. A CMDn using h264_nvenc/hevc_nvenc also needs video - use compute,utility,video (or all).
    volumes:
      - ${HOST_DIR:-/data}/ah4c/config:/opt/config # Settings saved from the web interface
      - ${HOST_DIR:-/data}/ah4c/scripts:/opt/scripts # pre/stop/bmitune.sh scripts will be stored in this bound host directory under streamer/app
      - ${HOST_DIR:-/data}/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:-/data}/ah4c/adb:/root/.android # Persistent data directory for adb keys
      - ${HOST_DIR:-/data}/ah4c/captions:/opt/captions # Closed caption settings, and the speech model, engine and any GPU driver downloaded from the Closed Captions page. Stays empty unless you turn captions on
      - ${HOST_DIR:-/data}/ah4c/preroll:/opt/preroll # A video or still image shown to the DVR instead of NULL packets, during a PLAYBACK_DELAY/PLAYBACK_DETECTION hold or a NULL_FRAME_INSERTION stall. Set PREROLL_FILE to a host path, or drop the file into this directory. Anything ffmpeg reads; prepared once at startup, loops until the real stream is ready
    restart: unless-stopped

And, here's a sample set of overrides for the minimal Compose:

TAG=beta
GPU_DEVICE=
HOST_DIR=/data

Here's what the new Settings page looks like:

Many thanks to @mackid1993, and I'm sure he'll add a post expanding on all the new features available through this beta.

2 Likes

Thank you @bnhf!

I think my favorite feature I added is the ability to pull scripts on demand directly from GitHub without waiting for a container rebuild. So if someone merges a PR for a new script or set of scripts you can query GitHub right away for that script and install it on your server rather than waiting for a Docker rebuild, which is easier for @bnhf and also better for the end user. It's also gated specifically to sullrich/ah4c do you know you're getting clean scripts you're not getting anything that is going to harm your server or anything like that. This means either sullrich or bnhf reviewed the scripts, and they're ready to go into production.

I also added an option to push an M3U file right into Channels DVR directly from ah4c without having to copy and paste the URL manually. Kind of like how FastChannels does it. You can also upload M3U files now, which is much easier than before, where you had to connect to a server and copy it over, maybe over SCP or over SFTP. Pre-roll is also handled through a browser upload function, which is much nicer and can be deleted through a browser upload function.

Same thing for custom scripts. You have to have the package of three, but you can set the path, like the streaming device and streaming app, right in the GUI and upload the three script files. And it creates the folders for you and chmods them and puts them in the scripts directory. And you can then choose it from the list.

Something I need an Apple TV user to graciously test if possible, I added a pairing interface for pyatv. When you get the code on your Apple TV, you just pop it right into the screen in ah4c. This is supposed to reduce friction, hopefully, but I just need to know that it definitely works. I have not been able to test it myself. In theory, it should work because I wrote tests to hopefully exercise it as much as I can. But having a real world example of it working would be nice to know. If it does not work, I would be happy to debug with whoever decides to test it and obviously push a test container myself to make sure it's working to not leave anyone stranded.

Lastly, there's a wizard for initial setup that guides you through setting your IP addresses, like for Channels DVR and the proxy address, along with some helpful pointers to make it easier for new folks. When you choose to not manage tuners through the environment variables, you set them completely in the GUI, which is really nice. And you can also check connectivity with the click of a button, which I prefer because it lets you know that it's connected. It also runs adb connect on Android devices, so you'll get that prompt to authorize them right away.

One piece of feedback I can use should we have an easily accessible button to rerun the wizard?

Currently, if you type http://MY_IP/7654/settings?wizard=1 i'll take you back to the wizard right away, but I can easily just program a little button to do that. I don't know if people find it useful enough for that to be a persistent option, or if it's just good one time. The reasoning is with the end of the cable card coming, I want to position AH4C to become a really easy-to-use tool for people who might not be as tech-savvy. So that was why I decided to design a first-time setup wizard to kind of get them acquainted with how HDMI encoders work and just the basics of setting the tool up.

Personally, I think managing it through the interface in settings is much easier than the environment variables, so I would definitely encourage everyone to try. The worst part of it is just switching your Docker Compose out and just plugging in your tuner and encoder addresses again. You don't really need to reauthorize them because that should all be saved in the bind mounts. So they'll just connect right away once you plug them in. It has to populate a settings.json file stored in /opt/config. Rather than setting your environment variables, you just tweak your settings right in the user interface. It will let you know if you have to restart the container, which it will easily do for you in the user interface. You don't have to go back out into your Docker manager and restart it. It'll automatically reload when the container is back up, which is super nice. Lastly, if there are active tunes, it will warn you before you restart the container, so you can defer or choose to restart immediately. I also added the option to easily graphically reorder tuners and encoders. If anyone wants the way that's done tweaked, please let me know. I initially tried drag and drop, but it was just way too wonky and seemed hard if you had a lot of encoders, so I just changed it to a numbered setup where no two numbers can collide.

The other thing is if you have the variable NUMBER_TUNERS set in any way, even set to zero, the container assumes that your tuners are managed through environment variables and just blocks out managing tuners through the interface. So don't set that. But if you don't have that set and start setting tuners through the environment variables, they're ignored. Something has to gate it, and I decided that was the best way to gate it off. If you're doing it through the interface, they're manually counted by the logic of the software, so there's really nothing else to do other than just input your number of tuners and it'll handle populating that. Initially, tried a mixed setup where you can maybe have some tuners manage through environment variables and some not, but that's just illogical, I felt like, and just going to lead to race conditions and issues.

You can, however, set things through environment variables for the most part and set certain things through the interface depending on what you want blocked off and what you want to control graphically. I would think most people would want to control most things in the GUI because it's so much easier. And that settings.json you can easily back up and restore. It's just stored in a bind mount on your server. I think it makes it a lot easier, especially setting up tuners and encoders. You can clearly see which tuner maps to which encoder, maps to which CMD command, etc.

Please do provide feedback, let me know what you think, and I can always expand on this, tweak things, add more things, whatever people like, I will do. I just want this to be the most flexible option for running Channels with HDMI encoders out there. This is also the beauty of free open source software. Anyone can kind of contribute, and we can kind of get a whole community rallied around something, and I love that personally.

2 Likes

so I've about had it with docker for windows. same old problems with reboots not starting portainer. an now tonight after windows update and docker update I'm getting this

failed to deploy a stack: compose up operation failed: Error response from daemon: ports are not available: exposing port TCP 0.0.0.0:7654 -> 127.0.0.1:0: /forwards/expose returned unexpected status: 500

I got that on my previously working stack, new stack, beta stack.. no ah4c for me

@Shaggylive I had a similar issue this morning with my Immich server port. Follow these steps and I bet it will fix it (use your port number not mine from the example)

Run this in an elevated PowerShell prompt on win11pc:
"PowerShell

netsh interface ipv4 show excludedportrange protocol=tcp"

Verification: Look through the start/end ranges. If 2283 falls inside any listed range, Windows has locked that port for system/hypervisor services.

  1. Release the Port Block ImmediatelyIn your Administrator PowerShell window, run:
"PowerShell

net stop winnat"

Run the check again to verify the block cleared:

"PowerShell

netsh interface ipv4 show excludedportrange protocol=tcp"

Permanent Fix: Lock 2283 Out of Dynamic Exclusions
Windows recalculates these dynamic pools on reboot, so port 2283 could get swallowed again down the road. You can prevent Windows from ever claiming it by adding an administered exclusion for Immich:

  ```"PowerShell

net stop winnat
netsh int ipv4 add excludedportrange protocol=tcp startport=2283 numberofports=1
net start winnat"
then deploy the stack in Portainer.

This was the first time I had ever seen this happen myself.

Thanks, I knew that update affected domains, but silly me thinking i'd have no problems.. lol

anyway before I fell alseep last night I had uninstalled docker and reinstalled with CDVR WinUtil, and installed the ezstart.
saw your post this am. the port was not in use, so I created a beta stack successfully!

@mackid1993 beta's working good so far, one thing I noticed since I nuked my setup is that i was unable to view/control the new tuners to authorize until I rebooted the stack.
also one of my recording locked a tuner before I could turn on CC, so I had to release it a couple times for cdvr to give up and let me turn CC on. however the tuner was still showing in use (in ah4c) even though cdvr was not recording it. I had to restart the stack again.
I could use a button for that in GUI, instead I had to change a setting and save to get a restart stack prompt.

ALSO, THANK YOU FOR FINDING A WAY TO UPLOAD M3U, terminal was a pain.!!!!!! :+1:

bnhf/ah4c:beta2 pushed this morning, with minor fixes and polish.

@Shaggylive

beta's working good so far, one thing I noticed since I nuked my setup is that i was unable to view/control the new tuners to authorize until I rebooted the stack.

This is expected.

also one of my recording locked a tuner before I could turn on CC, so I had to release it a couple times for cdvr to give up and let me turn CC on. however the tuner was still showing in use (in ah4c) even though cdvr was not recording it. I had to restart the stack again.

This is also expected. Channels reacquires the tuner of a recording in progress. I'm going to add some helper text to just let people know about that.

Then I'm also going to add a container restart button to the settings page just to make it easy.

Hopefully, it's going to be a very small diff, maybe @bnhf can add a quick update to that Beta 2 tag. I believe it's just going to be helper stuff at this point in the HTML portion. Not really any backend code changes.

I will also give you guys a test container right here to kind of try and just let me know if it works well. Just give me a couple of minutes and I'll update this post once I'm certain it looks good.

I have some cool new stuff coming, so there's going to be, for sure, a restart container button on the settings page.

Then, what I plan on is on the activity page, /status it will show whether a tuner is just live streaming or recording. When you release that tuner, it will let you release it right away. If it's live streaming or if it's recording, it will tell you, hey, you can stop the recording and prompt you to do so within ah4c.

@Shaggylive try pulling mackid1993/ah4c:beta or latest both are the same. Let me know how this works for you. Should be much more user friendly. Opening a PR now.

1 Like