Files
wcx_script/scan_and_prefix_pink.sh
2026-03-14 11:13:56 +01:00

179 lines
5.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# scan_and_prefix_pink.sh
#
# Scan a directory for MP4 files, detect a pink/magenta intro,
# and prefix matching files (unless already prefixed).
#
# Options:
# --dry-run, --recursive/-r, --prefix PREFIX, etc. (same as before)
set -euo pipefail
# ---- Defaults ----
DRY_RUN=0
RECURSIVE=0
PREFIX="[WUNF_*]"
DURATION="1.0"
FPS="6"
HUE_MIN="285"
HUE_MAX="330"
SAT_MIN="0.35"
VAL_MIN="0.35"
MIN_RATIO="0.6"
# ---- Parse args ----
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <directory> [--dry-run] [--recursive|-r] [--prefix PREFIX] ..." >&2
exit 2
fi
DIR="$1"; shift || true
[[ -d "$DIR" ]] || { echo "Not a directory: $DIR" >&2; exit 2; }
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=1; shift ;;
--recursive|-r) RECURSIVE=1; shift ;;
--prefix) PREFIX="${2:-}"; shift 2 ;;
--duration) DURATION="${2:-}"; shift 2 ;;
--fps) FPS="${2:-}"; shift 2 ;;
--hue-min) HUE_MIN="${2:-}"; shift 2 ;;
--hue-max) HUE_MAX="${2:-}"; shift 2 ;;
--sat-min) SAT_MIN="${2:-}"; shift 2 ;;
--val-min) VAL_MIN="${2:-}"; shift 2 ;;
--min-ratio) MIN_RATIO="${2:-}"; shift 2 ;;
--help|-h)
grep -E '^# ' "$0" | sed 's/^# //'; exit 0 ;;
*) echo "Unknown option: $1" >&2; exit 2 ;;
esac
done
# ---- Derived rename prefix ----
RENAME_PREFIX="$PREFIX"
# Om PREFIX har formen [TEXT_*] (t.ex. [WUNF_*]) så gör vi rename-prefix = [TEXT]_
if [[ "$PREFIX" =~ ^\[([^][]+)_\*\]$ ]]; then
RENAME_PREFIX="[${BASH_REMATCH[1]}]_"
fi
# ---- Helpers ----
print_result() { # $1=status $2=file $3=detail
printf "%-10s %s%s\n" "$1" "$2" "${3:+ ($3)}"
}
safe_rename() { # $1=path $2=prefix
local path="$1" pre="$2"
local dir base target
dir=$(dirname -- "$path")
base=$(basename -- "$path")
target="${dir}/${pre}${base}"
# Avoid collisions
if [[ -e "$target" ]]; then
local n=1
while [[ -e "${target}.${n}" ]]; do n=$((n+1)); done
target="${target}.${n}"
fi
if [[ $DRY_RUN -eq 1 ]]; then
print_result "RENAMED" "$path" "dry-run → $(basename -- "$target")"
else
if mv -- "$path" "$target"; then
print_result "RENAMED" "$path" "$(basename -- "$target")"
else
print_result "ERROR" "$path" "rename failed"
fi
fi
}
detect_pink() { # $1=file -> echoes "total pink ratio"
local file="$1"
LC_ALL=C ffmpeg -hide_banner -v error \
-i "$file" -t "$DURATION" \
-vf "fps=${FPS},scale=1:1:flags=area,format=rgb24" \
-f rawvideo - 2>/dev/null \
| od -An -tu1 -w3 \
| awk -v HMIN="$HUE_MIN" -v HMAX="$HUE_MAX" -v SMIN="$SAT_MIN" -v VMIN="$VAL_MIN" '
function fmod(a,b){ return a - int(a/b)*b }
function rgb2hsv(R,G,B, r,g,b,M,m,d,H,S,V) {
r=R/255.0; g=G/255.0; b=B/255.0;
M=r; if(g>M) M=g; if(b>M) M=b;
m=r; if(g<m) m=g; if(b<m) m=b;
d=M-m; V=M;
if (M==0) S=0; else S=(d==0?0:d/M);
if (d==0) H=0;
else if (M==r) H = 60.0 * fmod(((g-b)/d), 6);
else if (M==g) H = 60.0 * (((b-r)/d) + 2);
else H = 60.0 * (((r-g)/d) + 4);
if (H < 0) H += 360.0;
hsv[1]=H; hsv[2]=S; hsv[3]=V;
}
BEGIN{ total=0; pink=0; }
NF==3 {
R=$1; G=$2; B=$3; total++;
rgb2hsv(R,G,B); H=hsv[1]; S=hsv[2]; V=hsv[3];
if (H>=HMIN && H<=HMAX && S>=SMIN && V>=VMIN) pink++;
}
END {
if (total==0) { print "0 0 0"; exit; }
printf "%d %d %.3f\n", total, pink, pink/total;
}'
}
is_mp4() { case "$1" in *.mp4|*.MP4) return 0;; *) return 1;; esac; }
# Prefix-match med optional * = 13 siffror
is_prefixed() { # $1=basename $2=prefix
local base="$1" prefix="$2"
# Special handling for patterns like [TEXT_*]
if [[ "$prefix" =~ ^\[([^][]+)_\*\]$ ]]; then
local tag="${BASH_REMATCH[1]}"
# Already-prefixed means: [TAG]_... or [TAG_###]_... at the start
local re="^\[$tag(_[0-9]{1,3})?]_"
[[ "$base" =~ $re ]]
else
# Fallback: simple "starts with prefix"
[[ "$base" == "$prefix"* ]]
fi
}
# ---- File list ----
if [[ $RECURSIVE -eq 1 ]]; then
mapfile -t FILES < <(find "$DIR" -type f \( -iname '*.mp4' \))
else
mapfile -t FILES < <(ls "$DIR"/*.mp4 "$DIR"/*.MP4 2>/dev/null || true)
fi
# ---- Process ----
if [[ ${#FILES[@]} -eq 0 ]]; then
echo "No MP4 files found in: $DIR"
exit 0
fi
for f in "${FILES[@]}"; do
[[ -f "$f" ]] || { print_result "SKIPPED" "$f" "not a file"; continue; }
is_mp4 "$f" || { print_result "SKIPPED" "$f" "not mp4"; continue; }
base=$(basename -- "$f")
# Matchning använder PREFIX (med * → 13 siffror)
if is_prefixed "$base" "$PREFIX"; then
print_result "SKIPPED" "$f" "already prefixed"
continue
fi
read -r total pink ratio < <(detect_pink "$f")
if [[ "$total" -eq 0 ]]; then
print_result "ERROR" "$f" "no frames parsed"
continue
fi
awk -v r="$ratio" -v thr="$MIN_RATIO" 'BEGIN{exit !(r>=thr)}' && {
# Omdöpning använder RENAME_PREFIX (t.ex. [WUNF]_)
safe_rename "$f" "$RENAME_PREFIX"
continue
}
print_result "NOT_MATCH" "$f" "ratio=${ratio} (<${MIN_RATIO})"
done