您的进程挂起,因为您从未告诉ffmpeg您已完成对
StandardInput
流动所以它仍然在那里等待你发送更多的数据。
填充
和
输出文件
Process
类及其属性。
特别是,这意味着两件事:
-
当程序为流生成原始字节数据时,不能将输出数据视为字符。
-
必须
完成后关闭输入流,以便程序知道已到达输入流的末尾。
static void Main(string[] args)
{
Process proc = new Process();
proc.StartInfo.FileName = @"ffmpeg.exe";
proc.StartInfo.Arguments = String.Format("-f rawvideo -vcodec rawvideo -s {0}x{1} -pix_fmt rgb24 -r {2} -i - -an -codec:v libx264 -preset veryfast -f mp4 -movflags frag_keyframe+empty_moov -",
16, 9, 30);
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
FileStream fs = new FileStream(@"out.mp4", FileMode.Create, FileAccess.Write);
proc.Start();
var readTask = _ConsumeOutputAsync(fs, proc.StandardOutput.BaseStream);
//Generate frames and write to stdin
for (int i = 0; i < 30 * 60 * 60; i++)
{
byte[] myArray = Enumerable.Repeat((byte)Math.Min(i, 255), 9 * 16 * 3).ToArray();
proc.StandardInput.BaseStream.Write(myArray, 0, myArray.Length);
}
proc.StandardInput.BaseStream.Close();
readTask.Wait();
fs.Close();
Console.WriteLine("Done!");
Console.ReadKey();
}
private static async Task _ConsumeOutputAsync(FileStream fs, Stream baseStream)
{
int cb;
byte[] rgb = new byte[4096];
while ((cb = await baseStream.ReadAsync(rgb, 0, rgb.Length)) > 0)
{
fs.Write(rgb, 0, cb);
}
}
请注意,即使您动态生成数据,您的示例也显示了将输出写入文件。如果你真的想要输出到一个文件中,那么我会
肯定
输出文件
StandardOutput
你自己当您正在运行的外部进程将为您处理所有这些工作时,为什么要在数据处理中注入您自己的代码?
AutoResetEvent
对象,因为您从未等待过该对象,并且您对它的实现被破坏,因为您在使用它之前就处理了该对象。因此,上述修改后的示例并没有试图复制这种行为。没有它也可以。