DirecTV Osprey/Gemini Boxes

Look at your kernel version. Mine is Jun 10th yours is May 22nd. So I figured this out with Claude and tons of debugging.

Per my chat with Claude:
On a cold wake the DirecTV app now runs a startup → re-auth → "Your TV" home sequence. Two things gate the tune during that window:

  1. An entitlement check. The deeplink handler won't tune until the app confirms your account is active (subscribed, not paused). On a fresh wake that account state isn't loaded yet, so the tune is denied and postponed, and frequently dropped before it can be replayed.
  2. A "move to home" on wake. The box fires a HOME intent shortly after waking, which pulls the app into the "Your TV" home and auto-resumes the last channel — competing with your tune.

So wake, delay 2s tune seems to work around this.

Edit: I found a fix that preserves tuning speed going to open a pr for ah4c after I run it a few days.

main() {
  adbConnect
  adbWake
  $adbTarget shell input keyevent KEYCODE_HOME
}
#!/bin/bash
#prebmitune.sh for osprey/dtvosprey
# 2026.04.16

#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 2
    fi

    sleep 1 <------------------
    ((adbCounter++))
  done
}

adbWake() {

    $adbTarget shell input keyevent KEYCODE_WAKEUP; sleep 2;    <---------------------------------
    echo "Waking $streamerIP"
    touch $streamerNoPort/adbAppRunning

}

main() {
  adbConnect
  adbWake
}

main

I had to add the sleep 1 in adbconnect a while back and it helped, you/claude found that one.
wouldn't it make sense to change this 2nd wake command to the home key? (or the one on top, I can never remember which way the commands actually run. ( where I have <-------------)

good catch everybody, the last day or 2 i noticed a couple recording stuck not tuning correctly.

I would try taking out the sleep 1 and adding

main() {
  adbConnect
  adbWake
  $adbTarget shell input keyevent KEYCODE_HOME
}

to see if that helps. I had a box that was totally wedged and needed to manually unstick it.

Damn, more testing KEYCODE_HOME is not enough. The sleep is really needed.

main() {
adbConnect
adbWake
sleep 2
}
This is the only thing that seems to work...

edit: might even need sleep 3 now that I'm home and using my TV.

edit 1: @Shaggylive try this oneliner:

main() {
  adbConnect
  adbWake
  $adbTarget shell 'for i in $(seq 1 80); do dumpsys audio 2>/dev/null | grep -E "pack: com.att.tv.openvideo.*gain: GAIN " >/dev/null && break; dumpsys media_session 2>/dev/null | grep "PlaybackState {state=3" >/dev/null && break; sleep 0.1; done'
}

We've got two layers of redundancy it and it relies on android frameworks so DTV can't break it.

so all my boxes are still on the may22, appears any of my failed tunes are due to my internet issues, and possibly the fact the ospreys automatically enable wifi when ethernet fails. anyone know how to permanently disable the wifi?

I have actually been planning on finding the best way to verify the audio as a way to retune if none (one box sits on the same channel all day, so it really only tunes once in the morning.)
I was actually going to use the linkpi to verify the audio, but there's no reason checking both places would hurt (hopefully not delay)
tomorrow night I'll update a box and help test/verify any code you settle on by then.

1 Like

I decided I'd add your line, but not force update the ospreys. that way we can check stability with stability. that is as long as my internet stays stable. they did finally bury the neighborhood line so :crossed_fingers:

Let me know how it works. I have a draft PR open right now while I test to make sure it's somewhat stable, but I have a feeling they pushed a buggy update also.

same, I may update 1 box this weekend, but I'm going to the boundry waters next week, so I'm not sure I want to risk it. I don't have starlink on my tmobile :satellite: :camping:

anyway, while i've been playing around and seeing if the new code broke anything. (so far it has NOT ! :+1:) I did run into something I hadn't seen before, that might be showing it in action.

I was watching an ah4c channels in dvrdesk and I think one of my internet outages (router reboot) triggered a adb athorization box (but did not affect the tune)
so I was going through all the boxes and using a remote to make sure other boxes did not have a similar one hiding. I then used adb to reboot, and would change the channel in dvrdesk to grab another tuner, but this time I waited to long and it grabbed the same tuner during its bootup.
this video shows the audio being grabbed long before boot is complete. seems like proof of concept to me. :face_with_raised_eyebrow:
https://drive.google.com/file/d/1C-TkrXfY6U6AgdlbMdG8nBQ0AVU4TWqG/view?usp=drive_link

1 Like

