将参数从 PowerShell 传递到 FFMPEG 以进行批量视频转换时出现问题
problem passing parameters from PowerShell to FFMPEG for batch video conversion
我想使用 ffmpeg 将视频从一种格式转换为另一种格式,并且 "flexibility" 能够拥有一组预定义的转换设置。但是,如果我从 PowerShell 将参数作为数组或变量传递,它就不起作用。
项目文件夹的结构是:
- main folder
-- input <-folder
-- output <-folder
-- convert.ps1 <- script to launch batch conversion
我的代码是:
# this is content of convert.ps1
$VideoFileTypes = '*.mkv', '*.mp4', '*.webm', '*.mov'
$VideoInputFolderNamee = 'input'
$VideoOutputFolderName = 'output'
$VideoInputFolder = Join-Path -Path $PSScriptRoot -ChildPath $VideoInputFolderName
$VideoOutputFolder = Join-Path -Path $PSScriptRoot -ChildPath $VideoOutputFolderName
# FFMPEG convertion parameters ----------------------------------------------
[array]$h265 = '-c:v libx265', '-crf 22', '-c:a opus', '-b:a 128k'
$h264 = '-c:v libx264 -preset veryslow -crf 22 -c:a aac'
[array]$h264_2 = "-c:v libx264", "-preset veryslow", "-crf 22", "-c:a aac"
# ---------------------------------------------------------------------------
Get-ChildItem -Path $VideoInputFolder -Recurse -File -Include $VideoFileTypes | Foreach-Object {
$OutputFileName = $_.BaseName + ".mkv"
$OutputFilePath = Join-Path -Path $VideoOutputFolder -ChildPath $OutputFileName
Write-Output $_.FullName
Write-Output $OutputFilePath
# reference to one of existing configurations (specified above)
$parameters = $h265
# actuall call for conversion
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
}
如果参数集定义为带单引号的数组,如 $h265
,那么我会收到错误消息:
Invalid stream specifier: v libx265.
如果参数集定义为带双引号的数组,如 $h264_2
,那么我收到错误:
Unrecognized option 'crf 22'.
Error splitting the argument list: Option not found
如果参数集定义为字符串,如 $h264
,则错误为:
Invalid stream specifier: v libx264 -preset veryslow -crf 22 -c:a aac.
有一段时间,我认为 ffmpeg 设置本身有问题,如前所述 here。但是,我不这么认为,因为直接指定参数完全没问题:
& ffmpeg -i $_.FullName -c:v libx264 -preset veryslow -crf 22 -c:a aac -y $OutputFilePath
或
& ffmpeg -i $_.FullName -c:v libx265 -crf 28 -c:a opus -b:a 128k -y $OutputFilePath
请帮忙解决这个问题。
[解决方案]:
(1): 使用数组的每个部分:
...
$h265 = '-c:v', 'libx265', '-crf', '28', '-c:a', 'aac', '-b:a', '128k'
...
$parameters = $h265
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
...
(2) 使用字符串并拆分
...
$h265 = '-c:v libx265 -crf 28 -c:a aac -b:a 128k'
...
$parameters = $h265
$parameters = $parameters.Split(" ")
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
...
选项名称和值应作为单独的字符串发送,因此 '-crf', '22'
而不是 '-crf 22'
我想使用 ffmpeg 将视频从一种格式转换为另一种格式,并且 "flexibility" 能够拥有一组预定义的转换设置。但是,如果我从 PowerShell 将参数作为数组或变量传递,它就不起作用。
项目文件夹的结构是:
- main folder
-- input <-folder
-- output <-folder
-- convert.ps1 <- script to launch batch conversion
我的代码是:
# this is content of convert.ps1
$VideoFileTypes = '*.mkv', '*.mp4', '*.webm', '*.mov'
$VideoInputFolderNamee = 'input'
$VideoOutputFolderName = 'output'
$VideoInputFolder = Join-Path -Path $PSScriptRoot -ChildPath $VideoInputFolderName
$VideoOutputFolder = Join-Path -Path $PSScriptRoot -ChildPath $VideoOutputFolderName
# FFMPEG convertion parameters ----------------------------------------------
[array]$h265 = '-c:v libx265', '-crf 22', '-c:a opus', '-b:a 128k'
$h264 = '-c:v libx264 -preset veryslow -crf 22 -c:a aac'
[array]$h264_2 = "-c:v libx264", "-preset veryslow", "-crf 22", "-c:a aac"
# ---------------------------------------------------------------------------
Get-ChildItem -Path $VideoInputFolder -Recurse -File -Include $VideoFileTypes | Foreach-Object {
$OutputFileName = $_.BaseName + ".mkv"
$OutputFilePath = Join-Path -Path $VideoOutputFolder -ChildPath $OutputFileName
Write-Output $_.FullName
Write-Output $OutputFilePath
# reference to one of existing configurations (specified above)
$parameters = $h265
# actuall call for conversion
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
}
如果参数集定义为带单引号的数组,如 $h265
,那么我会收到错误消息:
Invalid stream specifier: v libx265.
如果参数集定义为带双引号的数组,如 $h264_2
,那么我收到错误:
Unrecognized option 'crf 22'.
Error splitting the argument list: Option not found
如果参数集定义为字符串,如 $h264
,则错误为:
Invalid stream specifier: v libx264 -preset veryslow -crf 22 -c:a aac.
有一段时间,我认为 ffmpeg 设置本身有问题,如前所述 here。但是,我不这么认为,因为直接指定参数完全没问题:
& ffmpeg -i $_.FullName -c:v libx264 -preset veryslow -crf 22 -c:a aac -y $OutputFilePath
或
& ffmpeg -i $_.FullName -c:v libx265 -crf 28 -c:a opus -b:a 128k -y $OutputFilePath
请帮忙解决这个问题。
[解决方案]:
(1): 使用数组的每个部分:
...
$h265 = '-c:v', 'libx265', '-crf', '28', '-c:a', 'aac', '-b:a', '128k'
...
$parameters = $h265
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
...
(2) 使用字符串并拆分
...
$h265 = '-c:v libx265 -crf 28 -c:a aac -b:a 128k'
...
$parameters = $h265
$parameters = $parameters.Split(" ")
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
...
选项名称和值应作为单独的字符串发送,因此 '-crf', '22'
而不是 '-crf 22'