Vier Beweise, die das Projekt tragen, als eigenständig lauffähige Skripte:
S1 Plasma Mobile in proot über genestetes kwin_wayland im X11-Backend.
Fällt selbsttätig auf startplasmamobile und dann auf XFCE zurück, damit
ein Fehlschlag eindeutig Plasma zuzuordnen ist und nicht der Umgebung.
S2 Mikrofon über PulseAudio mit OpenSL-Quelle. Misst den Pegel statt nur die
Dateigröße — der typische Fehlschlag ist eine formal korrekte WAV-Datei
voller Stille.
S3 Virtuelle PipeWire-Kamera per GStreamer-pipewiresink, ohne Kernel-Modul.
Setzt die Firefox-Einstellung vorab, damit der Test nicht an einem
vergessenen Häkchen scheitert.
S4 Intent-Handoff mit lauffähiger Mini-Bridge: xdg-open-Handler für geo:,
tel: und sms:, Token-Authentifizierung, feste Liste erlaubter Schemata.
provision/provision.sh setzt die Hintergrundbeschränkungen per ADB und benennt,
was ADB nicht kann und von Hand erledigt werden muss.
Dokumentiert sind auch die sieben verworfenen Wege — Waydroid, AVF, QEMU, SIP,
APK-Daten-Redirect, Fenster-Durchreichung und der Android-Server — mit Belegen,
damit sie nicht erneut durchdacht werden müssen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
128 lines
6.2 KiB
Bash
Executable File
128 lines
6.2 KiB
Bash
Executable File
#!/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'"
|