Well, that's good that it's working.

I may have solved my issue and it was an account state related issue. I don't want to speak too soon but later this evening I will document my findings here. I finally got it to tune with no wedge and no retune 5 mins in so far.

Update:
So it seems like some sort of device registration token was out of sync with DirecTV servers from what I could tell. The symptoms were on a cold wake and immediate tune, the boxes would freeze. And on a regular warm tune that would actually successfully complete, after about five minutes, it would tear down. There would be logging related to Widevine and it would retune the channel on its own because it tore itself down.

This is such a weird edge case that I am so surprised happened, but it might be worth adding to @spammedeeper's guide as a potential troubleshooting step for weird behavior.

What you want to do is be logged into your DirecTV account on the box and then run the following ADB commands:

adb shell pm clear com.att.ngc.core
adb reboot

You don't want to factory reset the device. That didn't work for me. It only started working again once I was logged into the device and cleared that package. That did whatever server-side refresh was necessary to get my boxes working again, and I just ran that across my entire fleet.

What will happen is when they boot back up the DirecTV logo will flash rapidly and kind of freak out for a little while and then it will eventually hit the home screen and start working again. Ever since I did that, my boxes have been tuning right away. I haven't had any issues, although it did help me contribute a defensive measure to the DirecTV ah4c scripts that should help prevent mistunes.

Edit: seems like the cold tune issue is a remote feature flag that is pushed (maybe an a/b test). The delay fixes that. From what I see now I cannot produce the Widevine teardown since clearing com.att.ngc.core.

Thank you for sharing, and sorry for the delay. I will try and find some time this weekend to test.

Well, don't break your boxes on it. Only clarify that if you're having actual issues, I would say.

I think the tuning with no delay thing, which does not happen with ADB tuner because ADB Tuner automatically inserts a three-second delay by default , is a server-side feature flag that is just rolling out to everyone.

The other teardown issue I was having that was actually resolved by clearing that package. This was related to Widevine authentication sort of expiring five minutes into a stream, tearing the stream down, and then reloading the channel. I timed it to exactly five minutes. And the teardown was pretty consistent until I cleared that package out while logged into the box and then rebooted. The symptom is you're watching TV, and everything's normal, and then all of a sudden the channel reloads itself. You get the whole blue splash screen with the loading bar, and it reloads the channel.

I don't know what caused it, but it was specific to something that I did. My only guess is I was using CH4C, and I have a feeling that maybe it flagged my account or something from repeated logins or something like that. That's the only thing I could think of. I also wonder if perhaps DIRECTV pushed out some sort of weird update that invalidated some sort of server-side state in my box that just needed a refresh, which clearing that package did.

I just thought it might be helpful as a last-resort troubleshooting step to add to your guide. Like something is super broken, try this as a last-resort catch-all.

I'm currently all ADBT for the moment, and honestly have neglected my setup. My three Osprey's had to do some updates and needed a reboot. Right now they seem to be working fine, but I will keep this in mind, but add your notes to the FAQ!

1 Like

I've been doing some digging because my pm clear suddenly stopped working. I found a new deeplink scheme similar to the one used by the app com.att.tv. It's dtvnow://deeplink.directvnow.com/ott/tune/live/channel/$channelName/$channelID. So far it's holding without any teardowns fingers crossed. I really need to test for a while though to be sure. If anyone is having issues it's worth a shot.

Edit: I have been watching TV all night without a single issue using this particular scheme. I have a Claude Code Ultracode session going right now, running ADB against all my boxes, logcatting everything and trying to synthesize what's going on to see if I can get a why rather than just a what.

I had it recur on one box, did the pm clear com.att.ngc.core agian and that box cleared up. I also noticed DNS queries have been going through my NextDNS resolver, similar to pi-hole. I set a DNAT rule on my Unifi to force my Ospreys to 8.8.8.8. Now I'm beginning to wonder if this only has been affecting me because it's the old adage about it always being DNS. :joy:

Has anyone figured out what the ip/home location lookup url is? I want to split tunnel my remote boxes so I don't have to send all traffic over my vpn.

I don't think that's something you could possibly do.
Maybe throw the Ospreys behind a VLAN and put the tunnel behind that.

I would be running the vpn at the router. In Unfi I can do a policy based route via destinations. I've tried various domains like att-idnes.net, directv.com, etc but have not been able to sniff the correct one.

Can't you also do policy based routing based on the source -- i.e. the LAN IP?

yes that works but I'm looking to only send the required information and have the cdn/video not go over the vpn.