私がDOSに次のコマンドを実行すると、うまく動作します
ffmpeg -f image2 -i frame%d.jpg -vcodec mpeg4 -b 800k video.avi
引数なしでc#でプロセスクラスを使用しようとすると、ffmpegがコンソールウィンドウに読み込まれ、通常のように消えます。ただし、上記のように引数を使用しようとすると、まったく同じ形式になります...機能しません!それでもffmpegはロードされますが、コンソールウィンドウが非常に速く閉じるため、エラーが何であるかを判断できません:/
Process ffmpeg = new Process();
ffmpeg.StartInfo.FileName = path + "//" + "ffmpeg.exe";
ffmpeg.StartInfo.Arguments = " -f image2 -i frame%d.jpg -vcodec mpeg4 -b 800k video.avi";
ffmpeg.Start();
誰がこれがなぜなのか知っていますか?コマンドがdosから機能し、引数がまったく同じでもc#を使用して機能しないのはなぜですか?私は以前に多くのことでこの方法を使用しましたが、これに遭遇したことはありません。
引数のファイル名を完全修飾してみてください-FileName部分でパスを指定していることに気づいたので、プロセスが別の場所で開始され、引数を見つけられずエラーが発生している可能性があります。
それが機能する場合は、StartInfoで WorkingDirectory プロパティを設定すると便利です。
実際には、リンクによると
UserNameとPasswordが指定されている場合、WorkingDirectoryプロパティを設定する必要があります。プロパティが設定されていない場合、デフォルトの作業ディレクトリは%SYSTEMROOT%\ system32です。
直接的な答えではありませんが、この種の「探索的な」C#プログラミングに LINQPad を使用することを強くお勧めします。
LINQPadに保存された「クエリ」として次のものがあります。
var p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c echo Foo && echo Bar";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardOutput.ReadToEnd().Dump();
必要に応じて自由に適応してください。
必ずフルパスを使用してください。 「video.avi」だけでなく、そのファイルへのフルパス。
デバッグの簡単なトリックは、cmd /k <command>
insteadを使用してコマンドウィンドウを開始することです。
string ffmpegPath = Path.Combine(path, "ffmpeg.exe");
string ffmpegParams = @"-f image2 -i frame%d.jpg -vcodec"
+ @" mpeg4 -b 800k C:\myFolder\video.avi"
Process ffmpeg = new Process();
ffmpeg.StartInfo.FileName = "cmd.exe";
ffmpeg.StartInfo.Arguments = "/k " + ffmpegPath + " " + ffmpegParams
ffmpeg.Start();
これにより、コマンドウィンドウが開いたままになり、出力を簡単に確認できます。
診断を改善するために、外部プログラムの標準出力と標準エラーストリームをキャプチャして、生成された出力と、期待どおりに実行されない理由を確認できます。
見上げる:
これらをそれぞれtrueに設定すると、後でprocess.StandardOutput.ReadToEnd()
およびprocess.StandardError.ReadToEnd()
を呼び出して、出力を文字列変数に取得できます。これは、デバッガーで簡単に検査したり、トレースする出力にしたりできます。またはログファイル。
非常にエッジケースですが、指定した場合にのみ正しく動作するプログラムを使用する必要がありました
StartInfo = {..., RedirectStandardOutput = true}
指定しないとエラーになります。後で出力を読む必要さえありませんでした。