📜Skript-Bibliothek

12 kommentierte Bash-Skripte für den eigenen Fernseher. Alle binden tv-lib.sh ein, prüfen die Verbindung und sprechen genau ein Gerät an. Das Ziel steht in der Variablen TV_HOST – voreingestellt ist die Beispieladresse192.0.2.50:5555, die es in keinem echten Netz gibt.

🚀In drei Schritten startklar

Einrichten
mkdir -p ~/tv && cd ~/tv
# alle Skripte in denselben Ordner laden (tv-lib.sh muss daneben liegen), dann:
chmod +x tv-*.sh

export TV_HOST=192.0.2.50:5555   # hier die Adresse des eigenen Fernsehers eintragen
./tv-info.sh                     # erster Test: Steckbrief

Gebraucht werden nur Bash und die Android SDK Platform-Tools (das Programm adb) – unter Linux, macOS oder im WSL von Windows.

Jedes Skript erklärt sich mit --help selbst. Skripte, die etwas ändern, sind unten gelb markiert; die Aufräum-Skripte laufen ohne --apply nur im Trockenlauf.

Eine Quelle für Anzeige und Download
Der Quelltext, den du hier siehst, wird beim Bauen der App aus genau den Dateien gelesen, die der Knopf „Herunterladen“ liefert. Ein automatischer Test vergleicht beides und prüft jedes Skript mit bash -n.

📎 Quellen: Android Developers – Android Debug Bridge (adb) · RFC 5737 – IPv4-Adressblöcke für Dokumentation

📚Die Skripte

🧩

Gemeinsame Funktionen

tv-lib.sh · 114 Zeilen
Grundlageliest nur

Wird von allen anderen Skripten eingebunden: Ziel über TV_HOST, Verbindungsprüfung mit klarer Fehlermeldung (unauthorized, offline), Paketprüfung über pm list packages, sicheres Quotieren.

  • TV_HOST=tv.example.org:5555 ./tv-info.shanderes Ziel für einen einzelnen Aufruf
⬇️ Herunterladen
#!/usr/bin/env bash
# tv-lib.sh – gemeinsame Funktionen für die Android-TV-Skripte (VisualAndroidTV)
#
# Wird von den anderen tv-*.sh-Skripten eingebunden, nicht direkt gestartet:
#   . "$(dirname "$0")/tv-lib.sh"
#
# Voraussetzungen:
#   - Android SDK Platform-Tools (adb) auf dem Rechner
#   - Entwickleroptionen + USB-/Netzwerk-Debugging auf dem EIGENEN Fernseher eingeschaltet
#   - Freigabedialog „USB-Debugging zulassen?“ am Fernseher einmal bestätigt
#
# Ziel wählen (Beispieladresse aus dem Dokumentationsnetz 192.0.2.0/24):
#   TV_HOST=192.0.2.50:5555 ./tv-info.sh
#   TV_HOST=tv.example.org:5555 ./tv-info.sh

TV_HOST="${TV_HOST:-192.0.2.50:5555}"   # Adresse:Port des Fernsehers (adbd lauscht auf TCP 5555)
ADB="${ADB:-adb}"                       # Pfad zum adb-Programm
TV_USER="${TV_USER:-0}"                 # Android-Benutzer; 0 = Hauptbenutzer

tv_die()  { printf 'Fehler: %s\n' "$*" >&2; exit 1; }
tv_info() { printf '%s\n' "$*" >&2; }

# Prüft, ob adb installiert ist.
tv_need_adb() {
  command -v "$ADB" >/dev/null 2>&1 \
    || tv_die "adb nicht gefunden – Android SDK Platform-Tools installieren."
}

# Zustand des Ziels laut „adb devices“: device | offline | unauthorized | (leer)
tv_state() {
  "$ADB" devices | tr -d '\r' | awk -v h="$TV_HOST" '$1 == h { print $2 }'
}

# Stellt die Verbindung her (falls nötig) und bricht mit klarer Meldung ab, wenn sie nicht steht.
tv_connect() {
  tv_need_adb
  local state
  state="$(tv_state)"
  if [ "$state" != "device" ]; then
    "$ADB" connect "$TV_HOST" >/dev/null 2>&1 || true
    state="$(tv_state)"
  fi
  case "$state" in
    device) return 0 ;;
    unauthorized)
      tv_die "$TV_HOST ist nicht freigegeben – Dialog „USB-Debugging zulassen?“ am Fernseher bestätigen." ;;
    offline)
      tv_die "$TV_HOST ist offline – Fernseher einschalten oder „adb disconnect“ und erneut versuchen." ;;
    *)
      tv_die "Keine Verbindung zu $TV_HOST – Adresse, Netzwerk und Debugging-Einstellung prüfen." ;;
  esac
}

