У меня возникают проблемы с отправкой вывода из процесса 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" не работает по мере необходимости.
Пришло простое решение.
Использование процесса 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.
}
Я изучаю столько, сколько я отвечаю здесь.
Кажется, что нет простого способа управлять несколькими процессами с тем же именем (int this case 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
параметр /min
для команды запуска, например start/min...
для минимизации окон.