使用 HandbrakeCLI + JSON 预设的观看目录 (Powershell) 的转换文件中的绿框/无字幕
Green frames / no subtitles in converted files of watching directory (Powershell) using HandbrakeCLI + JSON preset
所以我需要一个脚本来监视目录并使用 HandbrakeCLI 转换文件。我在 Whosebug 上找到了这个 powershell here 的一部分,并为我的项目调整了一些东西。
$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}
虽然一开始一切似乎都正常,但我开始注意到 "sometimes" 没有添加字幕或在每一帧之后插入了绿色帧(或替换了原始帧)(正常 - 绿色 - 正常 - 绿色- 等)。
一个例子:我在目录中添加了 2 个 mkv 文件,第一个文件转换得很好,带有字幕,而第二个文件没有任何字幕。
我是外行,不过我觉得跟& cmd.exe /c
有点关系。我还发现您可以在 powershell 中使用 Start-Process
,但我不知道如何使用它。
因此,如果有人可以帮助我将此 & cmd.exe /c $handbrakecli -i $path -o $mp4File --preset-import-file my_preset.json
转换为带有 Start-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个文件作为测试运行,结果:第一个闪烁,第二个OK,第三个闪烁。我不知道为什么有些很好,有些却闪烁。所以我正在考虑改用 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
不使用文件系统通知,而是围绕一个简单的无限循环构建脚本:
$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
变量指向的任何程序。
作为练习,您可以将顶级变量转换为脚本参数,以便您可以将脚本重新用于其他批处理作业。
所以我需要一个脚本来监视目录并使用 HandbrakeCLI 转换文件。我在 Whosebug 上找到了这个 powershell here 的一部分,并为我的项目调整了一些东西。
$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}
虽然一开始一切似乎都正常,但我开始注意到 "sometimes" 没有添加字幕或在每一帧之后插入了绿色帧(或替换了原始帧)(正常 - 绿色 - 正常 - 绿色- 等)。
一个例子:我在目录中添加了 2 个 mkv 文件,第一个文件转换得很好,带有字幕,而第二个文件没有任何字幕。
我是外行,不过我觉得跟& cmd.exe /c
有点关系。我还发现您可以在 powershell 中使用 Start-Process
,但我不知道如何使用它。
因此,如果有人可以帮助我将此 & cmd.exe /c $handbrakecli -i $path -o $mp4File --preset-import-file my_preset.json
转换为带有 Start-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个文件作为测试运行,结果:第一个闪烁,第二个OK,第三个闪烁。我不知道为什么有些很好,有些却闪烁。所以我正在考虑改用 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
不使用文件系统通知,而是围绕一个简单的无限循环构建脚本:
$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
变量指向的任何程序。
作为练习,您可以将顶级变量转换为脚本参数,以便您可以将脚本重新用于其他批处理作业。