Compressing mp4 videos files for drive space

D.O.A.

Well-known member
I have over 98,000 videos uploaded into threads/posts so I wanted to see if I can make any savings with ffmpeg, long story short, yes. I compressed 70,000 odd videos (mp4) and saved 154GB, for a 18% reduction of the total of 853GB. No loss in quality. So I'll leave it here. Probaly wouldn't hurt to chmod 600 the log file if you do it in /video.

Set your video path and run the bash script. Run it every now and then.
  • will create a temp video file.
  • if temp video file is smaller, replace original video.
  • if bigger, delete temp video file.
  • log result/check log on next run and skip processed files.
Code:
#!/bin/bash

# Set the parent directory
PARENT_DIR="/path/to/data/video"  # Change this to your actual parent directory

# Log file to track conversions
LOG_FILE="conversion.log"

# ffmpeg settings
FFMPEG_CMD="ffmpeg -i"

# Conversion options
VIDEO_CODEC="-c:v libx264 -preset slow -crf 23"
AUDIO_CODEC="-c:a aac -b:a 128k"
MOV_FLAGS="-movflags +faststart"

# Check if the log file exists, if not, create it
if [[ ! -f "$LOG_FILE" ]]; then
    touch "$LOG_FILE"
fi

# Function to log conversion results
log_conversion() {
    echo "$1" >> "$LOG_FILE"
}

# Flag to track if any conversions are done
conversion_done=false

# Find all MP4 files in the parent directory and subdirectories
find "$PARENT_DIR" -type f -name "*.mp4" | while read -r input_file; do
    # Check if the file was successfully converted or failed previously
    if grep -q "^$input_file: SUCCESS" "$LOG_FILE" || grep -q "^$input_file: FAILED" "$LOG_FILE"; then
        continue
    fi

    # Create a temporary output file
    temp_file="${input_file}.temp.mp4"

    # Run the ffmpeg compression command
    $FFMPEG_CMD "$input_file" $VIDEO_CODEC $AUDIO_CODEC $MOV_FLAGS "$temp_file" < /dev/null

    # Check if ffmpeg succeeded
    if [[ $? -eq 0 ]]; then
        # Compare the sizes of the original and the compressed file
        original_size=$(stat -c %s "$input_file")
        new_size=$(stat -c %s "$temp_file")

        # If the new file is smaller, replace the original
        if (( new_size < original_size )); then
            mv "$temp_file" "$input_file"
            log_conversion "$input_file: SUCCESS"
            conversion_done=true
        else
            # Delete the temporary file if it's not smaller
            rm "$temp_file"
            log_conversion "$input_file: FAILED (Larger or same size)"
        fi
    else
        # Log failure if ffmpeg failed
        rm -f "$temp_file"
        log_conversion "$input_file: FAILED (ffmpeg error)"
    fi
done

# If no conversions were done, print a message and exit
if [[ "$conversion_done" == false ]]; then
    echo "No files to convert. Exiting."
    exit 0
else
    echo "Conversion completed. Check the log file for details."
fi
 
Hi, thanks for the script.

Will it update also the XenForo data with the new file size of the video?
Thinking of running this agains't media gallery videos.
 
Hi, thanks for the script.

Will it update also the XenForo data with the new file size of the video?
Thinking of running this agains't media gallery videos.
I never checked that so I'm not sure. Videos work fine still though.
 
  • Love
Reactions: rdn
Back
Top Bottom