我試圖用C#2010中的MP3文件轉換爲通過ffmpeg.exe和NeroAACenc.exe音頻書M4A格式的程序。 爲此,我使用Diagnostics.Process類中的內部版本將ffmpeg的stdout重定向到我的應用程序中的Nero編碼器的標準輸出。試圖ffmpeg的二進制標準輸出重定向到NeroAacEnc標準輸入
一切似乎按預期工作,但由於某種原因,標準輸出.BaseStream 停止接收數據在某個時間。該過程不會退出並且ErrorDataReceived事件也不會引發。 生成的輸出m4a文件的長度總是大約2分鐘。如果我只是在不提供Nero的情況下將mp3文件編碼爲臨時wav文件,情況也是如此。
我試過相同的命令行,這工作沒有任何問題。
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");
}
}