Зеленые рамки / без субтитров в преобразованных файлах каталога просмотра (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 переменная указывает на.

В качестве упражнения вы можете преобразовать переменные верхнего уровня в параметры сценария, чтобы можно было повторно использовать сценарий для других пакетных заданий.

Другие вопросы по тегам