Пакетный файл для рекурсивного мультиплексирования .mp4 и .srt из разных папок

Пакетный файл для рекурсивного мультиплексирования .mp4 и .srt из разных папок

В торрентах появилась новая тенденция выпускать телепередачи и фильмы в формате x265 .mp4 с субтитрами .srt в отдельной папке, следуя следующей структуре папок:

Season1\title1.mp4
Season1\title2.mp4
Season1\title3.mp4
Season1\Subs\title1\subfile1.srt
Season1\Subs\title1\[subfile2.srt]
Season1\Subs\title1\[subfile3.srt]
Season1\Subs\title2\subfile1.srt
Season1\Subs\title2\[subfile2.srt]
Season1\Subs\title2\[subfile3.srt]
Season1\Subs\title3\subfile1.srt
Season1\Subs\title3\[subfile2.srt]
Season1\Subs\title3\[subfile3.srt]

Моя цель — скопировать каждый .mp4 в первый .srt в его папке subs.Я могу сделать это по одному, используя MKVToolNix GUI, но я искал более простой/быстрый способ сделать это с помощью пакетного файла (или скрипта PowerShell). Следующие два решения близки:

Пакетное слияние/мультиплексирование файлов MP4 и SRT в MKV

Пакетное слияние/мультиплексирование файлов .srt с файлами .mkv

Они работают, однако, только если .mp4 и .srt находятся в одной папке и имеют соответствующие названия. Моя проблема, и это то, с чем сталкиваются многие другие, заключается в том, что в соответствии с новым стандартом выпуска:

  • Файлы .mp4 и .srt находятся в разных папках.
  • Для каждого .mp4 может быть один или несколько файлов .srt. Если это так, то можно с уверенностью предположить, что мне нужен первый файл .srt, который обычно является английскими субтитрами по умолчанию.
  • Файлы .srt не следуют соглашению об именовании, где первый файл всегда имеет одинаковое название. Другими словами, пакетный файл должен будет использовать первый .srt, независимо от его имени.

Этот сценарий 2018 года отСуджай Пхадке, это хорошее начало.

for %%f in (*.mkv) do (
    echo %%~nf
    'C:\Program Files\MKVToolNix\mkvmerge.exe' -o "%%~nf_New.mkv" "%%~nf.mkv" --language 0:eng "%%~nf.srt"
    move /Y "%%~nf_New.mkv"  "%%~nf.mkv"

Он работает рекурсивно, пока все файлы (.mp4 и .srt) находятся в одной папке и правильно названы. Однако я ищу пакетный файл, который не включает переименование или перемещение файлов. Он будет использовать mkvmerge.exe для мультиплексирования каждого .mp4 в первый .srt в его подпапке и сохранять каждый новый .mkv в той же папке, что и .mp4.

По желанию, поскольку я могу это понять, Mkvmerge.exe должен установить .srt какАнглийский языкипринудительно установить флаг DefaultTrack.

Это сработает для всех файлов .mp4 в сезоне. Нет необходимости в том, чтобы это работало от сезона к сезону, если вы не чувствуете себя трудолюбивым. Затем я бы запустил пакетный файл для каждого сезона из той же папки, что и файлы .mp4 каждого сезона.

Извините за длинное объяснение, но это действительно выше моих сил, и мне нужна ваша помощь. Я ценю любые предложения.

решение1

@echo off 

setlocal && cd /d "%~dp0"
set "_mkv=C:\Program Files\MKVToolNix\mkvmerge.exe"
set "_flag_0=--default-language en --language 0:en"
set "_flag_1=--priority higher --flush-on-close --disable-track-statistics-tags -o"

for /f usebackq^delims^= %%G in (`dir /a:d /b ^|findstr Season.*[0-9] ^|find/v /i "\subs\"
   `)do if exist "%%G\*.mp4" for /f usebackq^delims^= %%i in (`2^>nul where "%%~G:*.mp4"
        `)do call %:^) "%%~G" "%%~ni" "%%~i" "%_mkv%" "%_flag_0%" "%_flag_1%" "*.srt"

