Skip to content

Instantly share code, notes, and snippets.

@tonkku107
Created July 3, 2021 18:32
Show Gist options
  • Save tonkku107/a0fa1772ea91e9af4902f449f375ca7d to your computer and use it in GitHub Desktop.
Save tonkku107/a0fa1772ea91e9af4902f449f375ca7d to your computer and use it in GitHub Desktop.
Script for copying subtitles between mkv files
#!/bin/bash
###
# Copies subtitles from mkv files in from/ folder to mkv files in to/ folder
# Output mkv files are saved in an out/ folder
###
# Get file lists
source_files=(from/*)
source_files=( "${source_files[@]##*/}" )
target_files=(to/*)
target_files=( "${target_files[@]##*/}" )
# Check amount of files in each folder is the same
if [ ! ${#source_files[@]} -eq ${#target_files[@]} ]; then
echo "ERROR: Amount of files is different"
exit 1
fi
# Print file associations for confirmation
for i in ${!source_files[@]}; do
printf "\e[1m\e[38;5;14m$(expr $i + 1). \e[0m\e[38;5;2m${source_files[$i]}\e[0m\e[1m -> \e[0m\e[38;5;10m${target_files[$i]}\n"
done
# Warning confirmation
echo ""
printf "\e[1m\e[38;5;9m!!! Make sure the episodes match. \e[0m"
read -p "Press ENTER to continue or CTRL+C to quit"
# Delay input
read -p "Delay for subtitles in ms [1000ms]: " delay
delay=${delay:-1000}
for i in ${!source_files[@]}; do
# Options for mkvmerge later
inputs=()
printf "\e[1m\e[38;5;14m=>\e[0m\e[1m Copying subtitles from \e[0m\e[38;5;2m${source_files[$i]}\e[0m\e[1m to \e[0m\e[38;5;10m${target_files[$i]}\e[0m\e[1m...\e[0m\n"
# Extract subtitles
printf " \e[1m\e[38;5;14m==>\e[0m\e[1m Extracting subtitles...\e[0m\n"
subs=$(mkvmerge -i "from/${source_files[$i]}" | awk '$4=="subtitles"')
while read sub; do
track=$(awk -F '[ :]' '{print $3}' <<< "$sub")
properties=$(mkvmerge -J "from/${source_files[$i]}" | jq ".tracks[$track].properties")
name=$(echo $properties | jq ".track_name" | sed -e 's/^"//' -e 's/"$//')
language=$(echo $properties | jq ".language" | sed -e 's/^"//' -e 's/"$//')
mkvextract -q tracks "from/${source_files[$i]}" "${track}:tmp/${source_files[$i]}-${track}.ass"
inputs+=("-y" "-1:${delay}" "--track-name" "-1:${name}" "--language" "-1:${language}" "tmp/${source_files[$i]}-${track}.ass")
done < <(echo "$subs")
# Extract attachments
printf " \e[1m\e[38;5;14m==>\e[0m\e[1m Extracting attachments...\e[0m\n"
attachments=$(mkvmerge -i "from/${source_files[$i]}" | awk '$1=="Attachment"')
while read attachment; do
track=$(awk -F '[ :]' '{print $3}' <<< "$attachment")
filename=$(awk -F "'" '{print $4}' <<< "$attachment")
type=$(awk -F "'" '{print $2}' <<< "$attachment")
mkvextract -q attachments "from/${source_files[$i]}" "${track}:tmp/attachments/${filename}"
inputs+=("--attachment-mime-type" ${type} "--attach-file" "tmp/attachments/${filename}")
done < <(echo "$attachments")
# Merge
printf " \e[1m\e[38;5;14m==>\e[0m\e[1m Merging to new file...\e[0m\n"
mkvmerge -q -o "out/${target_files[$i]}" "to/${target_files[$i]}" "${inputs[@]}"
# Clean tmp files
rm -r tmp
done
printf "\e[1m\e[38;5;14m=>\e[0m\e[1m Done!\e[0m\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment