Skip to content

Instantly share code, notes, and snippets.

@tomfun
Created September 12, 2024 18:47
Show Gist options
  • Save tomfun/a2d3cf4c5d5a9df8acc2e15ff8eaf510 to your computer and use it in GitHub Desktop.
Save tomfun/a2d3cf4c5d5a9df8acc2e15ff8eaf510 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Array of video file paths
video_files=(
# "Fille1.BdRip.1920.eng.mkv"
# "Fille1.BdRip.4k.eng.mkv"
"DISC_BLUEBIRD/BDMV/STREAM/00024.m2ts"
)
extra_crop=",crop=in_w:in_h-260"
#extra_crop=""
threads=4
# Output directory for screenshots
out_dir="Red.Lights.Screens"
mkdir -p "$out_dir"
# Time increment in seconds (for example, every 10 minutes, which is 600 seconds)
time_increment=600
# End time in seconds (01:50:00 is 6600 seconds)
end_time=600
# Loop over each video file
for video_file in "${video_files[@]}"; do
# Get the filename without the extension
filename=$(basename -- "$video_file")
# Retrieve the frame rate of the video (use ffprobe and calculate a single value)
frame_rate=$(ffprobe -v 0 -select_streams v:0 -show_entries stream=r_frame_rate -of csv=p=0 "$video_file" | head -n 1 | awk -F'/' '{if ($2 != "") {print $1/$2} else {print $1}}')
echo "Frame rate for $video_file: $frame_rate fps"
# Prepare the frame selection string for FFmpeg
frame_select=""
frame_counter=0
frame_list=()
# Loop over the time points up to the end time, starting from 60 seconds
for (( time=60; time<=end_time; time+=time_increment )); do
# Convert seconds to HH:MM:SS format
hhmmss=$(printf "%02d:%02d:%02d" $((time/3600)) $(((time%3600)/60)) $((time%60)))
# Calculate the frame number corresponding to the time
frame_number=$(echo "$time * $frame_rate" | bc)
# Append the frame number to the select filter
frame_select+=$(printf "eq(n\\,%d)" "$frame_number")
# Add a separator if there are more frames to process
if (( time + time_increment <= end_time )); then
frame_select+=" + "
fi
frame_list+=("$hhmmss $frame_number")
#output_image="$out_dir/${hhmmss}_frame_${frame_number}.${filename}.png"
# Output screenshot file name pattern (for later renaming)
done
output_image="$out_dir/%03d_${filename}.png"
# Run FFmpeg in a single pass, selecting all frames and saving them in one go
time nice ffmpeg -threads $threads -probesize 500000 -analyzeduration 1000000 -i "$video_file" -map 0:v:0 -an -sn -vf "select='$frame_select'$extra_crop" -vsync vfr -frame_pts 1 "$output_image"
# Check if ffmpeg command succeeded
if [ $? -eq 0 ]; then
echo -e "Screenshots saved in $out_dir\n"
else
echo -e "\nError capturing screenshots for $video_file\n"
fi
# Now rename the files based on the frame number and hhmmss
file_counter=1
for frame_info in "${frame_list[@]}"; do
hhmmss=$(echo "$frame_info" | awk '{print $1}')
frame_number=$(echo "$frame_info" | awk '{print $2}')
# Original extracted file
original_file=$(printf "$output_image" "$frame_number")
# New file with the desired pattern
new_file="$out_dir/${hhmmss}_frame_${frame_number}.${filename}.png"
# Rename the file
if [ -f "$original_file" ]; then
mv "$original_file" "$new_file"
echo "Renamed $original_file to $new_file"
fi
((file_counter++))
done
done
import sys
import re
# Factor by which to stretch the subtitles
stretch_factor = 1.09843127244944583 # For example, stretch by 10%
shift = -5430
# Function to convert time from SRT format to milliseconds
def time_to_ms(time_str):
hours, minutes, seconds, milliseconds = map(int, re.split('[:,]', time_str.replace(',', ':')))
return (((hours * 60 + minutes) * 60 + seconds) * 1000 + milliseconds) + shift
# Function to convert milliseconds to SRT format time
def ms_to_time(ms):
hours = ms // (3600 * 1000)
ms = ms % (3600 * 1000)
minutes = ms // (60 * 1000)
ms = ms % (60 * 1000)
seconds = ms // 1000
milliseconds = ms % 1000
return f"{hours:02}:{minutes:02}:{seconds:02},{milliseconds:03}"
# Process SRT file
def process_srt(input_srt, output_srt):
with open(input_srt, 'r') as infile, open(output_srt, 'w') as outfile:
for line in infile:
match = re.match(r"(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})", line)
if match:
start_time, end_time = match.groups()
start_ms = time_to_ms(start_time)
end_ms = time_to_ms(end_time)
# Stretch the times
new_start_ms = int(start_ms * stretch_factor)
new_end_ms = int(end_ms * stretch_factor)
# Write the adjusted times to output
outfile.write(f"{ms_to_time(new_start_ms)} --> {ms_to_time(new_end_ms)}\n")
else:
outfile.write(line)
if __name__ == "__main__":
if len(sys.argv) != 5:
print("Usage: python stretch_srt.py input.srt output.srt 1.001 -1000")
sys.exit(1)
input_srt = sys.argv[1]
output_srt = sys.argv[2]
stretch_factor = float(sys.argv[3])
shift = int(sys.argv[4])
process_srt(input_srt, output_srt)
print(f"Subtitles stretched and saved to {output_srt}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment