Kapitel 13/Tutorial.md aktualisiert

This commit is contained in:
2025-09-19 15:44:30 +00:00
parent e9f202dd54
commit 5dd57188e8

View File

@@ -1210,3 +1210,137 @@ curl -fsSL https://git.bratonien.de/Thomas/Homelab--Bratonein-Kontrollzentrum--T
Alternativ kann die Datei auch manuell heruntergeladen und dort abgelegt werden.
Die Datei enthält eine Liste von z.B. bekannten Anime-Namen eine pro Zeile.
</details>
Um nun die Clips zu schneiden, benötigen wir ein weiteres Skript und einen weiteren Node.
Lege mit ```nano <clipper-ordner>/bin/clipper-cut-vod ``` die benötigte Datei an und fülle sie mit dem folgenden COde:
```bash
#!/bin/bash
VOD_ID="$1"
# Abschnitt 1: Namensmodus erkennen
ETC_DIR="/srv/clipper/etc"
CODE_POOL="$ETC_DIR/codename_pool.txt"
ADJ_POOL="$ETC_DIR/adjektive_de.txt"
# Standardmodus
NAMING_MODE="fallback"
if [[ -s "$CODE_POOL" && -s "$ADJ_POOL" ]]; then
NAMING_MODE="adjektiv_codename"
elif [[ -s "$CODE_POOL" ]]; then
NAMING_MODE="codename"
fi
echo "[INFO] Namensmodus erkannt: $NAMING_MODE"
# Abschnitt 2: Namen wählen (robust & ohne Wiederholung)
USED_PATH="/srv/clipper/etc/used.json"
mkdir -p "$(dirname "$USED_PATH")"
touch "$USED_PATH"
USED_LIST=$(jq -r '.[]' "$USED_PATH" 2>/dev/null || echo "")
is_used() {
grep -Fxq "$1" <<< "$USED_LIST"
}
choose_final_name() {
case "$NAMING_MODE" in
"codename")
mapfile -t CANDIDATES < "$CODE_POOL"
;;
"adjektiv_codename")
mapfile -t CODES < "$CODE_POOL"
mapfile -t ADJS < "$ADJ_POOL"
CANDIDATES=()
for adj in "${ADJS[@]}"; do
for code in "${CODES[@]}"; do
CANDIDATES+=("${adj}-${code}")
done
done
;;
"fallback")
echo "$VOD_ID"
return 0
;;
esac
# Filtere bereits genutzte Namen
AVAILABLE=()
for name in "${CANDIDATES[@]}"; do
if ! is_used "$name"; then
AVAILABLE+=("$name")
fi
done
if [[ ${#AVAILABLE[@]} -eq 0 ]]; then
echo "[WARN] Keine verfügbaren Namen mehr nutze Fallback: $VOD_ID"
echo "$VOD_ID"
else
FINAL_NAME="${AVAILABLE[RANDOM % ${#AVAILABLE[@]}]}"
echo "[INFO] Gewählter Codename: $FINAL_NAME"
echo "$FINAL_NAME"
fi
}
# Codename in used.json speichern (wenn nicht fallback)
if [[ "$FINAL_NAME" != "$VOD_ID" ]]; then
if jq -e . >/dev/null 2>&1 <<< "$USED_LIST"; then
UPDATED=$(jq --arg name "$FINAL_NAME" '. + [$name]' <<< "$USED_LIST")
else
UPDATED="[$(printf '%s\n' "$USED_LIST" | jq -R . | jq -s .), \"$FINAL_NAME\"]"
fi
echo "$UPDATED" > "$USED_PATH"
fi
# Verzeichnisstruktur
TMP_DIR="/srv/clipper/temp/$VOD_ID"
VOD_PATH="/srv/clipper/out/$VOD_ID/original/$VOD_ID.mp4"
CANDIDATES_JSON="$TMP_DIR/candidates.json"
CLIPS_DIR="/srv/clipper/out/$VOD_ID/clips"
mkdir -p "$CLIPS_DIR/combined"
mkdir -p "$CLIPS_DIR/audio"
mkdir -p "$CLIPS_DIR/video"
# Ziel für temporären CSV-Index
INDEX_CSV="$TMP_DIR/index.csv"
echo "Typ;Quelle;Beginn;Ende;Dateiname;Pfad" > "$INDEX_CSV"
CLIP_NUM=1
for SECTION in combined only_audio only_video; do
case "$SECTION" in
combined) SUBDIR="kombiniert"; QUELLE="kombiniert" ;;
only_audio) SUBDIR="audio"; QUELLE="audio" ;;
only_video) SUBDIR="video"; QUELLE="video" ;;
esac
mkdir -p "$CLIPS_DIR/$SUBDIR"
jq -c ".$SECTION[]" "$CANDIDATES_JSON" | while read -r clip; do
START=$(jq -r '.start' <<< "$clip")
END=$(jq -r '.end' <<< "$clip")
DURATION=$(awk "BEGIN { printf \"%.2f\", $END - $START }")
OUT_NAME=$(printf "%03d_%s.mp4" "$CLIP_NUM" "$FINAL_NAME")
OUT_PATH="$CLIPS_DIR/$SUBDIR/$OUT_NAME"
echo "[INFO] Schneide Clip $OUT_NAME ($START - $END → $DURATION s)"
ffmpeg -hide_banner -loglevel error -ss "$START" -i "$VOD_PATH" -t "$DURATION" -c copy "$OUT_PATH"
# Zeitformat HH:MM:SS
START_FMT=$(date -u -d "@$START" +"%H:%M:%S")
END_FMT=$(date -u -d "@$END" +"%H:%M:%S")
echo "Clip;$QUELLE;$START_FMT;$END_FMT;$OUT_NAME;clips/$SUBDIR/" >> "$INDEX_CSV"
CLIP_NUM=$((CLIP_NUM + 1))
done
done
```