every.channel: sanitized baseline
This commit is contained in:
commit
897e556bea
258 changed files with 74298 additions and 0 deletions
108
scripts/determinism-cmaf.sh
Executable file
108
scripts/determinism-cmaf.sh
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${root}"
|
||||
|
||||
input=""
|
||||
seconds="6"
|
||||
chunk_ms="2000"
|
||||
|
||||
usage() {
|
||||
cat >&2 <<'EOF'
|
||||
usage:
|
||||
scripts/determinism-cmaf.sh --input <TS_FILE_OR_URL> [--seconds N] [--chunk-ms MS]
|
||||
|
||||
what it does:
|
||||
- runs the CMAF (HLS fMP4) encoder/segmenter twice with the deterministic x264 profile
|
||||
- compares sha256 of init + segments to check byte-for-byte determinism
|
||||
|
||||
notes:
|
||||
- requires `ffmpeg` on PATH
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--input)
|
||||
input="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--seconds)
|
||||
seconds="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--chunk-ms)
|
||||
chunk_ms="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "error: unknown arg: $1" >&2
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "${input}" ]]; then
|
||||
echo "error: --input is required" >&2
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
ts="$input"
|
||||
if [[ "${input}" == http://* || "${input}" == https://* ]]; then
|
||||
ts="$tmp/in.ts"
|
||||
ffmpeg -hide_banner -loglevel error -nostdin -y \
|
||||
-t "${seconds}" -i "${input}" -c copy -f mpegts "${ts}"
|
||||
fi
|
||||
|
||||
seg_secs="$(python3 - <<PY
|
||||
ms=int("${chunk_ms}")
|
||||
print(f"{ms/1000:.3f}")
|
||||
PY
|
||||
)"
|
||||
|
||||
run_one() {
|
||||
out="$1"
|
||||
rm -rf "$out"
|
||||
mkdir -p "$out"
|
||||
(cd "$out" && ffmpeg -hide_banner -loglevel error -nostdin -y \
|
||||
-i "pipe:0" \
|
||||
-map 0:v:0 -map 0:a:0? -sn -dn -map_metadata -1 \
|
||||
-c:v libx264 \
|
||||
-c:a aac -b:a 128k -ac 2 -ar 48000 \
|
||||
-pix_fmt yuv420p -g 60 -keyint_min 60 -sc_threshold 0 -bf 0 \
|
||||
-threads 1 \
|
||||
-fflags +bitexact -flags:v +bitexact -flags:a +bitexact \
|
||||
-f hls \
|
||||
-hls_time "${seg_secs}" \
|
||||
-hls_list_size 0 \
|
||||
-hls_segment_type fmp4 \
|
||||
-hls_flags independent_segments \
|
||||
-hls_fmp4_init_filename init.mp4 \
|
||||
-hls_segment_filename segment_%06d.m4s \
|
||||
index.m3u8 < "$ts")
|
||||
}
|
||||
|
||||
run_one "$tmp/a"
|
||||
run_one "$tmp/b"
|
||||
|
||||
(cd "$tmp/a" && shasum -a 256 init.mp4 segment_*.m4s | sort) > "$tmp/a.sha"
|
||||
(cd "$tmp/b" && shasum -a 256 init.mp4 segment_*.m4s | sort) > "$tmp/b.sha"
|
||||
|
||||
if diff -u "$tmp/a.sha" "$tmp/b.sha" >/dev/null; then
|
||||
echo "OK: deterministic (init + segments match)"
|
||||
else
|
||||
echo "DIFF: non-deterministic output"
|
||||
diff -u "$tmp/a.sha" "$tmp/b.sha" || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue