異なるフォルダから .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 をその subs フォルダーの最初の .srt に mux することです。MKVToolNix GUI を使用してこれを 1 つずつ実行することもできますが、バッチ ファイル (または PowerShell スクリプト) を使用してこれを実行するよりシンプルで高速な方法を探していました。次の 2 つのソリューションがそれに近いものです。

MP4 および SRT ファイルを MKV にバッチ結合/多重化します

.srt ファイルを .mkv ファイルにバッチ結合/多重化します

ただし、.mp4 と .srt が同じフォルダにあり、適切なタイトルが付けられている場合にのみ機能します。私の問題は、他の多くの人も対処しなければならない問題ですが、新しいリリース標準では次のようになります。

  • .mp4 と .srt は異なるフォルダーにあります。
  • .mp4 ごとに 1 つまたは複数の .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.このバッチをベース/ルート(SeasonX\フォルダの1つ上のレベル)に保存します。

2.ループを使用してfor /f各フォルダのフルパスを取得しますSeasonX\

3.そのフォルダに がある場合はany/more.mp4、今度はそのパスも取得します

4.必要なmkv/flagsとmkv実行ファイルのフルパスを保存し、関数内で使用します(:label

5.最初の subtitle\file.srt が見つかったときに、mp4 を処理するために使用される引数をすでに構成している関数を呼び出し、すぐに関数を終了します。


観察: 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 をその subs フォルダーの最初の .srt に mux することです...

このコードを使用する上で最も難しい部分は、正しい字幕を返すコマンドを調整することです。

  • 出力を目的に忠実にするにはどうすればよいかがわからず、ファイル、ファイル名、作成日/変更日、さらにはファイルの内容さえも確認していないことを理解してください。

  • したがって、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...

関連情報