From dd190cc48331ee5da4b6fab5e487c674ce225223 Mon Sep 17 00:00:00 2001 From: Emily Frost Date: Thu, 9 Dec 2021 13:27:16 -0600 Subject: [PATCH] Moved zsh functions out of private repository. --- ffmpeg-x265-main10 | 68 ++++++++++++++++++++++++++++++ freload | 6 +++ mkvmerge-add-subtitles | 94 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 ffmpeg-x265-main10 create mode 100644 freload create mode 100644 mkvmerge-add-subtitles diff --git a/ffmpeg-x265-main10 b/ffmpeg-x265-main10 new file mode 100644 index 0000000..55e9714 --- /dev/null +++ b/ffmpeg-x265-main10 @@ -0,0 +1,68 @@ +### ffmpeg-x265-main10 +# Transcode the videos in a given directory with x265's main10 profile, then put them in a +# subdirectory for easy replacement after manually checking results. + +RESULTS_DIRECTORY_NAME="_x265_main10" + +# TODO: This variable isn't referenced because I didn't figure out how to put it in the glob it +# needs to be in. Fix that. +VIDEO_EXTENSIONS="mkv,mp4,avi" + +_ffmpeg_x265_main10_ffmpeg () { + original_file="$1" + results_directory="$2" + partial_file="${results_directory}/$(basename "${original_file}").part" + complete_file="${results_directory}/$(basename "${original_file}")" + mkdir -p "$results_directory" + + if [ -e "$complete_file" ]; then + echo "${complete_file} already exists, skipping." + + else + ffmpeg -n -i "$original_file" \ + -map 0:v:0 -c:v libx265 -preset medium -profile:v main10 \ + -map 0:a -c:a copy \ + -map '0:s?' -c:s copy \ + -f matroska \ + "$partial_file" \ + || rm "$partial_file" + + if [ -e "$partial_file" ]; then + mv "$partial_file" "$complete_file" + fi + fi + + if [ -e "$destination" ]; then + rmdir --ignore-fail-on-non-empty "$destination" + fi +} + +arg_file="$1" + +if [ -z "$arg_file" ]; then + arg_file=. +fi + +if [ -f "$arg_file" ]; then + destination="${arg_file:h}/${RESULTS_DIRECTORY_NAME}" + _ffmpeg_x265_main10_ffmpeg "$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 hours of transcoding. + # - 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 + _ffmpeg_x265_main10_ffmpeg "$fname" "$destination" + done + +else + echo "ffmpeg_x265_main10: Error:${arg_file} is not a file or directory." +fi + +# vim:syntax=sh filetype=sh diff --git a/freload b/freload new file mode 100644 index 0000000..7aa54b7 --- /dev/null +++ b/freload @@ -0,0 +1,6 @@ +while (( $# )); do + unfunction $1; + autoload -U $1; + shift; +done +# vim:syntax=sh filetype=sh diff --git a/mkvmerge-add-subtitles b/mkvmerge-add-subtitles new file mode 100644 index 0000000..be61f1e --- /dev/null +++ b/mkvmerge-add-subtitles @@ -0,0 +1,94 @@ +# 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