ADBTuner: A "channel tuning" application for networked Google TV / Android TV devices

Move over to LinkPi thread.

I pushed a new build (20260906-4) to both stable and development this morning.

Compared to the previous development build it's just a few small bug fixes and some polish.

Compared to the last stable build it includes the following changes:

  • Updated admin user interface to make it easier to manage a large amount of tuners and/or channels
  • Added the ability to backup and restore an entire ADBTuner instance
  • Added additional capabilities to Tuning Configurations (in app docs: /ui/configurations/documentation)
  • Added (beta) feature that uses the Android remote interface to automatically re-enable ADB on Android 14 devices that disable ADB on each reboot (ex. CCWGTV). Devices that don't do this are still preferred, but this provides a reasonable path to continue using them.
  • Bug fixes and optimizations

Please let me know if you run into any issues. Thanks!

6 Likes

I’ve been using ADBTuner for quite some time with a single encoder.
As OTT channels evaporate from YouTubeTV, I’m adding a couple more encoders, and rolling every YouTube TV channel into ADBTuner. (Whether they’re available OTT or not)

Question: What are you guys doing for your channel numbering? So far I’ve been trying to follow the channel numbering that comes in from the guide data, but that lead to a channel number that doesn’t really make much sense.

  • Do you guys group all of the news channels together?
  • Do you guys group all of the sports channels together?
  • Do you guys group all of the entertainment channels together?
  • Do you alphabetize?

Just trying to think of some ways to have this make a bit more sense.

A new development build (20260907-9) was released this morning. It adds an activity feed to provide more insight into how well the application is working and to assist with troubleshooting.

Tuning logs are kept for 30 days, but are limited to the last 1,000 for those that may watch a ton of TV. Low resolution screenshots are included, but are automatically disabled if less than 500MB of storage is available in the docker volume.

2 Likes

I pushed a new development version (20260909-2) this morning. It adds a new feature I'm calling Passthrough Channels that will allow other projects to use ADBTuner's tuning resources.

It loads a remote playlist (m3u) and populates virtual ADBTuner channels with the channel fields provided by the remote playlist. These fields can then be used with custom tuning configurations.

This is new and probably needs some more work. If anyone has time to help test that would be appreciated. It works well with FastChannels "bridge" channels.

I wrote up some notes on that here:


4 Likes

I just happened to check my ADBTuner page today and while the tuners are actually working and I'm seeing channels playing through Channels DVR like normal, my latest version of ADBTuner is showing "Failed to Load Tuner Data" and to "Check the container logs for details". I tried restarting the container (I have it installed through portainer on an Ubuntu Server 26.04.1) and I even tried an entire reinstall of the container and same result. I'm attaching a picture of what I'm seeing.


And here is what my logs show:

return cls.__pydantic_validator__.validate_python(

           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^


        obj,


        ^^^^

    ...<5 lines>...

        by_name=by_name,

        ^^^^^^^^^^^^^^^^

    )

    ^

pydantic_core._pydantic_core.ValidationError: 1 validation error for TunerSchema

keep_alive

  Input should be a valid boolean [type=bool_type, input_value=None, input_type=NoneType]

    For further information visit https://errors.pydantic.dev/2.13/v/bool_type

2026-09-08 15:17:09.614 - uvicorn.access - 192.168.1.6:0 - "GET /api/v1/tuners/installed-packages HTTP/1.1" 200

2026-09-08 15:18:17.982 - stream - [Tune n2EKUqA5JN3QwumeeiqyFX] 192.168.1.36:5592 | channels-dvr/2026.09.05.0220 Go-http-client/1.1 (windows-x86_64)

2026-09-08 15:18:17.985 - stream - [Tune (n2EKUqA5JN3QwumeeiqyFX)] No active tuners found for NBC Sports Philadelphia. Reserving a new tuner.

2026-09-08 15:18:17.986 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Attempting to reserve tuner for: ['com.google.android.youtube.tvunplugged'].

2026-09-08 15:18:17.991 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Available Tuners:

2026-09-08 15:18:17.991 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Name: Google TV Priority: 1

2026-09-08 15:18:17.991 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Name: Google TV 2 Priority: 2

2026-09-08 15:18:17.991 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Using first available tuner (by priority).

2026-09-08 15:18:17.991 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Reserved Tuner: Name: Google TV Priority: 1

2026-09-08 15:18:17.991 - stream - [Tune (n2EKUqA5JN3QwumeeiqyFX)] Tuning to NBC Sports Philadelphia on Google TV

2026-09-08 15:18:17.994 - stream - [Tune (n2EKUqA5JN3QwumeeiqyFX)] Using channel configuration: Deep Links - Compatibility Mode (ADBTuner) (bb353259-17e0-4b38-a328-8629fb1ec2ca)

2026/09/08 15:18:18 [PROXY] Registered pending stream for key n2EKUqA5JN3QwumeeiqyFX

