Kapitel 13/Tutorial.md aktualisiert

This commit is contained in:
2025-08-28 12:08:23 +00:00
parent 98afdf772d
commit 942435f509

View File

@@ -220,9 +220,9 @@ Mit dieser Einrichtung sind **SSHSchlüssel**, **Berechtigungen** und **Pfade
## Abschnitt 3 n8n ↔ Twitch: VOD & Clips importieren, in Nextcloud ablegen, Clipper 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 **n8nWeboberfläche**, im **Terminal** oder in **Nextcloud** befinden. 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** > **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. > **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.
--- ---
@@ -245,312 +245,160 @@ Das bedeutet, dass sich der **Server-Hostkey** geändert hat. SSH blockiert dann
#### Lösung Schritt für Schritt (im n8n-LXC als root) #### Lösung Schritt für Schritt (im n8n-LXC als root)
1. **Fingerprint auf dem Clipper prüfen** 1. **Fingerprint auf dem Clipper prüfen**
```bash ```bash
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
``` ```
(SHA256-Wert merken und vergleichen) (SHA256-Wert merken und vergleichen)
2. **Alten Eintrag löschen** 2. **Alten Eintrag löschen**
```bash ```bash
ssh-keygen -R "<CLIPPER-IP>" ssh-keygen -R "<CLIPPER-IP>"
``` ```
> **Entscheidung & Begründung Sicherheitsprinzip** > **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. > 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.
</details> </details>
**SSH-Schlüssel für Clipper erzeugen:**
Melde dich zuerst im **Terminal deines n8nLXC** an. Wir richten hier die Verbindung zum Clipper und zu Nextcloud ein.
**SSHSchlüssel für Clipper erzeugen:**
```bash ```bash
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" ssh-keygen -t rsa -b 4096 -m PEM -f ~/.ssh/id_n8n_clipper -N ""
ssh-copy-id clipper@<CLIPPER-IP> ssh-copy-id -i ~/.ssh/id_n8n_clipper.pub clipper@<CLIPPER-IP>
ssh clipper@<CLIPPER-IP> "echo OK" ssh -i ~/.ssh/id_n8n_clipper clipper@<CLIPPER-IP> "echo OK"
``` ```
Ersetze `<CLIPPER-IP>` durch die IP/den Hostnamen deines ClipperLXC (z.B. `10.0.0.42`). Wenn **OK** erscheint, kann n8n ohne Passwort auf den Clipper zugreifen.
### Zugangsdaten für NextcloudWebDAV erstellen (Weboberfläche) Ersetze `<CLIPPER-IP>` 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.
> **Ort in Nextcloud**: Avatar (oben rechts) → **Persönliche Einstellungen** → **Sicherheit** → **ganz nach unten** zum Bereich **AppPasswörter**. > **Entscheidung & Begründung RSA (PEM) statt ed25519**
> n8n akzeptiert nur PEM-Schlüssel zuverlässig. Ed25519 erzeugt oft OpenSSH-Keys, die von n8n nicht geparst werden können. Mit `-m PEM` stellen wir sicher, dass das Format passt.
---
### 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:** **Anleitung:**
1. Melde dich in der **NextcloudWeboberfläche** an.
2. Gehe zu **Persönliche Einstellungen****Sicherheit**.
3. **Ganz nach unten scrollen** bis zum Abschnitt **AppPasswörter** (unscheinbar platziert).
4. Trage bei **AppName** z.B. `n8n Clipper` ein und klicke auf **Neues AppPasswort erstellen**.
5. Kopiere das **einmalig angezeigte AppPasswort** sofort und notiere zusätzlich deinen **Benutzernamen**. (Das Passwort wird später **nicht** erneut angezeigt.)
**WebDAVURL für n8n/Uploads:** 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**.
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**.
**WebDAV-URL für n8n/Uploads:**
``` ```
https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/dav/files/<DEIN_NC_BENUTZER>/ https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/dav/files/<DEIN_NC_BENUTZER>/
``` ```
*(Alternativ, je nach Setup: `https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/webdav/`)*
<details> ---
<summary>Schnelltest (optional, auf deinem n8nLXC)</summary>
```bash
curl -u "<BENUTZER>:<APP_PASSWORT>" \
-X PROPFIND -H "Depth: 0" \
-s -o /dev/null -w "%{http_code}\n" \
"https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/dav/files/<DEIN_NC_BENUTZER>/"
# Erwartet: 207
```
Optional kannst du die ersten Zeilen der Antwort prüfen:
```bash
curl -u "<BENUTZER>:<APP_PASSWORT>" \
-X PROPFIND -H "Depth: 0" -s \
"https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/dav/files/<DEIN_NC_BENUTZER>/" \
| head -n 5
# Erwartet: XML mit <d:multistatus ...>
```
**Fehler & Lösung (kurz):**
- **401/403** → Benutzername oder AppPasswort falsch.
- **404** → Pfad prüfen (richtiger Benutzerordner?).
- **AppPasswörter fehlen?** Admin muss sie in den NextcloudEinstellungen aktivieren.
</details>
**TwitchAPI Zugang:**
<details>
<summary>Twitch Developer Console App anlegen</summary>
### Twitch-API Zugang (Developer Console)
1. Gehe auf [Twitch Developer Console](https://dev.twitch.tv/console/apps) → **Applications****Register Your Application**. 1. Gehe auf [Twitch Developer Console](https://dev.twitch.tv/console/apps) → **Applications****Register Your Application**.
2. Felder ausfüllen: 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). * **Name:** frei wählbar
- **Category:** passend wählen (z. B. Chatbot/Website Integration). * **OAuth Redirect URL:** z. B. `https://localhost/`
* **Category:** passend wählen
3. App speichern → **Manage** öffnen. 3. App speichern → **Manage** öffnen.
4. **Client ID** notieren, **New Secret** klicken und **Client Secret** sichern. 4. **Client ID** notieren, **New Secret** klicken und **Client Secret** sichern.
</details>
### Twitch OAuth2 Credential in n8n (Client Credentials Flow) ### Twitch OAuth2 Credential in n8n (Client Credentials Flow)
Beim Anlegen in n8n → **Credentials → + Add → OAuth2 API**: * **Name:** Twitch API
* **Grant Type:** `Client Credentials`
- **Name:** Twitch API * **Authorization URL:** `https://id.twitch.tv/oauth2/authorize`
- **Grant Type:** `Client Credentials` * **Access Token URL:** `https://id.twitch.tv/oauth2/token`
- **Authorization URL:** `https://id.twitch.tv/oauth2/authorize` *(Pflichtfeld, wird in diesem Flow nicht genutzt)* * **Client ID / Secret:** aus Twitch Developer Console
- **Access Token URL:** `https://id.twitch.tv/oauth2/token` * **Scope:** leer lassen
- **Client ID:** *(aus Twitch Developer Console)* * **Authentication:** `Body`
- **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: <DEINE_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 ### Schritt 2: Twitch-User-ID herausfinden (n8n-Weboberfläche)
- **Authentication:** Predefined Credential Type → wähle dein `Twitch API` Credential
- **Headers:**
- `Client-Id: <DEINE_CLIENT_ID>`
n8n setzt automatisch `Authorization: Bearer <token>`.
---
### Schnelltest in n8n
HTTP Request Node: HTTP Request Node:
- Method: `GET`
- URL: `https://api.twitch.tv/helix/users?login=bratonien_tv`
- Header: `Client-Id: <DEINE_CLIENT_ID>`
**Ergebnis:** JSON mit `data[0].id`, `login`, usw. dann funktioniert OAuth2 korrekt. * Methode: GET
* URL:
```
https://api.twitch.tv/helix/users?login=<DEIN_LOGIN>
```
* Auth: OAuth2 Credential
* Header: `Client-Id: <DEINE_CLIENT_ID>`
Im Ergebnis findest du im Feld `data[0].id` deine **User-ID** (z. B. `123456789`).
--- ---
### Schritt 2: TwitchUserID herausfinden (n8nWeboberfläche) ### Schritt 3: Workflow bauen (n8n-Weboberfläche)
Die TwitchAPI benötigt deine **numerische UserID**, nicht den LoginNamen. Wir holen diese ID einmalig in n8n. 1. **Cron-Trigger:** alle 10 Minuten
2. **HTTP Request (Get Videos):**
1. Gehe in der n8nWeboberfläche auf **Workflows****+ New Workflow**. ```
2. Ziehe einen **HTTP Request Node** auf die Arbeitsfläche. https://api.twitch.tv/helix/videos?user_id=<DEINE_TWITCH_USER_ID>&type=archive&first=1
3. Konfiguriere ihn so: ```
- Methode: GET 3. **IF „Neu?“ Node:**
- URL: `https://api.twitch.tv/helix/users?login=<DEIN_LOGIN>`
- Authentifizierung: OAuth2 Credential (aus Schritt 1)
- Header: `Client-Id: <DEINE_CLIENT_ID>`
4. Klicke auf **Execute Node**.
5. Im Ergebnis findest du im Feld `data[0].id` deine **UserID** (z.B. `123456789`). Diese Zahl ist entscheidend und ersetzt ab jetzt `<DEINE_TWITCH_USER_ID>` in allen weiteren Schritten.
Referenz: [Get Users](https://dev.twitch.tv/docs/api/reference#get-users) ```js
{{ !$workflow.staticData.global.last_vod_id || $json.data[0].id !== $workflow.staticData.global.last_vod_id }}
```
> **Entscheidung & Begründung Login vs. UserID** → true: weiter, false: Ende
> Der „Login“ ist nur ein Anzeigename. Die API filtert zuverlässig über die **numerische ID** deshalb holen wir sie einmalig und verwenden sie konsequent. 4. **SSH (Download VOD auf Clipper):**
---
### Schritt 3: Workflow bauen (n8nWeboberflä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=<DEINE_TWITCH_USER_ID>&type=archive&first=1
```
* Auth: OAuth2 Credential
* Header: `Client-Id: <DEINE_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=<DEINE_TWITCH_USER_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 ```bash
CID="{{ $json.id }}" JOBID="{{ $json.data[0].id }}"
CURL="{{ $json.url }}" URL="{{ $json.data[0].url }}"
DIR="/srv/clipper/inbox/$CID" DIR="/srv/clipper/inbox/$JOBID"
mkdir -p "$DIR" mkdir -p "$DIR"
yt-dlp \ yt-dlp \
--download-archive "/srv/clipper/logs/yt-dlp.archive" \ --download-archive "/srv/clipper/logs/yt-dlp.archive" \
--no-part --restrict-filenames \ --no-part --restrict-filenames \
--abort-on-unavailable-fragment \
--retries 10 --fragment-retries 10 --retry-sleep 5 \ --retries 10 --fragment-retries 10 --retry-sleep 5 \
-o "$DIR/%(title)s-%(id)s.%(ext)s" \ -o "$DIR/%(title)s-%(id)s.%(ext)s" \
"$CURL" "$URL"
``` ```
5. **Nextcloud Upload (HTTP PUT, Basic Auth):**
6. **Upload nach Nextcloud (n8nWeboberfläche):** ```
https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/dav/files/<DEIN_NC_BENUTZER>/Clips/{{ $json.data[0].id }}/<Dateiname>
```
6. **Analyse starten (SSH):**
* Node: **HTTP Request** ```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 }}"
```
7. **State aktualisieren:**
* Methode: **PUT** ```js
$workflow.staticData.global.last_vod_id = $json.data[0].id;
* Auth: **Basic Auth** (Nextcloud App-Passwort) return items;
```
* URL:
```
https://<DEINE_NEXTCLOUD_DOMAIN>/remote.php/dav/files/<DEIN_NC_BENUTZER>/Clips/{{ $json.data[0].id }}/<Dateiname>
```
* Ergebnis: In Nextcloud liegt danach ein Ordner `Clips/<VOD-ID>/…`.
> **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 (n8nWeboberflä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: TwitchCommunityNode (n8nWeboberfläche)
Wenn du statt HTTP Requests lieber einen fertigen TwitchNode nutzen willst, kannst du in selfhosted n8n einen **CommunityNode** installieren. Die Anleitung: [n8n Community Nodes](https://docs.n8n.io/integrations/community-nodes/). Beachte: CommunityNodes sind DrittanbieterCode und können bei Updates Probleme machen. Für einen stabilen Dauerbetrieb empfehlen wir den APIWeg mit HTTP Request.
--- ---
### Kontrolle ### Kontrolle
Nach einem erfolgreichen Durchlauf prüfst du im **Terminal des ClipperLXC**: Im Clipper-LXC:
```bash ```bash
su - clipper su - clipper
ls -lh /srv/clipper/inbox/<VOD-ID> ls -lh /srv/clipper/inbox/<VOD-ID>
tail -n 50 /srv/clipper/logs/clipper.log tail -n 50 /srv/clipper/logs/clipper.log
``` ```
Und in der **NextcloudWeboberfläche** solltest du den Ordner `Clips/<VOD-ID>` sehen. Damit ist die Pipeline geschlossen: Twitch liefert VODs, n8n steuert den Ablauf, Clipper verarbeitet, Nextcloud speichert. In Abschnitt 4 gehen wir in die AnalyseLogik und die KIAuswertung.
Powered by Gitea In Nextcloud: Ordner `Clips/<VOD-ID>` sollte erscheinen.
Version:
1.24.5
Seite:
107ms
Template:
24ms