【发布时间】:2026-01-30 01:05:03
【问题描述】:
我正在尝试用 C# 2010 编写一个程序,通过 ffmpeg.exe 和 NeroAACenc.exe 将 mp3 文件转换为 m4a 格式的有声读物。 为此,我使用 Diagnostics.Process 类中的构建将 ffmpeg 的标准输出重定向到我的应用程序中 Nero 编码器的标准输入。
一切似乎都按预期工作,但出于某种原因 StandardOutput.BaseStream ffmpeg 有时会停止接收数据。该过程不会退出,并且 ErrorDataReceived 事件也不会引发。 生成的输出 m4a 文件的长度始终约为 2 分钟。如果我只是将 mp3 文件编码为临时 wav 文件而不提供 Nero,这同样适用。
我通过命令行尝试了同样的方法,这没有任何问题。
ffmpeg -i test.mp3 -f wav - | neroAacEnc -ignorelength -if - -of test.m4a
谁能告诉我我在这里做错了什么? 提前致谢。
class Encoder
{
private byte[] ReadBuffer = new byte[4096];
private Process ffMpegDecoder = new Process();
private Process NeroEncoder = new Process();
private BinaryWriter NeroInput;
//Create WAV temp file for testing
private Stream s = new FileStream("D:\\test\\test.wav", FileMode.Create);
private BinaryWriter outfile;
public void Encode()
{
ProcessStartInfo ffMpegPSI = new ProcessStartInfo("ffmpeg.exe", "-i D:\\test\\test.mp3 -f wav -");
ffMpegPSI.UseShellExecute = false;
ffMpegPSI.CreateNoWindow = true;
ffMpegPSI.RedirectStandardOutput = true;
ffMpegPSI.RedirectStandardError = true;
ffMpegDecoder.StartInfo = ffMpegPSI;
ProcessStartInfo NeroPSI = new ProcessStartInfo("neroAacEnc.exe", "-if - -ignorelength -of D:\\test\\test.m4a");
NeroPSI.UseShellExecute = false;
NeroPSI.CreateNoWindow = true;
NeroPSI.RedirectStandardInput = true;
NeroPSI.RedirectStandardError = true;
NeroEncoder.StartInfo = NeroPSI;
ffMpegDecoder.Exited += new EventHandler(ffMpegDecoder_Exited);
ffMpegDecoder.ErrorDataReceived += new DataReceivedEventHandler(ffMpegDecoder_ErrorDataReceived);
ffMpegDecoder.Start();
NeroEncoder.Start();
NeroInput = new BinaryWriter(NeroEncoder.StandardInput.BaseStream);
outfile = new BinaryWriter(s);
ffMpegDecoder.StandardOutput.BaseStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, new AsyncCallback(ReadCallBack), null);
}
private void ReadCallBack(IAsyncResult asyncResult)
{
int read = ffMpegDecoder.StandardOutput.BaseStream.EndRead(asyncResult);
if (read > 0)
{
NeroInput.Write(ReadBuffer);
NeroInput.Flush();
outfile.Write(ReadBuffer);
outfile.Flush();
ffMpegDecoder.StandardOutput.BaseStream.Flush();
ffMpegDecoder.StandardOutput.BaseStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, new AsyncCallback(ReadCallBack), null);
}
else
{
ffMpegDecoder.StandardOutput.BaseStream.Close();
outfile.Close();
}
}
private void ffMpegDecoder_Exited(object sender, System.EventArgs e)
{
Console.WriteLine("Exit");
}
private void ffMpegDecoder_ErrorDataReceived(object sender, DataReceivedEventArgs errLine)
{
Console.WriteLine("Error");
}
}
【问题讨论】:
标签: c# ffmpeg stdout stdin redirectstandardoutput