将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#

+0

嗯,这可能是我的问题。我没有意识到streamreader/streamwriter不是二进制安全的。我会尽快尝试,并将结果发回!感谢您的链接也。我明白我需要做什么。即使这不是我唯一的问题,但我可以看到它是一个需要修复的问题。 – Matthew 2009-09-04 16:43:06

+0

就是这样!谢谢! – Matthew 2009-09-04 21:39:47

的人谁愿意做同样的事情,在这里是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; 

     }