Compare commits
1 Commits
bf11c57ac8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 28efe130f9 |
+36
-9
@@ -9,12 +9,39 @@ action_merge_mkv() {
|
|||||||
local video_file="$1"
|
local video_file="$1"
|
||||||
local audio_file="$2"
|
local audio_file="$2"
|
||||||
local final_output_file="$3"
|
local final_output_file="$3"
|
||||||
|
local subtitle_file="$4"
|
||||||
|
|
||||||
mkvmerge \
|
# Файл 0 — аудио, 1 — видео, 2 — субтитры (если заданы).
|
||||||
-o "$TEMP_MERGE_FILE" \
|
# Порядок дорожек: видео, новая аудиодорожка, затем субтитры.
|
||||||
--track-order 1:0,0:0 \
|
local -a merge_cmd=()
|
||||||
--language 0:rus "$audio_file" \
|
|
||||||
"$video_file" \
|
if [[ -n "$subtitle_file" ]]; then
|
||||||
|
merge_cmd=(
|
||||||
|
mkvmerge
|
||||||
|
-o "$TEMP_MERGE_FILE"
|
||||||
|
--track-order 1:0,0:0,2:0
|
||||||
|
--language 0:rus "$audio_file"
|
||||||
|
"$video_file"
|
||||||
|
--language 0:rus
|
||||||
|
)
|
||||||
|
local subtitle_lower="${subtitle_file,,}"
|
||||||
|
case "$subtitle_lower" in
|
||||||
|
*.srt|*.ass|*.ssa|*.sub|*.txt)
|
||||||
|
merge_cmd+=(--sub-charset 0:UTF-8)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
merge_cmd+=("$subtitle_file")
|
||||||
|
else
|
||||||
|
merge_cmd=(
|
||||||
|
mkvmerge
|
||||||
|
-o "$TEMP_MERGE_FILE"
|
||||||
|
--track-order 1:0,0:0
|
||||||
|
--language 0:rus "$audio_file"
|
||||||
|
"$video_file"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
"${merge_cmd[@]}" \
|
||||||
&& \
|
&& \
|
||||||
mv "$TEMP_MERGE_FILE" "$final_output_file"
|
mv "$TEMP_MERGE_FILE" "$final_output_file"
|
||||||
}
|
}
|
||||||
@@ -37,12 +64,12 @@ run_processing() {
|
|||||||
|
|
||||||
local skip_count=0
|
local skip_count=0
|
||||||
local pending_count=0
|
local pending_count=0
|
||||||
local triplet video audio output
|
local triplet video audio output subtitle
|
||||||
# Снимок на момент старта. Файл, появившийся уже в этом запуске,
|
# Снимок на момент старта. Файл, появившийся уже в этом запуске,
|
||||||
# нельзя считать «и так был» — иначе отчёт завысит число обработанных.
|
# нельзя считать «и так был» — иначе отчёт завысит число обработанных.
|
||||||
local -A ALREADY_PRESENT=()
|
local -A ALREADY_PRESENT=()
|
||||||
for triplet in "${FILE_TRIPLETS[@]}"; do
|
for triplet in "${FILE_TRIPLETS[@]}"; do
|
||||||
IFS=$'\t' read -r video audio output <<< "$triplet"
|
IFS=$'\t' read -r video audio output subtitle <<< "$triplet"
|
||||||
if output_file_exists "$output"; then
|
if output_file_exists "$output"; then
|
||||||
ALREADY_PRESENT["$output"]=1
|
ALREADY_PRESENT["$output"]=1
|
||||||
skip_count=$((skip_count + 1))
|
skip_count=$((skip_count + 1))
|
||||||
@@ -82,7 +109,7 @@ run_processing() {
|
|||||||
local total_files=${#FILE_TRIPLETS[@]}
|
local total_files=${#FILE_TRIPLETS[@]}
|
||||||
local current_file_num=0
|
local current_file_num=0
|
||||||
|
|
||||||
while IFS=$'\t' read -r video audio output; do
|
while IFS=$'\t' read -r video audio output subtitle; do
|
||||||
((current_file_num++))
|
((current_file_num++))
|
||||||
local progress_before=$(( ((current_file_num - 1) * 100) / total_files ))
|
local progress_before=$(( ((current_file_num - 1) * 100) / total_files ))
|
||||||
|
|
||||||
@@ -104,7 +131,7 @@ run_processing() {
|
|||||||
|
|
||||||
case "$CURRENT_ACTION" in
|
case "$CURRENT_ACTION" in
|
||||||
"MERGE")
|
"MERGE")
|
||||||
action_merge_mkv "$video" "$audio" "$output" >/dev/null 2>&1 ;;
|
action_merge_mkv "$video" "$audio" "$output" "$subtitle" >/dev/null 2>&1 ;;
|
||||||
"SYMLINK")
|
"SYMLINK")
|
||||||
action_create_symlink "$video" "$output" >/dev/null 2>&1 ;;
|
action_create_symlink "$video" "$output" >/dev/null 2>&1 ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
+19
-2
@@ -41,12 +41,26 @@ logic_prepare_file_lists() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local -a sub_list_raw=()
|
||||||
|
if [[ -n "$SUB_SRC_DIR" ]]; then
|
||||||
|
mapfile -d '' sub_list_raw < <(find "$SUB_SRC_DIR" -name "$SUB_FILE_PATTERN" -print0 | sort -z)
|
||||||
|
if [ ${#sub_list_raw[@]} -eq 0 ]; then
|
||||||
|
ui_show_message "Ошибка" "Субтитры по шаблону '$SUB_FILE_PATTERN' не найдены."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ ${#video_list_raw[@]} -ne ${#sub_list_raw[@]} ]; then
|
||||||
|
ui_show_message "Ошибка" "Количество видео (${#video_list_raw[@]}), аудио (${#audio_list_raw[@]}) и субтитров (${#sub_list_raw[@]}) не совпадает."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
for i in "${!video_list_raw[@]}"; do
|
for i in "${!video_list_raw[@]}"; do
|
||||||
local video_file="${video_list_raw[$i]}"
|
local video_file="${video_list_raw[$i]}"
|
||||||
local audio_file="${audio_list_raw[$i]}"
|
local audio_file="${audio_list_raw[$i]}"
|
||||||
|
local subtitle_file="${sub_list_raw[$i]}"
|
||||||
local output_path
|
local output_path
|
||||||
output_path=$(logic_generate_output_name "$video_file") || return 1
|
output_path=$(logic_generate_output_name "$video_file") || return 1
|
||||||
FILE_TRIPLETS+=("$video_file"$'\t'"$audio_file"$'\t'"$output_path")
|
FILE_TRIPLETS+=("$video_file"$'\t'"$audio_file"$'\t'"$output_path"$'\t'"$subtitle_file")
|
||||||
done
|
done
|
||||||
|
|
||||||
# РЕЖИМ: СИМЛИНКИ
|
# РЕЖИМ: СИМЛИНКИ
|
||||||
@@ -161,7 +175,7 @@ logic_show_preview() {
|
|||||||
local count=1
|
local count=1
|
||||||
local skip_count=0
|
local skip_count=0
|
||||||
for triplet in "${FILE_TRIPLETS[@]}"; do
|
for triplet in "${FILE_TRIPLETS[@]}"; do
|
||||||
IFS=$'\t' read -r video audio output <<< "$triplet"
|
IFS=$'\t' read -r video audio output subtitle <<< "$triplet"
|
||||||
body+="$(printf "%02d" $count). \n"
|
body+="$(printf "%02d" $count). \n"
|
||||||
|
|
||||||
local exists=false
|
local exists=false
|
||||||
@@ -173,6 +187,9 @@ logic_show_preview() {
|
|||||||
if [ "$CURRENT_ACTION" == "MERGE" ]; then
|
if [ "$CURRENT_ACTION" == "MERGE" ]; then
|
||||||
body+=" \ZbВИДЕО:\Zn $(basename "$video")\n"
|
body+=" \ZbВИДЕО:\Zn $(basename "$video")\n"
|
||||||
body+=" \ZbАУДИО:\Zn $(basename "$audio")\n"
|
body+=" \ZbАУДИО:\Zn $(basename "$audio")\n"
|
||||||
|
if [[ -n "$subtitle" ]]; then
|
||||||
|
body+=" \ZbСУБТИТРЫ:\Zn $(basename "$subtitle")\n"
|
||||||
|
fi
|
||||||
body+=" \Zb-> ВЫВОД:\Zn $(basename "$output")\n"
|
body+=" \Zb-> ВЫВОД:\Zn $(basename "$output")\n"
|
||||||
else # SYMLINK
|
else # SYMLINK
|
||||||
body+=" \ZbИСТОЧНИК:\Zn $(basename "$video")\n"
|
body+=" \ZbИСТОЧНИК:\Zn $(basename "$video")\n"
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ ui_select_initial_action() {
|
|||||||
dialog "${DIALOG_OPTS[@]}" --title "Выбор действия" \
|
dialog "${DIALOG_OPTS[@]}" --title "Выбор действия" \
|
||||||
--cancel-label "Выход" \
|
--cancel-label "Выход" \
|
||||||
--menu "Выберите, что вы хотите сделать:" 15 70 2 \
|
--menu "Выберите, что вы хотите сделать:" 15 70 2 \
|
||||||
"MERGE" "Склеить видео и аудио (mkvmerge)" \
|
"MERGE" "Склеить видео и аудио, субтитры по желанию" \
|
||||||
"SYMLINK" "Создать симлинки с новыми именами"
|
"SYMLINK" "Создать симлинки с новыми именами"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,13 @@ TEMP_MERGE_FILE="/tmp/tmp.mkv"
|
|||||||
# ... (все переменные состояния остаются без изменений)
|
# ... (все переменные состояния остаются без изменений)
|
||||||
VIDEO_SRC_DIR=""
|
VIDEO_SRC_DIR=""
|
||||||
AUDIO_SRC_DIR=""
|
AUDIO_SRC_DIR=""
|
||||||
|
SUB_SRC_DIR=""
|
||||||
OUTPUT_BASE_DIR=""
|
OUTPUT_BASE_DIR=""
|
||||||
OUTPUT_SERIES_NAME=""
|
OUTPUT_SERIES_NAME=""
|
||||||
SEASON_NUMBER="01"
|
SEASON_NUMBER="01"
|
||||||
VIDEO_FILE_PATTERN="*.mkv"
|
VIDEO_FILE_PATTERN="*.mkv"
|
||||||
AUDIO_FILE_PATTERN="*.mka"
|
AUDIO_FILE_PATTERN="*.mka"
|
||||||
|
SUB_FILE_PATTERN="*.ass"
|
||||||
EPISODE_NUMBER_REGEX='.* ([0-9]{2}) .*'
|
EPISODE_NUMBER_REGEX='.* ([0-9]{2}) .*'
|
||||||
OUTPUT_FILENAME_TEMPLATE="{SERIES_NAME} s{SEASON}e{EPISODE}.mkv"
|
OUTPUT_FILENAME_TEMPLATE="{SERIES_NAME} s{SEASON}e{EPISODE}.mkv"
|
||||||
CURRENT_ACTION=""
|
CURRENT_ACTION=""
|
||||||
@@ -76,6 +78,7 @@ main() {
|
|||||||
local max_display_len=45 # Можете поменять это значение под свой экран
|
local max_display_len=45 # Можете поменять это значение под свой экран
|
||||||
local display_video_path=$(truncate_path_for_display "$VIDEO_SRC_DIR" "$max_display_len" "_не задан_")
|
local display_video_path=$(truncate_path_for_display "$VIDEO_SRC_DIR" "$max_display_len" "_не задан_")
|
||||||
local display_audio_path=$(truncate_path_for_display "$AUDIO_SRC_DIR" "$max_display_len" "_не задан_")
|
local display_audio_path=$(truncate_path_for_display "$AUDIO_SRC_DIR" "$max_display_len" "_не задан_")
|
||||||
|
local display_sub_path=$(truncate_path_for_display "$SUB_SRC_DIR" "$max_display_len" "_не задан_")
|
||||||
local display_output_path=$(truncate_path_for_display "$OUTPUT_BASE_DIR" "$max_display_len" "_не задан_")
|
local display_output_path=$(truncate_path_for_display "$OUTPUT_BASE_DIR" "$max_display_len" "_не задан_")
|
||||||
|
|
||||||
# Формируем пункты меню ДИНАМИЧЕСКИ
|
# Формируем пункты меню ДИНАМИЧЕСКИ
|
||||||
@@ -84,6 +87,7 @@ main() {
|
|||||||
|
|
||||||
if [ "$CURRENT_ACTION" == "MERGE" ]; then
|
if [ "$CURRENT_ACTION" == "MERGE" ]; then
|
||||||
menu_items+=("A" "Аудио каталог : $display_audio_path")
|
menu_items+=("A" "Аудио каталог : $display_audio_path")
|
||||||
|
menu_items+=("B" "Субтитры каталог : $display_sub_path")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
menu_items+=(
|
menu_items+=(
|
||||||
@@ -96,6 +100,7 @@ main() {
|
|||||||
|
|
||||||
if [ "$CURRENT_ACTION" == "MERGE" ]; then
|
if [ "$CURRENT_ACTION" == "MERGE" ]; then
|
||||||
menu_items+=("U" "Шаблон аудиофайлов : $AUDIO_FILE_PATTERN")
|
menu_items+=("U" "Шаблон аудиофайлов : $AUDIO_FILE_PATTERN")
|
||||||
|
menu_items+=("W" "Шаблон субтитров : $SUB_FILE_PATTERN")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
menu_items+=(
|
menu_items+=(
|
||||||
@@ -118,6 +123,7 @@ main() {
|
|||||||
case "$choice" in
|
case "$choice" in
|
||||||
V) VIDEO_SRC_DIR=$(ui_get_directory "Выберите каталог с видеофайлами" "$VIDEO_SRC_DIR" "$DEFAULT_TORRENTS_DIR") ;;
|
V) VIDEO_SRC_DIR=$(ui_get_directory "Выберите каталог с видеофайлами" "$VIDEO_SRC_DIR" "$DEFAULT_TORRENTS_DIR") ;;
|
||||||
A) AUDIO_SRC_DIR=$(ui_get_directory "Выберите каталог с аудиофайлами" "$AUDIO_SRC_DIR" "$VIDEO_SRC_DIR") ;;
|
A) AUDIO_SRC_DIR=$(ui_get_directory "Выберите каталог с аудиофайлами" "$AUDIO_SRC_DIR" "$VIDEO_SRC_DIR") ;;
|
||||||
|
B) SUB_SRC_DIR=$(ui_get_directory "Выберите каталог с субтитрами" "$SUB_SRC_DIR" "$VIDEO_SRC_DIR") ;;
|
||||||
O)
|
O)
|
||||||
OUTPUT_BASE_DIR=$(ui_get_directory "Выберите БАЗОВЫЙ каталог для результата" "$OUTPUT_BASE_DIR" "$DEFAULT_ARCHIVE_DIR")
|
OUTPUT_BASE_DIR=$(ui_get_directory "Выберите БАЗОВЫЙ каталог для результата" "$OUTPUT_BASE_DIR" "$DEFAULT_ARCHIVE_DIR")
|
||||||
OUTPUT_BASE_DIR="${OUTPUT_BASE_DIR%/}"
|
OUTPUT_BASE_DIR="${OUTPUT_BASE_DIR%/}"
|
||||||
@@ -129,6 +135,7 @@ main() {
|
|||||||
S) SEASON_NUMBER=$(ui_get_input "Введите номер сезона (например, 01, 02)" "$SEASON_NUMBER") ;;
|
S) SEASON_NUMBER=$(ui_get_input "Введите номер сезона (например, 01, 02)" "$SEASON_NUMBER") ;;
|
||||||
P) VIDEO_FILE_PATTERN=$(ui_get_input "Введите шаблон для поиска видео (*.mkv, *ep*.mkv)" "$VIDEO_FILE_PATTERN") ;;
|
P) VIDEO_FILE_PATTERN=$(ui_get_input "Введите шаблон для поиска видео (*.mkv, *ep*.mkv)" "$VIDEO_FILE_PATTERN") ;;
|
||||||
U) AUDIO_FILE_PATTERN=$(ui_get_input "Введите шаблон для поиска аудио (*.mka, *.ac3)" "$AUDIO_FILE_PATTERN") ;;
|
U) AUDIO_FILE_PATTERN=$(ui_get_input "Введите шаблон для поиска аудио (*.mka, *.ac3)" "$AUDIO_FILE_PATTERN") ;;
|
||||||
|
W) SUB_FILE_PATTERN=$(ui_get_input "Введите шаблон для поиска субтитров (*.ass, *.srt)" "$SUB_FILE_PATTERN") ;;
|
||||||
R) EPISODE_NUMBER_REGEX=$(ui_get_input "Введите ERE-regex для номера серии" "$EPISODE_NUMBER_REGEX") ;;
|
R) EPISODE_NUMBER_REGEX=$(ui_get_input "Введите ERE-regex для номера серии" "$EPISODE_NUMBER_REGEX") ;;
|
||||||
T) OUTPUT_FILENAME_TEMPLATE=$(ui_get_input "Введите шаблон имени выходного файла" "$OUTPUT_FILENAME_TEMPLATE") ;;
|
T) OUTPUT_FILENAME_TEMPLATE=$(ui_get_input "Введите шаблон имени выходного файла" "$OUTPUT_FILENAME_TEMPLATE") ;;
|
||||||
VIEW) logic_show_preview ;;
|
VIEW) logic_show_preview ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user