-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvideo-script
More file actions
executable file
·135 lines (112 loc) · 3.74 KB
/
video-script
File metadata and controls
executable file
·135 lines (112 loc) · 3.74 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/bash
# Function to display usage information
usage() {
echo "Usage: $0 /path/to/input.mp4 [ /path/to/output_directory ]"
exit 1
}
# Check if at least one argument (input file) is provided
if [ $# -lt 1 ]; then
usage
fi
# Assign input file and output directory from arguments
INPUT_FILE="$1"
# Check if input file exists
if [ ! -f "$INPUT_FILE" ]; then
echo "Error: Input file '$INPUT_FILE' does not exist."
exit 1
fi
# Check for required commands
for cmd in ffmpeg ffprobe; do
if ! command -v $cmd &> /dev/null; then
echo "Error: $cmd is not installed or not in PATH."
exit 1
fi
done
# Get the base filename without extension
FILENAME=$(basename "$INPUT_FILE")
BASENAME="${FILENAME%.*}"
# Determine input directory
INPUT_DIR=$(dirname "$INPUT_FILE")
# Assign output directory: second argument or default to current directory
if [ $# -ge 2 ]; then
OUTPUT_BASE_DIR="$2"
# Create the output base directory if it doesn't exist
mkdir -p "$OUTPUT_BASE_DIR"
else
OUTPUT_BASE_DIR="$PWD"
fi
# Create specific output directory within the base output directory using the base filename
OUTPUT_DIR="$OUTPUT_BASE_DIR/$BASENAME"
# Remove existing output directory if it exists
if [ -d "$OUTPUT_DIR" ]; then
echo "Output directory '$OUTPUT_DIR' already exists. Removing it to avoid unused .ts files."
rm -rf "$OUTPUT_DIR"
fi
mkdir -p "$OUTPUT_DIR"
# Get the frame rate of the input video
FRAME_RATE=$(ffprobe -v 0 -of default=noprint_wrappers=1:nokey=1 \
-select_streams v:0 -show_entries stream=avg_frame_rate "$INPUT_FILE")
# Convert frame rate to a number
IFS='/' read -r num denom <<< "$FRAME_RATE"
if [ -z "$denom" ] || [ "$denom" -eq 0 ]; then
denom=1
fi
FRAME_RATE=$(echo "scale=2; $num/$denom" | bc)
FRAME_RATE=${FRAME_RATE%.*}
# Calculate GOP size (number of frames per 4 seconds)
GOP_SIZE=$((FRAME_RATE * 4))
# Define resolutions, bitrates, and output names
RESOLUTIONS=("1280x720" "1920x1080" "3840x2160")
BITRATES=("1200k" "2500k" "8000k")
OUTPUTS=("720p" "1080p" "2160p")
PLAYLISTS=()
# Loop over the variants
for i in "${!RESOLUTIONS[@]}"; do
RES="${RESOLUTIONS[$i]}"
BITRATE="${BITRATES[$i]}"
OUTPUT_NAME="${OUTPUTS[$i]}"
PLAYLIST="${OUTPUT_NAME}.m3u8"
PLAYLISTS+=("$PLAYLIST")
# Set profile and level based on resolution
if [ "$OUTPUT_NAME" == "2160p" ]; then
PROFILE="high"
LEVEL="5.1"
elif [ "$OUTPUT_NAME" == "1080p" ]; then
PROFILE="high"
LEVEL="4.2"
else
PROFILE="main"
LEVEL="3.1"
fi
echo "Processing $OUTPUT_NAME..."
if ! ffmpeg -y -i "$INPUT_FILE" \
-c:v libx264 -preset veryfast -profile:v "$PROFILE" -level:v "$LEVEL" -b:v "$BITRATE" -s "$RES" \
-c:a aac -b:a 128k -ac 2 \
-g $GOP_SIZE -keyint_min $GOP_SIZE -sc_threshold 0 \
-force_key_frames "expr:gte(t,n_forced*4)" \
-hls_time 4 -hls_list_size 0 -hls_flags independent_segments \
-hls_segment_filename "$OUTPUT_DIR/${OUTPUT_NAME}_%03d.ts" \
"$OUTPUT_DIR/$PLAYLIST"; then
echo "Error: Failed to process $OUTPUT_NAME."
exit 1
fi
done
# Generate master playlist
MASTER_PLAYLIST="$OUTPUT_DIR/playlist.m3u8"
echo "Generating master playlist..."
{
echo "#EXTM3U"
echo "#EXT-X-VERSION:3"
for i in "${!RESOLUTIONS[@]}"; do
RESOLUTION="${RESOLUTIONS[$i]}"
OUTPUT_NAME="${OUTPUTS[$i]}"
PLAYLIST="${OUTPUTS[$i]}.m3u8"
BITRATE="${BITRATES[$i]}"
BANDWIDTH=$(( ${BITRATE%k} * 1000 + 128000 )) # Video bitrate + audio bitrate in bits per second
echo ""
echo "#EXT-X-STREAM-INF:BANDWIDTH=$BANDWIDTH,RESOLUTION=$RESOLUTION"
echo "$PLAYLIST"
done
} > "$MASTER_PLAYLIST"
echo "Processing completed successfully."
echo "Output directory: $OUTPUT_DIR"