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

I'll fix that piece on FC side.

1 Like

I’m seeing this issue while attempting to record using ADBTuner/FruitDeepLinks in a scheduled recording. These are not from a pass but a manually scheduled recording. I normally schedule about 2 days out and that has worked flawlessly until recently. In this case, when I scheduled it was slated for ESPN 261. The tuner does what it was asked and attempts to record on 261; the issue is that the game has switched to 211.

I’m going to try and set an advanced pass and see if that allievates the issue. Any other potential checks that I can do?

incorrect tune

2026-09-15T23:30:00.421153533Z 2026-09-15 23:30:00.420 - stream - [Tune Yyxwj8cRVeqjM2N78vQpfA] 10.0.1.65:5592 | channels-dvr/2026.09.14.0210 Go-http-client/1.1 (linux-x86_64)
2026-09-15T23:30:00.564268007Z 2026-09-15 23:30:00.564 - stream - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] No active tuners found for ESPN 261. Reserving a new tuner.
2026-09-15T23:30:00.565362396Z 2026-09-15 23:30:00.565 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Attempting to reserve tuner for: ['com.espn.gtv', 'com.espn.score_center'].
2026-09-15T23:30:00.572019863Z 2026-09-15 23:30:00.571 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Available Tuners:
2026-09-15T23:30:00.572392404Z 2026-09-15 23:30:00.572 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Name: Encoder 4 Priority: 1
2026-09-15T23:30:00.572639330Z 2026-09-15 23:30:00.572 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Name: Encoder 5 Priority: 2
2026-09-15T23:30:00.572760183Z 2026-09-15 23:30:00.572 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Name: ONN Priority: 3
2026-09-15T23:30:00.572822503Z 2026-09-15 23:30:00.572 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Using first available tuner (by priority).
2026-09-15T23:30:00.573452515Z 2026-09-15 23:30:00.572 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Reserved Tuner: Name: Encoder 4 Priority: 1
2026-09-15T23:30:00.573955540Z 2026-09-15 23:30:00.573 - stream - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] Tuning to ESPN 261 on Encoder 4
2026-09-15T23:30:00.652125296Z 2026-09-15 23:30:00.651 - stream - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] Using channel configuration: FruitDeepLinks - ESPN+ v2.0 (FireTV and AndroidTV) (bnhf) (51af5028-092f-4ddc-b4ea-d5e5fca58cac)
2026-09-15T23:30:01.409140297Z 2026-09-15 23:30:01.408 - stream - [Tune Yyxwj8cRVeqjM2N78vQpfA] MPEG null packets mode: Redirecting immediately to /proxy/5?requestKey=Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:30:01.383238274Z 2026/09/15 23:30:01 [PROXY] Registered pending stream for key Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:30:01.409872835Z 2026-09-15 23:30:01.409 - uvicorn.access - 172.22.0.1:0 - "GET /stream/261 HTTP/1.1" 307
2026-09-15T23:30:01.434977765Z 2026/09/15 23:30:01 [PROXY] 172.22.0.1 -> GET "/proxy/5?requestKey=Yyxwj8cRVeqjM2N78vQpfA" -> "http://10.0.1.34:8090/stream3"
2026-09-15T23:30:01.435135403Z 2026/09/15 23:30:01 [PROXY] Starting null packet stream for key Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:30:01.489618693Z 2026-09-15 23:30:01.489 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - input keyevent KEYCODE_WAKEUP
2026-09-15T23:30:04.141411309Z 2026-09-15 23:30:04.141 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - pidof com.espn.gtv
2026-09-15T23:30:04.480630447Z 2026-09-15 23:30:04.475 - tuning - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] Resolving dynamic URL (http://10.0.1.65:6655/api/adb/lanes/sportscenter/261/deeplink?format=json) for channel.
2026-09-15T23:30:05.201194990Z 2026-09-15 23:30:05.200 - tuning - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] Retrieved dynamic URL data: {'deeplink': None, 'lane_number': 261, 'message': 'No event scheduled at this time', 'provider_code': 'sportscenter', 'status': 'success', 'title': None}
2026-09-15T23:30:05.201576998Z 2026-09-15 23:30:05.201 - tuning - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] Using http://10.0.1.65:6655/api/adb/lanes/sportscenter/261/deeplink?format=json&dynamic_url_json_key=deeplink to load channel.
2026-09-15T23:30:05.202074866Z 2026-09-15 23:30:05.201 - tuning - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] Executing pre-tune commands: [{'type': 'ADB', 'command': 'input keyevent KEYCODE_MEDIA_STOP'}]
2026-09-15T23:30:05.202184899Z 2026-09-15 23:30:05.202 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - input keyevent KEYCODE_MEDIA_STOP
2026-09-15T23:30:05.376919454Z 2026-09-15 23:30:05.374 - tuning - [Tune Yyxwj8cRVeqjM2N78vQpfA] Fixed delay (5s) elapsed; starting real stream.
2026-09-15T23:30:06.436124230Z 2026/09/15 23:30:06 [PROXY] Sending null packets for key Yyxwj8cRVeqjM2N78vQpfA (5.001s elapsed, 65800 bytes sent)
2026-09-15T23:30:06.483825676Z 2026/09/15 23:30:06 [PROXY] Switching to real stream for key Yyxwj8cRVeqjM2N78vQpfA after 5.049s (50 batches sent)
2026-09-15T23:30:06.483426790Z 2026/09/15 23:30:06 [PROXY] Signaled stream start for key Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:30:07.034680364Z 2026/09/15 23:30:07 [PROXY] No keyframe found within 500ms for key Yyxwj8cRVeqjM2N78vQpfA (38540 bytes buffered), flushing buffer
2026-09-15T23:30:06.483887990Z 2026/09/15 23:30:06 [PROXY] Beginning reverse proxy for key Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:30:08.255563147Z 2026-09-15 23:30:08.255 - tuning - [Tune (Yyxwj8cRVeqjM2N78vQpfA)] Executing tune commands: [{'type': 'ADB', 'command': "am start -n 'com.espn.gtv'/com.espn.startup.presentation.StartupActivity -d 'http://10.0.1.65:6655/api/adb/lanes/sportscenter/261/deeplink?format=json&dynamic_url_json_key=deeplink'"}]
2026-09-15T23:30:07.376287613Z 2026-09-15 23:30:07.375 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - reconnected after a dropped connection.
2026-09-15T23:30:08.256156824Z 2026-09-15 23:30:08.255 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - am start -n 'com.espn.gtv'/com.espn.startup.presentation.StartupActivity -d 'http://10.0.1.65:6655/api/adb/lanes/sportscenter/261/deeplink?format=json&dynamic_url_json_key=deeplink'
2026-09-15T23:30:08.350439408Z 2026-09-15 23:30:08.350 - tuning - [Tune Yyxwj8cRVeqjM2N78vQpfA] Waiting 3 seconds to allow sleeping device to setup.
2026-09-15T23:30:16.355176212Z 2026-09-15 23:30:16.354 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - sleep 20
2026-09-15T23:30:16.418823156Z 2026-09-15 23:30:16.418 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: Sleeping for 20.0 seconds.
2026-09-15T23:30:24.628643474Z 2026-09-15 23:30:24.628 - server - 
2026-09-15T23:30:24.629173051Z Tuner "Encoder 4" is currently in use and locked.
2026-09-15T23:30:24.629142926Z --------------------------------------------------
2026-09-15T23:30:24.629106726Z 
2026-09-15T23:30:24.629222667Z Tune ID: Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:30:24.629251134Z Channel: ESPN 261
2026-09-15T23:30:24.629278210Z Lock Obtained: 2026-09-15 23:30:00 (0.41 minutes ago)
2026-09-15T23:30:24.629344878Z Bytes Transferred: 4357464 (4.16MB)
2026-09-15T23:30:24.629312404Z Last Seen: 2026-09-15 23:30:24 (0.63 seconds ago)
2026-09-15T23:30:24.629373210Z Remote User Agent:
2026-09-15T23:30:24.629399179Z channels-dvr/2026.09.14.0210 Go-http-client/1.1 
2026-09-15T23:30:24.629453012Z --------------------------------------------------
2026-09-15T23:30:24.629428880Z (linux-x86_64)
2026-09-15T23:30:36.419380449Z 2026-09-15 23:30:36.418 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - input keyevent KEYCODE_DPAD_DOWN
2026-09-15T23:30:37.795505737Z 2026-09-15 23:30:37.795 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - sleep 1
2026-09-15T23:30:37.795655246Z 2026-09-15 23:30:37.795 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: Sleeping for 1.0 seconds.
2026-09-15T23:30:38.796415531Z 2026-09-15 23:30:38.795 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - input keyevent KEYCODE_DPAD_DOWN
2026-09-15T23:30:39.693650756Z 2026-09-15 23:30:39.693 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - sleep 1
2026-09-15T23:30:39.693806097Z 2026-09-15 23:30:39.693 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: Sleeping for 1.0 seconds.
2026-09-15T23:30:40.697053161Z 2026-09-15 23:30:40.696 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - input keyevent KEYCODE_DPAD_RIGHT
2026-09-15T23:30:41.573382405Z 2026-09-15 23:30:41.573 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - sleep 1
2026-09-15T23:30:41.573543871Z 2026-09-15 23:30:41.573 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: Sleeping for 1.0 seconds.
2026-09-15T23:30:42.573789894Z 2026-09-15 23:30:42.573 - lib.adb - [Tune Yyxwj8cRVeqjM2N78vQpfA] ADB: 10.0.1.54 - input keyevent KEYCODE_DPAD_CENTER
2026-09-15T23:30:43.507537060Z 2026-09-15 23:30:43.506 - tuning - [Tune Yyxwj8cRVeqjM2N78vQpfA] Tuning completed after 43.14 seconds. Display was off, application (com.espn.gtv) was closed.
2026-09-15T23:30:54.650029714Z 2026-09-15 23:30:54.649 - server - 
2026-09-15T23:30:54.650775862Z Tune ID: Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:30:54.650738652Z Tuner "Encoder 4" is currently in use and locked.
2026-09-15T23:30:54.650709156Z --------------------------------------------------
2026-09-15T23:30:54.650660476Z 
2026-09-15T23:30:54.650834179Z Lock Obtained: 2026-09-15 23:30:00 (0.91 minutes ago)
2026-09-15T23:30:54.650805119Z Channel: ESPN 261
2026-09-15T23:30:54.650902190Z Bytes Transferred: 8770388 (8.36MB)
2026-09-15T23:30:54.650867173Z Last Seen: 2026-09-15 23:30:54 (0.65 seconds ago)
2026-09-15T23:30:54.650931453Z Remote User Agent:
2026-09-15T23:30:54.650962239Z channels-dvr/2026.09.14.0210 Go-http-client/1.1 
2026-09-15T23:31:24.700623833Z 2026-09-15 23:31:24.700 - server - 
2026-09-15T23:30:54.651017893Z --------------------------------------------------
2026-09-15T23:31:24.701199539Z 
2026-09-15T23:31:24.701447673Z Remote User Agent:
2026-09-15T23:30:54.650992297Z (linux-x86_64)

