-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompress_video.sh
executable file
·110 lines (93 loc) · 3.25 KB
/
compress_video.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/bin/bash
# Check for ffmpeg
if ! command -v ffmpeg &> /dev/null; then
echo "ffmpeg could not be found. Please install ffmpeg to use this script."
exit 1
fi
# Function to draw progress bar
draw_progress_bar() {
local width=50
local percentage=$1
local filled=$((percentage * width / 100))
local empty=$((width - filled))
# Create the bar
printf "\rProgress: ["
printf "%${filled}s" '' | tr ' ' '='
printf "%${empty}s" '' | tr ' ' ' '
printf "] %3d%%" "$percentage"
}
# Check if input file is provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <input_file>"
exit 1
fi
input_file="$1"
output_file="compressed_${input_file}"
# Get video duration using ffprobe
duration=$(ffmpeg -i "$input_file" 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed 's/,//')
# Convert duration to integer seconds
duration_seconds=$(echo "$duration" | awk -F: '{print int(($1 * 3600) + ($2 * 60) + $3)}')
# Create temporary file for progress monitoring
progress_file=$(mktemp)
trap "rm -f $progress_file" EXIT
# Start FFmpeg compression in background with progress output
ffmpeg -i "$input_file" -vcodec h264 -crf 28 \
-progress "$progress_file" \
"$output_file" 2>/dev/null &
ffmpeg_pid=$!
# Initialize progress variables
current_time=0
last_percentage=0
# Monitor progress
while kill -0 $ffmpeg_pid 2>/dev/null; do
if [[ -f "$progress_file" ]]; then
# Get current time from progress file and convert to integer seconds
current_time=$(grep "out_time_ms" "$progress_file" | tail -n 1 | cut -d'=' -f2)
if [[ ! -z "$current_time" ]]; then
# Convert milliseconds to integer seconds
current_time=$((current_time / 1000000))
percentage=$((current_time * 100 / duration_seconds))
# Ensure percentage doesn't exceed 100
if [ "$percentage" -gt 100 ]; then
percentage=100
fi
# Only update if percentage changed
if [ "$percentage" != "$last_percentage" ]; then
draw_progress_bar "$percentage"
last_percentage=$percentage
fi
fi
fi
sleep 0.1
done
# Wait for FFmpeg to finish
wait $ffmpeg_pid
echo # New line after progress bar
# Calculate and show the final compression results
if [ -f "$output_file" ]; then
original_size=$(stat -f%z "$input_file" 2>/dev/null || stat --format=%s "$input_file")
new_size=$(stat -f%z "$output_file" 2>/dev/null || stat --format=%s "$output_file")
size_reduction=$((100 - (new_size * 100 / original_size)))
# Function to format file size
format_size() {
local size=$1
for unit in B KB MB GB TB; do
if [ $size -lt 1024 ]; then
echo "$size $unit"
break
fi
size=$((size / 1024))
done
}
echo -e "\nCompression completed:"
echo "Original size: $(format_size $original_size)"
echo "New size: $(format_size $new_size)"
echo "File size reduced by: $size_reduction%"
# Show parent folder of output file
parent_folder=$(dirname "$(realpath "$output_file")")
echo "Parent folder: $parent_folder"
echo "Output file: $output_file"
else
echo -e "\nError: Compression failed"
exit 1
fi