From 81c5bc25bf6f004c8f33fb20bb90502261870a24 Mon Sep 17 00:00:00 2001 From: Thomas Dannenberg Date: Fri, 29 Aug 2025 19:17:22 +0000 Subject: [PATCH] Kapitel 13/Tutorial.md aktualisiert --- Kapitel 13/Tutorial.md | 199 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 190 insertions(+), 9 deletions(-) diff --git a/Kapitel 13/Tutorial.md b/Kapitel 13/Tutorial.md index 735e569..678c74e 100644 --- a/Kapitel 13/Tutorial.md +++ b/Kapitel 13/Tutorial.md @@ -428,22 +428,22 @@ Im Ergebnis findest du im Feld `data[0].id` deine **User-ID** (z. B. `123456789` Damit hat der Switch-Node drei klar benannte Ausgänge, die die weitere Logik steuern. 8. Pfad 1 - CREATE_AND_DOWNLOAD + Ziel: n8n erkennt neue VODs, erstellt/aktualisiert die State-Datei und lädt jedes VOD **sequenziell** im Clipper herunter und direkt in **Nextcloud** hoch (mit automatischem Aufräumen und Logfiles). Alles wird von n8n gesteuert, die Dateiübertragung übernimmt **rclone** im Clipper. - > [!IMPORTANT] - > Nextcloud-Verbindung einrichten (einmalig im Clipper-LXC) - > Damit VODs nach dem Download nicht den lokalen Speicher füllen, verschieben wir sie direkt in die Nextcloud. Dazu nutzen wir **rclone**. + --- + + **A. Vorbereitung (einmalig) – rclone an Nextcloud anbinden** + Ort: *Clipper‑LXC Shell* 1) rclone installieren (als root) ```bash apt update && apt install -y rclone ``` - - 2) Zum Benutzer *clipper* wechseln + 2) Zum Benutzer **clipper** wechseln ```bash su - clipper ``` - - 3) Remote **nc** korrekt anlegen (Passwort wird automatisch obskuriert) + 3) Remote **nc** anlegen (Passwort wird automatisch obskuriert) ```bash rclone config create nc webdav \ url=https://DEINE_DOMAIN/remote.php/dav/files/DEIN_BENUTZERNAME/ \ @@ -451,6 +451,187 @@ Im Ergebnis findest du im Feld `data[0].id` deine **User-ID** (z. B. `123456789` user=DEIN_BENUTZERNAME \ pass=$(rclone obscure 'DEIN_APP_PASSWORT') ``` - - 4) Verbindung testen (explizite Config-Pfadverwendung empfohlen) + 4) Verbindung testen ```bash + rclone ls nc: --config /home/clipper/.config/rclone/rclone.conf + ``` + > **Entscheidung & Begründung** + > Uploads laufen im Clipper mit rclone (WebDAV). Das ist robuster als Upload‑Nodes in n8n, vermeidet Binary‑Fehler und räumt lokal automatisch auf. + + --- + + **B. Download/Upload als Skript (übersichtlich & mit Logs)** + Ort: *Clipper‑LXC Shell* + + 1) Skript anlegen + ```bash + nano /bin/clipper-vod-get + ``` + + 2) Inhalt einfügen → speichern (**Ctrl+O**, Enter) → schließen (**Ctrl+X**) + ``` + #!/usr/bin/env bash + set -euo pipefail + + ID="${1:?need VOD id}" + URL="${2:-https://www.twitch.tv/videos/${ID}}" + + TMP="/temp" + LOGDIR="/logs" + CONF="/home/clipper/.config/rclone/rclone.conf" + DST="nc:/VODs/${ID}/" + + OUT="$TMP/${ID}.%(ext)s" + FILE="$TMP/${ID}.mp4" + TEMP="$TMP/${ID}.temp.mp4" + PART="$TMP/${ID}.mp4.part" + LOCK="$TMP/${ID}.lock" + LOG="$LOGDIR/${ID}.log" + + mkdir -p "$TMP" "$LOGDIR" + + log() { + echo "[$(date '+%F %T')] $*" | tee -a "$LOG" + } + + log "=== Start VOD $ID ===" + log "URL: $URL" + + if rclone lsf "$DST" --config "$CONF" >/dev/null 2>&1; then + log "SKIP: $ID bereits in Nextcloud" + exit 0 + fi + + if [[ -e "$LOCK" ]]; then + log "LOCK: $ID wird bereits verarbeitet" + exit 0 + fi + trap 'rm -f "$LOCK"' EXIT + : > "$LOCK" + + if [[ -s "$TEMP" && ! -s "$FILE" ]]; then + log "RESUME: TEMP gefunden → umbenennen" + mv -f "$TEMP" "$FILE" + fi + if [[ -s "$FILE" ]]; then + log "RESUME: fertige Datei gefunden → hochladen" + rclone move "$FILE" "$DST" --config "$CONF" --create-empty-src-dirs -v + rm -f "$PART" "$TEMP" || true + log "OK: $ID hochgeladen (Resume-Pfad)" + log "=== Done VOD $ID ===" + exit 0 + fi + + log "START: Download mit yt-dlp" + yt-dlp -q --no-progress \ + --retries 20 --fragment-retries 50 --retry-sleep 5 --socket-timeout 30 \ + --hls-prefer-ffmpeg --remux-video mp4 \ + -o "$OUT" "$URL" + + [[ -s "$FILE" ]] || { [[ -s "$TEMP" ]] && mv -f "$TEMP" "$FILE"; } + if [[ ! -s "$FILE" ]]; then + log "ERROR: Download fehlgeschlagen ($FILE fehlt/leer)" + exit 2 + fi + log "OK: Download abgeschlossen ($(du -h "$FILE" | awk '{print $1}'))" + + log "START: Upload nach Nextcloud" + rclone move "$FILE" "$DST" --config "$CONF" --create-empty-src-dirs -v + log "OK: Upload abgeschlossen" + + rm -f "$PART" "$TEMP" || true + log "CLEANUP: temporäre Dateien entfernt" + log "=== Done VOD $ID ===" + ``` + + 3) Rechte setzen + ```bash + chmod 755 /bin /bin/clipper-vod-get + chown clipper:clipper /bin/clipper-vod-get + ``` + + > **Hinweis** + > Pro VOD entsteht ein Logfile in `/logs/.log`. Live-Ansicht mit `tail -f /logs/.log` + + --- + + **C. n8n‑Verkabelung (Überblick)** + Ort: *n8n Weboberfläche* + + **Verkabelung (Kurzüberblick):** + 1) HTTP Request → + 2) Item Lists: Split Out (data) → + 3) Switch (Pfad: CREATE_AND_DOWNLOAD) → + 4) Merge (Combine → All Possible Combinations) → + 5) Split In Batches (1) → + 6) SSH Node 1 (State-Datei schreiben) → + 7) SSH Node 2 (Download & Upload) + + --- + + **D. Node-Einstellungen (1:1 in n8n eintragen)** + + **1) HTTP Request – Get Videos** + - **Node-Typ:** HTTP Request + - **Methode:** GET + - **URL:** + ``` + https://api.twitch.tv/helix/videos?user_id=&type=archive&first=20 + ``` + - **Authentifizierung:** OAuth2 (Credential: *Twitch API*) + - **Header:** `Client-Id: ` + - **Response Format:** JSON + + **2) Item Lists – Split Out** + - **Node-Typ:** Item Lists + - **Operation:** Split Out Items + - **Field to Split Out:** `data` + + **3) Switch – Pfadwahl** + - **Node-Typ:** Switch + - **Property Name:** + ``` + {{ $json.state }} + ``` + - **Gültiger Pfad für Pfad 1:** `CREATE_AND_DOWNLOAD` + + **4) Merge – Combine** + - **Node-Typ:** Merge + - **Mode:** Combine + - **Combine Mode:** All Possible Combinations + - **Eingang 1:** Switch (Ausgang: CREATE_AND_DOWNLOAD) + - **Eingang 2:** Item Lists: Split Out + + **5) Split In Batches** + - **Node-Typ:** Split In Batches + - **Batch Size:** `1` + + **6) SSH Node 1 – State-Datei schreiben** + - **Node-Typ:** SSH + - **Credentials:** *SSH Clipper* (User = `clipper`) + - **Operation:** Execute Command + - **Command is an Expression:** **ON** + - **Command:** + ```bash + {{`set -euo pipefail; STATE="/state/vod_seen.list"; mkdir -p "$(dirname "$STATE")"; if [ -s "$STATE" ]; then printf "%s\n" "${$json.id}" >> "$STATE"; else printf "%s\n" "${$json.id}" > "$STATE"; fi`}} + ``` + + **7) SSH Node 2 – Download & Upload (Skript)** + - **Node-Typ:** SSH + - **Credentials:** *SSH Clipper* (User = `clipper`) + - **Operation:** Execute Command + - **Command is an Expression:** **ON** + - **Command:** + ```bash + /bin/clipper-vod-get "{{$('Merge').item.json.data.id}}" "{{ $json.url || ('https://www.twitch.tv/videos/' + $('Merge').item.json.data.id) }}" + ``` + - **Hinweis:** Keine Binary-Nodes hinter diesem Schritt – Upload erfolgt im Skript via rclone. + + --- + + **Ergebnis** + - n8n steuert den gesamten Prozess, Upload erfolgt zuverlässig im Clipper via rclone. + - Pro VOD entsteht **eine** MP4 in Nextcloud: `/VODs//`. + - Pro VOD gibt es ein eigenes Logfile unter `/logs/.log`. + - Lokaler Speicher bleibt frei (automatisches Löschen nach Upload). + - Logs der Schritte findest du im SSH‑Node‑Output und persistent im Logfile.