Just like regular PowerShell strings come in two flavors - '...'
(single-quoted, verbatim) vs. "..."
(double-quoted, expandable aka interpolating) - so do here-strings.
Since you need interpolation - your string contains subexpressions ($(...)
) whose output you want to incorporate into the string - you must use the double-quoted here-string variant (@"<newline>...<newline>"@
):
$ArgumentList = @"
-i "$($args[0])" -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" "$([IO.Path]::ChangeExtension($args[0], 'mp4'))"
"@
Note: So as to also handle paths with spaces correctly, $($args[0])
is also enclosed in "..."
.
Passing all pass-through arguments to Start-Process
's -ArgumentList
parameter as a single string in which all arguments are included, using embedded "..."
quoting as necessary, is preferable to passing the arguments individually, unfortunately, due to a longstanding bug - see this answer.
Taking a step back: You don't need to use Start-Process
in order to synchronously invoke a console application in the current console window; direct invocation does just that, while additionally allowing you to capture the output from the application.
It even simplifies the syntax, as you then pass the arguments individually and needn't worry about explicit quoting of variable references or expressions (PowerShell will double-quote values with spaces for you, behind the scenes):
C:\ffmpeg\bin\ffmpeg.exe -i $args[0] -movflags faststart -pix_fmt yuv420p -vf 'scale=trunc(iw/2)*2:trunc(ih/2)*2' ([IO.Path]::ChangeExtension($args[0], 'mp4'))
See this answer for more information.