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

In general, the network apps are all buggy and poorly supported by the networks. Providers such as YouTube TV, Hulu Live, Sling, Fubo, and Philo have much better apps that respond well to loading content via URLs.

As you know, no deep links with DTV, but ah4c does a great job with that!

1 Like

Actually we do now have deeplinks for DTV, but they're a bit tricky to capture and are more variable based on subscriber plan and location than some of the other streaming services. They were working with ADBTuner, but a recent app update seems to have killed that compatibility -- so the net result is pretty much the same as you said, which is that ah4c remains the way to go with DTV.

I wasn't sure if you meant having another device streaming a 2nd channel or changing to another channel on the same device. I tested both ways and can confirm it works. On the same device, I see it cycling to different Fire Sticks when I change channels (I have 3). I also tested with just one Fire Stick and that also worked fine. It takes 5-10 seconds for a channel to load.

Thanks @turtletank for the information! I thought I was going crazy or something. I will just for now manually back out and go back into it.

Yeah, the issue was usually caused by changing to another Philo channel on the same device. That's great that it is fixed.

Is there a way to stop Philo from picking up where it left off when going back to a channel? It's kind of annoying. I think it gives you the option if you manually go back to the channel, but not when using ADBTuner. This isn't the start from the beginning thing - it's where I'll watch a channel, leave for a while, then when I go back it picks up where it left off.

Hi there,
did you set your account to play from live rather than starting from beginning in account settings?
I'm using my two Android ONN boxes and it seems to work ok here.

Yes, I specified that in the last sentence. This is when you leave a channel for a few minutes, then go back to that channel. It's like you paused it, left for a while, then came back and pressed play. I don't know if that's because I don't have compatibility enabled, but it stops working if I enable compatibility mode.

Anyone else have Philo with compatibility mode off?

1 Like

I just took a look at this and I'm actually seeing this behavior with compatibility mode on as well. It seems if you load a show you were previously watching it will default to resume regardless of if you have closed the app or not. I need to test this further to confirm, but I think it goes to live if the selected channel has begun showing a different program.

At the moment I don't have any recommendations on how to work around this. There is no setting that can be changed to alter this behavior and I don't see an effective way to trigger the "jump to live" action.

Thank you for checking into it. I was starting to think I was losing my mind. Seems to happen even if it doesn't pick the same Fire Stick when going back to the channel. Hoping there will be an eventual fix.

@turtletank ADBTuner has been working great. I typically don't watch live TV but with the Olympics on I find myself watching it more. The issue that I am having is with buffering. I watch a live channel and usually I get 2-3 pauses randomly. If I pause the stream for a couple of seconds then it works perfect. When I look at the stats I see that there are buffer pauses recorded. I also see that the buffer is under 1MB and when I pause for a few seconds this increases and then the problem is gone. As a test I opened up a stream from my mlb docker and it's buffer is ~10MB right at the start. I also see in the logs that Channels is showing that it has a ~5sec live delay which probably accounts for the larger buffer.

Is there any way that ADBTuner could do the same thing? Or maybe have a parameter that we can change to increase this?

Thanks for all your hard work :slight_smile:

