0

所以我需要一个脚本来监视目录并使用 HandbrakeCLI 转换文件。我在 stackoverflow 上找到了这个 powershell 的一部分,为我的项目调整了一些东西。

$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.jsonStart-Process ...,也许它会帮助我。

编辑

所以我做了 Tomalak 建议的改变(这种方式更简单),但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 次 OK,第 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

4

1 回答 1

0

不要使用文件系统通知,而是围绕一个简单的无限循环构建脚本:

$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变量指向的任何程序。

作为练习,您可以将顶级变量转换为脚本参数,以便您可以将脚本重新用于其他批处理作业。

于 2017-10-19T15:29:24.127 回答