重定向stdin和stdout,其中stdin首先关闭

这实际上与我已经回答的另一个问题有关。 这个问题在这里: 将一个进程对象的stdout重定向到另一个进程对象的stdin

我的问题是(我认为)获得输入的程序应该在程序输出之前退出。 这是我正在做的bash相当于:tccat -i / dev / sr0 -T 1 | ffmpeg -i – -r 1 -t 1 -s 96×72 -ss 5 /tmp/wsmanage/preview_tmp/test\%03d.jpg

这只是使用一个名为tccat的程序来读取DVD的第一个标题。 这将输出到ffmpeg,它将以.jpg格式创建一个每秒1帧的输出文件,长度为1秒。 一旦输出其框架(或两个),它就会存在。 这很好用。

但是,以下代码没有。 我得到了“打印行到ffmpeg”的大量内容,而命令行版本只需一秒钟即可退出。 然后,它在30或40秒左右停止打印。 FFmpeg永远不会退出,我的程序永远不会继续。

我这样做对吗?

Process tccatProcess = new Process(); tccatProcess.StartInfo.FileName = "tccat"; tccatProcess.StartInfo.Arguments = String.Format("-i {0} -T {1}", devNode, title); tccatProcess.StartInfo.UseShellExecute = false; tccatProcess.StartInfo.RedirectStandardOutput = true; Process ffmpegProcess = new Process(); string bashSafePreviewTemplate = slasher.bashSlash(previewTempDir + "/test%03d.jpg"); ffmpegProcess.StartInfo.FileName = "ffmpeg"; ffmpegProcess.StartInfo.Arguments = String.Format("-i - -r 1 -t 1 -s {1}x{2} -ss {3} {0}", bashSafePreviewTemplate, width, height, timePosition); ffmpegProcess.StartInfo.UseShellExecute = false; ffmpegProcess.StartInfo.RedirectStandardInput = true; try{ tccatProcess.Start(); ffmpegProcess.Start(); StreamReader tccatOutput = tccatProcess.StandardOutput; StreamWriter ffmpegInput = ffmpegProcess.StandardInput; string line; while(!ffmpegProcess.HasExited) { ffmpegProcess.Refresh(); if((line = tccatOutput.ReadLine()) != null) { Console.WriteLine("Printing line to ffmpeg"); Console.Out.Flush(); ffmpegInput.WriteLine(line); ffmpegInput.Flush(); } } Console.WriteLine("Closing tccat"); Console.Out.Flush(); tccatProcess.Close(); Console.WriteLine("Tccat closed"); Console.Out.Flush(); }catch(Exception e){ //uninteresting log code return false; } 

由于您正在使用video和图像,因此不会输出二进制数据吗? 如果是这样,你不应该直接读/写输入/输出流而不是将它们包装在文本阅读器中?

如果是这样你想要使用我可以将二进制文件放入stdin吗? C#

对于想要做类似事情的人来说,以下是适用KeeperOfTheSoul建议的新版本:

  Process tccatProcess = new Process(); tccatProcess.StartInfo.FileName = "tccat"; tccatProcess.StartInfo.Arguments = String.Format("-i {0} -T {1}", devNode, title); tccatProcess.StartInfo.UseShellExecute = false; tccatProcess.StartInfo.RedirectStandardOutput = true; Process ffmpegProcess = new Process(); string bashSafePreviewTemplate = slasher.bashSlash(previewTempDir + "/test%03d.jpg"); ffmpegProcess.StartInfo.FileName = "ffmpeg"; ffmpegProcess.StartInfo.Arguments = String.Format("-i - -r 1 -t 1 -s {1}x{2} -ss {3} {0}", bashSafePreviewTemplate, width, height, timePosition); ffmpegProcess.StartInfo.UseShellExecute = false; ffmpegProcess.StartInfo.RedirectStandardInput = true; Console.WriteLine("tccat command: {0} {1}", tccatProcess.StartInfo.FileName, tccatProcess.StartInfo.Arguments); Console.WriteLine("ffmpeg command: {0} {1}", ffmpegProcess.StartInfo.FileName, ffmpegProcess.StartInfo.Arguments); //return true; try{ tccatProcess.Start(); ffmpegProcess.Start(); BinaryReader tccatOutput = new BinaryReader(tccatProcess.StandardOutput.BaseStream); BinaryWriter ffmpegInput = new BinaryWriter(ffmpegProcess.StandardInput.BaseStream); int buffSize = 4096; byte[] buff = new byte[buffSize]; while(!ffmpegProcess.HasExited) { ffmpegProcess.Refresh(); buff = tccatOutput.ReadBytes(buffSize); ffmpegInput.Write(buff); ffmpegInput.Flush(); } tccatProcess.Kill(); tccatProcess.Close(); ffmpegProcess.Close(); }catch(Exception e){ //uninteresting log code return false; }