%:^)
if "%~1" == "" (endlocal & goto :eof)else for /f ^usebackq^delims^= %%# in (`2^>nul ^
     where "%~1\Subs\%~2:%~7"`)do "%~4" %~6 "%~dpn3.mkv" "%~3" %~5 "%%~f#" & exit /b
     

1.Сохраните этот bat-файл в base/root (на 1 уровень выше SeasonX\папок:

2.Используйте for /fцикл, чтобы получить полный путь к каждой папке.SeasonX\

3.Если в этой папке есть any/more.mp4, то на этот раз получите и их путь

4.Сохраните нужный вам mkv-файл /flagsи полный путь к исполняемому файлу mkv, а затем используйте его внутри функции ( :label)

5.Вызвать функцию, уже составив аргументы, которые будут использоваться в ней для обработки mp4, когда будет найден первый subtitle\file.srt, и немедленно выйти из функции.


Наблюдение: 1.Функция Findstrотфильтрует подпапки и разрешит запуск всех папок, которые соответствуют макету имени папки. Ниже приведены некоторые параметры, которые помогут вам выбрать наиболее подходящий для вашего сценария.

dir /a:d /b | findstr /ei Season.[0-9]       |find/v /i "\subs\"
dir /a:d /b | findstr /ei Season.*[0-9]      |find/v /i "\subs\"
dir /a:d /b | findstr /ei Season[0-9][0-9]   |find/v /i "\subs\"
dir /a:d /b | findstr /ei Season.[0-9][0-9]  |find/v /i "\subs\"
dir /a:d /b | findstr /ei Season.*[0-9][0-9] |find/v /i "\subs\"

Наблюдение: 2.При вызове функции в bat необходимо передать переменные/строку (в аргументах), чтобы можно было их использовать:

::  call :label/function and passing all arguments
:: 
::  call %:^) "%%~G" "%%~ni" "%%~i" "%_mkv%" "%_flag_0%" "%_flag_1%" "* .srt"
::  call %:ˆ) "Season1" "title1" "C:\Users\Answer42\Videos\SU-2022\Season1\title1.mp4" "C:\Program Files\MKVToolNix\mkvmerge.exe" "--default-language en --language 0:en" "--priority higher --flush-on-close --disable-track-statistics-tags -o" "*.srt"
:: 
:: ------------------------------------------------------------------------------- ::
::
:: %1  ==      "%%~G" == folder where .mp4 files are
:: %2  ==     "%%~ni" == the name without extension for the current mp4
:: %3  ==      "%%~i" == the full path to the current mp4 file
:: %4  ==    "%_mkv%" == the full path to the mkvmerge executable
:: %5  == "%_flag_0%" == mkv flag for process the first subtitle :: input in loop
:: %6  == "%_flag_1%" == mkv flag to process and output file
:: %7  ==     "*.srt" == subtitle extension
:: 
:: ------------------------------------------------------------------------------- ::

Наблюдение: 3.Ваши команды внутри for /fцикла (внутри функции/метки) и результат, полученный в цикле for с использованием аргументов:

for /f ... (`where "%~1\Subs\%~2:%~7"`)do...
for /f ... (`where "C:\Users\Answer42\Videos\SU-2022\Season1\Subs\title1:*.str`)do...

...)do "%~4" %~6 "%~dpn3.mkv" "%~3" %~5 "%%~f#"
...)do "C:\Program Files\MKVToolNix\mkvmerge.exe" --priority higher --flush-on-close --disable-track-statistics-tags -o "C:\Users\Answer42\Videos\SU-2022\Season1\title1.mkv" "C:\Users\Answer42\Videos\SU-2022\Season1\title1.mp4" --default-language en --language 0:en "C:\Users\Answer42\Videos\SU-2022\Season1\Subs\title1\subfile1.srt"


Моя цель — объединить каждый .mp4 в первый .srt в его папке subs...

Самая сложная часть при использовании этого кода — настройка команды, которая возвращает вас к правильным субтитрам....

  • Поймите, мы не знаем, как сделать вывод, соответствующий поставленной цели, и мы даже не видели файл, имя файла, дату создания/изменения или даже его содержимое.

  • Таким образом, сложно определить, что квалифицирует вас как first (или english.str), поэтому вам следует перейти к этой части, чтобы внести необходимые изменения, заменив текущую команду в функции одной из возможных команд ниже:

%:^)
if "%~1" == "" (endlocal & goto :eof)else for /f ^usebackq^delims^= %%# in (`2^&>nul ^
     where "%~1\Subs\%~2:%~7"`)do "%~4" %~6 "%~dpn3.mkv" "%~3" %~5 "%%~f#" & exit /b

:: Possible adjustments/replacement/in command:
     where "%~1\Subs\%~2:%~7"`)do...

     where "%~1\Subs\%~2:%~7"^|sort`)do...
     where "%~1\Subs\%~2:%~7"^|sort /r`)do...

     dir /b /a:-d /on /s "%~1\Subs\%~2\%~7"`)do...
     dir /b /a:-d /o-n /s "%~1\Subs\%~2\%~7"`)do...

     dir /b /a:-d /od /tc /s "%~1\Subs\%~2\%~7"`)do...
     dir /b /a:-d /o-d /tc /s "%~1\Subs\%~2\%~7"`)do...

     dir /b /a:-d /on /s "%~1\Subs\%~2\%~7" ˆ|sort /r`)do...
     dir /b /a:-d /o-n /s "%~1\Subs\%~2\%~7" ˆ|sort /r`)do...

     dir /b /a:-d /od /tc /s "%~1\Subs\%~2\%~7" ^|sort`)do...
     dir /b /a:-d /o-d /tc /s "%~1\Subs\%~2\%~7" ^|sort /r`)do...

Связанный контент