add nvenc-compress package
This commit is contained in:
87
global/nvenc_compress.sh
Executable file
87
global/nvenc_compress.sh
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Usage: nvenc_compress.sh <video_path> [target_size_mb]
|
||||
|
||||
VIDEO="$1"
|
||||
TARGET_MB="${2:-9}"
|
||||
TARGET_BYTES=$((TARGET_MB * 1024 * 1024))
|
||||
|
||||
if [[ ! -f "$VIDEO" ]]; then
|
||||
echo "Error: file not found: $VIDEO"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BASENAME="${VIDEO##*/}"
|
||||
BASENAME="${BASENAME%.*}"
|
||||
OUTDIR="$(dirname "$VIDEO")"
|
||||
OUTFILE="$OUTDIR/${BASENAME}_compressed.mp4"
|
||||
|
||||
# nvenc cq range: 0 (best/largest) to 51 (worst/smallest)
|
||||
# We binary search this range to hit the target file size
|
||||
LO=0
|
||||
HI=51
|
||||
BEST_DIFF=999999999
|
||||
BEST_CQ=23
|
||||
MAX_ITERATIONS=20
|
||||
|
||||
echo "Target size: ${TARGET_MB}MB (${TARGET_BYTES} bytes)"
|
||||
echo "Encoding with nvenc (h264_nvenc)..."
|
||||
echo ""
|
||||
|
||||
for ((i=0; i<MAX_ITERATIONS; i++)); do
|
||||
CQ=$(( (LO + HI) / 2 ))
|
||||
TMPFILE="${OUTFILE}_iter_${i}_cq${CQ}.mp4"
|
||||
|
||||
echo "--- Iteration $((i+1))/$MAX_ITERATIONS ---"
|
||||
echo "Trying cq=$CQ (lo=$LO, hi=$HI)"
|
||||
|
||||
ffmpeg -y -i "$VIDEO" -c:v h264_nvenc -cq "$CQ" -c:a copy -preset p7 -f mp4 "$TMPFILE" 2>/dev/null
|
||||
|
||||
if [[ ! -f "$TMPFILE" ]]; then
|
||||
echo "Error: ffmpeg failed at cq=$CQ"
|
||||
rm -f "$TMPFILE"
|
||||
break
|
||||
fi
|
||||
|
||||
FILE_SIZE=$(stat -c%s "$TMPFILE" 2>/dev/null || stat -f%z "$TMPFILE" 2>/dev/null)
|
||||
DIFF=$(( FILE_SIZE - TARGET_BYTES ))
|
||||
ABS_DIFF=${DIFF#-}
|
||||
|
||||
echo " Size: $(( FILE_SIZE / 1024 / 1024 ))MB (diff: $(( DIFF / 1024 / 1024 ))MB)"
|
||||
|
||||
if (( ABS_DIFF < BEST_DIFF )); then
|
||||
BEST_DIFF=$ABS_DIFF
|
||||
BEST_CQ=$CQ
|
||||
cp "$TMPFILE" "$OUTFILE"
|
||||
fi
|
||||
|
||||
rm -f "$TMPFILE"
|
||||
|
||||
# If within 1% of target, we're close enough
|
||||
if (( ABS_DIFF < TARGET_BYTES / 100 )); then
|
||||
echo ""
|
||||
echo "Within tolerance! Stopping."
|
||||
break
|
||||
fi
|
||||
|
||||
# Binary search direction:
|
||||
# Higher cq = smaller file, lower cq = larger file
|
||||
if (( FILE_SIZE > TARGET_BYTES )); then
|
||||
# File too big, need higher cq (smaller)
|
||||
LO=$(( CQ + 1 ))
|
||||
else
|
||||
# File too small, need lower cq (larger)
|
||||
HI=$(( CQ - 1 ))
|
||||
fi
|
||||
|
||||
if (( LO > HI )); then
|
||||
echo ""
|
||||
echo "Range exhausted. Stopping."
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Done! Best cq=$BEST_CQ, final size: $(( BEST_DIFF / 1024 / 1024 ))MB from target"
|
||||
echo "Output: $OUTFILE"
|
||||
Reference in New Issue
Block a user