Live video on the AT Protocol
at next 121 lines 5.0 kB view raw
1#!/bin/bash 2 3set -euo pipefail 4 5ONE="$(realpath "$1")" 6TWO="$(realpath "$2")" 7BASE_ONE="$(basename "$ONE")" 8BASE_TWO="$(basename "$TWO")" 9 10if [[ -d "$ONE" && -d "$TWO" ]]; then 11 FILES_ONE=$(find "$ONE" -maxdepth 1 -mindepth 1 -type f -name '*.mp4' | xargs -L 1 basename | sort) 12 FILES_TWO=$(find "$TWO" -maxdepth 1 -mindepth 1 -type f -name '*.mp4' | xargs -L 1 basename | sort) 13 14 NUM_FILES_ONE=$(echo "$FILES_ONE" | wc -l) 15 NUM_FILES_TWO=$(echo "$FILES_TWO" | wc -l) 16 17 if [[ "$NUM_FILES_ONE" -ne "$NUM_FILES_TWO" ]]; then 18 echo "Directory contents differ: different number of files" 19 comm -3 <(echo "$FILES_ONE") <(echo "$FILES_TWO") 20 exit 1 21 fi 22 23 # Compare files by their order in the sorted lists, regardless of filenames 24 paste <(echo "$FILES_ONE") <(echo "$FILES_TWO") | while read -r file_one file_two; do 25 # skip if either file entry is empty (may only occur if line counts mismatched, but that's handled above) 26 [ -n "$file_one" ] && [ -n "$file_two" ] || continue 27 echo "Comparing $file_one <=> $file_two" 28 set +e 29 "$0" "$ONE/$file_one" "$TWO/$file_two" 30 set -e 31 done 32 exit 0 33fi 34 35 36cd "$(mktemp -d)" 37HASH_ONE=$(openssl sha256 "$ONE" | awk '{print $2}') 38HASH_TWO=$(openssl sha256 "$TWO" | awk '{print $2}') 39if [ "$HASH_ONE" = "$HASH_TWO" ]; then 40 echo "Identical: $BASE_ONE $BASE_TWO $(pwd)" 41 exit 0 42fi 43pwd 44echo "Hash for $ONE: $HASH_ONE" 45echo "Hash for $TWO: $HASH_TWO" 46 47xxd "$ONE" > "1.xxd" 48xxd "$TWO" > "2.xxd" 49(diff --color=always "1.xxd" "2.xxd" || true) | head -n 5 50 51ffmpeg -y -loglevel fatal -i "$ONE" -c copy -f framemd5 "1.md5" 52ffmpeg -y -loglevel fatal -i "$TWO" -c copy -f framemd5 "2.md5" 53(diff --color=always "1.md5" "2.md5" || true) | head -n 5 54 55ffprobe -loglevel fatal -show_frames "$ONE" > "1.frames" 56ffprobe -loglevel fatal -show_frames "$TWO" > "2.frames" 57(diff --color=always "1.frames" "2.frames" || true) | head -n 5 58 59set +e 60echo -e "\033[0m" 61video_frames_one="$(cat 1.frames | grep media_type=video | wc -l | xargs)" 62video_frames_two="$(cat 2.frames | grep media_type=video | wc -l | xargs)" 63if [[ "$video_frames_one" -ne "$video_frames_two" ]]; then 64 echo "Video frame count mismatch: $video_frames_one -> $video_frames_two" 65fi 66set -e 67 68audio_frames_one="$(cat 1.frames | grep media_type=audio | wc -l | xargs)" 69audio_frames_two="$(cat 2.frames | grep media_type=audio | wc -l | xargs)" 70if [[ "$audio_frames_one" -ne "$audio_frames_two" ]]; then 71 echo "Audio frame count mismatch: $audio_frames_one -> $audio_frames_two" 72fi 73 74# ffmpeg -y -loglevel fatal -i "$ONE" -frames:v 1 -c copy -an 1frame.h264 75# ffmpeg -y -loglevel fatal -i "$TWO" -frames:v 1 -c copy -an 2frame.h264 76 77bash -c "ffmpeg -y -bsf:v trace_headers -i \"$ONE\" -c copy -f null /dev/null 2>&1" | sed 's/\[trace_headers @ 0x[0-9a-f]*\]//' > 1.trace_headers 78bash -c "ffmpeg -y -bsf:v trace_headers -i \"$TWO\" -c copy -f null /dev/null 2>&1" | sed 's/\[trace_headers @ 0x[0-9a-f]*\]//' > 2.trace_headers 79(diff --color=always "1.trace_headers" "2.trace_headers" || true) | head -n 5 80 81go install github.com/Eyevinn/mp4ff/cmd/mp4ff-info@latest || true 82mp4ff-info "$ONE" > 1.mp4ff-info 83mp4ff-info "$TWO" > 2.mp4ff-info 84(diff --color=always "1.mp4ff-info" "2.mp4ff-info" || true) | head -n 5 85 86# ffmpeg -y -loglevel fatal -i "$ONE" -c copy 1tweaked.mp4 87# ffmpeg -y -loglevel fatal -i "$TWO" -c copy 2tweaked.mp4 88 89# ffmpeg -y -bsf:v trace_headers -i 1tweaked.mp4 -c copy -f null /dev/null 2>&1 | sed 's/.*\]//' > 1.trace_headers 90# ffmpeg -y -bsf:v trace_headers -i 2tweaked.mp4 -c copy -f null /dev/null 2>&1 | sed 's/.*\]//' > 2.trace_headers 91 92# diff --color=always "1.trace_headers" "2.trace_headers" || true 93 94# ffmpeg -y -loglevel fatal -bsf:v h264_redundant_pps -i "$ONE" -c copy 1tweaked.mp4 95# ffmpeg -y -loglevel fatal -bsf:v h264_redundant_pps -i "$TWO" -c copy 2tweaked.mp4 96 97# ffmpeg -y -loglevel fatal -i 1tweaked.mp4 -c copy -f framemd5 "1tweaked.mp4.md5" 98# ffmpeg -y -loglevel fatal -i 2tweaked.mp4 -c copy -f framemd5 "2tweaked.mp4.md5" 99# (diff --color=always "1tweaked.mp4.md5" "2tweaked.mp4.md5" || true) 100 101# (diff --color=always "1.trace_headers" "2.trace_headers" || true) 102 103# ffmpeg -y -loglevel fatal -i "$ONE" -c:v copy -bsf:v h264_mp4toannexb -an 1.ts 104# ffmpeg -y -loglevel fatal -i "$TWO" -c:v copy -bsf:v h264_mp4toannexb -an 2.ts 105# ffmpeg -y -loglevel fatal -i 1.ts -c copy -f framemd5 "1.ts.md5" 106# ffmpeg -y -loglevel fatal -i 2.ts -c copy -f framemd5 "2.ts.md5" 107# (diff --color=always "1.ts.md5" "2.ts.md5" || true) 108 109echo -e "\033[0m" 110echo "Useful commands:" 111echo "Compare ffprobe -show_frames data:" 112echo " meld $(realpath 1.frames) $(realpath 2.frames)" 113echo "Compare frame headers:" 114echo " meld $(realpath 1.trace_headers) $(realpath 2.trace_headers)" 115echo "Compare hex hashes:" 116echo " meld $(realpath 1.xxd) $(realpath 2.xxd)" 117echo "Compare framemd5 hashes:" 118echo " meld $(realpath 1.md5) $(realpath 2.md5)" 119echo "Compare mp4ff-info data:" 120echo " meld $(realpath 1.mp4ff-info) $(realpath 2.mp4ff-info)" 121exit 1