# adb gezielt für diesen Fernseher aufrufen.
tv_adb() { "$ADB" -s "$TV_HOST" "$@"; }

# Shell-Befehl auf dem Fernseher; -n verhindert, dass adb die Standardeingabe des Skripts verbraucht.
tv_shell() { tv_adb shell -n "$@"; }

# Wie tv_shell, aber ohne Wagenrücklauf am Zeilenende (ältere Geräte liefern \r\n).
tv_out() { tv_shell "$@" | tr -d '\r'; }

# Text für die Shell AUF DEM FERNSEHER in einfache Anführungszeichen setzen.
tv_quote() {
  local s=$1
  s=${s//\'/\'\\\'\'}
  printf "'%s'" "$s"
}

# API-Level des Fernsehers (z. B. 33 für Android 13).
tv_sdk() { tv_out getprop ro.build.version.sdk; }

# Paketlisten einmal laden (spart viele einzelne adb-Aufrufe).
TV_PKG_INSTALLED=""
TV_PKG_DISABLED=""
TV_PKG_KNOWN=""
tv_load_packages() {
  TV_PKG_INSTALLED="$(tv_out pm list packages --user "$TV_USER")"
  TV_PKG_DISABLED="$(tv_out pm list packages -d --user "$TV_USER")"
  TV_PKG_KNOWN="$(tv_out pm list packages -u --user "$TV_USER")"
}

# Zustand eines Pakets: aktiv | deaktiviert | entfernt | fehlt
#   entfernt = für den Benutzer deinstalliert, liegt aber noch im System (wiederherstellbar)
#   fehlt    = auf diesem Gerät unbekannt
tv_pkg_state() {
  local line="package:$1"
  [ -n "$TV_PKG_KNOWN" ] || tv_load_packages
  if grep -qxF -- "$line" <<<"$TV_PKG_DISABLED"; then
    echo "deaktiviert"
  elif grep -qxF -- "$line" <<<"$TV_PKG_INSTALLED"; then
    echo "aktiv"
  elif grep -qxF -- "$line" <<<"$TV_PKG_KNOWN"; then
    echo "entfernt"
  else
    echo "fehlt"
  fi
}

# Paketnamen aus einer Liste lesen: eine Zeile je Paket, # leitet Kommentare ein.
tv_read_list() {
  [ -r "$1" ] || tv_die "Liste nicht lesbar: $1"
  sed -e 's/#.*$//' -e 's/^package://' -e 's/[[:space:]]//g' "$1" | grep -v '^$' || true
}

# Nur Zeichen zulassen, die in Paketnamen vorkommen.
tv_valid_package() {
  case "$1" in
    ""|*[!A-Za-z0-9._]*) return 1 ;;
    *.*) return 0 ;;
    android) return 0 ;;
    *) return 1 ;;
  esac
}
🪪

Geräte-Steckbrief

tv-info.sh · 37 Zeilen
Diagnoseliest nur

Modell, Android-Version, API-Level, Build, Sicherheitspatch, Sprache, Auflösung, Dichte – ideal als erster Verbindungstest.

  • ./tv-info.shSteckbrief ausgeben
⬇️ Herunterladen
🎮

Fernbedienung

tv-remote.sh · 102 Zeilen
Steuerungändert etwas

Tasten per Name oder Zahl, lange drücken, Text eingeben, Lautstärke setzen, HDMI-Eingang wählen, Makros mit Wartezeiten.

  • ./tv-remote.sh key HOMEStartbildschirm
  • ./tv-remote.sh volume 10Medienlautstärke auf Index 10
  • ./tv-remote.sh macro HOME wait:1 DPAD_RIGHT DPAD_CENTERTastenfolge mit Pause
⬇️ Herunterladen
⏻

Ein, Aus, Schlaf-Timer

tv-power.sh · 40 Zeilen
Steuerungändert etwas

Aufwecken, schlafen legen, Zustand abfragen, Schlaf-Timer und Neustart.

  • ./tv-power.sh statusAwake, Asleep oder Dreaming
  • ./tv-power.sh timer 30in 30 Minuten schlafen legen
⬇️ Herunterladen
📦

Apps starten und installieren

tv-app.sh · 75 Zeilen
Appsändert etwas