Correct tune:

2026-09-15T23:51:45.873855838Z 2026-09-15 23:51:45.873 - stream - [Tune ByEKpLe8UPriUDzENiUacR] 10.0.1.65:5592 | channels-dvr/2026.09.14.0210 Go-http-client/1.1 (linux-x86_64)
2026-09-15T23:51:45.886290245Z 2026-09-15 23:51:45.886 - stream - [Tune (ByEKpLe8UPriUDzENiUacR)] No active tuners found for ESPN 211. Reserving a new tuner.
2026-09-15T23:51:45.886721077Z 2026-09-15 23:51:45.886 - tuner_management - [Tune ByEKpLe8UPriUDzENiUacR] Attempting to reserve tuner for: ['com.espn.gtv', 'com.espn.score_center'].
2026-09-15T23:51:45.889489311Z 2026-09-15 23:51:45.889 - tuner_management - [Tune ByEKpLe8UPriUDzENiUacR] Available Tuners:
2026-09-15T23:51:45.889676229Z 2026-09-15 23:51:45.889 - tuner_management - [Tune ByEKpLe8UPriUDzENiUacR] Name: Encoder 5 Priority: 2
2026-09-15T23:51:45.889722040Z 2026-09-15 23:51:45.889 - tuner_management - [Tune ByEKpLe8UPriUDzENiUacR] Name: ONN Priority: 3
2026-09-15T23:51:45.889755538Z 2026-09-15 23:51:45.889 - tuner_management - [Tune ByEKpLe8UPriUDzENiUacR] Using first available tuner (by priority).
2026-09-15T23:51:45.889827107Z 2026-09-15 23:51:45.889 - tuner_management - [Tune ByEKpLe8UPriUDzENiUacR] Reserved Tuner: Name: Encoder 5 Priority: 2
2026-09-15T23:51:45.889911180Z 2026-09-15 23:51:45.889 - stream - [Tune (ByEKpLe8UPriUDzENiUacR)] Tuning to ESPN 211 on Encoder 5
2026-09-15T23:51:45.916227915Z 2026-09-15 23:51:45.916 - stream - [Tune (ByEKpLe8UPriUDzENiUacR)] Using channel configuration: FruitDeepLinks - ESPN+ v2.0 (FireTV and AndroidTV) (bnhf) (51af5028-092f-4ddc-b4ea-d5e5fca58cac)
2026-09-15T23:51:46.156116128Z 2026/09/15 23:51:46 [PROXY] Registered pending stream for key ByEKpLe8UPriUDzENiUacR
2026-09-15T23:51:46.157690294Z 2026-09-15 23:51:46.157 - stream - [Tune ByEKpLe8UPriUDzENiUacR] MPEG null packets mode: Redirecting immediately to /proxy/6?requestKey=ByEKpLe8UPriUDzENiUacR
2026-09-15T23:51:46.227517643Z 2026-09-15 23:51:46.158 - uvicorn.access - 172.22.0.1:0 - "GET /stream/211 HTTP/1.1" 307
2026-09-15T23:51:46.227564581Z 2026-09-15 23:51:46.225 - lib.adb - [Tune ByEKpLe8UPriUDzENiUacR] ADB: 10.0.1.51 - input keyevent KEYCODE_WAKEUP
2026-09-15T23:51:46.227609762Z 2026/09/15 23:51:46 [PROXY] 172.22.0.1 -> GET "/proxy/6?requestKey=ByEKpLe8UPriUDzENiUacR" -> "http://10.0.1.34:8090/stream4"
2026-09-15T23:51:46.227655390Z 2026/09/15 23:51:46 [PROXY] Starting null packet stream for key ByEKpLe8UPriUDzENiUacR
2026-09-15T23:51:48.215219770Z 2026-09-15 23:51:48.214 - lib.adb - [Tune ByEKpLe8UPriUDzENiUacR] ADB: 10.0.1.51 - pidof com.espn.gtv
2026-09-15T23:51:48.411044414Z 2026-09-15 23:51:48.410 - tuning - [Tune (ByEKpLe8UPriUDzENiUacR)] Resolving dynamic URL (http://10.0.1.65:6655/api/adb/lanes/sportscenter/211/deeplink?format=json) for channel.
2026-09-15T23:51:49.019212384Z 2026-09-15 23:51:49.018 - tuning - [Tune (ByEKpLe8UPriUDzENiUacR)] Retrieved dynamic URL data: {'channel_id': 'sportscenter211', 'channel_name': 'ESPN+ V2', 'deeplink': 'sportscenter://x-callback-url/showWatchStream?playID=bf6e551b-7608-4b0d-b867-b8357f507e9f', 'deeplink_format': 'scheme', 'event_end_utc': '2026-09-16T01:35:00+00:00', 'event_start_utc': '2026-09-15T23:30:00+00:00', 'lane_number': 211, 'provider_code': 'sportscenter', 'start_utc': '2026-09-15T23:30:00+00:00', 'status': 'success', 'stop_utc': '2026-09-16T01:35:00+00:00', 'title': "Women's College Volleyball: Louisiana Ragin' Cajuns at Southeastern Louisiana Lions"}
2026-09-15T23:51:49.019503274Z 2026-09-15 23:51:49.018 - tuning - [Tune (ByEKpLe8UPriUDzENiUacR)] Using sportscenter://x-callback-url/showWatchStream?playID=bf6e551b-7608-4b0d-b867-b8357f507e9f to load channel.
2026-09-15T23:51:49.019566194Z 2026-09-15 23:51:49.019 - tuning - [Tune (ByEKpLe8UPriUDzENiUacR)] Executing pre-tune commands: [{'type': 'ADB', 'command': 'input keyevent KEYCODE_MEDIA_STOP'}]
2026-09-15T23:51:49.019709313Z 2026-09-15 23:51:49.019 - lib.adb - [Tune ByEKpLe8UPriUDzENiUacR] ADB: 10.0.1.51 - input keyevent KEYCODE_MEDIA_STOP
2026-09-15T23:51:50.880946905Z 2026-09-15 23:51:50.880 - tuning - [Tune ByEKpLe8UPriUDzENiUacR] Fixed delay (5s) elapsed; starting real stream.
2026-09-15T23:51:51.012136733Z 2026-09-15 23:51:51.011 - tuning - [Tune (ByEKpLe8UPriUDzENiUacR)] Executing tune commands: [{'type': 'ADB', 'command': "am start -n 'com.espn.gtv'/com.espn.startup.presentation.StartupActivity -d 'sportscenter://x-callback-url/showWatchStream?playID=bf6e551b-7608-4b0d-b867-b8357f507e9f'"}]
2026-09-15T23:51:51.012380554Z 2026-09-15 23:51:51.012 - lib.adb - [Tune ByEKpLe8UPriUDzENiUacR] ADB: 10.0.1.51 - am start -n 'com.espn.gtv'/com.espn.startup.presentation.StartupActivity -d 'sportscenter://x-callback-url/showWatchStream?playID=bf6e551b-7608-4b0d-b867-b8357f507e9f'
2026-09-15T23:51:51.134061629Z 2026-09-15 23:51:51.133 - tuning - [Tune ByEKpLe8UPriUDzENiUacR] Waiting 3 seconds to allow sleeping device to setup.
2026-09-15T23:51:51.208296696Z 2026/09/15 23:51:51 [PROXY] Sending null packets for key ByEKpLe8UPriUDzENiUacR (5.001s elapsed, 65800 bytes sent)
2026-09-15T23:51:51.213044783Z 2026-09-15 23:51:51.212 - tuner_management - Releasing tuner 5 as it has been inactive for 10 seconds.
2026-09-15T23:51:51.213240187Z 2026-09-15 23:51:51.213 - tuner_management - Releasing tuner: {'lock_obtained': 1789515000, 'tuner_name': 'Encoder 4', 'name': 'ESPN 261', 'number': 260, 'provider_name': 'sportscenter', 'tuner_id': 5, 'channel_id': 261, 'url_or_identifier': 'http://10.0.1.65:6655/api/adb/lanes/sportscenter/261/deeplink?format=json&dynamic_url_json_key=deeplink', 'tuning_status': 'tuned', 'request_key': 'Yyxwj8cRVeqjM2N78vQpfA', 'target_package': 'com.espn.gtv'}
2026-09-15T23:51:51.366857495Z 2026/09/15 23:51:51 [PROXY] Switching to real stream for key ByEKpLe8UPriUDzENiUacR after 5.16s (51 batches sent)
2026-09-15T23:51:51.366515625Z 2026/09/15 23:51:51 [PROXY] Signaled stream start for key ByEKpLe8UPriUDzENiUacR
2026-09-15T23:51:51.366984286Z 2026/09/15 23:51:51 [PROXY] Beginning reverse proxy for key ByEKpLe8UPriUDzENiUacR
2026-09-15T23:51:51.930678359Z 2026/09/15 23:51:51 [PROXY] No keyframe found within 500ms for key ByEKpLe8UPriUDzENiUacR (313020 bytes buffered), flushing buffer
2026-09-15T23:51:51.950034752Z 2026-09-15 23:51:51.949 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Using configuration: FruitDeepLinks - ESPN+ v2.0 (FireTV and AndroidTV) (bnhf) (51af5028-092f-4ddc-b4ea-d5e5fca58cac) for channel cleanup.
2026-09-15T23:51:51.950327019Z 2026-09-15 23:51:51.950 - tuner_management - Post tune commands: [{'type': 'ADB', 'command': 'input keyevent KEYCODE_MEDIA_STOP'}, {'type': 'ADB', 'command': 'input keyevent KEYCODE_MEDIA_PAUSE'}, {'type': 'ADB', 'command': 'input keyevent KEYCODE_HOME'}]
2026-09-15T23:51:55.691342684Z 2026-09-15 23:51:55.691 - server - 
2026-09-15T23:51:54.787353228Z 2026-09-15 23:51:54.786 - lib.adb - [Pool 5] ADB: 10.0.1.54 - input keyevent KEYCODE_HOME
2026-09-15T23:51:53.596599603Z 2026-09-15 23:51:53.596 - lib.adb - [Pool 5] ADB: 10.0.1.54 - input keyevent KEYCODE_MEDIA_PAUSE
2026-09-15T23:51:51.950504246Z 2026-09-15 23:51:51.950 - lib.adb - [Pool 5] ADB: 10.0.1.54 - input keyevent KEYCODE_MEDIA_STOP
2026-09-15T23:51:55.691492187Z 
2026-09-15T23:51:55.691542047Z Tuner "Encoder 4" is currently in use and locked.
2026-09-15T23:51:55.691518612Z --------------------------------------------------
2026-09-15T23:51:55.691574627Z Tune ID: Yyxwj8cRVeqjM2N78vQpfA
2026-09-15T23:51:55.691630095Z Lock Obtained: 2026-09-15 23:30:00 (21.93 minutes ago)
2026-09-15T23:51:55.691598874Z Channel: ESPN 261
2026-09-15T23:51:55.691690785Z Bytes Transferred: 616785888 (588.21MB)
2026-09-15T23:51:55.691661527Z Last Seen: 2026-09-15 23:51:41 (14.69 seconds ago)
2026-09-15T23:51:55.691718616Z Remote User Agent:
2026-09-15T23:51:55.691743885Z channels-dvr/2026.09.14.0210 Go-http-client/1.1 
2026-09-15T23:51:55.691772358Z (linux-x86_64)
2026-09-15T23:51:55.691860140Z Tuner "Encoder 5" is currently in use and locked.
2026-09-15T23:51:55.691838807Z --------------------------------------------------
2026-09-15T23:51:55.691818662Z 
2026-09-15T23:51:55.691797383Z --------------------------------------------------
2026-09-15T23:51:55.691885547Z Tune ID: ByEKpLe8UPriUDzENiUacR
2026-09-15T23:51:55.691908343Z Channel: ESPN 211
2026-09-15T23:51:55.691940129Z Lock Obtained: 2026-09-15 23:51:45 (0.18 minutes ago)
2026-09-15T23:51:55.691966318Z Last Seen: 2026-09-15 23:51:55 (0.69 seconds ago)
2026-09-15T23:51:55.691993867Z Bytes Transferred: 864424 (0.82MB)
2026-09-15T23:51:55.692039440Z channels-dvr/2026.09.14.0210 Go-http-client/1.1 
2026-09-15T23:51:55.692065862Z (linux-x86_64)
2026-09-15T23:51:55.692087777Z --------------------------------------------------
2026-09-15T23:51:55.692017457Z Remote User Agent:
2026-09-15T23:51:57.664416972Z 2026-09-15 23:51:57.664 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Released tuner (5).
2026-09-15T23:51:57.664952470Z 2026-09-15 23:51:57.664 - tuner_management - [Tune Yyxwj8cRVeqjM2N78vQpfA] Cleanup complete. Encoder 4 (ESPN 261)

Well, I've come a long way in my ADBTuner journey. Now I'm deep into understanding the nuances with the integration with Channels. I have some questions about maintenance and channel updates. I'll start with this one... Every time I upload a channel update (even if only a Gracenote ID change), my collections get stomped on and I have to rebuild it from scratch (see image below). Is this a Channels thing or an ADBTuner thing (or an operator headspace thing. :laughing:). What can I do to stop this?

Kind of all of the above. Channels follows uniqueness that is used in Channels Collections and elsewhere by the channel-id tag in the m3u playlist:

Assuming you are loading ADBTuner -> Channels DVR directly, something you are doing in ADBTuner is most likely causing the channel-ids to reset to a new value. There's not much details with what you've provided, but if you are deleting the stations and re-adding or changing certain things about them, you could be causing a change to this tag. It must be maintained for identification, and they must all be unique.

To deal with this, I also highly recommend parsing ADBTuner and all other sources like FAST stations through Playlist Manger for Channels as it will eliminate this exact situation by always having a unique and consistent channel-id for a Parent station. Yours was my exact use case where I didn't want to care anymore about what the source was and just wanted my Channel Collections to stay still without any manual maintenance.

Aha! There's my misunderstanding. Thank you, @babsonnexus. I thought the uniqueness was the "tvc-guide-stationid". So this issue definitely comes from how I've been updating ADBTuner channels.

So this leads me to another question: Does Channels match "channel-id" or "tvc-guide-stationid" to match them as the same channel when there are multiple sources with the same channel? I used to think it was "tvc-guide-stationid". But my experience has been mixed when I combine ADBTuner sources with TVE sources.

Ultimately, I want to use YouTube TV during college football season, then go back to Philo afterwards. Both using TVE for the channels that still work with it, and ADBTuner channels for non-TVE channels. Big bonus is if I don't have to re-create collections every time I go back and forth. Right now, they aren't playing nice together.

Is that something that PLM can facilitate? I see you have a video for it. I'll watch it tonight. But knowing you think it is possible will give me more motivation to proceed further. :grin:

The tvc-guide-stationid is the Gracenote ID, so it will give them the same guide data. You can have different stations with uniqueness by the channel-id with the same guide data, although usually that's unnecessary.

Yes, because PLM always has it's same "Parent" with it's own unique channel-id, it doesn't care what the underlying "Child" or "Children" stations are. Take for instance this situation with HGTV:

My default choice is to use Channels TVE through Cox/Spectrum. If that fails, it can fallback to FastChannels TVE through the same providers. If that fails, then it launches ADBTuner using HDMI Encoder Native Apps. If that fails or all my ADBTuner tuners are taken, it falls back to Roku Bridge. Finally, if that is not available, it will use PrismCast. If I had another provider like Philo or YouTube TV, I could shove them anywhere in that chain, and disable them when they're not in use and PLM would skip over them. Meanwhile, as far a Channels is concerned, it is the same HGTV with the same channel-id, so it always stays put in my Channels Collection.

1 Like

This sounds awesome. I will give it a try... after I get back from a desperately needed vacation. :beach_umbrella: I'll let you know how it goes. Thanks again.

1 Like

Hello, first thank you for all your hard work on adbtuner. It has worked great as a replacement for my Verizon cable cards. Just some background - I’m an enthusiast, not a programmer. I consider myself a really good integrator. I currently use adbtuner to interface between my Emby server and my Direct TV Gemini device. I don’t use adbtuner to send deep link commands to the DirecTV app on the Gemini. The Gemini device works more like a dedicated set top box. Using the Gemini which is based on a google TV device I can send adb input commands to change the DIRECTV channel. I modified a tuning configuration to send the input keyevents that I entered into the adbtuner channel url. As example my url for CNN channel 202 is keyevent 9 keyevent 7 keyevent 9. When the Gemini receives the input command it immediately tunes DIRECTV to channel 202 in 2 seconds or less. There is also no issues with profiles or who’s watching. This worked flawlessly in an older version of adbtuner but in more recent versions something changed in your code and I’m no longer able to build and send the adb input command. I reverted back to an older version and all is well. My ask of you is could you provide an option for us users to send adb (none deep link) commands to all turners or any specific tuners. Not only would this help my situation but it could also add great functionality to adb tuner. Such as creating channels the can change the hdmi input on a google tv etcc…. Thanks again for all your hard work and consideration.

1 Like

:exploding_head: I'm now excited to figure out the best way to wake my tv from it's screen saver when the morning news comes on and start playing it!!!

Can you share the custom tuning configuration you were using? Something like this should take the channel number from the "URL or Identifier" box and enter each digit one at a time. You can adjust any delay before entering the channel number and you can adjust the time between keypresses.

"tune_commands": [
{"ADB": {"command": "adbtuner_open_app ||TARGET_PACKAGE_NAME||"}},
	{"WAIT_FOR_FOCUS": {"package_name": "||TARGET_PACKAGE_NAME||"}},
	{"ADB": {"command": "sleep 1"}},
	{"ADB_NUMBER_INPUT_SEQUENCE": {"number": "||TARGET_URL_OR_IDENTIFIER||", "input_delay_seconds": 0.3}}
]

Hello. Thank you for responding. I have attached images of the channel setup screen and the tuning configuration - at least I hope there attached. The docker image tag for the adbtuner version that works is 20260907-5. I don't know if any later versions work, I do know that the latest version did something to the construction of the adb input command which cause the command to be ignored. I appreciate your recommended fix, but for the Gemini device you cannot send is multiple input commands. I tried that originally and the device would immediately tune to the first keyevent it received. As an example tuning to channel 202 using multiple input commands changes the channel to 2 than 0 than 2. The device needs to receive the entire number using one input statement with no delays between numbers. To change the channel on the Gemini the correct input command would be --- input keyevent 9 keyevent 7 keyevent 9 --- this sends the entire channel number 202 to the device using one input command. Hey since I have some of your attention - this thing would really rock if you could develop an interface to Home Assistant and log a channel number change as an event. The possibilities of integration would be immense. Take for instance setting mood lighting, configuring your display for best picture, turning on and configuring audio equipment all based on what channel youre viewing. Anyway just a thought. Thank you again for all your work.

Heres the second image.
Snapshot_9

1 Like

If this configuration worked as-is then replacing the "tune_command" block with the following and putting the channel number in the "URL or Identifier" box for each channel should get things working correctly.

"tune_commands": [
    {"ADB_NUMBER_INPUT_SEQUENCE": {"number": "||TARGET_URL_OR_IDENTIFIER||", "input_delay_seconds": 0.1}}
]
1 Like

Thank you. I’ll try it later today and let you know the outcome.

Works great. Thanks for fixing this and the bonus of not having to manually convert the channel numbers into keyevents.

Hello. is there a way to force a tuner to unlock using a command in the tuning configuration? Thanks

1 Like

What are you looking to solve by doing this? If a tuner isn't being unlocked when it should be that's an issue worth investigating.

Technically the answer is yes because you can hit ADBTuner's own API endpoint, but you wouldn't know which tuner id to address.

"tune_commands": [
  {
    "HTTP": {
      "method": "POST",
      "action": "http://127.0.0.1:5593/api/v1/tuners/<tuner id>/unlock",
      "timeout": 5
    }
  }
]
1 Like

Thank You turtletank!!!! WOW! WOW! not only for your code but for what it also does for me. Your code demonstrated how send HTTP post commands using your interface. With this I now have full control over all my A/V equipment, home automation system, security cameras, really anything that I own that accepts HTTP commands. This really rocks. Now based on what channels I select I can configure my sound equipment, control lighting, set display characteristics, etc... It truly rocks. Now for why i needed the unlock. When you have only one tuner configured, and you change channels, the change is delayed by approximately 7 seconds waiting for adbtuner to detect the media stream ended and release the tuner for the channel change. Releasing the tuner immediately following the channel change, allows channel change to occur without the delay. This off course is optimal for single tuner single user configurations. With multiple tuners, set at 0 priority you don't incur the delay as long as one the turners is in an idle state - but if all tuners are used you again incur the 8 second delay. Obviously not locking the tuner would open the possibility of a tuner being hijacked by a different user or a timed recording. Is there any way to unlock the tuner faster or is there a different way to prevent hijacking?
Also, when I originally reached out to you, I was working with the DirectTV streaming devices and using ADB to control/change channels on the devices. Well -- this has failed as these devices must have some protections built in for ADB. Initially you can activate Developer mode and USB debugging but after rebooting the device a few times (maybe 10) the device will no longer stream content if Developer mode is enabled. So I can no longer access the devices using ADB, but the device does accept external control. I used the Home Assistant AndroidTV plugin to access the remote features of the DirecTV device. By using some trickery I can change the channel of the DirecTv device using adbtuner. Basically I have a Onn device configured as tuner recognized by adbtuner but send a seperate command using a modified tuning configuration to Home Assistant to tune the DirecTv device. It works but it's messy. Is there any way to add a tuner without ADB access to adbtuner. As I said I can control the device but not without tricking adbtuner by using the Onn. Anything you can offer to assist is deeply appreciated. Your work is awesome.

1 Like

@turtletank Given the extent of what @Jubeejb is trying to do, any thought that ah4c might be the better project for him?

1 Like

Well I think ADBTuner is a capable little app that can do a lot of things that haven't been explored yet. As a hobbyist I'd like to see what @Jubeejb can pull off.

But yeah, if someone is looking to automate their home on each channel change then being able to run whatever code they want inside the ah4c container will certainly make it easier to achieve that goal. edit: The DirecTV thing might be easier to figure out as well.

3 Likes