Я пытаюсь написать программу на C # 2010, которая конвертирует mp3-файлы в аудиокнигу в формате m4a через ffmpeg.exe и NeroAACenc.exe.Для этого я перенаправляю стандартный вывод ffmpeg на стандартный кодировщик Nero в моем приложении, используя встроенный класс Diagnostics.Process.
Кажется, что все работает, как и ожидалось, но по какой-то причине 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");
}
}