Apps auflisten, über den Leanback-Starter öffnen, beenden, Vordergrund-App anzeigen, Link öffnen, APK installieren (Sideload).

  • ./tv-app.sh start com.example.tvappApp öffnen
  • ./tv-app.sh url https://example.org/Link mit ACTION_VIEW öffnen
  • ./tv-app.sh install app.apkAPK installieren oder aktualisieren
⬇️ Herunterladen
📸

Bildschirmfoto und Aufnahme

tv-screenshot.sh · 43 Zeilen
Diagnoseliest nur

PNG über adb exec-out screencap -p direkt auf den Rechner; optional Video mit screenrecord (höchstens 180 s, ohne Ton).

  • ./tv-screenshot.sh wohnzimmer.pngBildschirmfoto
  • ./tv-screenshot.sh --record 2020 Sekunden Video
⬇️ Herunterladen
💾

Paketlisten sichern

tv-backup-packages.sh · 49 Zeilen
Aufräumenliest nur

Schreibt alle, System-, eigene, deaktivierte und entfernte Pakete in einen Ordner – immer VOR dem Aufräumen ausführen.

  • ./tv-backup-packages.shOrdner tv-pakete-… anlegen
⬇️ Herunterladen
🧹

Pakete deaktivieren

tv-debloat.sh · 126 Zeilen
Aufräumenändert etwas

Trockenlauf als Standard, Paketprüfung vor jeder Aktion, Schutzliste für unverzichtbare Systempakete, Protokoll für den Rückweg.

  • ./tv-debloat.sh -f pakete.txtnur anzeigen, was passieren würde
  • ./tv-debloat.sh --apply -f pakete.txtausführen und Protokoll schreiben
⬇️ Herunterladen
↩️

Aufräumen rückgängig machen

tv-debloat-undo.sh · 67 Zeilen
Aufräumenändert etwas

Installiert entfernte Pakete wieder für den Benutzer (cmd package install-existing) und aktiviert deaktivierte (pm enable).

  • ./tv-debloat-undo.sh --apply -f tv-debloat-20261008-120000.logalles aus dem Protokoll zurückholen
⬇️ Herunterladen
🌍

Sprache lesen und setzen

tv-language.sh · 109 Zeilen
Spracheändert etwas

Systemsprache anzeigen, über eine Hilfs-App umstellen, Sprache einzelner Apps setzen (ab Android 13), Sprachmenü öffnen.

  • ./tv-language.sh getaktuelle Sprache
  • ./tv-language.sh set de-DESystemsprache Deutsch
  • ./tv-language.sh app com.example.tvapp en-USnur eine App auf Englisch
⬇️ Herunterladen
🎚️

Anzeige und Animationen

tv-tweaks.sh · 97 Zeilen
Anzeigeändert etwas

Animationsfaktoren, Bildschirmschoner- und Schlafzeit, „Aktiv lassen“, Auflösung und Dichte – mit reset.

  • ./tv-tweaks.sh animations 0.5Animationen halb so lang
  • ./tv-tweaks.sh resetAuflösung, Dichte, Animationen zurücksetzen
⬇️ Herunterladen
🛠️

Speicher, Logcat, Debugging aus

tv-maintenance.sh · 60 Zeilen
Diagnoseändert etwas

Freier Speicher, Arbeitsspeicher, App-Caches leeren, Logcat mitschneiden und zum Schluss ADB wieder ausschalten.

  • ./tv-maintenance.sh trimApp-Caches leeren
  • ./tv-maintenance.sh debug-offADB am Fernseher ausschalten
⬇️ Herunterladen

📎 Quellen: Android Developers – Android Debug Bridge (adb) · AOSP – PackageManagerShellCommand (Quelltext von „pm“) · AOSP – InputShellCommand (Quelltext von „input“) · AOSP – VolumeCtrl (Quelltext von „media volume“) · Android Developers – UI/Application Exerciser Monkey · AOSP – android.provider.Settings (Quelltext) · Android Developers – Logcat-Kommandozeile

🗂️Aufgabe → Skript → Befehl dahinter

