R
Rüdiger Küpper
fix: [vo/gpu/libplacebo] vk->CreateSwapchainKHR(...): VK_ERROR_OUT_OF_HOST_MEMORY [vo/gpu/…
2f4d870b
vor 11 Tagen
scripts/diagnose.sh
193 Zeilen · 7.4 KB · Shell
| 1 | |
| 2 | # =========================================================================== |
| 3 | # TV-Wall - Selbsttest. Sammelt alles, was man zur Fehlersuche braucht. |
| 4 | # |
| 5 | # Aufruf: sudo /opt/tvwall/scripts/diagnose.sh |
| 6 | # =========================================================================== |
| 7 | set -uo pipefail |
| 8 | |
| 9 | CONF="${1:-/etc/tvwall/tvwall.conf}" |
| 10 | |
| 11 | hdr() { printf '\n\033[1;36m── %s ─────────────────────────────────────\033[0m\n' "$*"; } |
| 12 | ok() { printf '\033[1;32m ✓\033[0m %s\n' "$*"; } |
| 13 | bad() { printf '\033[1;31m ✗\033[0m %s\n' "$*"; } |
| 14 | warn() { printf '\033[1;33m !\033[0m %s\n' "$*"; } |
| 15 | note() { printf ' %s\n' "$*"; } |
| 16 | |
| 17 | RUN_USER="tvwall"; DISPLAY_MODE="auto"; STATE_DIR="/var/lib/tvwall"; AP_SSID="?" |
| 18 | if [[ -f "$CONF" ]]; then |
| 19 | set -a; . "$CONF" 2>/dev/null; set +a |
| 20 | fi |
| 21 | RUN_USER="${RUN_USER:-tvwall}" |
| 22 | DISPLAY_MODE="${DISPLAY_MODE:-auto}" |
| 23 | STATE_DIR="${STATE_DIR:-/var/lib/tvwall}" |
| 24 | |
| 25 | hdr "System" |
| 26 | note "$(. /etc/os-release 2>/dev/null && echo "$PRETTY_NAME")" |
| 27 | note "Kernel: $(uname -srm)" |
| 28 | note "Modell: $(tr -d '\0' < /proc/device-tree/model 2>/dev/null || echo unbekannt)" |
| 29 | note "Standard-Ziel: $(systemctl get-default 2>/dev/null)" |
| 30 | |
| 31 | hdr "Konfiguration ($CONF)" |
| 32 | if [[ -f "$CONF" ]]; then |
| 33 | note "DISPLAY_MODE = $DISPLAY_MODE" |
| 34 | note "RUN_USER = $RUN_USER" |
| 35 | note "STATE_DIR = $STATE_DIR" |
| 36 | note "AP_SSID = ${AP_SSID:-?}" |
| 37 | else |
| 38 | bad "Konfigurationsdatei fehlt" |
| 39 | fi |
| 40 | |
| 41 | hdr "Programme" |
| 42 | for p in mpv ffmpeg nmcli; do |
| 43 | if command -v "$p" >/dev/null; then ok "$p: $(command -v "$p")"; else bad "$p fehlt"; fi |
| 44 | done |
| 45 | if [[ -x /usr/local/bin/tvwall ]]; then |
| 46 | ok "tvwall: $(/usr/local/bin/tvwall -version 2>/dev/null || echo vorhanden)" |
| 47 | else |
| 48 | bad "/usr/local/bin/tvwall fehlt" |
| 49 | fi |
| 50 | |
| 51 | hdr "Dienst" |
| 52 | if systemctl is-active --quiet tvwall; then ok "tvwall laeuft"; else bad "tvwall laeuft NICHT"; fi |
| 53 | if systemctl is-enabled --quiet tvwall 2>/dev/null; then ok "Autostart aktiv"; else warn "Autostart nicht aktiv"; fi |
| 54 | note "Unit-Benutzer: $(systemctl show -p User --value tvwall 2>/dev/null)" |
| 55 | note "Neustarts: $(systemctl show -p NRestarts --value tvwall 2>/dev/null)" |
| 56 | |
| 57 | hdr "Benutzer $RUN_USER" |
| 58 | if id "$RUN_USER" >/dev/null 2>&1; then |
| 59 | ok "$(id "$RUN_USER")" |
| 60 | for g in video render input; do |
| 61 | id -nG "$RUN_USER" | tr ' ' '\n' | grep -qx "$g" \ |
| 62 | && ok "in Gruppe $g" || bad "NICHT in Gruppe $g" |
| 63 | done |
| 64 | else |
| 65 | bad "Benutzer existiert nicht" |
| 66 | fi |
| 67 | |
| 68 | hdr "Bildschirm" |
| 69 | COMPOSITOR="$(pgrep -a -x 'labwc|wayfire|Xorg|Xwayland|weston|kwin_wayland' 2>/dev/null | head -3)" |
| 70 | if [[ -n "$COMPOSITOR" ]]; then |
| 71 | warn "Es laeuft eine Desktop-Oberflaeche:" |
| 72 | echo "$COMPOSITOR" | sed 's/^/ /' |
| 73 | note "-> DISPLAY_MODE muss 'desktop' oder 'auto' sein, NICHT 'drm'." |
| 74 | else |
| 75 | ok "keine Desktop-Oberflaeche aktiv (DRM/Konsole moeglich)" |
| 76 | fi |
| 77 | |
| 78 | FOUND_SESSION=0 |
| 79 | for d in /run/user/*; do |
| 80 | [[ -d "$d" ]] || continue |
| 81 | socks="$(ls "$d"/wayland-* 2>/dev/null | grep -v '\.lock$' | tr '\n' ' ')" |
| 82 | [[ -z "$socks" ]] && continue |
| 83 | FOUND_SESSION=1 |
| 84 | u="$(getent passwd "$(basename "$d")" | cut -d: -f1)" |
| 85 | ok "Wayland-Sitzung von '$u': $socks" |
| 86 | if [[ "$u" != "$RUN_USER" ]]; then |
| 87 | bad "Der Dienst laeuft als '$RUN_USER', die Sitzung gehoert aber '$u'." |
| 88 | note "-> In $CONF setzen: RUN_USER=\"$u\" und DISPLAY_MODE=\"desktop\"" |
| 89 | note "-> danach: sudo /opt/tvwall/install.sh --no-ap" |
| 90 | fi |
| 91 | done |
| 92 | ls /tmp/.X11-unix/X* >/dev/null 2>&1 && { ok "X11-Sitzung vorhanden: $(ls /tmp/.X11-unix/)"; FOUND_SESSION=1; } |
| 93 | [[ $FOUND_SESSION -eq 0 ]] && note "keine Desktop-Sitzung gefunden" |
| 94 | |
| 95 | for dev in /dev/dri/card*; do |
| 96 | [[ -e "$dev" ]] && note "$(ls -l "$dev")" |
| 97 | done |
| 98 | |
| 99 | hdr "Medien" |
| 100 | if [[ -d "$STATE_DIR/media" ]]; then |
| 101 | COUNT="$(find "$STATE_DIR/media" -maxdepth 1 -type f | wc -l | tr -d ' ')" |
| 102 | ok "$COUNT Datei(en) in $STATE_DIR/media" |
| 103 | ls -lh "$STATE_DIR/media" 2>/dev/null | tail -n +2 | head -10 | sed 's/^/ /' |
| 104 | [[ "$COUNT" == "0" ]] && warn "Ordner ist leer - dann bleibt der Bildschirm schwarz." |
| 105 | else |
| 106 | bad "$STATE_DIR/media fehlt" |
| 107 | fi |
| 108 | [[ -f "$STATE_DIR/playlist.m3u" ]] && note "Playliste: $(($(wc -l < "$STATE_DIR/playlist.m3u") - 1)) Eintraege" |
| 109 | |
| 110 | if command -v ffprobe >/dev/null; then |
| 111 | echo |
| 112 | note "Videodateien im Detail:" |
| 113 | shopt -s nullglob nocaseglob |
| 114 | for f in "$STATE_DIR"/media/*.{mp4,m4v,mov,mkv,avi,webm,mpg,mpeg,wmv,flv,ts,3gp,ogv}; do |
| 115 | V="$(ffprobe -v error -select_streams v:0 \ |
| 116 | -show_entries stream=codec_name,width,height,avg_frame_rate \ |
| 117 | -of csv=p=0 "$f" 2>/dev/null)" |
| 118 | D="$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$f" 2>/dev/null)" |
| 119 | printf ' %-28s %s %ss\n' "$(basename "$f")" "${V:-?}" "${D%%.*}" |
| 120 | W="$(echo "$V" | cut -d, -f2)" |
| 121 | C="$(echo "$V" | cut -d, -f1)" |
| 122 | if [[ -n "$W" ]] && (( W > 1920 )); then |
| 123 | warn " ${W}px breit - fuer den Pi zu gross, bitte auf 1920 herunterrechnen" |
| 124 | fi |
| 125 | if [[ "$C" == "hevc" || "$C" == "h264" ]] && [[ "${MPV_HWDEC:-no}" != "no" ]]; then |
| 126 | warn " MPV_HWDEC=${MPV_HWDEC} - auf dem Pi 5 bleibt $C damit haengen." |
| 127 | note " -> MPV_HWDEC=\"no\" in $CONF setzen" |
| 128 | fi |
| 129 | done |
| 130 | shopt -u nullglob nocaseglob |
| 131 | fi |
| 132 | |
| 133 | hdr "Ton" |
| 134 | if command -v mpv >/dev/null && id "$RUN_USER" >/dev/null 2>&1; then |
| 135 | RUN_UID="$(id -u "$RUN_USER")" |
| 136 | DEVS="$(sudo -u "$RUN_USER" XDG_RUNTIME_DIR="/run/user/$RUN_UID" \ |
| 137 | timeout 10 mpv --audio-device=help 2>/dev/null | grep -v "^ *'auto'" | head -8)" |
| 138 | if [[ -n "$DEVS" ]]; then |
| 139 | ok "mpv sieht diese Audiogeraete:" |
| 140 | echo "$DEVS" | sed 's/^/ /' |
| 141 | else |
| 142 | warn "mpv findet kein Audiogeraet - Videos mit Tonspur koennen dadurch haengen bleiben." |
| 143 | note "-> In $CONF setzen: AUDIO=\"no\"" |
| 144 | fi |
| 145 | note "Aktuell eingestellt: AUDIO=${AUDIO:-yes} MUTE=${MUTE:-no}" |
| 146 | fi |
| 147 | |
| 148 | hdr "Webinterface" |
| 149 | PORT="${WEB_PORT:-80}" |
| 150 | CODE="$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:$PORT/healthz" 2>/dev/null)" |
| 151 | if [[ "$CODE" == "200" ]]; then |
| 152 | ok "erreichbar auf Port $PORT" |
| 153 | curl -s "http://127.0.0.1:$PORT/api/state" 2>/dev/null \ |
| 154 | | tr ',' '\n' | grep -E '"(running|display|current|last_error)"' | sed 's/^/ /' |
| 155 | else |
| 156 | bad "nicht erreichbar auf Port $PORT (HTTP $CODE)" |
| 157 | fi |
| 158 | |
| 159 | hdr "Access Point" |
| 160 | if command -v nmcli >/dev/null; then |
| 161 | nmcli -t -f NAME,DEVICE,STATE connection show --active 2>/dev/null | sed 's/^/ /' |
| 162 | nmcli -t -f NAME connection show --active 2>/dev/null | grep -qx tvwall-ap \ |
| 163 | && ok "tvwall-ap aktiv" || warn "tvwall-ap nicht aktiv" |
| 164 | fi |
| 165 | |
| 166 | hdr "Bildausgabe" |
| 167 | SWAP="$(journalctl -u tvwall --since "-30 min" --no-pager 2>/dev/null | grep -ci swapchain)" |
| 168 | if [[ "${SWAP:-0}" -gt 0 ]]; then |
| 169 | bad "$SWAP Swapchain-Fehler in den letzten 30 Minuten" |
| 170 | note "Die Vulkan-Anbindung von mpv laeuft auf dem Pi 5 nach wenigen" |
| 171 | note "Bildwechseln aus dem Speicher: der Bildschirm friert ein, waehrend" |
| 172 | note "das Webinterface weiterzaehlt." |
| 173 | note "-> In $CONF setzen: MPV_GPU_API=\"opengl\" und Dienst neu starten" |
| 174 | else |
| 175 | ok "keine Swapchain-Fehler (MPV_GPU_API=${MPV_GPU_API:-opengl})" |
| 176 | fi |
| 177 | |
| 178 | hdr "Letzte Protokollzeilen" |
| 179 | journalctl -u tvwall -n 40 --no-pager 2>/dev/null | sed 's/^/ /' |
| 180 | |
| 181 | hdr "Direkter mpv-Test" |
| 182 | FIRST="$(find "$STATE_DIR/media" -maxdepth 1 -type f 2>/dev/null | head -1)" |
| 183 | if [[ -n "$FIRST" ]]; then |
| 184 | note "So laesst sich mpv unabhaengig vom Dienst pruefen:" |
| 185 | note " sudo systemctl stop tvwall" |
| 186 | if [[ -n "$COMPOSITOR" ]]; then |
| 187 | note " sudo -u $RUN_USER XDG_RUNTIME_DIR=/run/user/\$(id -u $RUN_USER) mpv --fullscreen '$FIRST'" |
| 188 | else |
| 189 | note " sudo -u $RUN_USER mpv --vo=gpu --gpu-context=drm --fullscreen '$FIRST'" |
| 190 | fi |
| 191 | note " sudo systemctl start tvwall" |
| 192 | fi |
| 193 | echo |