#!/usr/bin/env bash ######################################################################## # # This bash script was written by ChatGPT, but not this docblock. # Everything works after testing, but not 2 functions: # - Adding metadata to compressed MP4 file. # - Checking if the file has already been compressed by this script. # ######################################################################## set -u SCRIPT_NAME="$(basename "$0")" UNIQUE_PREFIX="r-" ######################################## # Encoding presets overview: # # none : balanced quality, AAC 96k # vlog : spoken voice / crowd, copy audio # tiny : max compression, AAC 64k # # Resolutions: 720p | 1080p ######################################## show_help() { cat < $SCRIPT_NAME [none|vlog|tiny] [720p|1080p] $SCRIPT_NAME batch Batch: Compresses all MP4 + MKV files using: mode=none, resolution=1080p Defaults: mode=none resolution=720p EOF exit 0 } [[ "${1:-}" == "--help" ]] && show_help MODE="none" RES="720p" # --- Batch mode --- if [[ "${1:-}" == "batch" ]]; then MODE="none" RES="1080p" shift || true shopt -s nullglob FILES=( *.mp4 *.mkv ) shopt -u nullglob if [[ ${#FILES[@]} -eq 0 ]]; then echo "No MP4 or MKV files found." exit 0 fi for f in "${FILES[@]}"; do "$0" "$MODE" "$RES" "$f" done exit 0 fi # --- Parse arguments --- if [[ $# -eq 1 ]]; then INPUT="$1" elif [[ $# -eq 2 ]]; then MODE="$1" INPUT="$2" elif [[ $# -eq 3 ]]; then MODE="$1" RES="$2" INPUT="$3" else show_help fi [[ ! -f "$INPUT" ]] && { echo "File not found: $INPUT"; exit 1; } BASENAME="${INPUT%.*}" OUTPUT="${BASENAME}-r.mp4" SUMMARY="${BASENAME}-summary.json" ######################################## # Resolution ######################################## case "$RES" in 720p) SCALE="scale=-2:720" ;; 1080p) SCALE="scale=-2:1080" ;; *) echo "Invalid resolution"; exit 1 ;; esac ######################################## # Mode settings ######################################## CQ=23 AUDIO_OPTS=("-c:a" "aac" "-b:a" "96k") case "$MODE" in vlog) AUDIO_OPTS=("-c:a" "copy") CQ=23 ;; tiny) AUDIO_OPTS=("-c:a" "aac" "-b:a" "64k") CQ=28 ;; none) ;; *) echo "Invalid mode" exit 1 ;; esac ######################################## # Metadata detection (robust) ######################################## EXISTING_ID="$(ffprobe -v error \ -show_entries format_tags=compressed_by \ -of default=nk=1:nw=1 "$INPUT" 2>/dev/null || true)" if [[ "$EXISTING_ID" =~ ^${UNIQUE_PREFIX}[A-Za-z0-9]+$ ]]; then echo "Skipping already-compressed file: $INPUT" exit 0 fi ######################################## # Generate unique ID ######################################## COMPRESS_ID="${UNIQUE_PREFIX}$(tr -dc A-Za-z0-9 $OUTPUT" if ! ffmpeg -y -hide_banner -loglevel error -stats \ -i "$INPUT" \ -map 0:v:0 -map 0:a? \ -vf "$SCALE" \ -c:v hevc_nvenc \ -preset p6 -tune hq \ -rc vbr -multipass fullres \ -profile:v main -pix_fmt yuv420p \ -spatial_aq 1 -temporal_aq 1 -aq-strength 8 \ -cq "$CQ" \ "${AUDIO_OPTS[@]}" \ -movflags +faststart \ -metadata compressed_by="$COMPRESS_ID" \ "$OUTPUT"; then echo "FFmpeg failed for $INPUT" exit 0 fi ######################################## # Size check ######################################## ORIG_SIZE=$(stat -c%s "$INPUT") NEW_SIZE=$(stat -c%s "$OUTPUT") if (( NEW_SIZE >= ORIG_SIZE )); then echo "Result larger than original → skipping" rm -f "$OUTPUT" exit 0 fi ######################################## # JSON summary ######################################## HUMAN_ORIG=$(numfmt --to=iec --suffix=B "$ORIG_SIZE") HUMAN_NEW=$(numfmt --to=iec --suffix=B "$NEW_SIZE") OCCURRED=$(date +"%Y-%m-%d %H:%M:%S") cat > "$SUMMARY" <