2009-09-03 11 views
3

これは実際に私が既に回答していた別の質問に関連しています。その質問はここにあります:Redirecting stdout of one process object to stdin of anotherstdinと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

これは、dvdの最初のタイトルを読み取るためにtccatというプログラムを使用するだけです。これはffmpegに出力されます.ffmpegは1秒間に1フレームの出力ファイルを作成し、1秒間に.jpg形式で出力します。そのフレーム(または2つ)を出力するとすぐにそれが存在します。これは正常に動作します。

ただし、次のコードはありません。私は "print line to ffmpeg"の襲撃を受けるが、コマンドライン版はちょうど1秒以上で終了する。それで、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

ビデオや画像を扱っているので、tccatはバイナリデータを出力しませんか?そうであれば、テキストリーダーでラッピングするのではなく、直接入出力ストリームに読み書きするべきではありませんか?

ので、あなたが似た何かをしたい人のためのCan i put binary in stdin? C#

+0

ああ、これは私の問題かもしれません。 streamreader/streamwriterがバイナリセーフではないことはわかりませんでした。私はできるだけ早くこれを試し、結果を投稿します!リンクもありがとう。私は何をする必要があるのか​​分かります。これが私の唯一の問題ではないとしても、私はそれが確定する必要があることを確かに見ることができます。 – Matthew

+0

それでした!ありがとう! – Matthew

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; 

     }