I want to convert videos from one format to another using the ffmpeg and have some "flexibility" in being able to have a set of pre-defined conversion settings. However, it doesn't work if I'm passing parameters as array or variables from PowerShell.
The structure of the project folder is:
- main folder
-- input <-folder
-- output <-folder
-- convert.ps1 <- script to launch batch conversion
My code is:
# 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
}
If the set of parameters is defined as an array with single quotes, like $h265
, then I receive the error:
Invalid stream specifier: v libx265.
If the set of parameters is defined as an array with double quotes, like $h264_2
, then I receive the error:
Unrecognized option 'crf 22'.
Error splitting the argument list: Option not found
If the set of parameters is defined as string, like $h264
, than error is:
Invalid stream specifier: v libx264 -preset veryslow -crf 22 -c:a aac.
For a while, I thought that there is something wrong with ffmpeg setup itself, as mentioned here. But, I don't think so, since direct specifying of parameters works totaly fine:
& ffmpeg -i $_.FullName -c:v libx264 -preset veryslow -crf 22 -c:a aac -y $OutputFilePath
or
& ffmpeg -i $_.FullName -c:v libx265 -crf 28 -c:a opus -b:a 128k -y $OutputFilePath
Please, help to resolve this issue.
[SOLUTION]:
(1): use each part of array:
...
$h265 = '-c:v', 'libx265', '-crf', '28', '-c:a', 'aac', '-b:a', '128k'
...
$parameters = $h265
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
...
(2) use the string and split
...
$h265 = '-c:v libx265 -crf 28 -c:a aac -b:a 128k'
...
$parameters = $h265
$parameters = $parameters.Split(" ")
& ffmpeg -i $_.FullName $parameters -y $OutputFilePath
...
The option name and value should be sent as separate strings, so '-crf', '22'
instead of '-crf 22'