# đŸ› ïž Kapitel 13 – Clipper (Tutorial) --- ## Einleitung Clips sind der beste Weg, lange Streams in kurze, teilbare Highlights zu verwandeln. Unser Ziel in diesem Kapitel: Wir bauen ein System, das neue Videos automatisch erkennt, sinnvolle Stellen analysiert, passende Highlights schneidet und die Ergebnisse in Nextcloud ablegt – inklusive Titeln und Hashtags fĂŒr jede Plattform. Der Clipper selbst ĂŒbernimmt dabei die technische Verarbeitung, wĂ€hrend **n8n** fĂŒr Steuerung, Analyse und Benachrichtigungen sorgt. Das System bleibt dadurch flexibel, ressourcenschonend und jederzeit erweiterbar. --- ## Voraussetzungen - **Proxmox LXC** mit Debian 12 (Bookworm) - **Nextcloud** (Pflicht, Zielort fĂŒr Clips & Metadaten) - **n8n-Instanz** (Automatisierung, Steuerung Clipper, Analyse, Metadaten-Erzeugung) - **Twitch-Entwickler-Account** inkl. API-Key (fĂŒr VOD- und Clip-Zugriff) - **Optional**: RTMP-Server, falls VODs lokal aufgezeichnet werden - **Ressourcen fĂŒr den LXC**: 1 vCPU, 1–2 GB RAM, 10 GB Speicher reichen aus - **Grundwissen**: SSH-Verbindung, Nano-Editor, Basiskenntnisse in n8n --- ## Vorbereitung Wir beginnen mit einem frischen Debian‑12‑LXC in Proxmox, benennen ihn `clipper` und vergeben die im Abschnitt oben genannten Ressourcen. Danach bringen wir das System auf Stand und installieren die Grundwerkzeuge: ```bash apt update && apt upgrade -y apt install -y curl unzip ffmpeg inotify-tools ``` Eine korrekte Systemzeit ist entscheidend, da Schnittmarken spĂ€ter auf exakten Sekunden basieren. PrĂŒfe die Zeit mit: ```bash timedatectl status ``` Wenn hier UTC steht und du lieber „Europe/Berlin“ nutzen willst: ```bash timedatectl list-timezones | grep Europe timedatectl set-timezone Europe/Berlin timedatectl status ``` Die Zeit wird sofort angepasst, Logs und Schnittzeiten passen damit zur lokalen Umgebung. Zum Schluss legen wir die Arbeitsordner an: ```bash mkdir -p /srv/clipper/{watch,out,temp,logs} ``` - `watch` – Eingangsordner fĂŒr neue Videos (egal ob von Twitch oder RTMP) - `out` – fertige Clips und Metadaten - `temp` – Zwischenspeicher fĂŒr Analyse - `logs` – Protokolle aller AblĂ€ufe Damit ist das Fundament gelegt. --- ## Abschnitt 2 – Clipper‑LXC einrichten (Benutzer, Verzeichnisse, Pakete, Skripte) In diesem Abschnitt richten wir den **Clipper‑Container** so ein, dass **SSH‑SchlĂŒssel**, **Downloads** und **n8n‑Aufrufe** ohne Berechtigungsfehler funktionieren. Wir arbeiten jetzt **im Terminal deines Clipper‑LXC als root**. > **Entscheidung & BegrĂŒndung – Benutzer mit Home & Bash** > Der Benutzer **clipper** bekommt ein **Homeverzeichnis** (`/home/clipper`) und eine **Login‑Shell**. So können SSH‑SchlĂŒssel sauber in `~clipper/.ssh` landen und n8n spĂ€ter per SSH Befehle ausfĂŒhren. Varianten ohne Home (System‑User) fĂŒhren bei `ssh-copy-id` zu Fehlern. ### 2.1 Benutzer und Verzeichnisse anlegen (Terminal, als root) ```bash adduser --home /home/clipper --shell /bin/bash clipper ``` Vergib ein Passwort und bestĂ€tige die Abfragen. Danach legst du die Arbeitsordner an und ĂŒbertrĂ€gst den Besitz an `clipper`: ```bash mkdir -p /srv/clipper/{inbox,watch,out,temp,logs,bin} chown -R clipper:clipper /srv/clipper chmod 750 /srv/clipper ``` (optional, aber hilfreich fĂŒr `ssh-copy-id` spĂ€ter): ```bash install -d -m 700 -o clipper -g clipper /home/clipper/.ssh ``` > **Falls du den Benutzer bereits ohne Home angelegt hast:** > Richte ihn so nach: > `mkdir -p /home/clipper/.ssh && chown -R clipper:clipper /home/clipper && chmod 700 /home/clipper/.ssh` ### 2.2 Pakete installieren (Terminal, als root) ```bash apt update && apt install -y yt-dlp jq python3 python3-venv curl unzip inotify-tools sudo ``` - **ffmpeg**: Analyse & Schnitt - **yt-dlp**: Twitch‑VOD/Clip‑Downloads (HLS) - **jq**: JSON‑Handling - **python3/venv**: spĂ€tere Analyse‑Tools - **inotify-tools**: Dateisystem‑Events (optional) - **sudo**: fĂŒr gezielte Rechteerhöhungen falls nötig ### 2.3 Zentrale Konfiguration (Terminal, als root) Bevor wir die Umgebungsdatei anlegen, brauchen wir ein eigenes Konfigurationsverzeichnis. Das existiert standardmĂ€ĂŸig nicht, daher legen wir es einmalig an: ```bash mkdir -p /etc/clipper chown root:clipper /etc/clipper chmod 750 /etc/clipper ``` > **Entscheidung & BegrĂŒndung – eigenes /etc/clipper** > Konfiguration gehört nach `/etc`. Mit einem eigenen Ordner `/etc/clipper` bleibt alles ĂŒbersichtlich getrennt. > Besitzer ist `root`, die Gruppe `clipper`. So kann der Clipper-User die Datei lesen, aber nicht verĂ€ndern – genau die Balance zwischen Sicherheit und Funktion. Entscheidung & BegrĂŒndung – eigenes /etc/clipper Konfiguration gehört nach /etc. Mit einem eigenen Ordner /etc/clipper bleibt alles ĂŒbersichtlich getrennt. Besitzer ist root, die Gruppe clipper. So kann der Clipper-User die Datei lesen, aber nicht verĂ€ndern – genau die Balance zwischen Sicherheit und Funktion. Lege eine Umgebungsdatei an, die beide Skripte laden: ```bash nano /etc/clipper/clipper.env ``` Inhalt: ``` CLIPPER_INBOX=/srv/clipper/inbox CLIPPER_IN=/srv/clipper/watch CLIPPER_OUT=/srv/clipper/out CLIPPER_TMP=/srv/clipper/temp CLIPPER_LOG=/srv/clipper/logs/clipper.log ``` Dateirechte setzen, damit `clipper` sie lesen darf: ```bash chown root:clipper /etc/clipper/clipper.env chmod 640 /etc/clipper/clipper.env ``` ### 2.4 Python‑Umgebung vorbereiten (Wechsel zu Benutzer *clipper*) Wechsle jetzt **zum Benutzer clipper**: ```bash su - clipper ``` Erzeuge und fĂŒlle eine virtuelle Umgebung fĂŒr die spĂ€tere Analyse: ```bash python3 -m venv /srv/clipper/.venv source /srv/clipper/.venv/bin/activate pip install --upgrade pip pip install numpy opencv-python-headless deactivate ``` Wechsle fĂŒr die nĂ€chsten Schritte **im Benutzer clipper** weiter. ### 2.5 Einstiegsskripte erstellen (im Benutzer *clipper*) **Analyse‑Stub** – prĂŒft Eingaben, schreibt Logs, erzeugt leere Kandidatenliste: ```bash nano /srv/clipper/bin/clipper-analyze ``` Inhalt: ```bash #!/usr/bin/env bash set -euo pipefail ENV_FILE="/etc/clipper/clipper.env"; [ -r "$ENV_FILE" ] || { echo "ENV nicht lesbar: $ENV_FILE" >&2; exit 1; }; source "$ENV_FILE" IN="$1" # absolute Datei JOBID="${2:-manual}" mkdir -p "$CLIPPER_TMP/$JOBID" echo "$(date '+%F %T') [ANALYZE] job=$JOBID file=$IN" | tee -a "$CLIPPER_LOG" OUT_JSON="$CLIPPER_TMP/$JOBID/candidates.json" echo '[]' > "$OUT_JSON" echo "$OUT_JSON" ``` **Schneid‑Stub** – protokolliert Schnittaufrufe, echte Logik folgt in Abschnitt 5: ```bash nano /srv/clipper/bin/clipper-cut ``` Inhalt: ```bash #!/usr/bin/env bash set -euo pipefail ENV_FILE="/etc/clipper/clipper.env"; [ -r "$ENV_FILE" ] || { echo "ENV nicht lesbar: $ENV_FILE" >&2; exit 1; }; source "$ENV_FILE" IN="$1" # absolute Datei RANGES_JSON="$2" # Zeitbereiche (kommt spĂ€ter aus Abschnitt 4) JOBID="${3:-manual}" mkdir -p "$CLIPPER_OUT/$JOBID" echo "$(date '+%F %T') [CUT] job=$JOBID file=$IN ranges=$RANGES_JSON" | tee -a "$CLIPPER_LOG" exit 0 ``` Rechte setzen und EigentĂŒmer korrigieren: ```bash chmod +x /srv/clipper/bin/clipper-* chown -R clipper:clipper /srv/clipper/bin ``` ### 2.6 Logrotation (zurĂŒck zu root) Beende die Session (`exit`) und kehre zu **root** zurĂŒck. Richte Logrotation ein: ```bash nano /etc/logrotate.d/clipper ``` Inhalt: ``` /srv/clipper/logs/*.log { rotate 14 daily missingok notifempty compress delaycompress copytruncate } ``` > **Schnelltest (optional):** > ZurĂŒck im **Benutzer clipper**: > `/srv/clipper/bin/clipper-analyze /srv/clipper/watch/demo.mp4 job-001` > `/srv/clipper/bin/clipper-cut /srv/clipper/watch/demo.mp4 /srv/clipper/temp/job-001/ranges.json job-001` > `tail -n 50 /srv/clipper/logs/clipper.log` Mit dieser Einrichtung sind **SSH‑SchlĂŒssel**, **Berechtigungen** und **Pfade** konsistent. `ssh-copy-id` aus Abschnitt 3 funktioniert dadurch ohne Fehlermeldungen – und n8n kann die Skripte stabil starten. --- ## Abschnitt 3 – n8n ↔ Twitch: VOD & Clips importieren, in Nextcloud ablegen, Clipper starten In diesem Abschnitt verbinden wir n8n mit Twitch, Nextcloud und dem Clipper. Das Ziel: n8n erkennt automatisch neue VODs auf Twitch, lĂ€dt sie zusammen mit Clips herunter, legt sie in Nextcloud ab und startet dann die Analyse auf dem Clipper. Wir gehen Schritt fĂŒr Schritt vor – immer mit klaren Hinweisen, ob wir uns gerade in der **n8n‑WeboberflĂ€che**, im **Terminal** oder in **Nextcloud** befinden. > **Entscheidung & BegrĂŒndung – Rollenverteilung** > **n8n** steuert (APIs, Logik, Benachrichtigungen). **Clipper** arbeitet (Download, Analyse, Schnitt). **Nextcloud** speichert (Archiv & Übergabe). So bleibt n8n schlank und ausfallsicher, wĂ€hrend Clipper CPU/IO fĂŒr Medienjobs bekommt. --- ### Schritt 1: Zugriff zwischen den Containern vorbereiten (Terminal)
Optional: SSH Known-Hosts zurĂŒcksetzen (falls Clipper schon einmal erstellt wurde) Wenn du den Clipper-LXC bereits frĂŒher erstellt und neu aufgesetzt hast, kann es zu einem SSH-Fehler kommen: ``` @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ``` Das bedeutet, dass sich der **Server-Hostkey** geĂ€ndert hat. SSH blockiert dann aus SicherheitsgrĂŒnden. #### Lösung Schritt fĂŒr Schritt (im n8n-LXC als root) 1. **Fingerprint auf dem Clipper prĂŒfen** ```bash ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub ``` (SHA256-Wert merken und vergleichen) 2. **Alten Eintrag löschen** ```bash ssh-keygen -R "" ``` > **Entscheidung & BegrĂŒndung – Sicherheitsprinzip** > SSH schĂŒtzt vor Man-in-the-Middle-Angriffen, indem es Hostkeys prĂŒft. Wenn ein Container neu erstellt wird, ist ein neuer Hostkey normal. Wir löschen den alten Eintrag bewusst, prĂŒfen den neuen Fingerprint und akzeptieren ihn erst danach. So bleibt die Verbindung sicher **und** stabil.
### Schritt 1.1: SSH-SchlĂŒssel fĂŒr n8n erzeugen (n8n-LXC, Terminal) Damit n8n spĂ€ter Befehle im Clipper ausfĂŒhren kann, benötigt es einen SSH-SchlĂŒssel im kompatiblen Format. ```bash # SchlĂŒssel fĂŒr n8n → Clipper erzeugen (RSA, PEM-Format) ssh-keygen -t rsa -b 4096 -m PEM -f ~/.ssh/id_n8n_clipper -N "" ``` * **-t rsa**: RSA ist breiter kompatibel als ed25519. * **-m PEM**: n8n benötigt diesen Formattyp, sonst kommt "Unsupported key format". * **-N ""**: kein Passwort (n8n kann keine Passphrase abfragen). ### Schritt 1.2: Public Key auf dem Clipper hinterlegen ```bash ssh-copy-id -i ~/.ssh/id_n8n_clipper.pub clipper@ ``` Test der Verbindung (ohne Passwort): ```bash ssh -i ~/.ssh/id_n8n_clipper clipper@ "echo OK" ``` > **Entscheidung & BegrĂŒndung – RSA statt ed25519** > Ed25519 ist moderner, erzeugt aber oft OpenSSH-Private Keys, die n8n nicht korrekt verarbeiten kann. Das klassische PEM-Format mit RSA ist voll kompatibel mit n8n und vermeidet Fehler. --- ### Schritt 1.3: SSH Credential in n8n eintragen **Ort:** n8n WeboberflĂ€che → **Credentials** → **+ Add** → **SSH** Felder: * **Name:** z. B. `clipper-ssh` * **Host:** `` * **Port:** `22` * **Username:** `clipper` * **Private Key:** Inhalt von `~/.ssh/id_n8n_clipper` (nicht `.pub`!) * **Passphrase:** leer lassen > **Fehler & Lösung** > "Unsupported key format" → Der Private Key muss im PEM-Format vorliegen und **mit** > `-----BEGIN RSA PRIVATE KEY-----` beginnen und `-----END RSA PRIVATE KEY-----` enden. > Nicht `.pub` einfĂŒgen. Kein Passwort setzen. Keine Zeilen umbrechen oder manipulieren. Damit ist der n8n-Zugriff auf den Clipper fertig eingerichtet – ohne spĂ€tere Konvertierungen, Fehlermeldungen oder Korrekturen. Ersetze `` durch die IP/den Hostnamen deines Clipper‑LXC (z. B. `10.0.0.42`). Wenn **OK** erscheint, kann n8n ohne Passwort auf den Clipper zugreifen. ### Zugangsdaten fĂŒr Nextcloud‑WebDAV erstellen (WeboberflĂ€che) > **Ort in Nextcloud**: Avatar (oben rechts) → **Persönliche Einstellungen** → **Sicherheit** → **ganz nach unten** zum Bereich **App‑Passwörter**. **Anleitung:** 1. Melde dich in der **Nextcloud‑WeboberflĂ€che** an. 2. Gehe zu **Persönliche Einstellungen** → **Sicherheit**. 3. **Ganz nach unten scrollen** bis zum Abschnitt **App‑Passwörter** (unscheinbar platziert). 4. Trage bei **App‑Name** z. B. `n8n Clipper` ein und klicke auf **Neues App‑Passwort erstellen**. 5. Kopiere das **einmalig angezeigte App‑Passwort** sofort und notiere zusĂ€tzlich deinen **Benutzernamen**. (Das Passwort wird spĂ€ter **nicht** erneut angezeigt.) **WebDAV‑URL fĂŒr n8n/Uploads:** ``` https:///remote.php/dav/files// ``` *(Alternativ, je nach Setup: `https:///remote.php/webdav/`)*
Schnelltest (optional, auf deinem n8n‑LXC) ```bash curl -u ":" \ -X PROPFIND -H "Depth: 0" \ -s -o /dev/null -w "%{http_code}\n" \ "https:///remote.php/dav/files//" # Erwartet: 207 ``` Optional kannst du die ersten Zeilen der Antwort prĂŒfen: ```bash curl -u ":" \ -X PROPFIND -H "Depth: 0" -s \ "https:///remote.php/dav/files//" \ | head -n 5 # Erwartet: XML mit ``` **Fehler & Lösung (kurz):** - **401/403** → Benutzername oder App‑Passwort falsch. - **404** → Pfad prĂŒfen (richtiger Benutzerordner?). - **App‑Passwörter fehlen?** Admin muss sie in den Nextcloud‑Einstellungen aktivieren.
**Twitch‑API Zugang:**
Twitch Developer Console – App anlegen 1. Gehe auf [Twitch Developer Console](https://dev.twitch.tv/console/apps) → **Applications** → **Register Your Application**. 2. Felder ausfĂŒllen: - **Name:** frei wĂ€hlbar (muss einzigartig sein). - **OAuth Redirect URL:** z. B. `https://localhost/` (Platzhalter; fĂŒr Client-Credentials Flow nicht genutzt). - **Category:** passend wĂ€hlen (z. B. Chatbot/Website Integration). 3. App speichern → **Manage** öffnen. 4. **Client ID** notieren, **New Secret** klicken und **Client Secret** sichern.
### Twitch OAuth2 Credential in n8n (Client Credentials Flow) Beim Anlegen in n8n → **Credentials → + Add → OAuth2 API**: - **Name:** Twitch API - **Grant Type:** `Client Credentials` - **Authorization URL:** `https://id.twitch.tv/oauth2/authorize` *(Pflichtfeld, wird in diesem Flow nicht genutzt)* - **Access Token URL:** `https://id.twitch.tv/oauth2/token` - **Client ID:** *(aus Twitch Developer Console)* - **Client Secret:** *(aus Twitch Developer Console)* - **Scope:** *(leer lassen)* - **Authentication:** `Body` ← **wichtig, sonst Fehler** - **OAuth Redirect URL:** `https://automation.bratonien.de/rest/oauth2-credential/callback` *(muss in Twitch-App eingetragen sein, auch wenn bei Client Credentials nicht genutzt)* Speichern. **PrĂŒfen (kein „Test“-Button bei Client Credentials):** 1. Lege einen **HTTP Request**-Node an. 2. **Authentication:** Predefined Credential Type → wĂ€hle dein `Twitch API` Credential. 3. **Headers:** `Client-Id: ` 4. **URL:** `https://api.twitch.tv/helix/users?login=bratonien_tv` 5. **Execute Node** → kommt JSON mit `data[0].id`, ist OAuth korrekt. --- ### Nutzung in HTTP Request Nodes - **Authentication:** Predefined Credential Type → wĂ€hle dein `Twitch API` Credential - **Headers:** - `Client-Id: ` n8n setzt automatisch `Authorization: Bearer `. --- ### Schnelltest in n8n HTTP Request Node: - Method: `GET` - URL: `https://api.twitch.tv/helix/users?login=bratonien_tv` - Header: `Client-Id: ` **Ergebnis:** JSON mit `data[0].id`, `login`, usw. – dann funktioniert OAuth2 korrekt. --- ### Schritt 2: Twitch‑User‑ID herausfinden (n8n‑WeboberflĂ€che) Die Twitch‑API benötigt deine **numerische User‑ID**, nicht den Login‑Namen. Wir holen diese ID einmalig in n8n. 1. Gehe in der n8n‑WeboberflĂ€che auf **Workflows** → **+ New Workflow**. 2. Ziehe einen **HTTP Request Node** auf die ArbeitsflĂ€che. 3. Konfiguriere ihn so: - Methode: GET - URL: `https://api.twitch.tv/helix/users?login=` - Authentifizierung: OAuth2 Credential (aus Schritt 1) - Header: `Client-Id: ` 4. Klicke auf **Execute Node**. 5. Im Ergebnis findest du im Feld `data[0].id` deine **User‑ID** (z. B. `123456789`). Diese Zahl ist entscheidend und ersetzt ab jetzt `` in allen weiteren Schritten. Referenz: [Get Users](https://dev.twitch.tv/docs/api/reference#get-users) > **Entscheidung & BegrĂŒndung – Login vs. User‑ID** > Der „Login“ ist nur ein Anzeigename. Die API filtert zuverlĂ€ssig ĂŒber die **numerische ID** – deshalb holen wir sie einmalig und verwenden sie konsequent. --- ### Schritt 3: Workflow bauen (n8n‑WeboberflĂ€che) Jetzt bauen wir den eigentlichen Workflow, der regelmĂ€ĂŸig neue VODs prĂŒft, herunterlĂ€dt und ablegt. 1. **Cron-Trigger anlegen:** * Ziehe einen **Cron Node** auf die ArbeitsflĂ€che. * Stelle ihn auf „Every 10 minutes“. Damit prĂŒft n8n alle 10 Minuten auf neue VODs. 2. **VOD-Daten abrufen:** * Ziehe einen weiteren **HTTP Request Node** an den Cron-Node. * URL: ``` https://api.twitch.tv/helix/videos?user_id=&type=archive&first=1 ``` * Auth: OAuth2 Credential * Header: `Client-Id: ` * Ergebnis: In `data[0]` stehen `id`, `title`, `url`, `created_at`, `published_at`. Referenz: [Get Videos](https://dev.twitch.tv/docs/api/reference#get-videos) 3. **IF „Neu?“ Node hinzufĂŒgen:** * Bedingung (Expression): ``` {{$json.data[0].id !== $workflow.staticData.global.last_vod_id}} ``` * true → weiter; false → Ende > **Entscheidung & BegrĂŒndung – State merken** > Nur wenn die ID sich Ă€ndert, ist ein neues VOD da. So entstehen keine leeren Ordner und keine unnötigen API- oder SSH-Aufrufe. 4. **VOD herunterladen (SSH Execute Command im Clipper-LXC):** * Node: **SSH Execute Command** (Credential: *Clipper*) * Command: ```bash JOBID="{{ $json.data[0].id }}" URL="{{ $json.data[0].url }}" DIR="/srv/clipper/inbox/$JOBID" mkdir -p "$DIR" yt-dlp \ --download-archive "/srv/clipper/logs/yt-dlp.archive" \ --no-part --restrict-filenames \ --abort-on-unavailable-fragment \ --retries 10 --fragment-retries 10 --retry-sleep 5 \ -o "$DIR/%(title)s-%(id)s.%(ext)s" \ "$URL" ``` > **Entscheidung & BegrĂŒndung – yt-dlp Archive** > `--download-archive` verhindert doppelte Downloads. Retries sichern HLS-Streams ab. Alles passiert auf Clipper, aber **gesteuert durch n8n**. 5. **Clips abrufen (optional):** * Node: **HTTP Request** * URL: ``` https://api.twitch.tv/helix/clips?broadcaster_id=&started_at={{$json.data[0].created_at}}&ended_at={{$json.data[0].published_at}} ``` * Danach: **Split in Batches** → je Clip-URL an **SSH Execute Command** Command (SSH): ```bash CID="{{ $json.id }}" CURL="{{ $json.url }}" DIR="/srv/clipper/inbox/$CID" mkdir -p "$DIR" yt-dlp \ --download-archive "/srv/clipper/logs/yt-dlp.archive" \ --no-part --restrict-filenames \ --retries 10 --fragment-retries 10 --retry-sleep 5 \ -o "$DIR/%(title)s-%(id)s.%(ext)s" \ "$CURL" ``` 6. **Upload nach Nextcloud (n8n‑WeboberflĂ€che):** * Node: **HTTP Request** * Methode: **PUT** * Auth: **Basic Auth** (Nextcloud App-Passwort) * URL: ``` https:///remote.php/dav/files//Clips/{{ $json.data[0].id }}/ ``` * Ergebnis: In Nextcloud liegt danach ein Ordner `Clips//
`. > **Entscheidung & BegrĂŒndung – Warum Nextcloud?** > Zentrales, versionierbares Speicherziel mit Freigaben/Quotas/Backups. Clipper und andere Systeme können darauf zugreifen, ohne erneut von Twitch laden zu mĂŒssen. 7. **Analyse starten (SSH Execute Command):** * Command: ```bash VIDDIR="/srv/clipper/inbox/{{ $json.data[0].id }}" MAINFILE="$(find "$VIDDIR" -maxdepth 1 -type f -name '*.mp4' -o -name '*.mkv' | head -n1)" /srv/clipper/bin/clipper-analyze "$MAINFILE" "vod-{{ $json.data[0].id }}" ``` > **Entscheidung & BegrĂŒndung – Arbeitsteilung** > n8n stĂ¶ĂŸt nur an, Clipper rechnet. So bleibt n8n leicht und ausfallsicher. 8. **State aktualisieren (n8n‑WeboberflĂ€che):** * Node: **Function** oder **Set** ```js $workflow.staticData.global.last_vod_id = $json.data[0].id; return items; ``` Damit merkt sich der Workflow, welches VOD zuletzt verarbeitet wurde. ### Alternative: Twitch‑Community‑Node (n8n‑WeboberflĂ€che) Wenn du statt HTTP Requests lieber einen fertigen Twitch‑Node nutzen willst, kannst du in self‑hosted n8n einen **Community‑Node** installieren. Die Anleitung: [n8n Community Nodes](https://docs.n8n.io/integrations/community-nodes/). Beachte: Community‑Nodes sind Drittanbieter‑Code und können bei Updates Probleme machen. FĂŒr einen stabilen Dauerbetrieb empfehlen wir den API‑Weg mit HTTP Request. --- ### Kontrolle Nach einem erfolgreichen Durchlauf prĂŒfst du im **Terminal des Clipper‑LXC**: ```bash su - clipper ls -lh /srv/clipper/inbox/ tail -n 50 /srv/clipper/logs/clipper.log ``` Und in der **Nextcloud‑WeboberflĂ€che** solltest du den Ordner `Clips/` sehen. Damit ist die Pipeline geschlossen: Twitch liefert VODs, n8n steuert den Ablauf, Clipper verarbeitet, Nextcloud speichert. In Abschnitt 4 gehen wir in die Analyse‑Logik und die KI‑Auswertung.