AufgabeAufrufAndroid-Befehl dahinter
Verbindung und Status prüfen./tv-info.shadb devices · getprop
Geräte-Steckbrief (Modell, Android-Version, Build)./tv-info.shgetprop ro.product.model · ro.build.version.release · ro.build.display.id
Bildschirmfoto./tv-screenshot.shadb exec-out screencap -p > bild.png
Bildschirmaufnahme./tv-screenshot.sh --record 20screenrecord --time-limit 20 /sdcard/…mp4
App starten (Leanback-Starter)./tv-app.sh start <paket>monkey -p <paket> -c android.intent.category.LEANBACK_LAUNCHER 1
Deep-Link oder Adresse öffnen./tv-app.sh url <adresse>am start -a android.intent.action.VIEW -d <adresse>
APK installieren (Sideload)./tv-app.sh install app.apkadb install -r app.apk
Paketliste sichern./tv-backup-packages.shpm list packages [-s|-3|-d|-u]
Lautstärke setzen./tv-remote.sh volume 10media volume --stream 3 --set 10
Ein, Aus, Schlaf-Timer./tv-power.sh on|off|timer 30input keyevent KEYCODE_WAKEUP / KEYCODE_SLEEP
HDMI-Eingang wechseln./tv-remote.sh hdmi 2input keyevent KEYCODE_TV_INPUT_HDMI_2 (geräteabhängig)
Bildschirmschoner und Ruhezustand./tv-tweaks.sh screensaver 600 · sleep 3600settings put system screen_off_timeout · secure sleep_timeout
Animationen abschalten./tv-tweaks.sh animations 0settings put global *_animation_scale 0
Auflösung und Dichte, mit Reset./tv-tweaks.sh size 1280x720 · density 240 · resetwm size · wm density · wm size reset
Cache und Speicher./tv-maintenance.sh storage · memory · trimdf -h /data · dumpsys meminfo · pm trim-caches
Logcat mitschneiden./tv-maintenance.sh logcat 30adb logcat -v threadtime
Neustart./tv-power.sh rebootadb reboot
Debugging wieder ausschalten./tv-maintenance.sh debug-offsettings put global adb_enabled 0
Geräteabhängig
Kopiergeschützte Inhalte erscheinen in Bildschirmfotos schwarz. screenrecord fehlt auf manchen Fernsehern. Welche Zeitschlüssel die Oberfläche auswertet und ob sie HDMI-Tasten kennt, entscheidet der Hersteller.
Vorsicht bei wm size und wm density
Eine unpassende Auflösung macht das Bild unlesbar. ./tv-tweaks.sh reset funktioniert auch blind – halte das Terminal offen, bis das Bild wieder stimmt.

📎 Quellen: Android Developers – Android Debug Bridge (adb) · AOSP – PackageManagerShellCommand (Quelltext von „pm“) · Android Developers – UI/Application Exerciser Monkey · AOSP – android.provider.Settings (Quelltext) · AOSP – VolumeCtrl (Quelltext von „media volume“) · Android Developers – Logcat-Kommandozeile · Android Developers – android.view.KeyEvent

🤖Einbinden: cron, Home Assistant, ioBroker

⏰ cron

Zeitgesteuert auf einem Rechner im selben Netz – etwa abends ausschalten. cron kennt den Suchpfad der Anmeldeshell nicht, deshalb ADB mit vollem Pfad angeben.

cron
# m  h  Tag Monat Wochentag  Befehl
30 23 * * *  ADB=/usr/bin/adb TV_HOST=192.0.2.50:5555 /opt/tv/tv-power.sh off >/dev/null 2>&1
🏠 Home Assistant

Als shell_command lassen sich die Skripte aus Automationen aufrufen (adb muss in der Home-Assistant-Umgebung vorhanden sein). Home Assistant bringt außerdem eine eigene Integration „Android Debug Bridge“ mit, die ADB-Befehle als Aktion anbietet.

Home Assistant
# configuration.yaml
shell_command:
  tv_aus: "TV_HOST=192.0.2.50:5555 /config/tv/tv-power.sh off"
  tv_home: "TV_HOST=192.0.2.50:5555 /config/tv/tv-remote.sh key HOME"
🧱 ioBroker

Im JavaScript-Adapter mit exec() – in dessen Instanzeinstellungen muss der Befehl exec erlaubt sein.

ioBroker
// Skript im JavaScript-Adapter
exec('TV_HOST=192.0.2.50:5555 /opt/tv/tv-power.sh status', (error, stdout) => {
  if (!error) log('Fernseher: ' + stdout.trim());
});
Automationen brauchen eine dauerhafte Freigabe
Damit ein Skript ohne Zuschauer läuft, muss der Schlüssel des ausführenden Rechners am Fernseher mit „Von diesem Computer immer zulassen“ bestätigt sein – und das Debugging muss eingeschaltet bleiben. Das ist ein Dauerzugang zum Fernseher: Lies dazuSicherheit. Pfade wie /opt/tv und /config/tv sind Beispiele.

📎 Quellen: Home Assistant – Integration „Android Debug Bridge“ · Android Developers – Android Debug Bridge (adb)