You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Playbook IDs: U (routing + safety)
Companion post:Fix Your NVIDIA Shield in 7 Minutes: Slow Menus, Plex "Indirect," 24p Judder
Agent prompt (paste this first)
You are applying NVIDIA Shield 2019 client fixes from this gist cluster. Stop if adb devices does not show device (not unauthorized or offline). Stop if asked to paste house IPs, SSIDs, or adapter names as required values. Stop if asked to pm uninstallcom.nvidia.ota, com.google.android.gms, or com.google.android.apps.mediashell. Substitute the reader's own IP, subnet, and adapter names. Contract: verify → apply → verify → revert. Record model, build, ABI, and app versions before changing anything.
Who this is for
2019 Shield TV or Shield TV Pro (product sif Tube, mdarcy Pro). Shield Experience 9.2.x, Android 11. You already own the box. You are not shopping for a replacement.
Safety rules (never skip)
Disable, don't uninstall. Use pm disable-user --user 0 <pkg>. Recovery is pm enable --user 0 <pkg>.
Never touchcom.nvidia.ota (updates), com.google.android.gms (Play services), com.google.android.apps.mediashell (Cast).
No Magisk, LineageOS, WAN port forwards, or factory reset as a first move.
No house values. If a command has an IP, subnet, or adapter name, it is an example. Replace it with yours.
ADB first.adb devices must say device. If it says unauthorized, accept the prompt on the TV. If it says offline, reconnect.
Pick your symptom
You see
Open this gist
Picture looks soft, or Plex says Indirect / retries only on the Shield
Write those three values down. The 2019 Tube (sif) may report armeabi-v7a (32-bit). The 2019 Pro (mdarcy) is arm64-v8a. Sideloaded APKs must match.
Network ADB, if you use it, is port 5555. Wireless debugging must be allowed on the Shield first.
How an AI tool should run these
Open the matching gist in Cursor, Claude Code, or Codex CLI. Paste that gist's Agent prompt as the first message. The agent:
Reads stop-conditions.
Verifies current state (dumpsys, settings, dashboard).
Changes one thing.
Verifies the change.
Leaves a revert command.
If a check fails, the agent stops and reports. It does not invent a next guess.
Lab scope (so you don't over-generalize)
Measured September 2026 on two 2019 Shields, Shield Experience 9.2.4. Sleep still answering Cast, set-home-activity as a no-op, and Plex Custom URLs not publishing without Remote Access are scoped findings for that build. Re-verify after any Shield OTA.
Playbook IDs: E10a (Relay / LAN Networks), E10b (retries on Shield only)
Linked from: post H2 Plex says "Indirect" or needs retries on your own network
Agent prompt (paste this first)
You are applying the Plex LAN/retry fix on a 2019 NVIDIA Shield. Stop if the Shield client and the Plex server are not on the same subnet. Before editing anything, read and record: Secure connections, LAN Networks, Relay, and the Shield's Allow insecure connections. Do not rely on Custom server access URLs while Remote Access is unmapped. Do not add WAN port forwards. Substitute the reader's subnet. Verify → apply → verify → revert.
Human, five lines
Phone and laptop play fine, Shield does not → the server is up; the path is wrong.
Fault 1 = picture is soft, Shield shows an Indirect playback warning, or the dashboard says Indirect / relayed / client 127.0.0.1.
Fault 2 = library or playback needs two or three tries, Shield only.
Fix Fault 1 on the server (LAN Networks + Relay). Fix Fault 2 on the Shield (insecure on same network).
Custom URLs may save and never publish if Remote Access is not mapped. That is not your first move.
Stop conditions
Client and server on different subnets / VLANs → stop. This gist does not do mDNS across VLANs.
LAN Networks field missing → Plex Pass network preference; stop and say so.
Asked to forward TCP 32400 on the router → stop (out of scope).
Asked to set Allow insecure connections to Always → stop. Use On same network as server only.
Verify (before any change)
A. Same-subnet check
On a PC on the LAN:
# Shield can reach the server (replace both IPs)
adb -s <shield-serial> shell ping -c 4 <server-ip>
adb -s <shield-serial> shell toybox nc -zvw 2 <server-ip> 32400
You should see replies and port 32400 open. If not, stop: this is not a Plex-settings problem.
B. Indirect check while the Shield plays
Play a movie on the Shield. An Indirect playback warning on the Shield player is already Fault 1. On a computer you can also open Plex Web → Activity → Dashboard → expand the playing card. Direct URL after you click your server in Settings (hex in the address bar between /server/ and the next /):
Already local + Direct Play, but the Shield needed 2–3 retries to get here
Fault 2
Phone also Indirect
Server/network, not Shield-only; still do Fault 1, then stop
Relay is Plex sending the movie out to the internet and back. It is capped (~1–2 Mbps depending on plan). That is why the picture goes soft. Docs: Relay, Network settings.
C. Read the three server fields (do not edit yet)
Plex Web → Settings → [server] → Network → Show Advanced, or:
Remote Access status (mapped port vs not mapped / publicPort=0)
D. Read the Shield client field
On the Shield: Plex → Settings → Advanced → Allow insecure connections
Write down the current value: Never / On same network as server / Always.
Apply — Fault 1 (soft / Indirect)
One change at a time. Save after each.
LAN Networks: enter your subnet in CIDR, for example 192.168.1.0/24. Blank means only the server's own subnet counts as local. A relayed client presents as 127.0.0.1, which is not in that subnet.
Uncheck Enable Relay unless you actually watch away from home today.
Turn on Treat WAN IP as LAN Bandwidth.
Do not start with Custom server access URLs. In the lab they saved and never published because Remote Access was unmapped (not yet mapped, publicPort=0 in the server log). Plex docs say Custom URLs inherit the Remote Access port. If Remote Access is unmapped, skip Custom URLs.
Verify — Fault 1
Force-stop Plex on the Shield, play again, expand the dashboard card.
You should now see local, not relayed, Direct Play (or video copy) for a compatible file.
Still Indirect? Stop. Next suspects live outside this gist (DNS rebinding on some routers is real, but it was ruled out in the lab where *.plex.direct resolved correctly). Do not add a router recipe here.
Ceiling check
Click the movie's ⋯ → Get Info. The file is the file. A 1482×620 source will not become 1080p. If video still says Transcode, picture-style (image-format) subtitles can force a video re-encode — change subtitle burn-in, then re-check the video decision.
Apply — Fault 2 (retries on Shield only)
On the Shield: Plex → Settings → Advanced → Allow insecure connections → On same network as server.
Settings → Apps → Plex → Force stop. Reopen Plex. Play a movie.
Verify — Fault 2
Cold-start the Shield (or Force stop Plex). Library and playback should start on the first try. Dashboard still local + Direct Play.
This setting was the whole difference between two lab Shields on the same server.
Revert
On the server: re-enable Relay if you need it; clear LAN Networks; restore Treat WAN IP as LAN to whatever you wrote down.
On the Shield: Allow insecure connections → Never.
# Plex background restriction was a false lead. If you (or a previous gist) set it:
adb -s <serial> shell cmd appops set com.plexapp.android RUN_ANY_IN_BACKGROUND default
adb -s <serial> shell cmd appops get com.plexapp.android RUN_ANY_IN_BACKGROUND
# expect: RUN_ANY_IN_BACKGROUND: default
What was ruled out (do not chase these first)
Router DNS rebinding, Windows firewall, Plex GDM UDP ports, a down VPN adapter, server load, and "the Shield IP is missing from the PMS log" (Plex does not log client IPs at default verbosity — a working phone is also absent). RUN_ANY_IN_BACKGROUND ignore on Plex did not cause or fix retries and was reverted.
Agent stop / report
If Fault 1 and Fault 2 are both already correct (local Direct Play, first-try load) → stop and say so. Do not keep editing.
Cast: sleep, ports, handshake, and Windows multicast
Playbook IDs: E2, E6, E7 (receiver), E3 (Windows sender)
Linked from: post fork line 5 and closing
Agent prompt (paste this first)
You are applying the Cast fix. Stop if dumpsys power cannot print mWakefulness. Never infer sleep from a timer. A TCP connect to 8008 or 8009 is not a completed CastV2 session. Chrome's picker is a human check — do not claim the picker works from a script. Do not name a specific virtual adapter as a required value. Discover local adapters; change only a demonstrated offender; restore saved metrics. Do not paste house IPs or Cast display names. Verify → apply → verify → revert.
Human, five lines
If your phone can cast to the Shield, the Shield is fine. The problem is the PC.
Sleep does not kill Cast on Shield Experience 9.2.4. A confirmed-asleep Shield still answered the ports and completed a Cast session, which woke the TV.
An open TCP port is not a Cast session. Session = TLS to :8009, CONNECT, PING/PONG, GET_STATUS, LAUNCH, media load.
On Windows, virtual adapters (Hyper-V, VPN, leftover Wi-Fi) can steal multicast. Inventory them. Don't guess a metric number.
Google's sample MP4 bucket now returns 403. Use a short clip on your LAN if you test media load.
Stop conditions
mWakefulness cannot be read → stop (ADB not useful).
Asked to "just disable IGMP snooping" or "uninstall Google Cast updates" as the first fix → those are untested community steps; do not lead with them.
Asked to keep the Shield awake forever → stop (OLED burn-in; also makes the sleep question moot).
Branch A — Is the Shield even the problem?
Cast from your phone to the Shield.
Phone works → Shield receiver is fine. Go to Branch C (PC / Windows).
Phone fails too → Branch B (receiver).
Branch B — Receiver (the Shield)
B1. Prove sleep with power state, not a clock
The two 2019 models can have different sleep timeouts (lab: Pro 20 min, Tube 5 min). Waiting N minutes mislabels one of them.
You should see mWakefulness=Asleep and display OFF. If you still see Awake, wait or press sleep again. Do not continue until the state is confirmed.
B2. Ports while confirmed asleep
Replace <shield-ip> with the reader's Shield IP (discover it; do not invent one):
# from a PC on the same LAN
curl -sS "http://<shield-ip>:8008/setup/eureka_info"
TCP 8008, 8009, and 8443 should still be open. eureka_info should still return 200 and a name. Ping may get slower while asleep (Wi-Fi power save). That is normal.
Scoped lab result (9.2.4): asleep Shield still answered ICMP + those three ports and still served eureka_info.
B3. Port open ≠ session
A TCP connect to :8009 only proves something is listening. CastV2 is TLS on 8009, then CONNECT, heartbeat PING/PONG, GET_STATUS, LAUNCH Default Media Receiver (CC1AD845), then media QUEUE_LOAD. Open-port-only "fixes" contradict that standard.
If you run a session test:
Do not use commondatastorage.googleapis.com/gtv-videos-bucket — it 403s.
Serve a 10-second clip from a computer on the same LAN.
Pass = TLS up, PONG, LAUNCH, MEDIA_STATUS reaches PLAYING and holds, STOP is clean.
After a session started while asleep, mWakefulness should become Awake and the display ON. Casting wakes the Shield.
B4. Chrome picker (human only)
Open Chrome on a phone or a PC that already works. Confirm the Shield name appears and a cast plays. Scripts cannot see that native picker. Report PASS/FAIL from a human.
Branch C — Sender (Windows PC)
Google's checklist already covers VPN and firewall. The extra piece: which interface multicast actually leaves from.
Write down: alias, Connected vs Disconnected, InterfaceMetric.
Look for: Hyper-V vEthernet (...), VPN adapters, phantom Wi-Fi (Disconnected but still in the metric race), VMware/WSL/Docker.
C2. Observe, then change only the offender
Raising one obvious virtual adapter's metric can be not enough. Disconnected leftover adapters can still outrank the real Wi-Fi. The lab: Hyper-V 15→100 was insufficient; phantom Wi-Fi + VPN still won.
Do not publish "set metric N" as a universal cure.
For each leftover virtual / disconnected adapter that outranks the real LAN:
Record its current InterfaceMetric.
Raise it above the real Wi-Fi metric (example: real Wi-Fi 30, leftovers 100+).
Recheck Chrome's picker.
# EXAMPLE — replace the alias with one from YOUR inventorySet-NetIPInterface-InterfaceAlias '<alias-from-inventory>'-InterfaceMetric 100
Optional: set the real LAN profile to Private if it is Public (Cast discovery likes a private profile). Use the profile name from Get-NetConnectionProfile, not a copied SSID.
C3. Verify sender
Chrome picker shows the Shield without binding tricks.
Phone still works (you didn't break the receiver).
If Chrome still fails after leftovers are outranked, stop. Next layer is router multicast / VLAN reflection — saturated, not in this gist.
Revert
# restore each metric you changed, using the numbers you wrote downSet-NetIPInterface-InterfaceAlias '<alias>'-InterfaceMetric <original>
Re-enable any adapter you disabled. Do not leave the Shield forced awake.
Untested community steps (do not lead with these)
Uninstalling Google Cast updates, clearing Cast data, disabling IGMP snooping. Incomplete in public threads. Mention only after Branches B and C fail, and label them untested here.
Playbook IDs: E8, E9
Linked from: post slow-menus teaser and closing
Agent prompt (paste this first)
You are applying the launcher swap. Stop unless a second HOME is installed and visibly running. Check ro.product.cpu.abi first: 2019 Tube (sif) may be 32-bit armeabi-v7a; 2019 Pro (mdarcy) is arm64-v8a. cmd package set-home-activity reporting Success is not proof. Confirm resolver priority. Expect stock HOME priority 2 vs Projectivy 0. Disable stock only with pm disable-user after Projectivy is on screen. Never uninstall the stock launcher or OTA. cmd role does not exist on Shield Android 11. Verify → apply → verify → revert. After any Shield OTA, re-check HOME.
Human, five lines
Install Projectivy from Play Store (not a random APK). Open it. You must see it on the TV.
set-home-activity can print Success and change nothing while stock is enabled.
Stock launcher wins because its HOME priority is 2; Projectivy is 0; FallbackHome is −1000.
Disable stock with pm disable-user only after step 1. Keep OTA enabled.
A system update can turn stock back on. Re-run the disable. Recovery is one pm enable.
Stop conditions
Projectivy not installed, or installed but not on screen → stop.
Asked to pm uninstallcom.google.android.tvlauncher or com.nvidia.ota → stop.
Tube (sif) and a 64-bit-only sideload → stop; use Play Store or a matching ABI.
Network ADB not confirmed working → stop (you need a way back if HOME breaks).
Expect: Package com.google.android.tvlauncher new state: disabled-user
Onboarding notes (match a conservative setup): allow storage and TV listings if asked; skip notification access; skip anonymous crash reporting. Projectivy's "Launcher wallpaper = Reddit" pulls images from the internet — set wallpaper to None if you don't want that. Commit the dropdown with the center button; Back cancels.
Then reboot. Pick HOME from the on-screen picker if Android asks.
After a Shield OTA
Stock can come back because it still outranks Projectivy. Re-run the pm disable-user command. Re-verify resolver. This is expected, not a failed install.
Playbook ID: E5
Linked from: post H2 24p judder and closing
Agent prompt (paste this first)
You are applying the frame-rate fix. Capture mActiveModeIdbefore playback. Claim a switch only if that mode id changes during 24p. NVIDIA Match frame rate (beta) must not be used with Plex or Kodi. There is no settings key for this feature — do not grep for one and call the job done. Dolby Vision / new-Plex-interface stutter is a different branch; stop if the mode already switched and judder remains. Verify → apply → verify → revert.
Human, five lines
Only do this if film pans actually stutter. Most people never notice.
Plex:Settings → Advanced → Refresh Rate Switching → On. It can be OFF with nobody noticing.
Do not also use NVIDIA's Quick Settings beta with Plex or Kodi. KB 4908.
Other apps: add the beta to Quick Settings, start the video, press Settings, select it. Short black screen is normal.
Prove it with dumpsys display, not a menu screenshot. Idle is often 59.94 Hz; 24p should become 23.976 or 24.
Stop conditions
Cannot capture mActiveModeId → stop.
Asked to turn on both the NVIDIA beta and Plex switching → stop. NVIDIA says not to.
Mode already 23.976/24 and pans still stutter → stop (TV motion processing or Dolby Vision; not this toggle).
No 23.976/24 modes in dumpsys display → the TV path can't switch; stop and say so.
Verify (before changing toggles)
NVIDIA's 2019 path is notDisplay & Sound → Advanced → Match content frame rate. It is Quick Settings. No ADB key exists:
adb -s <serial> shell "settings list system | grep -iE 'frame|refresh|match'"
adb -s <serial> shell "settings list secure | grep -iE 'frame|refresh|match'"
adb -s <serial> shell "settings list global | grep -iE 'frame|refresh|match'"
Empty is expected. A grep cannot prove the feature is on.
The id must differ from the idle capture. On lab TVs that meant moving off a 59.94 mode onto a 23.976 or 24.000 mode. Your TV's info panel showing 23.976/24 is also acceptable proof.
If the id did not change: the toggle didn't take, the file isn't 24p, or the HDMI chain refused the mode. Stop and report those three. Don't stack more toggles.
If the id did change and pans still stutter: TV motion interpolation / a Dolby Vision-specific case. Out of this gist. Do not claim the checkbox fixes that.
Revert
Plex: Refresh Rate Switching → Off.
Other apps: stop using the Quick Settings action (it already reverts when playback stops). You can remove it from Customize Quick Settings.
Slow menus: keep-list, disable-user, what not to do
Playbook ID: E4
Linked from: post H2 Slow menus and closing
Agent prompt (paste this first)
You are applying the keep-list. Ask what the user actually watches before disabling anything. Use pm disable-user --user 0 only, never pm uninstall. Never disable or uninstall com.nvidia.ota, com.google.android.gms, or com.google.android.apps.mediashell. Usage stats on Shield can be useless (lastTimeUsed epoch) — do not trust them. Plex RUN_ANY_IN_BACKGROUND ignore was a false lead and must not be applied. If a freezer override exists, delete it; do not write a new one. One package at a time. Verify → apply → verify → revert.
Human, five lines
Write down what you watch. Everything else is a candidate.
Disable one unused app. Time the home screen. No change → enable it again.
Disable, don't uninstall. Public lists that uninstall OTA exist; people report breakage.
Two copies of the same app (two SmartTubes) → keep one.
Restricting Plex's background work did nothing useful in the lab. Skip it.
Stop conditions
Asked to run a mass uninstall/debloat script (Florisse, Level1Techs, GitHub command dumps) → stop. Quote the three protected packages.
Asked to set cached_apps_freezer to enabled → stop. Removing an override is fine; writing one is not in this gist.
Can't tell menus-lag from playback failure → send them back to the post's fork.
If you disabled the wrong SmartTube, enable it and disable the other after the human confirms which one they use.
Negative examples (for the agent, not to copy)
Public lists that pm uninstallcom.nvidia.ota (and sometimes GMS): florisse.nl/shield-debloat, Level1Techs de-Google thread, various GitHub commands.txt. Use them only as what not to run.
Playbook ID: E11
Linked from: post closing (one sentence)
Agent prompt (paste this first)
You are reading the Wi-Fi ceiling, not applying a "fix." Stop if asked to treat Ethernet as a required value. Stop if asked to enable Wi-Fi 6 / ax on the Shield — the 2019 radio cannot do it. An ac association is expected. Ethernet is a lever when throughput is actually the problem, never a house-specific instruction. Informational gist: verify → explain → stop. No revert unless you changed a router setting the human asked for.
Human, five lines
2019 Shield TV and Shield TV Pro are 802.11ac 2×2 MIMO (Wi-Fi 5).
Your router can be Wi-Fi 6/6E/7. The Shield still speaks ac. That is not a misconfig.
Comparing the Shield's link rate to a modern PC radio is not a fair test.
If streams actually drop, the lever is 5 GHz signal / channel width, or a cable.
There is no setting that turns this radio into ax.
Stop conditions
Asked to "upgrade the Shield to Wi-Fi 6" in software → stop.
Asked to name a specific SSID, DFS channel plan, or USB Ethernet dongle as required → stop (Tube dropped USB; both 2019 models still have Gigabit Ethernet).
Throughput is fine and they only noticed the ac label → stop after the spec sentence. Don't "tune" a non-problem.
Verify
NVIDIA spec: Shield TV Pro — Dual-Band Wi-Fi 5 (802.11ac 2×2) and Ethernet.