#!/bin/bash # Läuft INNERHALB des Debian-Rootfs, aufgerufen von 03-s3-pipewire-kamera.sh. set -uo pipefail export DEBIAN_FRONTEND=noninteractive export DISPLAY=:0 export XDG_RUNTIME_DIR=/tmp/hpos-runtime export XDG_CURRENT_DESKTOP=KDE export LANG=de_DE.UTF-8 mkdir -p "$XDG_RUNTIME_DIR" && chmod 700 "$XDG_RUNTIME_DIR" echo "── Debian-Seite: virtuelle PipeWire-Kamera ──" # ── Pakete ─────────────────────────────────────────────────────────────────── # xdg-desktop-portal-kde ist der Grund, warum Plasma Mobile hier im Vorteil ist: # die GTK- und wlr-Portale können das Kamera-Portal nicht bedienen. if ! command -v pw-cli >/dev/null 2>&1; then echo "── Installiere PipeWire und GStreamer (einmalig) ──" apt-get update -qq apt-get install -y --no-install-recommends \ pipewire pipewire-pulse wireplumber pipewire-bin \ gstreamer1.0-pipewire gstreamer1.0-plugins-base gstreamer1.0-plugins-good \ gstreamer1.0-tools xdg-desktop-portal xdg-desktop-portal-kde \ || echo " ! Paketinstallation unvollständig" fi # ── PipeWire starten ───────────────────────────────────────────────────────── # Kein systemd im proot, also die Dienste von Hand — und in dieser Reihenfolge, # sonst findet WirePlumber den Daemon nicht. echo "── Dienste starten ──" pkill -f 'pipewire|wireplumber|xdg-desktop-portal' 2>/dev/null; sleep 1 if [ ! -e /run/dbus/system_bus_socket ]; then mkdir -p /run/dbus && dbus-daemon --system --fork 2>/dev/null || true fi eval "$(dbus-launch --sh-syntax)" 2>/dev/null || true pipewire >/tmp/hpos-pipewire.log 2>&1 & sleep 2 pipewire-pulse >/tmp/hpos-pw-pulse.log 2>&1 & sleep 1 wireplumber >/tmp/hpos-wireplumber.log 2>&1 & sleep 2 if pgrep -x pipewire >/dev/null; then echo " ✓ pipewire läuft"; else echo " ✗ pipewire startet nicht:"; tail -n 20 /tmp/hpos-pipewire.log | sed 's/^/ /'; exit 1 fi pgrep -x wireplumber >/dev/null && echo " ✓ wireplumber läuft" \ || echo " ! wireplumber läuft nicht — Nodes werden evtl. nicht verwaltet" /usr/libexec/xdg-desktop-portal-kde >/tmp/hpos-portal-kde.log 2>&1 & sleep 1 /usr/libexec/xdg-desktop-portal >/tmp/hpos-portal.log 2>&1 & sleep 2 pgrep -f xdg-desktop-portal >/dev/null && echo " ✓ Portal läuft" \ || echo " ! Portal läuft nicht — Firefox wird die Kamera nicht sehen" # ── Die virtuelle Kamera ───────────────────────────────────────────────────── # Im Spike steht ein Testbild statt der echten Kamera. Das ist Absicht: bewiesen # werden soll der PIPEWIRE-Weg, nicht die Bridge. Später ersetzt der Bridge-Stream # videotestsrc — sonst nichts. echo "" echo "── Virtuelle Kamera starten ──" gst-launch-1.0 -q videotestsrc pattern=ball is-live=true \ ! video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 \ ! pipewiresink mode=provide \ stream-properties="props,media.class=Video/Source,node.description=HPOS-Testkamera,node.name=hpos_kamera" \ >/tmp/hpos-kamera.log 2>&1 & GST_PID=$! sleep 4 if ! kill -0 "$GST_PID" 2>/dev/null; then echo " ✗ GStreamer sofort beendet:" tail -n 25 /tmp/hpos-kamera.log | sed 's/^/ /' echo " Häufigste Ursache: gstreamer1.0-pipewire fehlt." exit 1 fi echo " ✓ GStreamer läuft (PID $GST_PID)" # ── Nachweis, dass der Node existiert ──────────────────────────────────────── echo "" echo "── Node-Nachweis ──" if command -v wpctl >/dev/null 2>&1; then wpctl status 2>&1 | sed 's/^/ /' fi if pw-cli ls Node 2>/dev/null | grep -qi 'hpos_kamera\|HPOS-Testkamera'; then echo " ✓ Kamera-Node ist in PipeWire registriert" else echo " ! Node nicht eindeutig gefunden — vollständige Liste:" pw-cli ls Node 2>/dev/null | grep -Ei 'node.name|media.class' | sed 's/^/ /' fi # ── Firefox ────────────────────────────────────────────────────────────────── # Ohne media.webrtc.camera.allow-pipewire fragt Firefox weiterhin nur V4L2 ab und # findet folgerichtig nichts. Die Einstellung wird hier vorab ins Profil geschrieben, # damit der Test nicht an einem vergessenen Häkchen scheitert. echo "" echo "── Firefox vorbereiten ──" if ! command -v firefox >/dev/null 2>&1 && ! command -v firefox-esr >/dev/null 2>&1; then apt-get install -y --no-install-recommends firefox-esr >/dev/null 2>&1 \ || echo " ! Firefox-Installation fehlgeschlagen" fi FF=$(command -v firefox || command -v firefox-esr || true) if [ -n "$FF" ]; then PROFIL=$(find "$HOME/.mozilla/firefox" -maxdepth 1 -name '*.default*' -type d 2>/dev/null | head -1) if [ -z "$PROFIL" ]; then timeout 25 "$FF" --headless --screenshot /tmp/ff-init.png about:blank >/dev/null 2>&1 || true PROFIL=$(find "$HOME/.mozilla/firefox" -maxdepth 1 -name '*.default*' -type d 2>/dev/null | head -1) fi if [ -n "$PROFIL" ]; then { echo 'user_pref("media.webrtc.camera.allow-pipewire", true);' echo 'user_pref("widget.use-xdg-desktop-portal.camera", 1);' } >>"$PROFIL/user.js" echo " ✓ Einstellungen ins Profil geschrieben: $PROFIL" else echo " ! Kein Firefox-Profil gefunden — bitte manuell in about:config setzen:" echo " media.webrtc.camera.allow-pipewire = true" fi echo "" echo " Starte Firefox mit dem Kameratest …" "$FF" https://webcamtests.com/ >/tmp/hpos-firefox.log 2>&1 & sleep 3 echo " → In der Termux:X11-App die Quelle 'HPOS-Testkamera' auswählen." echo " Erwartet: ein springender Ball. Erscheint er, ist S3 bestanden." else echo " ! Ohne Firefox lässt sich der entscheidende Teil nicht prüfen." fi echo "" echo " Beenden mit: kill $GST_PID ; pkill -f 'pipewire|wireplumber'"