Archivo por lotes para mezclar recursivamente .mp4 y .srt desde diferentes carpetas

Archivo por lotes para mezclar recursivamente .mp4 y .srt desde diferentes carpetas

Hay una nueva tendencia en torrents de publicar TV y películas como x265 .mp4 con subs .srt en una carpeta separada, siguiendo esta estructura de carpetas:

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]

Mi objetivo es mezclar cada .mp4 con el primer .srt en su carpeta subs.Puedo hacer esto, uno a la vez, usando la GUI de MKVToolNix, pero he estado buscando una forma más sencilla y rápida de hacerlo con un archivo por lotes (o un script de PowerShell). Las siguientes dos soluciones se acercan:

Fusione/mux por lotes archivos MP4 y SRT a MKV

Fusión por lotes/mux .srt con archivos .mkv

Sin embargo, solo funcionan si .mp4 y .srt están en la misma carpeta y tienen el título apropiado. Mi problema, y ​​esto es algo con lo que muchos otros también tienen que lidiar, es que según el nuevo estándar de versión:

  • El .mp4 y el .srt están en carpetas diferentes.
  • Puede haber uno o varios archivos .srt por cada .mp4. Si este es el caso, es seguro asumir que quiero el primer archivo .srt, que normalmente son los subtítulos en inglés predeterminados.
  • Los archivos .srt no siguen una convención de nomenclatura en la que el primer archivo siempre tenga el mismo título. En otras palabras, el archivo por lotes tendría que utilizar el primer .srt, sin importar su nombre.

Este guión de 2018 deSujay Phadke, es un buen comienzo.

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"

Funciona de forma recursiva siempre que todos los archivos (.mp4 y .srt) estén en la misma carpeta y tengan el título adecuado. Sin embargo, lo que estoy buscando es un archivo por lotes que no implique cambiar el nombre ni mover archivos. Utilizaría mkvmerge.exe para mezclar cada .mp4 con el primer .srt en su subcarpeta y guardar cada nuevo .mkv en la misma carpeta que el .mp4.

Opcionalmente, dado que puedo resolver esto, Mkvmerge.exe debería configurar el .srt comoIdioma: inglésyforzar la bandera DefaultTrack.

Funcionaría para todos los archivos .mp4 de una temporada. No es necesario que funcione de una temporada a otra a menos que se sienta trabajador. Luego ejecutaría el archivo por lotes para cada temporada, desde la misma carpeta que los archivos .mp4 de cada temporada.

Perdón por la larga explicación, pero esto realmente me supera y me vendría bien tu ayuda. Agradezco cualquier sugerencia.

Respuesta1

@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.Guarde este murciélago en la base/raíz (1 nivel por encima de SeasonX\las carpetas:

2.Utilice un for /fbucle para obtener la ruta completa de cada carpetaSeasonX\

3.Si en esa carpeta hay un archivo any/more.mp4, esta vez obtenga también su ruta.

4.Guarde el mkv /flagsque necesita y también la ruta completa del ejecutable mkv, y utilícelo dentro de la función ( :label)

5.Llame a una función que ya contenga los argumentos que se utilizarán en ella para procesar el mp4 cuando se encuentre el primer subtítulo\archivo.srt y salga de la función inmediatamente.


Obs.: 1.Filtrará Findstrlas subcarpetas y permitirá que se ejecute en todas las que coincidan con el diseño del nombre de su carpeta, debajo de algunas opciones para verificar cuál se aplica mejor a su escenario.

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\"

Obs.: 2.Al llamar a una función en bat, es necesario pasar las variables/cadena (en argumentos) para que sea posible hacer uso de ellas:

::  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
:: 
:: ------------------------------------------------------------------------------- ::

Obs.: 3.Tus comandos dentro del for /fbucle (dentro de la función/etiqueta) y el resultado obtenido en el bucle for usando los argumentos:

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"


Mi objetivo es mezclar cada .mp4 con el primer .srt en su carpeta subs...

La parte más complicada al usar este código sería ajustar el comando que lo devuelve al subtítulo correcto....

  • Comprenda que no sabemos qué hacer para que el resultado sea fiel al objetivo y ni siquiera vimos el archivo, el nombre del archivo, la fecha de creación/cambio o incluso su contenido.

  • Por lo tanto, es difícil definir qué te califica como primero (o english.str), por lo que entrarías en esta parte para hacer el ajuste si es necesario reemplazando el comando actual en la función con uno de los posibles comandos a continuación:

%:^)
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...

información relacionada