I'd like to convert a pipe of video stream between streamlink
and ffmpeg
from cmd to Powershell. But from what I searched powershell only supports piping objects.
Is there any way to reproduce this in Powershell without using Start-Process -FilePath "cmd" -ArgumentList [...]
? I'd prefer not to use it because I need access to the exit code.
streamlink $stream_url best -O | ffmpeg -i pipe: "output_file.mp4"
note: the line above had some args removed for better clarity
In PowerShell (Core) 7 - specifically in v7.4+ - your command would work as-is, because in these versions piping raw bytes (binary data) is supported and automatically employed when piping between two external programs (see this answer for more information).
In earlier versions, notably including Windows PowerShell (the legacy, ships-with-Windows, Windows-only edition of PowerShell whose latest and last version is 5.1), the simplest workaround is to directly invoke your command line via cmd /c
to take advantage of cmd.exe
's binary pipeline:
cmd /c "streamlink `"$stream_url`" best -O | ffmpeg -i pipe: `"output_file.mp4`""
As shown above, direct invocation of cmd.exe
is possible (no need for Start-Process
)[1], which relays the exit code reported by the given command line to PowerShell, allowing you to query it via the automatic $LASTEXITCODE
variable.
Note that, for robustness, embedded (escaped) "..."
quoting was also applied to the $stream_url
argument, as its expanded value could contain cmd.exe
metacharacters such as &
that would otherwise break the command.
[1] The general advice applies:
To synchronously execute console applications or batch files in the current console (terminal), call them directly (some.exe
or c:\path\to\some.exe ...
or & 'c:\path with spaces\to\some.exe' ...
or & $exePathStoredInVariable ...
). This also allows you to capture their output directly and to later query their exit code via $LASTEXITCODE
. Do not use Start-Process
(or the System.Diagnostics.Process
API it is based on). See this answer and this guidance.
That said, in scenarios where you do need Start-Process
, you can obtain the exit code of the launched process as follows: use the -PassThru
switch, which makes Start-Process
emit a process-information object; once the process has exited (which you can await with the -Wait
switch or by calling .WaitForExit()
on the process-information object), you can obtain the exit code via its .ExitCode
property.