Kapitel 13/Tutorial.md aktualisiert

This commit is contained in:
2025-08-28 15:23:09 +00:00
parent 76c081506a
commit 1d1a327a8c

View File

@@ -1,4 +1,4 @@
# 🛠️ Kapitel 13 Clipper (Tutorial) # 🛠️ Kapitel 13 Clipper (Tutorial)
--- ---
@@ -340,64 +340,101 @@ Im Ergebnis findest du im Feld `data[0].id` deine **User-ID** (z. B. `123456789`
### Schritt 3: Workflow bauen (n8n-Weboberfläche) ### Schritt 3: Workflow bauen (n8n-Weboberfläche)
1. **Cron-Trigger:** alle 10 Minuten 1. **Cron-Trigger:** alle 10 Minuten
2. **HTTP Request (Get Videos):** 2. **HTTP Request (Get Videos):**
``` ```
https://api.twitch.tv/helix/videos?user_id=<DEINE_TWITCH_USER_ID>&type=archive&first=1 https://api.twitch.tv/helix/videos?user_id=<DEINE_TWITCH_USER_ID>&type=archive&first=1
``` ```
3. **IF „Neu?“ Node:**
3. **SSH Credentials in n8n anlegen**
Damit n8n mit dem Clipper arbeiten kann, legen wir zunächst ein SSH Credential an:
* **Name:** SSH Clipper
* **Host:** `<CLIPPER-IP>` (z. B. `10.0.0.42`)
* **Port:** 22
* **Username:** `clipper`
* **Private Key:** Inhalt von `~/.ssh/id_n8n_clipper` (PEM-Format)
* **Working Directory:** `/srv/clipper`
4. **SSH Node State-Datei prüfen**
Jetzt prüfen wir, ob die Datei `/srv/clipper/state/vod_seen.list` existiert und ob bereits VOD-IDs darin stehen.
**Command (als Expression):**
```js ```js
{{ !$workflow.staticData.global.last_vod_id || $json.data[0].id !== $workflow.staticData.global.last_vod_id }} {{"set -euo pipefail; STATE_FILE=\"/srv/clipper/state/vod_seen.list\"; fe=false; ne=false; arr='[]'; if [ -f \"$STATE_FILE\" ]; then fe=true; if [ -s \"$STATE_FILE\" ]; then ne=true; mapfile -t L < \"$STATE_FILE\"; json='['; sep=''; for id in \"${L[@]}\"; do id_trim=\"${id//[$'\\t\\r\\n ']}\"; [ -n \"$id_trim\" ] || continue; json+=\"$sep\\\"$id_trim\\\"\"; sep=','; done; json+=']'; arr=\"$json\"; fi; fi; printf '{\\"file_exists\\":%s,\\"non_empty\\":%s,\\"vods\\":%s}\\n' \"$fe\" \"$ne\" \"$arr\""}}
``` ```
→ true: weiter, false: Ende **Beispiele für den Output:**
4. **SSH (Download VOD auf Clipper):**
```bash ```json
JOBID="{{ $json.data[0].id }}" {"file_exists":false,"non_empty":false,"vods":[]}
URL="{{ $json.data[0].url }}" {"file_exists":true,"non_empty":false,"vods":[]}
DIR="/srv/clipper/inbox/$JOBID" {"file_exists":true,"non_empty":true,"vods":["123456789","987654321"]}
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"
``` ```
5. **Nextcloud Upload (HTTP PUT, Basic Auth):**
``` 5. **Set Node Felder übernehmen**
https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/dav/files/<DEIN_NC_BENUTZER>/Clips/{{ $json.data[0].id }}/<Dateiname> Direkt nach dem SSH Node fügen wir einen **Edit Fields (Set)** Node ein.
``` Damit parsen wir das JSON aus `stdout` in echte Felder, die wir später leicht in IF- oder anderen Nodes verwenden können.
6. **Analyse starten (SSH):**
```bash **Felder (Expressions):**
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 }}"
```
7. **State aktualisieren:**
```js * `file_exists` → `={{ JSON.parse($json.stdout).file_exists }}`
$workflow.staticData.global.last_vod_id = $json.data[0].id; * `non_empty` → `={{ JSON.parse($json.stdout).non_empty }}`
return items; * `vods` → `={{ JSON.parse($json.stdout).vods }}`
```
```md
## Schritt 3: Workflow bauen (n8n-Weboberfläche)
1. **Cron-Trigger:** alle 10 Minuten
2. **HTTP Request (Get Videos):**
```
[https://api.twitch.tv/helix/videos?user\_id=](https://api.twitch.tv/helix/videos?user_id=)\<DEINE\_TWITCH\_USER\_ID>\&type=archive\&first=1
````
### 6. State ermitteln (Set-Node EIN Feld)
Wir bewerten **nur den Dateistatus**. `vodId` aus Twitch wird erst später benötigt, wenn die Datei existiert **und** nicht leer ist.
**Feld:** `state`
**Expression:**
```js
{{ $json.file_exists === false
? 'CREATE_AND_DOWNLOAD'
: ($json.non_empty === false
? 'APPEND_AND_DOWNLOAD'
: 'NEED_CHECK') }}
```
--- ---
### Kontrolle ### 7. Switch-Node drei klare Wege
Im Clipper-LXC: **Switch → Property Name:** `={{ $json.state }}`
**Cases:**
* **CREATE\_AND\_DOWNLOAD** → Datei anlegen **und** VOD sofort downloaden.
* **APPEND\_AND\_DOWNLOAD** → Datei ist leer → VOD-ID direkt eintragen und downloaden.
* **NEED\_CHECK** → Datei existiert und ist nicht leer → hier prüfen, ob die aktuelle VOD-ID schon enthalten ist.
---
### Branch `NEED_CHECK`
1. **Set (kurz)**
* `currentVod` → `={{ $json.vodId ?? $json.data[0].id }}`
* `contains_vod` → `={{ Array.isArray($json.vods) && $json.vods.includes($json.currentVod) }}`
2. **IF Node (einmalig in diesem Branch)**
* **Bedingung:** `={{ $json.contains_vod === true }}`
* **True:** Pfad beenden (VOD bereits verarbeitet)
* **False:** Download & Analyse starten, danach ID anhängen
```bash
su - clipper
ls -lh /srv/clipper/inbox/<VOD-ID>
tail -n 50 /srv/clipper/logs/clipper.log
```
In Nextcloud: Ordner `Clips/<VOD-ID>` sollte erscheinen.