2026-09-08 15:18:18.009 - stream - [Tune n2EKUqA5JN3QwumeeiqyFX] MPEG null packets mode: Redirecting immediately to /proxy/1?requestKey=n2EKUqA5JN3QwumeeiqyFX

2026-09-08 15:18:18.009 - uvicorn.access - 192.168.1.6:0 - "GET /stream/51 HTTP/1.1" 307

2026/09/08 15:18:18 [PROXY] 192.168.1.6 -> GET "/proxy/1?requestKey=n2EKUqA5JN3QwumeeiqyFX" -> "http://192.168.1.26:8090/stream0"

2026/09/08 15:18:18 [PROXY] Starting null packet stream for key n2EKUqA5JN3QwumeeiqyFX

2026-09-08 15:18:18.181 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] ADB: 192.168.1.2 - pidof com.google.android.youtube.tvunplugged

2026-09-08 15:18:18.279 - tuning - [Tune (n2EKUqA5JN3QwumeeiqyFX)] Using https://tv.youtube.com/watch/89dEK_TTJTM to load channel.

2026-09-08 15:18:18.279 - tuning - [Tune (n2EKUqA5JN3QwumeeiqyFX)] Executing pre-tune commands: [{'type': 'ADB', 'command': 'input keyevent KEYCODE_MEDIA_STOP'}, {'type': 'ADB', 'command': "am force-stop 'com.google.android.youtube.tvunplugged'"}, {'type': 'ADB', 'command': 'sleep 2'}]

2026-09-08 15:18:18.279 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] ADB: 192.168.1.2 - input keyevent KEYCODE_MEDIA_STOP

2026-09-08 15:18:18.399 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] ADB: 192.168.1.2 - am force-stop 'com.google.android.youtube.tvunplugged'

2026-09-08 15:18:18.518 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] ADB: 192.168.1.2 - sleep 2

2026-09-08 15:18:18.518 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] ADB: Sleeping for 2.0 seconds.

2026-09-08 15:18:20.519 - tuning - [Tune (n2EKUqA5JN3QwumeeiqyFX)] Executing tune commands: [{'type': 'ADB', 'command': "am start -W -a android.intent.action.VIEW -d 'https://tv.youtube.com/watch/89dEK_TTJTM' 'com.google.android.youtube.tvunplugged'"}]

2026-09-08 15:18:20.519 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] ADB: 192.168.1.2 - am start -W -a android.intent.action.VIEW -d 'https://tv.youtube.com/watch/89dEK_TTJTM' 'com.google.android.youtube.tvunplugged'

2026-09-08 15:18:21.161 - tuning - [Tune n2EKUqA5JN3QwumeeiqyFX] Starting tune match text monitoring. Match commands: [{'match_text': ["who's watching", 'choose an account', 'edit profiles'], 'commands': [{'type': 'ADB', 'command': 'input keyevent KEYCODE_DPAD_CENTER'}], 'start_checking_after_seconds': 5}]

2026-09-08 15:18:21.600 - tuning - [Tune n2EKUqA5JN3QwumeeiqyFX] Waiting for playback start. Status: unknown

2026/09/08 15:18:23 [PROXY] Sending null packets for key n2EKUqA5JN3QwumeeiqyFX (5.001s elapsed, 65800 bytes sent)

2026-09-08 15:18:23.243 - server - 

--------------------------------------------------

Tuner "Google TV" is currently in use and locked.

Tune ID: n2EKUqA5JN3QwumeeiqyFX

Channel: NBC Sports Philadelphia

Lock Obtained: 2026-09-08 15:18:17 (0.1 minutes ago)

Last Seen: 2026-09-08 15:18:23 (0.24 seconds ago)

Bytes Transferred: 68432 (0.07MB)

Remote User Agent:

channels-dvr/2026.09.05.0220 Go-http-client/1.1 

(windows-x86_64)

--------------------------------------------------

2026-09-08 15:18:25.379 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] Detected 100.0% black pixels. Assuming HDCP is active and video is playing.

2026/09/08 15:18:25 [PROXY] Signaled stream start for key n2EKUqA5JN3QwumeeiqyFX

2026/09/08 15:18:25 [PROXY] Switching to real stream for key n2EKUqA5JN3QwumeeiqyFX after 7.381s (73 batches sent)

2026/09/08 15:18:25 [PROXY] Beginning reverse proxy for key n2EKUqA5JN3QwumeeiqyFX

2026-09-08 15:18:25.392 - tuning - [Tune n2EKUqA5JN3QwumeeiqyFX] Signaled proxy to start real stream.

2026-09-08 15:18:25.393 - tuning - [Tune n2EKUqA5JN3QwumeeiqyFX] Tuning completed after 7.41 seconds. [Tune n2EKUqA5JN3QwumeeiqyFX] Display was on, application (com.google.android.youtube.tvunplugged) was closed.

2026-09-08 15:18:25.393 - tuning - Initializing keep active command schedule for tuner Google TV (1).

2026/09/08 15:18:25 [PROXY] No keyframe found within 500ms for key n2EKUqA5JN3QwumeeiqyFX (16732 bytes buffered), flushing buffer

