Last active
April 13, 2021 08:41
-
-
Save 19wolf/91c4f5203a706ea6980ff08d1edd2da0 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 | |
#Extract .ass subtitles from mkv, convert to .srt, strip html, re-add them | |
max_threads=4 | |
function process_file () { | |
local input_file="$1" | |
file_start=`date +%s` | |
check_file "$input_file" && process_subtitles "$input_file" || return 1 | |
file_end=`date +%s` | |
file_runtime=$((file_end-file_start)) | |
echo "Completed in $file_runtime seconds -- $input_file" >> "$logfile" | |
} | |
function check_file () { | |
local this_file="$1" | |
if $(! grep -q "mkv" <<< "$this_file"); then #check that it's a supported type (currently only mkv) | |
echo "Not an mkv -- $input_file" >> "$logfile" | |
return 1 | |
elif $(ffprobe -loglevel quiet -show_entries format_tags=description "$this_file" | grep -q "wolf-converted"); then #check if it's been converted | |
echo "Already converted -- $input_file" >> "$logfile" | |
return 1 | |
elif $(! ffprobe -loglevel panic -select_streams s -show_entries stream=codec_name -of csv=p=0 "$this_file" | grep -q 'ass'); then #check there is something to convert | |
echo "Nothing to do -- $input_file" >> "$logfile" | |
return 1 | |
else | |
return 0 | |
fi #if all the checks pass, continue | |
} | |
function process_subtitles () { | |
local this_file="$1" | |
local combined_tracks=$(mktemp -up /tmp/ tmp-XXX.mkv) | |
local combined_tracks_tmp=$(mktemp -up /tmp/ tmp-XXX.mkv) | |
local temp_output=$(mktemp -up /tmp tmp-XXX.mkv) | |
subtitle_tracks=$(ffprobe -loglevel panic -select_streams s -show_entries stream=index,codec_name -of csv=p=0 "$this_file" | awk -F, '/ass/ {print $1}') #get a list of .ass subtitle track numbers | |
echo "Found $(echo $subtitle_tracks | wc -w) subtitles -- $this_file" >> "$logfile" | |
for subtitle_track in $subtitle_tracks; do #for each individual subtitle track of all the tracks, $subtitle_track the track number, not a counter | |
process_subtitle_track "$subtitle_track" "$this_file" "$combined_tracks-$subtitle_track.mkv" & #process track of file.mkv into file-track.mkv | |
if [[ $(jobs -r -p | wc -l) -ge $max_threads ]]; then #if number of background jobs is >= 4 wait for a job to finish | |
wait -n | |
fi | |
done | |
wait | |
for subtitle_track in $subtitle_tracks; do | |
if [ ! -f "$combined_tracks" ]; then | |
ffmpeg -loglevel error -i "$combined_tracks-$subtitle_track.mkv" -c copy "$combined_tracks" #copy file-track.mkv into combined-tracks.mkv | |
else | |
ffmpeg -loglevel error -i "$combined_tracks" -i "$combined_tracks-$subtitle_track.mkv" -c copy -map 0 -map 1 "$combined_tracks_tmp" && mv "$combined_tracks_tmp" "$combined_tracks" #copy file-track.mkv into combined-tracks.mkv | |
fi | |
rm -f "$combined_tracks-$subtitle_track.mkv" | |
done | |
ffmpeg -loglevel error -i "$this_file" -i "$combined_tracks" -c copy -map 0:v -map 0:a -map 0:s -map 1:s -metadata "description=wolf-converted" "$temp_output" && mv "$temp_output" "$this_file" #copy new subtitles to end of original file | |
rm "$combined_tracks" | |
} | |
function process_subtitle_track () { | |
local this_track="$1" #input track | |
local the_file="$2" #input file | |
local subtitle_mkv="$3" #output file | |
local subtitle_tmp=$(mktemp -up /tmp/ tmp-XXX.tmp) | |
local subtitle_srt=$(mktemp -up /tmp/ tmp-XXX.srt) | |
track_title=$(ffprobe -loglevel error -select_streams $this_track -show_entries stream_tags=title "$the_file" | sed 's/TAG://g' | grep "title"); : "${track_title:=title=}" #save the track title for later, set it if blank | |
track_language=$(ffprobe -loglevel error -select_streams $this_track -show_entries stream_tags=language "$the_file" | sed 's/TAG://g' | grep "language"); : "${track_language:=language=}" #save the track language for later, set it if blank | |
ffmpeg -loglevel error -i "$the_file" -map 0:$this_track -c:s srt "$subtitle_srt" #convert subtitle track to srt | |
sed 's/<[^>]*>//g' "$subtitle_srt" > "$subtitle_tmp" && mv "$subtitle_tmp" "$subtitle_srt" #remove any html formatting | |
ffmpeg -loglevel error -i "$subtitle_srt" -c copy -map 0 -metadata:s:0 "$track_title" -metadata:s:0 "$track_language" "$subtitle_mkv" && rm "$subtitle_srt" #create the mkv file from the srt file | |
echo "Converted track $this_track of $the_file" >> "$logfile" | |
} | |
#Main code | |
if [ -f "$sonarr_episodefile_path" ]; then #if sonarr file exists | |
logfile="/config/sonarr-script.log" | |
for input_file_path in "$sonarr_episodefile_path"; do # for each file from input | |
echo "Processing -- $sonarr_episodefile_path" >> "$logfile" | |
process_file "$input_file_path" & | |
if [[ $(jobs -r -p | wc -l) -ge $max_threads ]]; then #if number of background jobs is >= 1 wait for job to finish | |
wait -n | |
fi | |
done #done looping through files | |
else | |
logfile="/var/log/sonarr-script.log" | |
for input_file_path in "$@"; do # for each file from input | |
process_file "$input_file_path" & | |
if [[ $(jobs -r -p | wc -l) -ge $max_threads ]]; then #if number of background jobs is >= 1 wait for job to finish | |
wait -n | |
fi | |
done #done looping through files | |
fi | |
wait | |
rm -f /tmp/tmp-* #remove any leftover temp files |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment