Update 2025-04-12_09:56:11
This commit is contained in:
76
ffmpeg_video_compress.sh
Executable file
76
ffmpeg_video_compress.sh
Executable file
@ -0,0 +1,76 @@
|
||||
#!/bin/zsh
|
||||
# Script Version: 14
|
||||
# Description: Compress a video using ffmpeg with NVIDIA CUDA for acceleration, aiming for a smaller file size. Push GPU usage and CPU multicore hyperthreading to maximize performance by parallel processing.
|
||||
|
||||
# Set variables
|
||||
# ========
|
||||
INPUT_VIDEO="$1"
|
||||
OUTPUT_VIDEO="${INPUT_VIDEO%.*}_compressed.mkv" # Output filename based on input with '_compressed' suffix and .mkv extension
|
||||
TEMP_DIR="/tmp/ffmpeg_chunks"
|
||||
CHUNK_DURATION=30 # Split video into 30-second chunks for parallel processing
|
||||
NUM_CHUNKS=4 # Limit to 4 chunks
|
||||
|
||||
# Main Process
|
||||
# ========
|
||||
if [[ -z "$INPUT_VIDEO" ]]; then
|
||||
echo "Usage: $0 <input_video>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if GNU Parallel is installed
|
||||
if ! command -v parallel &> /dev/null; then
|
||||
echo "GNU Parallel is required but not installed. Please install it with: apt-get install parallel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create a temporary directory for storing chunks
|
||||
mkdir -p "$TEMP_DIR"
|
||||
|
||||
# Split the input video into smaller chunks, ensuring proper timestamps and avoiding timestamp issues
|
||||
ffmpeg -fflags +genpts -copyts -i "$INPUT_VIDEO" -c copy -map 0 -segment_time "$CHUNK_DURATION" -reset_timestamps 1 -f segment "$TEMP_DIR/chunk_%03d.mkv"
|
||||
|
||||
# Verify if splitting succeeded
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Error: Failed to split the video into chunks."
|
||||
rm -rf "$TEMP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Limit the number of chunks to 4
|
||||
CHUNKS=$(ls "$TEMP_DIR"/chunk_*.mkv | head -n "$NUM_CHUNKS")
|
||||
|
||||
# Compress each chunk in parallel using GNU Parallel
|
||||
echo "$CHUNKS" | parallel -j "$NUM_CHUNKS" ffmpeg -hwaccel cuda -i {} -c:v hevc_nvenc -preset p1 -rc constqp -qp 20 -b:v 5M -maxrate 10M -bufsize 20M -c:a copy {.}_compressed.mkv
|
||||
|
||||
# Verify if compression succeeded
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Error: Compression failed for one or more chunks."
|
||||
rm -rf "$TEMP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Concatenate the compressed chunks into the final output file
|
||||
ls "$TEMP_DIR"/*_compressed.mkv | sort | xargs -I {} echo "file '{}'" > "$TEMP_DIR/file_list.txt"
|
||||
ffmpeg -f concat -safe 0 -i "$TEMP_DIR/file_list.txt" -c copy "$OUTPUT_VIDEO"
|
||||
|
||||
# Verify if concatenation succeeded
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Error: Failed to concatenate the compressed chunks."
|
||||
rm -rf "$TEMP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up temporary files
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
# Output status
|
||||
if [[ -f "$OUTPUT_VIDEO" ]]; then
|
||||
echo "Compression complete. Output file: $OUTPUT_VIDEO"
|
||||
else
|
||||
echo "Compression failed. Output file was not created."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display file sizes
|
||||
ls -lh "$INPUT_VIDEO" "$OUTPUT_VIDEO" | awk '{print $9, $5}'
|
||||
|
Reference in New Issue
Block a user