2024/08/10 18:30:27.971760 [TNR] Opened connection to M3U-LinkPi for ch5810 USA
2024/08/10 18:31:07.366286 [SNR] Buffer statistics for 10.100.12.78 (Seth's Office ATV) for ch5810 USA: buf=0% drop=0%
2024/08/10 18:31:07.366479 [TNR] Closed connection to M3U-LinkPi for ch5810 USA
2024/08/10 18:31:23.597253 [M3U] stream timestamps: 2_MLBTV.NYY: start_at=2024-08-10T16:28:42-04:00 end_at=2024-08-10T18:31:13-04:00 live_delay=5.799252147s
2024/08/10 18:31:23.597389 [TNR] Opened connection to M3U-mlbtvservernew for ch1016 Yankees
2024/08/10 18:32:00.028126 [SNR] Rewriter statistics for 10.100.12.78 (Seth's Office ATV) for ch1016 Yankees: discontinuity_detected=0 transport_errors=0 saw_pcr=true saw_pmt=true highest_pts=44.394356
2024/08/10 18:32:00.028514 [SNR] Buffer statistics for 10.100.12.78 (Seth's Office ATV) for ch1016 Yankees: buf=0% drop=0%
2024/08/10 18:32:00.028821 [SNR] Streaming statistics for 10.100.12.78 (Seth's Office ATV) for ch1016 Yankees: timeouts=0 segment_timeouts=0 playlist_timeouts=0
2024/08/10 18:32:00.065847 [TNR] Closed connection to M3U-mlbtvservernew for ch1016 Yankees

I seem to be having a Problem I am getting this error ...

2024/08/24 10:20:14.588915 [ERR] Failed to start stream for ch851: M3U: GET: http://192.168.50.162:5592/stream/1: 500 Internal Server Error
2024/08/24 10:20:14.588915 [HLS] Couldn't generate stream playlist for ch851-dANY-ip192.168.50.186: M3U: GET: http://192.168.50.162:5592/stream/1: 500 Internal Server Error
2024/08/24 10:20:14.589432 [HLS] Stopping transcoder session ch851-dANY-ip192.168.50.186 (out=0s finished=false first_seq=0 last_seq=-1)

Can you share the docker logs from ADBTuner?

I can look into this. In the meantime, have you tried lowering the bitrate in your encoder?

    raise exc
  File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/usr/local/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__
    raise e
  File "/usr/local/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 241, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 169, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 2177, in run_sync_in_worker_thread
    return await future
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 859, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 586, in stream_redirect
    available_tuner = tuner_manager.reserve_tuner()
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 99, in reserve_tuner
    selected_tuner = available_tuners[0]
                     ~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range
2024-08-24 17:24:53.154 - server - Available Tuners:
2024-08-24 17:24:53.154 - server - Using first available tuner (by priority).
2024-08-24 17:24:53.155 - uvicorn.access - 172.23.0.1:40064 - "GET /stream/1 HTTP/1.1" 500
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 435, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 284, in __call__
    await super().__call__(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 86, in __call__
    await self.app(scope, receive, send_wrapper)
  File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/usr/local/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__
    raise e
  File "/usr/local/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 241, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 169, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 2177, in run_sync_in_worker_thread
    return await future
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 859, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 586, in stream_redirect
    available_tuner = tuner_manager.reserve_tuner()
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 99, in reserve_tuner
    selected_tuner = available_tuners[0]
                     ~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

Thanks. A new build has been pushed with a fix for this. I failed to check if any tuners were actually available before assigning one. Oops.

No tuners available ..... I had 4 available. They disappeared ... re-adding them

2024-08-24 21:36:07.290 - server - No tuners available.
2024-08-24 21:36:07.293 - uvicorn.access - 172.23.0.1:36382 - "GET /stream/1 HTTP/1.1" 404
2024-08-24 21:36:18.444 - server - No tuners available.
2024-08-24 21:36:18.448 - uvicorn.access - 172.23.0.1:38164 - "GET /stream/1 HTTP/1.1" 404
2024-08-24 21:36:29.324 - server - No tuners available.
2024-08-24 21:36:29.326 - uvicorn.access - 172.23.0.1:56262 - "GET /stream/1 HTTP/1.1" 404
2024-08-24 21:37:06.068 - server - No tuners available.
2024-08-24 21:37:06.071 - uvicorn.access - 172.23.0.1:58410 - "GET /stream/4 HTTP/1.1" 404
2024-08-24 21:37:17.187 - server - No tuners available.
2024-08-24 21:37:17.190 - uvicorn.access - 172.23.0.1:35900 - "GET /stream/4 HTTP/1.1" 404
2024-08-24 21:37:28.098 - server - No tuners available.
2024-08-24 21:37:28.100 - uvicorn.access - 172.23.0.1:59744 - "GET /stream/4 HTTP/1.1" 404
2024-08-24 21:38:35.466 - server - No tuners available.
2024-08-24 21:38:35.467 - uvicorn.access - 172.23.0.1:35264 - "GET /stream/5 HTTP/1.1" 404
2024-08-24 21:38:46.613 - server - No tuners available.
2024-08-24 21:38:46.614 - uvicorn.access - 172.23.0.1:56904 - "GET /stream/5 HTTP/1.1" 404
2024-08-24 21:38:58.116 - server - No tuners available.
2024-08-24 21:38:58.117 - uvicorn.access - 172.23.0.1:48170 - "GET /stream/5 HTTP/1.1" 404

@turtletank ... Appears to be working after I re-added my tuners have no clue why they dissappeared.

Hmm.. Yeah the root cause for both of these errors was that there were no available tuners. It's really odd that they all disappeared like that. Please let me know if it happens again and maybe we can get some logs that might indicate how they got deleted. Thanks!

I'm considering picking up an HDMI encoder to pull in channels via YouTube TV but also the NESN 360 app. It's obviously a big investment to purchase the encoder and the Android TV devices all for a few channels.

I guess my question is, will this solution ALWAYS work or could Google change things on their end that would prevent this from not working in the future? Nearly $500 wanted if Google makes a switch.

Also, what's the most economical encoder devices for 2-3-4 inputs? I'm thinking I really just need a stream for NESN, NBC Sports, but don't want to purchase an encoder and then realize I need more later on.

Another question, are devices shareable? Meaning NESN could be watched on two devices at once. Can that stream from a single device be shared?