2009-09-03 99 views
3

這實際上與我已經回答的另一個問題有關。這個問題在這裏: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; 
} 

回答

0

由於您使用的是視頻和圖像,不會輸出二進制數據嗎?如果是這樣,你不應該直接讀/寫輸入/輸出流而不是將它們包裝在文本閱讀器中?

如果是這樣,你要使用應用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

0

的人誰願意做同樣的事情,在這裏是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; 

     }