Kapitel 13/Tutorial.md aktualisiert
This commit is contained in:
@@ -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 <clipper-ordner>/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="<clipper-ordner>/temp"
|
||||
LOGDIR="<clipper-ordner>/logs"
|
||||
CONF="/home/clipper/.config/rclone/rclone.conf"
|
||||
DST="nc:<gewünschter Ordner>/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 <clipper-ordner>/bin <clipper-ordner>/bin/clipper-vod-get
|
||||
chown clipper:clipper <clipper-ordner>/bin/clipper-vod-get
|
||||
```
|
||||
|
||||
> **Hinweis**
|
||||
> Pro VOD entsteht ein Logfile in `<clipper-ordner>/logs/<ID>.log`. Live-Ansicht mit `tail -f <clipper-ordner>/logs/<ID>.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=<DEINE_TWITCH_USER_ID>&type=archive&first=20
|
||||
```
|
||||
- **Authentifizierung:** OAuth2 (Credential: *Twitch API*)
|
||||
- **Header:** `Client-Id: <DEINE_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="<clipper-ordner>/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
|
||||
<clipper-ordner>/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: `<gewünschter Ordner>/VODs/<ID>/`.
|
||||
- Pro VOD gibt es ein eigenes Logfile unter `<clipper-ordner>/logs/<ID>.log`.
|
||||
- Lokaler Speicher bleibt frei (automatisches Löschen nach Upload).
|
||||
- Logs der Schritte findest du im SSH‑Node‑Output und persistent im Logfile.
|
||||
|
||||
Reference in New Issue
Block a user