2

У меня есть папка с:

  • ТВ-шоу - Эпизод 01.mkv
  • ТВ-шоу - Эпизод 01.srt
  • ТВ-шоу - Эпизод 02.mkv
  • ТВ-шоу - Эпизод 02.srt
  • ТВ-шоу - Эпизод 03.mkv
  • ТВ-шоу - Эпизод 03.srt

и так далее...

Я уже знаю, что я могу сделать это с MKVMerge один за другим. Это заняло бы значительное количество времени, так что ... Я хочу сделать пакетный скрипт, который может сделать это для всех файлов в папке с MKVToolNix, mkvmerge или подобным.

Мне также нужно, чтобы пакетный сценарий был относительным, чтобы я мог применить сценарий позднее, когда имена файлов различаются.Имя файла не всегда может быть "TVShow", но, например, "Second TV Show".

1. Я хочу преобразовать внешний файл субтитров (srt) в соответствующий файл фильма (mkv).

2. Я также хочу сделать субтитры по умолчанию и принудительные субтитры соответствующего файла фильма.

Как я могу сделать пакетный скрипт, как это? Я немного разбираюсь в пакетных сценариях и несколько часов гуглял, не находя полезной информации.

Я начал с этого, но он не работает, а также не устанавливает субтитры по умолчанию или принудительно:

"B:\OneDrive\Portable applications\mkvtoolnix\mkvmerge.exe" "FOR %%A IN (*.mkv) DO mkvmerge -o "remux-%%~nA.mkv" "%%~A" "%%~dpnA.srt"

5 ответов5

2
for %%A IN (*.mkv) do (
"B:\OneDrive\Portable applications\mkvtoolnix\mkvmerge.exe" -o "remux-%%~nxA" "%%~A" "%%~nA.srt"
echo  Replace this Line with your othr commands!
)

И посмотрите mkvpropedit - измените свойства существующей Matroska и измените язык / субтитры по умолчанию в файлах MKV

1

У меня была та же проблема, что и у вас, и я собрал приведенный ниже скрипт PowerShell для достижения пакетного смешивания субтитров.

#Batch Merge Subtitles with MKVMerge - Iain McCain

#Set MKVMerge.exe Path
$MKVMerge = 'C:\Program Files\MKVToolNix\mkvmerge.exe'
#Set Target
$Directory = "Z:\Films\"
#Set Subtitle Extension
$SubExtension = 'eng.srt'

#Process
$Subs = Get-ChildItem $Directory -Filter "*.$SubExtension" -Recurse | % { $_.FullName } | Sort-Object
$Count = $Subs.count
Write-Host "$Count MKV's to be processed."

Foreach ($Sub in $Subs) 
{
#Get File Name
$FormatName = $Sub.ToString()
$Name = $FormatName.TrimEnd(".$SubExtension")
$MKV = $Name + '.mkv'

#Set Output File Name
$Output = $Name + '___MERGED' + '.mkv'

#Execute
& $MKVMerge -o "$Output" --default-track "0" --language "0:eng" "$Sub" "$MKV"

#Clean Up
Remove-Item $MKV
Remove-Item $Sub
Rename-Item $Output -NewName $MKV
} 
1

Я нашел хороший пример в другом ответе [ 1 ], используйте общий эскиз ниже:

for %%f in (*.mkv) do (
        echo %%~nf
         mkvmerge -o "%%~nf_New.mkv" "%%~nf_New.mkv" --language 0:eng "%%~nf.srt"

)

Пример более похожий я нашел на сайте mkvmerge [ 2 ]

mkvmerge -o with-lang-codes.mkv --language 2:ger --language 3:dut \
--default-track 3 without-lang-codes.mkv --language 0:eng english.srt \
--default-track 0 --language 0:fre french.srt

Достаточно, чтобы вы поместили в цикл for командную строку, которая работает в вашем отдельном случае, изменив файл mkv с помощью %%~nf.mkv и srt с помощью %%~nf.srt и все параметры в правильном месте.

0

Все благодарности Иану Маккейну выше за это редактирование их кода.

TrimEnd - это буква за буквой, а не строка, поэтому любой файл, заканчивающийся буквой в имени расширения, вызовет сбои. Поскольку скрипт не проверяет наличие ошибок, файлы sub и mkv удаляются, даже если возникают ошибки, препятствующие созданию мультиплексированного файла. Это может привести к потере данных.

Мне нужно было использовать сценарий для слияния файлов idx/sub в мои MKV вместо файлов srt, и они назывались так же, как видеофайлы с расширениями .sub и .idx вместо .mkv. Я также добавил проверку ошибок, чтобы никакие файлы не удалялись / переименовывались, если файл ___MERGED не был создан из-за какой-либо ошибки. Это мое законченное решение.

    #Batch Merge Subtitles with MKVMerge - Iain McCain

#Set MKVMerge.exe Path
$MKVMerge = 'C:\Program Files\MKVToolNix\mkvmerge.exe'
#Set Target
$Directory = "Z:\Movies\"
#Set Subtitle Extension
$SubExtension = 'idx'
$SecondSubExtension = "sub"

#Process
$Subs = Get-ChildItem $Directory -Filter "*.$SubExtension" -Recurse | % { $_.FullName } | Sort-Object
$Count = $Subs.count
Write-Host "$Count MKV's to be processed."

Foreach ($Sub in $Subs) {
    #Get File Name
    $FormatName = $Sub.ToString()
    #$Name = $FormatName.TrimEnd(".$SubExtension")
    $Name = $FormatName.Substring(0,$FormatName.Length-($SubExtension.Length+1))
    $MKV = $Name + '.mkv'
    $OtherSub = $Name + '.' + $SecondSubExtension

    #Set Output File Name
    $Output = $Name + '___MERGED' + '.mkv'

    #Execute
    & $MKVMerge -o "$Output" --default-track "0" --language "0:eng" "$Sub" "$MKV"

    If (Test-Path $Output) {
        #Clean Up
        Remove-Item $MKV
        Remove-Item $Sub
        Remove-Item $OtherSub
        Rename-Item $Output -NewName $MKV
    } Else {
        write-host "NON-EXISTANT - $Output" -foreground "red"
        "NON-EXISTANT - $Output" | Out-File $Directory + "Errors.txt" -Append
    }
}
0

Большое спасибо @Ian, @Hastur и другим. Вот скрипт, который исправляет ошибки в других, опубликованных здесь, и перемещает измененный файл обратно в исходное имя файла. (замените "путь" на путь к исполняемому файлу)

for %%f in (*.mkv) do (
    echo %%~nf
    <path>mkvmerge.exe -o "%%~nf_New.mkv" "%%~nf.mkv" --language 0:eng "%%~nf.srt"
    move /Y "%%~nf_New.mkv"  "%%~nf.mkv"

)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .