# Remux videos to include subtitle files of the same name. RESULTS_DIRECTORY_NAME="_remux" DEFAULT_LANGUAGE_CODE="eng" # TODO: This needs to be used in the glob, but I don't know how. VIDEO_EXTENSIONS="mkv,mp4,avi" _mkvmerge_add_subtitles_mkvmerge () { original_file="$1" results_directory="$2" partial_file="${results_directory}/${original_file:t:r}.mkv.part" complete_file="${results_directory}/${original_file:t:r}.mkv" subtitle_options_array=() mkdir -p "$results_directory" # Given a file name, find subtitles and determine their language. # The following patterns should be supported, with [basename] being the given filename's # basename. # * [basename].srt # * [basename].[language code].srt # * Subs/[track_number]_[language].srt # * Subs/[basename]/[track_number]_[language].srt # TODO: Support the other patterns listed in the above comment. video_basename="$1" # Include subtitles with language codes in their filenames. # For example [basename].[language code].srt coded_subtitle_files=(${original_file:r}.*.srt(N)) if [[ ! -z $coded_subtitle_files ]]; then for fname in "$coded_subtitle_files"; do language_code="${${fname:r}:e}" subtitle_options_array+=("--language" "0:${language_code}" "$fname") done fi # Include subtitles without language codes, assuming $DEFAULT_LANGUAGE_CODE is correct. # For example: [basename].srt uncoded_subtitle_name="${original_file:r}.srt" if [[ -f "$uncoded_subtitle_name" ]]; then subtitle_options_array+=("--language" "0:${DEFAULT_LANGUAGE_CODE}" "$uncoded_subtitle_name") fi # Finally, actually mux all the subtitles in if there are any. if [[ "${#subtitle_options_array}" -eq 0 ]]; then echo "No subtitles found for file ${original_file}" else echo "Remuxing ${original_file}..." mkvmerge --quiet -o "$partial_file" "$original_file" ${(@)subtitle_options_array} \ || rm "$partial_file" echo "Done!" if [[ -e "$partial_file" ]]; then mv "$partial_file" "$complete_file" fi fi if [[ -e "$results_directory" ]]; then rmdir --ignore-fail-on-non-empty "$results_directory" fi } arg_file="$1" if [[ -z "$arg_file" ]]; then arg_file=. fi if [[ -f "$arg_file" ]]; then destination="${arg_file:h}/${RESULTS_DIRECTORY_NAME}" _mkvmerge_add_subtitles_mkvmerge "$arg_file" "$destination" elif [[ -d "$arg_file" ]]; then destination="${arg_file}/${RESULTS_DIRECTORY_NAME}" # List all the video files in an array for future expansions like: # - A prompt before you commit to remuxing. # - Removing items that are already completed. # - Interactively discarding list items # - etc. # TODO: Use $VIDEO_EXTENSIONS here instead of hard-coding extension names. files=($arg_file/*.{mkv,mp4,avi}(N)) for fname in $files; do _mkvmerge_add_subtitles_mkvmerge "$fname" "$destination" done else echo "mkvmerge-add-subtitles: Error:${arg_file} is not a file or directory." fi # vim:syntax=sh filetype=sh