Kapitel 13/Tutorial.md aktualisiert

This commit is contained in:
2025-08-30 19:37:32 +00:00
parent 7649a3fbe4
commit 923b1f7407

View File

@@ -451,82 +451,96 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
``` ```
Nun befüllst du sie mit: Nun befüllst du sie mit:
```bash ```bash
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
. /etc/clipper/clipper.env . /etc/clipper/clipper.env
ID="${1:?need VOD id}" ID="${1:?need VOD id}"
URL="${2:-https://www.twitch.tv/videos/${ID}}" URL="${2:-https://www.twitch.tv/videos/${ID}}"
TMP="${CLIPPER_TMP}" TMP="${CLIPPER_TMP}"
OUT_BASE="${CLIPPER_OUT}/${ID}" OUT_BASE="${CLIPPER_OUT}/${ID}"
LOGDIR="${CLIPPER_LOG}/${ID}" LOGDIR="${CLIPPER_LOG}/${ID}"
CONF="/home/clipper/.config/rclone/rclone.conf" CONF="/home/clipper/.config/rclone/rclone.conf"
DST="${CLIPPER_NC_REMOTE}/VODs/${ID}/" DST="${CLIPPER_NC_REMOTE}/VODs/${ID}/"
OUT="$TMP/${ID}.%(ext)s" OUT="$TMP/${ID}.%(ext)s"
FILE="$TMP/${ID}.mp4" FILE="$TMP/${ID}.mp4"
TEMP="$TMP/${ID}.temp.mp4" TEMP="$TMP/${ID}.temp.mp4"
PART="$TMP/${ID}.mp4.part" PART="$TMP/${ID}.mp4.part"
LOCK="$TMP/${ID}.lock" LOCK="$TMP/${ID}.lock"
mkdir -p "$TMP" "$LOGDIR" mkdir -p "$TMP" "$LOGDIR" "$OUT_BASE"
LOG="$LOGDIR/download.log" LOG="$LOGDIR/download.log"
log(){ echo "[$(date '+%F %T')] $*"; } log(){ echo "[$(date '+%F %T')] $*"; }
exec > >(tee -a "$LOG") 2>&1 exec > >(tee -a "$LOG") 2>&1
log "=== Start VOD $ID ===" # ---- atomarer Lock (kein Race zwischen zwei Starts)
log "URL: $URL" exec 9>"$LOCK"
log "DST: $DST" if ! flock -n 9; then
log "LOCK: $ID wird bereits verarbeitet"
exit 0
fi
trap 'flock -u 9; rm -f "$LOCK"' EXIT
if rclone lsf "$DST" --config "$CONF" >/dev/null 2>&1; then log "=== Start VOD $ID ==="
log "SKIP: $ID bereits in Nextcloud" log "URL: $URL"
exit 0 log "DST: $DST"
fi
if [[ -e "$LOCK" ]]; then # ---- Prüfe, ob die ZIELDATEI bereits existiert (nicht nur der Ordner)
log "LOCK: $ID wird bereits verarbeitet" if rclone lsf "$DST" --config "$CONF" | grep -qx "${ID}.mp4"; then
exit 0 log "SKIP: $ID.mp4 bereits in Nextcloud"
fi exit 0
trap 'rm -f "$LOCK"' EXIT fi
: > "$LOCK"
# Resume # ---- Resume: unvollständigen Download sauber fortsetzen
if [[ -s "$TEMP" && ! -s "$FILE" ]]; then if [[ -s "$TEMP" && ! -s "$FILE" ]]; then
log "RESUME: $TEMP -> $FILE" log "RESUME: $TEMP -> $FILE"
mv -f "$TEMP" "$FILE" mv -f "$TEMP" "$FILE"
fi fi
if [[ -s "$FILE" ]]; then # ---- Gemeinsame rclone-Flags: Nextcloud-Chunking + robuste Timeouts
log "MOVE (resume): $FILE → $DST" export RCLONE_WEBDAV_CHUNK_SIZE=100Mi # wirkt bei neueren rclone Versionen
rclone move "$FILE" "$DST" --config "$CONF" --create-empty-src-dirs -v
rm -f "$PART" "$TEMP" || true
log "CLEANUP: $TMP"
rm -rf "${TMP:?}/"*
log "=== Done VOD $ID (resume path) ==="
exit 0
fi
# Download + Remux rclone move "$FILE" "$DST" \
yt-dlp -q --no-progress --retries 20 --fragment-retries 50 --retry-sleep 5 \ --config "$CONF" --create-empty-src-dirs \
--socket-timeout 30 --hls-prefer-ffmpeg --remux-video mp4 -o "$OUT" "$URL" --transfers 1 --checkers 4 \
--retries 10 --low-level-retries 50 --retries-sleep 30s \
--timeout 1h --contimeout 1m --expect-continue-timeout 10m \
-v
[[ -s "$FILE" ]] || { [[ -s "$TEMP" ]] && mv -f "$TEMP" "$FILE"; } # ---- Wenn Datei schon da: nur noch hochschieben
if [[ -s "$FILE" ]]; then
log "MOVE (resume): $FILE → $DST"
rclone move "$FILE" "$DST" "${RCLONE_FLAGS[@]}"
rm -f "$PART" "$TEMP" || true
log "CLEANUP: $TMP"
rm -rf "${TMP:?}/"*
log "=== Done VOD $ID (resume path) ==="
exit 0
fi
if [[ ! -s "$FILE" ]]; then # ---- Download + Remux
log "ERROR: Download fehlgeschlagen ($FILE fehlt/leer)" yt-dlp -q --no-progress --retries 20 --fragment-retries 50 --retry-sleep 5 \
exit 2 --socket-timeout 30 --hls-prefer-ffmpeg --remux-video mp4 -o "$OUT" "$URL"
fi
log "MOVE: $FILE → $DST" [[ -s "$FILE" ]] || { [[ -s "$TEMP" ]] && mv -f "$TEMP" "$FILE"; }
rclone move "$FILE" "$DST" --config "$CONF" --create-empty-src-dirs -v
rm -f "$PART" "$TEMP" || true
log "CLEANUP: $TMP" if [[ ! -s "$FILE" ]]; then
rm -rf "${TMP:?}/"* log "ERROR: Download fehlgeschlagen ($FILE fehlt/leer)"
exit 2
fi
log "=== Done VOD $ID ===" log "MOVE: $FILE → $DST"
rclone move "$FILE" "$DST" "${RCLONE_FLAGS[@]}"
rm -f "$PART" "$TEMP" || true
log "CLEANUP: $TMP"
rm -rf "${TMP:?}/"*
log "=== Done VOD $ID ==="
"
``` ```
Mit diesem Skript laden wir die aktuellen VODs herunter, laden sie in die Nextcloud für die weitere Verabeitung und räumen wieder auf. Zusätzlich erzeugen wir logs in `<clipper-ordner>/logs/<ID>.log`. Mit diesem Skript laden wir die aktuellen VODs herunter, laden sie in die Nextcloud für die weitere Verabeitung und räumen wieder auf. Zusätzlich erzeugen wir logs in `<clipper-ordner>/logs/<ID>.log`.