管道流程输出到新流程

Posted

技术标签:

【中文标题】管道流程输出到新流程【英文标题】:Piping process output to new process 【发布时间】:2014-05-21 22:39:43 【问题描述】:

我在将 rtmpdump 进程的输出通过管道传输到 ffmpeg 时遇到问题,我认为问题在于我的进程正在窃取 rtmpdump 的输出。

在我的研究中,我听说过尝试使用 cmd.exe 进程并在其中将 rtmpdump.exe 作为 /C 命令运行,但这个问题是我失去了对由此产生的 rtmpdump.exe 进程的引用,并且我需要能够在我的程序中管理多个 rtmpdump 进程,并有时选择性地杀死某些进程。

我最初尝试了类似这样的简单方法:

var p = new Process();
p.StartInfo.FileName = "rtmpdump.exe";
p.StartInfo.Arguments = "-v -r rtmp://somehost.com/app-name -o - | ffmpeg.exe -loglevel quiet -i - -c:v copy -c:a libvo_aacenc -b:a 128k \"test.mp4\"";

这根本不起作用。

以“cmd.exe”作为初始进程:

var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C rtmpdump.exe -v -r rtmp://somehost.com/app-name -o - | ffmpeg.exe -loglevel quiet -i - -c:v copy -c:a libvo_aacenc -b:a 128k \"test.mp4\"";

这让我更接近我需要它启动一个 rtmpdump 进程并重定向到 ffmpeg,但现在“p”将引用一个不存在的“cmd.exe”进程,该进程运行命令以启动 rtmpdump,然后是“cmd.exe”终止。

我唯一关心的是能够保持对创建的 rtmpdump.exe 进程的引用。 ffmpeg 会在 rtmpdump 关闭后自行终止,可以忽略它的进程。

编辑: 如果问题不清楚。我正在尝试将 rtmpdump 的输出通过管道传输到 ffmpeg。使用重定向运算符 | 作为命令参数的一部分执行此操作的正常方式不起作用。并且无法根据需要使用“cmd.exe”进程。

【问题讨论】:

到底是什么问题? 我正在尝试将 rtmpdump 的输出通过管道传输到 ffmpeg,但使用 |作为进程参数的一部分的重定向运算符不起作用。 @LittleBill902 也许您可以尝试将taskkill /im "rtmpdump.exe" 作为杀戮过程。我不确定如何获取 PID 并使用它。 一次可以有多个“rtmpdump.exe”进程。 【参考方案1】:

想出了一个简单的解决方案。

使用 CMD 进程作为您的启动进程。

var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C rtmpdump.exe -v -r rtmp://somehost.com/app-name -o - |       ffmpeg.exe -loglevel quiet -i - -c:v copy -c:a libvo_aacenc -b:a 128k \"test.mp4\"";
test.Start();

并在启动进程后立即使用这段代码来获取最后创建的 rtmpdump 进程。

Process[] allDumps = Process.GetProcessesByName("rtmpdump"); // get all rtmp processes
if (allDumps.Any())

    Process newestProcess = allDumps.OrderByDescending(x => x.StartTime).First(); // get the last one created     
    // Add the newly captured process to your list of processes for use later.

【讨论】:

【参考方案2】:

我正在学习,就像我在这里回答一样。

似乎没有一种简单的方法来管理具有相同名称的多个进程(在这种情况下为rtmpdump.exe)。

除了使用进程名称或 PID,似乎还有另一种方法,即使用控制台命令 START 并为其提供由 START 启动的不同窗口标题名称。

在命令控制台中,您可以输入如下内容:

C:\>start "dumpProc01" rtmpdump.exe -v -r .......
C:\>start "dumpProc02" rtmpdump.exe -v -r .......
C:\>start "dumpProc03" rtmpdump.exe -v -r .......

并使用taskkill 命令杀死一个特定进程。例如:

C:\>taskkill /fi "windowtitle eq dumpProc01"

要将START 应用于您的流程创建,流程参数将是:

// from this
p.StartInfo.Arguments = "/C rtmpdump.exe ....

// to this
p.StartInfo.Arguments = "/C start \"dumpProc01\" rtmpdump.exe -v -r ....

为了杀死一个特定的进程,你可以创建一个taskkill 进程:

Process kp = new Process();
kp.StartInfo.FileName = "taskkill.exe";
kp.StartInfo.Arguments = "/fi \"windowtitle eq dumpProc01\" ";
kp.Start();

您可以为启动命令提供/min 选项,如start /min ... 以最小化窗口。

【讨论】:

这不起作用,因为它不允许您通过管道传输 rtmpdump 的输出。相反,重定向运算符尝试重定向 START 命令

以上是关于管道流程输出到新流程的主要内容,如果未能解决你的问题,请参考以下文章

我可以将多个 ffmpeg 输出通过管道传输到不同的管道吗?

渲染管道像素阶段“子流程”

渲染管道像素阶段“子流程”

使用命名管道模拟流程替换

Java IO PipedInputStream 和 PipedOutputStream

单独的时间管道流程