将stdin和stdout重定向到stdin首先关闭的位置
问题描述:
这实际上与我已经回答的另一个问题有关。这个问题在这里:Redirecting stdout of one process object to stdin of another将stdin和stdout重定向到stdin首先关闭的位置
我的问题是(我认为)得到输入的程序应该在程序输出之前退出。这里是我在做什么的bash等价物:tccat -i/dev/sr0 -T 1 | ffmpeg -i - -r 1 -t 1 -s 96x72 -ss 5 /tmp/wsmanage/preview_tmp/test\%03d.jpg
这只是使用称为tccat的程序来读取DVD的第一个标题。这会得到输出到ffmpeg,它将以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;
}
答
由于您使用的是视频和图像,不会输出二进制数据吗?如果是这样,你不应该直接读/写输入/输出流而不是将它们包装在文本阅读器中?
如果是这样,你要使用应用Can i put binary in 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;
}
嗯,这可能是我的问题。我没有意识到streamreader/streamwriter不是二进制安全的。我会尽快尝试,并将结果发回!感谢您的链接也。我明白我需要做什么。即使这不是我唯一的问题,但我可以看到它是一个需要修复的问题。 – Matthew 2009-09-04 16:43:06
就是这样!谢谢! – Matthew 2009-09-04 21:39:47