Skip to content

Instantly share code, notes, and snippets.

@unixabg
Last active February 18, 2025 01:01
Show Gist options
  • Save unixabg/3ab52bb5067d88cf6372892da6f3931c to your computer and use it in GitHub Desktop.
Save unixabg/3ab52bb5067d88cf6372892da6f3931c to your computer and use it in GitHub Desktop.
Script to generate clip rips from a video
#!/bin/bash
# clip-ripper v1.0.0
# Author: Richard Nelson [email protected]
# Description: A script to slice videos into smaller clips using FFmpeg.
# Usage: Run with required parameters to extract video segments.
VERSION="1.0.0"
# Function to display help message
usage() {
echo ""
echo "Clip-Ripper v$VERSION"
echo "Usage: $0 --input-video <input_video> --length <segment_length_in_seconds> --slice-file <slice_file> [--output-dir <output_directory>] [--prefix-time <seconds>] [--separator <char>]"
echo ""
echo "Parameters:"
echo " --input-video <input_video> Required. Path to the input video file."
echo " --length <seconds> Required. Length of each segment in seconds."
echo " --slice-file <slice_file> Required. File containing HH:MM:SS and tags."
echo " --output-dir <directory> Optional. Directory to save sliced video files."
echo " --prefix-time <seconds> Optional. Shift start time of each slice backward."
echo " --separator <char> Optional. Custom field separator (default: '|')."
echo ""
echo "Example:"
echo " $0 --input-video myVideo.MOV --length 3 --slice-file slices.txt --output-dir clips --prefix-time 2 --separator '|'"
echo ""
exit 1
}
# Show help message if no arguments are provided or if --help is used
if [[ "$#" -eq 0 || "$1" == "--help" ]]; then
usage
fi
# Default separator
separator="|"
# Parse command-line arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--input-video) input_file="$2"; shift 2;;
--length) segment_length="$2"; shift 2;;
--slice-file) slice_file="$2"; shift 2;;
--output-dir) output_dir="$2"; shift 2;;
--prefix-time) prefix_time="$2"; shift 2;;
--separator) separator="$2"; shift 2;;
*) echo "Unknown parameter: $1"; usage;;
esac
done
# Validate required parameters
if [[ -z "$input_file" || -z "$segment_length" || -z "$slice_file" ]]; then
echo "Error: Missing required parameters."
usage
fi
# Validate input video
if [[ ! -f "$input_file" ]]; then
echo "Error: Input video file '$input_file' does not exist."
usage
fi
# Validate segment length
if ! [[ "$segment_length" =~ ^[0-9]+$ ]]; then
echo "Error: Segment length must be a positive integer."
usage
fi
# Validate slice file
if [[ ! -f "$slice_file" ]]; then
echo "Error: Slice file '$slice_file' does not exist."
usage
fi
# Validate prefix time (default to 0 if not set)
if [[ -z "$prefix_time" ]]; then
prefix_time=0
elif ! [[ "$prefix_time" =~ ^[0-9]+$ ]]; then
echo "Error: Prefix time must be a positive integer."
usage
fi
# Validate and create output directory if specified
if [[ -n "$output_dir" ]]; then
mkdir -p "$output_dir" || { echo "Error: Failed to create output directory '$output_dir'"; exit 1; }
else
output_dir="." # Default to current directory
fi
counter=1
while IFS="$separator" read -r start_time tag_info; do
# Trim whitespace from tag_info
tag_info=$(echo "$tag_info" | xargs)
# Validate HH:MM:SS format using regex
if ! [[ "$start_time" =~ ^[0-9]{2}:[0-9]{2}:[0-9]{2}$ ]]; then
echo "Error: Invalid time format '$start_time'. Expected HH:MM:SS."
exit 1
fi
# Convert start time to total seconds
IFS=: read -r h m s <<< "$start_time"
start_seconds=$((10#$h * 3600 + 10#$m * 60 + 10#$s))
# Apply prefix-time shift **backwards**
adjusted_start_seconds=$((start_seconds - prefix_time))
# Ensure start time doesn't go negative
if [[ "$adjusted_start_seconds" -lt 0 ]]; then
adjusted_start_seconds=0
fi
# Calculate end time
end_seconds=$((adjusted_start_seconds + segment_length))
# Convert times back to HH:MM:SS format
adjusted_start_time=$(printf "%02d:%02d:%02d" $((adjusted_start_seconds/3600)) $(((adjusted_start_seconds%3600)/60)) $((adjusted_start_seconds%60)))
end_time=$(printf "%02d:%02d:%02d" $((end_seconds/3600)) $(((end_seconds%3600)/60)) $((end_seconds%60)))
# Sanitize tag for filename (keep alphanumeric and spaces)
if [[ -n "$tag_info" ]]; then
safe_tag=$(echo "$tag_info" | tr -cd '[:alnum:] ') # Keep only alphanumeric and spaces
safe_tag=$(echo "$safe_tag" | tr ' ' '_') # Replace spaces with underscores
output_file="$output_dir/${input_file%.*}-slice${counter}-${safe_tag}.${input_file##*.}"
else
output_file="$output_dir/${input_file%.*}-slice${counter}.${input_file##*.}"
fi
# Generate FFmpeg command
echo "ffmpeg -i \"$input_file\" -ss $adjusted_start_time -to $end_time -c copy \"$output_file\""
counter=$((counter + 1))
done < "$slice_file"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment