Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ffmpeg and ffplay piped together in PowerShell

I have switched my current video project from command prompt to PowerShell so that I can take full advantage of the Tee-Object for a multi output code.

Currently, I have a version of my code working in batch, but I need to add one more feature through a tee. This is my first time using PowerShell, so this is probably a simple fix...

Currently I have figured out how to run ffmpeg and ffplay in PowerShell, and I have a program in batch which takes an ffmpeg output and pipes it to ffplay, and this works just fine. I can also play through ffplay in PS just fine. In PS, this code works:

ffplay -video_size 1280x720 -pixel_format uyvy422 -framerate 60 -i video="Decklink Video Capture"

And as a batch, this code works fine for what I'm doing:

ffmpeg -video_size 1280x720 -pixel_format uyvy422 -framerate 60 -i video="Decklink Video Capture" -c:v libx265 -preset ultrafast -mpegts pipe: | ffplay pipe:

It takes the video I want and plays it through the pipe to the screen. When played through PowerShell, though, the video doesn't even pop up. I don't get any warnings or anything, and it seems to run fine, but I don't get the picture to display.

End goal is to be able to play the video on the host display in full resolution, and publish a lower bitrate to the network, if that helps.

like image 360
SpacePirateRob Avatar asked Nov 08 '22 06:11

SpacePirateRob


1 Answers

The reason you are seeing strange behavior, is that piping in PowerShell does not work the same way as in the old cmd-interpreter/console. Basically it is parsed by PowerShell before being passed on to the next command. You may read more in this GitHub issue about some of the ongoing work to enable two native processes to pass raw byte-streams in PowerShell.

If you are unable to just run your command in a legacy cmd-shell (it would probably be the easiest way), you may use the module Use-RawPipeline.

Install-Module -Name Use-RawPipeline

Then you can construct a command line like this (I've simplified the argument list to just to use a file and skip the decklink-source for brevity):

Invoke-NativeCommand -FilePath .\ffmpeg -ArgumentList @("-i", "C:\temp\testfile.mp4","-f","h264", "pipe:") |
Invoke-NativeCommand -FilePath .\ffplay.exe -ArgumentList @("pipe:") |
Receive-RawPipeline

If you need to add more command to the pipeline, just insert another Invoke-NativeCommand -FilePath <command> before the Receive-RawPipeline.

Note: I am not sure about the performance of this solution, but I have confirmed it will pipe the output of ffmpeg to ffplay and display the encoded stream.

like image 108
espenwa Avatar answered Nov 15 '22 07:11

espenwa