2026-09-08 15:18:28.750 - tuning - [Tune n2EKUqA5JN3QwumeeiqyFX] Text match result: Text to match: ["who's watching", 'choose an account', 'edit profiles']. Matches found: None.

2026-09-08 15:18:34.478 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] On screen text: '7 =o  ore jj  crp  cuetamer recnancihility praaram  pgworks.com'

2026-09-08 15:18:34.478 - tuning - [Tune n2EKUqA5JN3QwumeeiqyFX] Text match result: Text to match: ["who's watching", 'choose an account', 'edit profiles']. Matches found: None.

2026-09-08 15:18:37.068 - lib.adb - [Tune n2EKUqA5JN3QwumeeiqyFX] Detected 100.0% black pixels. Assuming HDCP is active and video is playing.

2026-09-08 15:18:37.070 - tuning - [Tune n2EKUqA5JN3QwumeeiqyFX] Media playback detected. Stopping tuning text match process.

2026-09-08 15:18:53.258 - server - 

--------------------------------------------------

Tuner "Google TV" is currently in use and locked.

Tune ID: n2EKUqA5JN3QwumeeiqyFX

Channel: NBC Sports Philadelphia

Lock Obtained: 2026-09-08 15:18:17 (0.6 minutes ago)

Last Seen: 2026-09-08 15:18:53 (0.26 seconds ago)

Bytes Transferred: 19687924 (18.78MB)

Remote User Agent:

channels-dvr/2026.09.05.0220 Go-http-client/1.1 

(windows-x86_64)

--------------------------------------------------

2026-09-08 15:19:02.056 - tuner_management - Releasing tuner 1 as it has been inactive for 8 seconds.

2026-09-08 15:19:02.056 - tuner_management - Releasing tuner: {'lock_obtained': 1788880697, 'tuner_name': 'Google TV', 'name': 'NBC Sports Philadelphia', 'number': 48, 'provider_name': 'YouTube TV', 'tuner_id': 1, 'channel_id': 51, 'tuning_status': 'tuned', 'request_key': 'n2EKUqA5JN3QwumeeiqyFX', 'target_package': 'com.google.android.youtube.tvunplugged'}

2026-09-08 15:19:02.209 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Using configuration: Deep Links - Compatibility Mode (ADBTuner) (bb353259-17e0-4b38-a328-8629fb1ec2ca) for channel cleanup.

2026-09-08 15:19:02.209 - tuner_management - Post tune commands: [{'type': 'ADB', 'command': "am force-stop 'com.google.android.youtube.tvunplugged'"}, {'type': 'ADB', 'command': 'input keyevent KEYCODE_HOME'}]

2026-09-08 15:19:02.209 - lib.adb - [Pool 1] ADB: 192.168.1.2 - am force-stop 'com.google.android.youtube.tvunplugged'

2026-09-08 15:19:02.370 - lib.adb - [Pool 1] ADB: 192.168.1.2 - input keyevent KEYCODE_HOME

2026-09-08 15:19:02.776 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Released tuner (1).

2026-09-08 15:19:02.776 - tuner_management - [Tune n2EKUqA5JN3QwumeeiqyFX] Cleanup complete. Google TV (NBC Sports Philadelphia)

2026-09-08 15:19:09.108 - uvicorn.access - 192.168.1.6:0 - "GET /api/v1/tuners/installed-packages HTTP/1.1" 200

2026-09-08 15:19:17.276 - uvicorn.access - 192.168.1.6:0 - "GET /api/v1/repositories HTTP/1.1" 200

2026-09-08 15:19:17.284 - uvicorn.access - 192.168.1.6:0 - "GET /api/v1/repositories/settings HTTP/1.1" 200

2026-09-08 15:19:33.040 - tuner_operations - Starting health check for 2 tuner(s).

2026-09-08 15:19:33.040 - tuner_operations - Google TV: Starting health check.

2026-09-08 15:19:33.123 - tuner_operations - Google TV: Health check complete.

2026-09-08 15:19:33.123 - tuner_operations - Google TV 2: Starting health check.

2026-09-08 15:19:33.227 - tuner_operations - Google TV 2: Health check complete.

2026-09-08 15:19:33.243 - uvicorn.access - 192.168.1.6:0 - "GET /up HTTP/1.1" 200

2026-09-08 15:19:41.400 - uvicorn.access - 192.168.1.6:0 - "GET /api/v1/tuners/installed-packages HTTP/1.1" 200

2026-09-08 15:19:43.242 - uvicorn.access - 192.168.1.6:0 - "GET /api/v1/tuners/installed-packages HTTP/1.1" 200

2026-09-08 15:19:44.629 - uvicorn.access - 192.168.1.6:0 - "GET /api/v1/tuners/installed-packages HTTP/1.1" 200`Preformatted text`

Not quite sure what is going on here. Hoping someone can help me out. Thanks!
1 Like

Can you pull the updated version (20260909-9) and let me know if this is fixed?

1 Like

Working good now with version 20260909-10 Thanks!