Files
custom_scripts/generate-thumb
2025-11-17 00:41:24 +01:00

121 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
SCENEDETECT="$HOME/.venvs/scenedetect-env/bin/scenedetect"
PROCESSED_LOG="$HOME/.cache/processed_videos.log"
set -e
# Ensure log file exists
mkdir -p "$(dirname "$PROCESSED_LOG")"
touch "$PROCESSED_LOG"
# Find all video files (case-insensitive match)
find . -type f \( -iname "*.mp4" -o -iname "*.mkv" -o -iname "*.avi" \) -print0 |
while IFS= read -r -d '' video; do
echo "🔍 Processing: $video"
# Skip if already processed
if grep -Fxq "$video" "$PROCESSED_LOG"; then
echo "⚠️ Already processed, skipping: $video"
continue
fi
# Get duration in seconds
duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$video")
duration=${duration%.*}
start=180
end=$((duration - 180))
[[ "$end" -le "$start" ]] && echo "❌ Skipping (too short): $video" && continue
length=$((end - start))
base="${video%.*}"
trimmed="${base}_trimmed_tmp.mp4"
workdir="${base}_thumb_tmp"
mkdir -p "$workdir"
# Suppress ffmpeg output
ffmpeg -hide_banner -loglevel error -y -ss "$start" -i "$video" -t "$length" -c copy "$trimmed"
# Scene detection
"$SCENEDETECT" -i "$trimmed" -o "$workdir" detect-content save-images
# Rank images by sharpness
best_image=""
best_score=0
for img in "$workdir"/*.jpg; do
score=$(identify -format "%[standard-deviation]" "$img" 2>/dev/null | cut -d',' -f1)
score_float=$(printf "%.6f\n" "$score")
if (( $(echo "$score_float > $best_score" | bc -l) )); then
best_score=$score_float
best_image="$img"
fi
done
thumb="${base}-thumb.jpg"
cp "$best_image" "$thumb"
echo "✅ Thumbnail saved: $thumb"
echo "$video" >> "$PROCESSED_LOG"
rm -rf "$workdir" "$trimmed"
done
########## Using full video duration ##########
# #!/bin/bash
# SCENEDETECT="$HOME/.venvs/scenedetect-env/bin/scenedetect"
# PROCESSED_LOG="$HOME/.cache/processed_videos.log"
# set -e
# video="$1"
# [[ ! -f "$video" ]] && echo "Video not found: $video" && exit 1
# # Ensure log file exists
# mkdir -p "$(dirname "$PROCESSED_LOG")"
# touch "$PROCESSED_LOG"
# # Check if video is already processed
# if grep -Fxq "$video" "$PROCESSED_LOG"; then
# echo "⚠️ Video already processed: $video"
# exit 0
# fi
# # Prepare paths
# base="${video%.*}"
# workdir="${base}_thumb_tmp"
# mkdir -p "$workdir"
# # Step 1: Scene detection
# "$SCENEDETECT" -i "$video" -o "$workdir" detect-content save-images
# # Step 2: Rank images by sharpness (standard deviation)
# best_image=""
# best_score=0
# for img in "$workdir"/*.jpg; do
# # Get standard deviation of luminance
# score=$(identify -format "%[standard-deviation]" "$img" 2>/dev/null | cut -d',' -f1)
# # Compare scores
# score_float=$(printf "%.6f\n" "$score")
# if (( $(echo "$score_float > $best_score" | bc -l) )); then
# best_score=$score_float
# best_image="$img"
# fi
# done
# # Step 3: Save best image with Jellyfin naming scheme
# thumb="${base}-thumb.jpg"
# cp "$best_image" "$thumb"
# echo "✅ Thumbnail saved: $thumb"
# # Step 4: Mark as processed
# echo "$video" >> "$PROCESSED_LOG"
# # Step 5: Cleanup
# rm -rf "$workdir"