Created
September 12, 2024 18:47
-
-
Save tomfun/a2d3cf4c5d5a9df8acc2e15ff8eaf510 to your computer and use it in GitHub Desktop.
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 characters
#!/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 |
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 characters
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