Created
November 7, 2024 16:58
-
Star
(228)
You must be signed in to star a gist -
Fork
(93)
You must be signed in to fork a gist
-
-
Save stenuto/9ff19ce89f07c7419a8d0976736ebe12 to your computer and use it in GitHub Desktop.
Revisions
-
stenuto renamed this gist
Nov 7, 2024 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
stenuto created this gist
Nov 7, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,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"