diff --git a/Kapitel 13/Tutorial.md b/Kapitel 13/Tutorial.md index 5148a3c..f26d274 100644 --- a/Kapitel 13/Tutorial.md +++ b/Kapitel 13/Tutorial.md @@ -125,7 +125,7 @@ SFTP_USER=sftp_uploader SFTP_KEY=/home/clipper/.ssh/nc_sftp_ed25519 DROP_BASE="/mnt/hdd/incoming" CLIPPER_PEAK_THRESHOLD=0.85 - +CLIPPER_MATCH_TOLERANCE=4.0 CLIPPER_IN=/srv/clipper/watch CLIPPER_OUT=/srv/clipper/out @@ -826,86 +826,112 @@ Das folgende Schaubild zeigt dir die konkrete Verkabelung ``` ```bash - #!/usr/bin/env bash - set -euo pipefail + #!/bin/bash - . /etc/clipper/clipper.env +set -euo pipefail - ID="${1:?need VOD id}" +# Umgebungsvariablen laden +if [ -f "/etc/clipper/clipper.env" ]; then + set -a + . "/etc/clipper/clipper.env" + set +a +else + echo "[ERROR] Environment file not found: /etc/clipper/clipper.env" >&2 + exit 1 +fi - VOD_IN_MP4="${CLIPPER_OUT}/${ID}/original/${ID}.mp4" - OUT_BASE="${CLIPPER_OUT}/${ID}" - ANALYSIS="${OUT_BASE}/analysis" - LOGDIR="${CLIPPER_LOG}/${ID}" +# Erwartete Umgebungsvariablen prüfen +: "${CLIPPER_PEAK_THRESHOLD:?Environment variable CLIPPER_PEAK_THRESHOLD is not set.}" +: "${CLIPPER_TMP:?Environment variable CLIPPER_TMP is not set.}" +: "${CLIPPER_LOG:?Environment variable CLIPPER_LOG is not set.}" - mkdir -p "$ANALYSIS" "$LOGDIR" - exec > >(tee -a "${LOGDIR}/analyze.log") 2>&1 - echo "== Analyze $ID ==" +# ID aus dem Aufruf übernehmen +VOD_ID="$1" - echo "[FFMPEG] Szenewechselanalyse läuft..." - ffmpeg -hide_banner -loglevel error -i "${VOD_IN_MP4}" \ - -vf "scale=-2:360,select=gt(scene\,0.30),showinfo" -an -f null - \ - 2> "${LOGDIR}/sceneinfo.log" +VOD_PATH="/srv/clipper/out/$VOD_ID/original/$VOD_ID.mp4" +TMP_DIR="$CLIPPER_TMP/$VOD_ID" +TMP_AUDIO="$TMP_DIR/audio.wav" +LOG_DIR="$CLIPPER_LOG/$VOD_ID" +TMP_LOG_AUDIO="$LOG_DIR/audio.log" +TMP_JSON="$TMP_DIR/candidates.json" - echo "[FFMPEG] Audiostatistik läuft..." - ffmpeg -hide_banner -loglevel error -i "${VOD_IN_MP4}" \ - -vn -ac 1 -ar 16000 \ - -af "astats=metadata=1:reset=2,ametadata=print:key=lavfi.astats.Overall.RMS_level" \ - -f null - \ - 2> "${LOGDIR}/astats.log" || true +mkdir -p "$TMP_DIR" "$LOG_DIR" +exec > >(tee -a "${LOG_DIR}/analyze.log") 2>&1 +echo "== Analyze $VOD_ID ==" +echo "[INFO] VOD gefunden: $VOD_PATH" +echo "[INFO] Extrahiere WAV aus $VOD_PATH → $TMP_AUDIO" - ANALYSIS="$ANALYSIS" LOGDIR="$LOGDIR" python3 - <<'PY' - import os, re, json, sys - from datetime import datetime +# Audio extrahieren mit Logging +ffmpeg -v warning -i "$VOD_PATH" -ac 1 -ar 16000 -vn "$TMP_AUDIO" 2> "$TMP_LOG_AUDIO" +echo "[OK] Audio extrahiert: $TMP_AUDIO ($(du -h "$TMP_AUDIO" | cut -f1))" - def log(msg): - timestamp = datetime.now().strftime("%F %T") - print(f"[PY] [{timestamp}] {msg}") +echo "[INFO] Verwende Schwelle: $CLIPPER_PEAK_THRESHOLD" +echo "[INFO] Starte Python-Analyse..." - out = os.environ["ANALYSIS"] - logdir = os.environ["LOGDIR"] +# Python-Analyse +/srv/clipper/.venv/bin/python3 - < cutoff)[0] - target = os.path.join(out, "candidates.json") - try: - with open(target, "w", encoding="utf-8") as f: - json.dump(cands, f, ensure_ascii=False, indent=2) - log(f"{len(cands)} Kandidaten gespeichert → {target}") - except Exception as e: - log(f"Fehler beim Schreiben von candidates.json: {e}") - sys.exit(2) - PY +if len(high_energy) == 0: + print("[INFO] Keine Peaks über Schwelle gefunden.") + with open(outfile, 'w') as f: + json.dump([], f) + print(f"[DONE] {outfile} geschrieben mit 0 Clip(s)") + exit(0) - echo "== Done $ID ==" +# Zeiträume berechnen +candidates = [] +t_start = None +for i in range(len(energy)): + t = i * frame_length / sr + if energy[i] > cutoff: + if t_start is None: + t_start = t + elif t_start is not None: + t_end = t + if t_end - t_start > 5: + candidates.append({"start": round(t_start, 2), "end": round(t_end, 2)}) + t_start = None + +if t_start is not None: + t_end = len(y) / sr + if t_end - t_start > 5: + candidates.append({"start": round(t_start, 2), "end": round(t_end, 2)}) + +with open(outfile, 'w') as f: + json.dump(candidates, f) +print(f"[DONE] {outfile} geschrieben mit {len(candidates)} Clip(s)") +EOF ``` 1. **SSH Node – Analyze VOD** (Node-Name: Analyze VOD) - Node-Typ: SSH