public void DoEncode(object sender, DoWorkEventArgs e) { _bw = (BackgroundWorker)sender; string status = Processing.GetResourceString("lame_encoding_audio_status"); _bw.ReportProgress(-10, status); _bw.ReportProgress(0, status); AudioInfo item = _jobInfo.AudioStreams[_jobInfo.StreamId]; int outChannels = ((MP3Profile)_jobInfo.AudioProfile).OutputChannels; switch (outChannels) { case 0: outChannels = item.ChannelCount > 2 ? 2 : 0; break; case 1: outChannels = 1; break; } int outSampleRate = ((MP3Profile)_jobInfo.AudioProfile).SampleRate; switch (outSampleRate) { case 1: outSampleRate = 8000; break; case 2: outSampleRate = 11025; break; case 3: outSampleRate = 22050; break; case 4: outSampleRate = 44100; break; case 5: outSampleRate = 48000; break; default: outSampleRate = 0; break; } int encMode = ((MP3Profile)_jobInfo.AudioProfile).EncodingMode; int bitrate = ((MP3Profile)_jobInfo.AudioProfile).Bitrate; int quality = ((MP3Profile)_jobInfo.AudioProfile).Quality; string preset = ((MP3Profile)_jobInfo.AudioProfile).Preset; string inputFile = AviSynthGenerator.GenerateAudioScript(item.TempFile, item.Format, item.FormatProfile, item.ChannelCount, outChannels, item.SampleRate, outSampleRate); string outFile = Processing.CreateTempFile(item.TempFile, "encoded.mp3"); StringBuilder sb = new StringBuilder(); switch (encMode) { case 2: sb.AppendFormat(AppSettings.CInfo, "-V {0:0} ", quality); break; case 0: sb.AppendFormat("--preset {0:0} ", bitrate); break; case 1: sb.AppendFormat("--preset cbr {0:0} ", bitrate); break; case 3: sb.AppendFormat("--preset {0} ", preset); break; } sb.Append("- "); sb.AppendFormat(AppSettings.CInfo, "\"{0}\" ", outFile); string localExecutable = Path.Combine(AppSettings.ToolsPath, Executable); _startTime = DateTime.Now; using (Process encoder = new Process(), decoder = BePipe.GenerateProcess(inputFile)) { ProcessStartInfo encoderParameter = new ProcessStartInfo(localExecutable) { WorkingDirectory = AppSettings.DemuxLocation, Arguments = sb.ToString(), CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardInput = true }; encoder.StartInfo = encoderParameter; decoder.StartInfo.RedirectStandardError = true; decoder.ErrorDataReceived += OnDecoderOnErrorDataReceived; encoder.ErrorDataReceived += OnEncoderOnErrorDataReceived; Log.InfoFormat("lame {0:s}", encoderParameter.Arguments); bool encStarted; bool decStarted; try { encStarted = encoder.Start(); } catch (Exception ex) { encStarted = false; Log.ErrorFormat("lame exception: {0}", ex); _jobInfo.ExitCode = -1; } try { decStarted = decoder.Start(); } catch (Exception ex) { decStarted = false; Log.ErrorFormat("bepipe exception: {0}", ex); _jobInfo.ExitCode = -1; } if (encStarted && decStarted) { encoder.PriorityClass = AppSettings.GetProcessPriority(); encoder.BeginErrorReadLine(); decoder.PriorityClass = AppSettings.GetProcessPriority(); decoder.BeginErrorReadLine(); Processing.CopyStreamToStream(decoder.StandardOutput.BaseStream, encoder.StandardInput.BaseStream, 32768, (src, dst, exc) => { src.Close(); dst.Close(); if (exc == null) { return; } Log.Debug(exc.Message); Log.Debug(exc.StackTrace); }); while (!encoder.HasExited) { if (_bw.CancellationPending) { encoder.Kill(); decoder.Kill(); } Thread.Sleep(200); } encoder.WaitForExit(10000); encoder.CancelErrorRead(); decoder.WaitForExit(10000); decoder.CancelErrorRead(); _jobInfo.ExitCode = encoder.ExitCode; Log.InfoFormat("Exit Code: {0:g}", _jobInfo.ExitCode); if (_jobInfo.ExitCode == 0) { _jobInfo.TempFiles.Add(inputFile); _jobInfo.TempFiles.Add(item.TempFile); _jobInfo.TempFiles.Add(item.TempFile + ".d2a"); _jobInfo.TempFiles.Add(item.TempFile + ".ffindex"); item.TempFile = outFile; AudioHelper.GetStreamInfo(item); } } } _bw.ReportProgress(100); _jobInfo.CompletedStep = _jobInfo.NextStep; e.Result = _jobInfo; }
/// <summary> /// AC3 encode processing function, called by BackgroundWorker thread /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void DoEncodeAc3(object sender, DoWorkEventArgs e) { _bw = (BackgroundWorker)sender; bool use64BitEncoder = AppSettings.Use64BitEncoders && AppSettings.Ffmpeg64Installed && Environment.Is64BitOperatingSystem; int[] sampleRateArr = { 0, 8000, 11025, 22050, 44100, 48000 }; int[] channelArr = { 0, 2, 3, 4, 1 }; string status = Processing.GetResourceString("ffmpeg_encoding_audio_status"); _bw.ReportProgress(-10, status); _bw.ReportProgress(0, status); AudioInfo item = _jobInfo.AudioStreams[_jobInfo.StreamId]; int outChannels = -1; int outSampleRate = -1; switch (_jobInfo.AudioProfile.Type) { case ProfileType.AC3: outChannels = ((AC3Profile)_jobInfo.AudioProfile).OutputChannels; outChannels = channelArr[outChannels]; if (item.ChannelCount > 6) { outChannels = 6; } outSampleRate = ((AC3Profile)_jobInfo.AudioProfile).SampleRate; outSampleRate = sampleRateArr[outSampleRate]; break; case ProfileType.Copy: outChannels = item.ChannelCount > 6 ? 6 : item.ChannelCount; outSampleRate = item.SampleRate; if (_jobInfo.EncodingProfile.OutFormat == OutputType.OutputDvd && outSampleRate != 48000) { outSampleRate = 48000; } break; } string inputFile = AviSynthGenerator.GenerateAudioScript(item.TempFile, item.Format, item.FormatProfile, item.ChannelCount, outChannels, item.SampleRate, outSampleRate); string outFile = Processing.CreateTempFile(item.TempFile, "encoded.ac3"); string localExecutable = Path.Combine(AppSettings.ToolsPath, use64BitEncoder ? Executable64 : Executable); DateTime startTime = DateTime.Now; using (Process encoder = new Process(), decoder = BePipe.GenerateProcess(inputFile)) { ProcessStartInfo encoderParameter = new ProcessStartInfo(localExecutable) { WorkingDirectory = AppSettings.DemuxLocation, Arguments = FfmpegCommandLineGenerator.GenerateAC3EncodeLine( _jobInfo, "-", outFile), CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardInput = true }; encoder.StartInfo = encoderParameter; _localItem = item; _encodingStart = startTime; encoder.ErrorDataReceived += Ac3EncodeOnErrorDataReceived; Log.InfoFormat("ffmpeg {0:s}", encoderParameter.Arguments); bool encStarted; bool decStarted; try { encStarted = encoder.Start(); } catch (Exception ex) { encStarted = false; Log.ErrorFormat("ffmpeg exception: {0}", ex); _jobInfo.ExitCode = -1; } try { decStarted = decoder.Start(); } catch (Exception ex) { decStarted = false; Log.ErrorFormat("bepipe exception: {0}", ex); _jobInfo.ExitCode = -1; } if (encStarted && decStarted) { encoder.PriorityClass = AppSettings.GetProcessPriority(); encoder.BeginErrorReadLine(); decoder.PriorityClass = AppSettings.GetProcessPriority(); Processing.CopyStreamToStream(decoder.StandardOutput.BaseStream, encoder.StandardInput.BaseStream, 32768, (src, dst, exc) => { src.Close(); dst.Close(); if (exc == null) { return; } Log.Debug(exc.Message); Log.Debug(exc.StackTrace); }); while (!encoder.HasExited) { if (_bw.CancellationPending) { encoder.Kill(); decoder.Kill(); } Thread.Sleep(200); } encoder.WaitForExit(10000); encoder.CancelErrorRead(); decoder.WaitForExit(10000); _jobInfo.ExitCode = encoder.ExitCode; Log.InfoFormat("Exit Code: {0:g}", _jobInfo.ExitCode); if (_jobInfo.ExitCode == 0) { _jobInfo.TempFiles.Add(inputFile); _jobInfo.TempFiles.Add(item.TempFile); _jobInfo.TempFiles.Add(item.TempFile + ".d2a"); _jobInfo.TempFiles.Add(item.TempFile + ".ffindex"); item.TempFile = outFile; AudioHelper.GetStreamInfo(item); } } } _bw.ReportProgress(100); _jobInfo.CompletedStep = _jobInfo.NextStep; e.Result = _jobInfo; }