Files
wcx_script/compare_simple.sh
2025-10-09 10:55:52 +02:00

88 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# compare_simple.sh file1.mp4 file2.mp4
set -euo pipefail
f1="${1:-}"; f2="${2:-}"
if [[ -z "$f1" || -z "$f2" ]]; then
echo "Usage: $0 <file1> <file2>" >&2
exit 2
fi
for f in "$f1" "$f2"; do
[[ -f "$f" ]] || { echo "Not found: $f" >&2; exit 2; }
done
probe() {
local f="$1"
# format props
local size dur br
size=$(stat -c%s "$f" 2>/dev/null || stat -f%z "$f")
dur=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$f" || echo "")
br=$(ffprobe -v error -show_entries format=bit_rate -of default=nw=1:nk=1 "$f" || echo "")
# first video stream
local vcodec w h fps
vcodec=$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f" || echo "")
w=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=nw=1:nk=1 "$f" || echo "")
h=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of default=nw=1:nk=1 "$f" || echo "")
# r_frame_rate like 24000/1001 → convert to float
local rfr
rfr=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=nw=1:nk=1 "$f" || echo "")
if [[ "$rfr" == */* ]]; then
fps=$(awk -v r="$rfr" 'BEGIN{split(r,a,"/"); if(a[2]==0) print 0; else printf "%.3f", a[1]/a[2]}')
else
fps=$(awk -v r="$rfr" 'BEGIN{printf "%.3f", r+0}')
fi
# audio summary (codec:channels@rate, semicolon-separated)
local ainfo
ainfo=$(ffprobe -v error -select_streams a -show_entries stream=codec_name,channels,sample_rate -of csv=p=0 "$f" \
| awk -F, '{printf "%s:%s@%s", $1, $2, $3; if (NR!=0) printf "\n"}' \
| paste -sd';' - || true)
echo "$size|$dur|$br|$vcodec|${w}x${h}|$fps|$ainfo"
}
read -r s1 d1 br1 vc1 res1 fps1 a1 <<<"$(probe "$f1" | tr '|' ' ')"
read -r s2 d2 br2 vc2 res2 fps2 a2 <<<"$(probe "$f2" | tr '|' ' ')"
# helpers
absdiff() { awk -v a="$1" -v b="$2" 'BEGIN{d=a-b; if(d<0)d=-d; print d}'; }
pctdiff() { awk -v a="$1" -v b="$2" 'BEGIN{if(a==0&&b==0){print 0;exit} m=(a+b)/2; if(m==0){print 100;exit} d=a-b; if(d<0)d=-d; printf "%.2f", (d/m)*100 }'; }
dur_diff=$(absdiff "${d1:-0}" "${d2:-0}")
fps_diff=$(absdiff "${fps1:-0}" "${fps2:-0}")
size_pct=$(pctdiff "${s1:-0}" "${s2:-0}")
printf "File 1: %s\n" "$f1"
printf " Size: %s bytes\n Duration: %.3fs\n Video: %s, %s, %.3f fps\n" "$s1" "${d1:-0}" "${vc1:-?}" "${res1:-?}" "${fps1:-0}"
printf " Audio: %s\n" "${a1:-none}"
printf "\n"
printf "File 2: %s\n" "$f2"
printf " Size: %s bytes\n Duration: %.3fs\n Video: %s, %s, %.3f fps\n" "$s2" "${d2:-0}" "${vc2:-?}" "${res2:-?}" "${fps2:-0}"
printf " Audio: %s\n" "${a2:-none}"
printf "\n"
echo "Differences:"
printf " Size delta: %s%%\n" "$size_pct"
printf " Duration delta: %.3fs\n" "$dur_diff"
printf " FPS delta: %.3f\n" "$fps_diff"
printf " Resolution match: %s\n" "$([[ "$res1" == "$res2" ]] && echo yes || echo no)"
printf " Video codec match: %s\n" "$([[ "$vc1" == "$vc2" ]] && echo yes || echo no)"
printf " Audio tracks match: %s\n" "$([[ "$a1" == "$a2" ]] && echo yes || echo no)"
echo
# verdict heuristics
likely="Different"
# allow small tolerance on duration/fps
dur_ok=$(awk -v d="$dur_diff" 'BEGIN{print (d<=1.0)?"1":"0"}')
fps_ok=$(awk -v d="$fps_diff" 'BEGIN{print (d<=0.5)?"1":"0"}')
if [[ "$res1" == "$res2" && "$dur_ok" == "1" && "$fps_ok" == "1" ]]; then
likely="Likely same content (possibly different encode)"
fi
if [[ "$vc1" == "$vc2" && "$a1" == "$a2" && "$size_pct" == "0.00" ]]; then
likely="Identical encode/container"
fi
echo "Verdict: $likely"