Зеленые рамки / без субтитров в преобразованных файлах каталога просмотра (Powershell) с использованием предустановки HandbrakeCLI + JSON
Поэтому мне нужен был скрипт, который просматривает каталог и конвертирует файлы с помощью HandbrakeCLI. Я нашел часть этого PowerShell здесь на stackru и я настроил некоторые вещи для своего проекта.
$global:watch = "C:\~\cmp\" ### watching directory
$global:convert = "C:\~\convert\" ### handbrakecli and preset location
$global:outp = "C:\~\output_folder\" ### output location
$global:extIn = ".mkv"
$global:extOut = ".mp4"
Write-Host "Watching directory = $watch"
Write-Host "HandbrakeCLI / json preset location = $convert"
Write-Host "Output directory = $outp"
Write-Host "Input extension = $extIn ; Output extension = $extOut"
Write-Host "Waiting for change in directory..."
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher;
$watcher.Path = $watch;
$watcher.Filter = "*"+$extIn;
$watcher.IncludeSubdirectories = $false;
$watcher.EnableRaisingEvents = $false;
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action =
{
$path = $Event.SourceEventArgs.FullPath;
$handbrakecli = $convert+"HandBrakeCLI.exe";
$fl = Split-Path $path -leaf;
Write-Host "New file found: $fl";
$flName, $flExt = $fl.split('.')
$mp4File = $watch+"\"+$flName+$extOut
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
Add-content -path ($convert+"log.txt") -value $logline
Write-Host "Added entry to log"
Write-Host "Start converting using HandbrakeCLI..."
& cmd.exe /c $handbrakecli -i $path -o $mp4File --preset-import-file my_preset.json
Write-Host "Done converting!"
Write-Host "Moving file to folder..."
& cmd.exe /c move /Y $mp4File $outp
Write-Host "File moved!"
& cmd.exe /c del $path /F
Write-Host "$fl has been removed from local folder"
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
Register-ObjectEvent $watcher "Changed" -Action $action
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}
Хотя поначалу казалось, что все работает, я начал замечать, что "иногда" субтитры не добавляются или зеленые рамки вставляются (или заменяются исходными) после каждого кадра (обычный - зеленый - обычный - зеленый - и т. Д.).
Пример: я добавил 2 mkv-файла в каталог, первый был преобразован очень хорошо с субтитрами, в то время как у второго файла не было никаких субтитров.
Я любитель, когда дело доходит до этого, но я думаю, что это как-то связано с & cmd.exe /c
, Я также обнаружил, что вы могли бы Start-Process
в PowerShell, но я не знаю, как его использовать.
Так что, если кто-то может помочь мне преобразовать это & cmd.exe /c $handbrakecli -i $path -o $mp4File --preset-import-file my_preset.json
к чему-то с Start-Process ...
, может быть, это поможет мне.
РЕДАКТИРОВАТЬ
Поэтому я внес изменения, предложенные Томалаком (проще так), но Move-Item
а также Remove-Item
не похоже на работу.
РЕДАКТИРОВАТЬ 2
добавленной -LiteralPath
в качестве аргумента для Move-Item / Remove-Item (необходим для имен файлов, содержащих квадратные скобки)
$inputFolder = "C:\~\cmp\"
$outputFolder = "C:\~\output_folder\"
$handbrake = "C:\~\convert\HandBrakeCLI.exe"
$presetJson ="C:\~\convert\my_preset.json"
$extIn = "mkv"
$extOut = "mp4"
while ($true) {
Get-ChildItem -Path $inputFolder -Filter "*.$extIn" | ForEach-Object {
$inFile = $_.FullName
$outFile = $inputFolder + $_.FullName.split('\.')[-2] + ".$extOut" #changed this because I wanted the file in the same directory as input file
Write-Host "Converting: $inFile"
& $handbrake -i $inFile -o $outFile --preset-import-file $presetJson
if ($LASTEXITCODE -eq 0) {
Move-Item -LiteralPath $outFile $outputFolder -Force #move to output folder
Write-Host "Done: $outFile"
Remove-Item -LiteralPath $inFile -Force #removing the input item, not output
Write-Host "Removed input file!"
} else {
Write-Error "Conversion failed!"
}
}
sleep 5
}
Хотя субтитры добавляются ко всем выходным файлам, иногда я по-прежнему мерцаю зеленым цветом. В качестве тестового прогона я использовал 3 файла, результат: 1-е мерцание, 2-е ОК, 3-е мерцание. Я понятия не имею, почему у некоторых все хорошо, а у некоторых мерцание. Так что я подумываю использовать ffmpeg вместо этого.
РЕДАКТИРОВАТЬ 3
Для будущих посетителей: используйте ffmpeg вместо HandbrakeCLI:
ffmpeg.exe -i "C:\~\inputfile.mkv" -filter_complex "subtitles='C\:/Users/~/inputfile.mkv'" -c:v libx264 -preset veryfast -b:v 2750k -c:a aac $outputfile.mp4
1 ответ
Вместо того, чтобы использовать уведомления файловой системы, структурируйте ваш скрипт вокруг простого бесконечного цикла:
$inputFolder = "C:\~\cmp"
$outputFolder = "C:\~\convert"
$handbrake = "C:\~\convert\HandBrakeCLI.exe"
$presetJson = "C:\~\convert\my_preset.json"
$extIn = "mkv"
$extOut = "mp4"
while ($true) {
Get-ChildItem -Path $inputFolder -Filter "*.$extIn" | ForEach-Object {
$inFile = $_.FullName
$outFile = "$($_.BaseName).$extOut"
if (Test-Path $outFile) { Remove-Item $outFile -Force -LiteralPath }
Write-Host "Converting: $inFile"
& $handbrake -i $inFile -o $outFile --preset-import-file $presetJson
if ($LASTEXITCODE -eq 0) {
Move-Item $outFile $outputFolder -Force -LiteralPath
Write-Host "Done: $outFile"
} else {
Write-Error "Conversion not successful."
}
}
sleep 5
}
&
заставляет Powershell выполнять любую программу $handbrake
переменная указывает на.
В качестве упражнения вы можете преобразовать переменные верхнего уровня в параметры сценария, чтобы можно было повторно использовать сценарий для других пакетных заданий.