private string GetMediaInfoAnalysis(MediaAnalyzeInfo mediaInfo) { if (mediaInfo == null) { return(""); } StringBuilder sb = new StringBuilder(); sb.AppendLine($"{nameof(mediaInfo.Filename)}: {mediaInfo.Filename}"); sb.AppendLine("######################"); sb.AppendLine($"Resolution: {mediaInfo.VideoInfo?.Width} x {mediaInfo.VideoInfo?.Height}"); sb.AppendLine($"{nameof(mediaInfo.VideoInfo.Bitrate)}: {mediaInfo.VideoInfo?.Bitrate}"); sb.AppendLine($"{nameof(mediaInfo.VideoInfo.Length)}: {new TimeSpan(0, 0, 0, 0, (int)mediaInfo.VideoInfo?.Length)}"); sb.AppendLine($"{nameof(mediaInfo.VideoInfo.CodecID)}: {mediaInfo.VideoInfo?.CodecID}"); sb.AppendLine($"{nameof(mediaInfo.VideoInfo.FrameRateMode)}: {mediaInfo.VideoInfo?.FrameRateMode}"); sb.AppendLine("######################"); sb.AppendLine($"{nameof(mediaInfo.NeedsVideoReencode)}: {mediaInfo.NeedsVideoReencode}"); sb.AppendLine($"TargetResolution: {mediaInfo.TargetVideoWidth} x {mediaInfo.TargetVideoHeight}"); sb.AppendLine($"{nameof(mediaInfo.TargetVideoBitrate)}: {mediaInfo.TargetVideoBitrate}"); if (mediaInfo.AudioInfo != null) { sb.AppendLine("######################"); sb.AppendLine($"{nameof(mediaInfo.NeedsAudioReencode)}: {mediaInfo.NeedsAudioReencode}"); sb.AppendLine($"{nameof(mediaInfo.TargetAudioBitrate)}: {mediaInfo.TargetAudioBitrate}"); sb.AppendLine($"{nameof(mediaInfo.AudioInfo.Length)}: {new TimeSpan(0, 0, 0, 0, (int)mediaInfo.AudioInfo?.Length)}"); } sb.AppendLine("######################"); sb.AppendLine($"{nameof(mediaInfo.Size)}: {Math.Round((double)mediaInfo.Size / 1024.0 / 1024.0, 2, MidpointRounding.AwayFromZero)} MB"); sb.AppendLine($"{nameof(mediaInfo.TargetSize)}: {Math.Round((double)mediaInfo.TargetSize / 1024.0 / 1024.0, 2, MidpointRounding.AwayFromZero)} MB"); return(sb.ToString()); }
public int Encode(MediaAnalyzeInfo mediaAnalyzeInfo, string x264FileName, Action <string> logAction, Action <string> progressAction, out string outputFileName) { // Get AviSynth script AviSynthScriptService aviSynthScriptService = ServiceFactory.GetService <AviSynthScriptService>(); string avsScript = aviSynthScriptService.CreateAviSynthVideoScript(mediaAnalyzeInfo); outputFileName = $"{mediaAnalyzeInfo.Filename}.reencode.mkv".GetNewFileName(); X264ProcessRunnerService service = ServiceFactory.GetService <X264ProcessRunnerService>(); var parameters = service.GetAllParameters(x264FileName); // Pass 1 parameters .ResetParameters() .IncludeParameterWithValue("infile", avsScript) .IncludeParameterWithValue("output", outputFileName) .IncludeParameterWithValue("pass", "1") .IncludeParameterWithValue("preset", "placebo") .IncludeParameterWithValue("bitrate", Math.Ceiling(mediaAnalyzeInfo.TargetVideoBitrateInKbps).ToString("#0")) .IncludeParameterWithValue("deblock", "-1:-1") .IncludeParameterWithValue("bframes", "3") .IncludeParameterWithValue("ref", "3") .IncludeParameterWithValue("qpmin", "10") .IncludeParameterWithValue("qpmax", "51") .IncludeParameterWithValue("vbv-bufsize", "50000") .IncludeParameterWithValue("vbv-maxrate", "50000") .IncludeParameterWithValue("ratetol", "2.0") .IncludeParameterWithValue("rc-lookahead", "40") .IncludeParameterWithValue("merange", "16") .IncludeParameterWithValue("me", "umh") .IncludeParameterWithValue("subme", "6") .IncludeParameterWithValue("trellis", "1") .IncludeParameterWithNoValue("no-dct-decimate") .IncludeParameterWithValue("muxer", "mkv"); logAction?.Invoke($"Encoding {mediaAnalyzeInfo.Filename} with x264 1st pass..."); DefaultProcessRunnerService defaultProcessRunnerService = ServiceFactory.GetService <DefaultProcessRunnerService>(); defaultProcessRunnerService.RunProcess(parameters, new Action <Process, string>((process, line) => progressAction?.Invoke(line))); // Pass 2 parameters.IncludeParameterWithValue("pass", "2"); logAction?.Invoke($"Encoding {mediaAnalyzeInfo.Filename} with x264 2nd pass..."); return(defaultProcessRunnerService.RunProcess(parameters, new Action <Process, string>((process, line) => progressAction?.Invoke(line)))); }
public int Encode(MediaAnalyzeInfo mediaAnalyzeInfo, IAudioEncoder audioEncoder, IAudioEncoderSettings settings, Action <string> logAction, Action <string> progressAction, out string outputFileName) { // Get AviSynth script AviSynthScriptService aviSynthScriptService = ServiceFactory.GetService <AviSynthScriptService>(); // Open the AviSynth script AviSynthFileService aviSynthFileService = ServiceFactory.GetService <AviSynthFileService>(); // Get the AviSynth audio script string avsScript = aviSynthScriptService.CreateAviSynthAudioScript(mediaAnalyzeInfo); // Try to open the Avs Script IAviSynthAudioSourceService audioSourceService = null; while (true) { try { using (var avsFile = aviSynthFileService.OpenAviSynthScriptFile(avsScript)) { break; } } catch (Exception) { // Check if we already tried again if (audioSourceService != null) { throw; } // In case it fails, try to create audio AviSynth script with the DirectShowSource audioSourceService = ServiceFactory.GetService <AviSynthDirectShowAudioSourceService>(); avsScript = aviSynthScriptService.CreateAviSynthAudioScript(mediaAnalyzeInfo, audioSourceService: audioSourceService); continue; } } // Determine the output filename outputFileName = $"{mediaAnalyzeInfo.Filename}.reencode.{settings.FileExtension}".GetNewFileName(); // Open the AviSynth Script to generate the timecodes using (var avsFile = aviSynthFileService.OpenAviSynthScriptFile(avsScript)) { // Check for audio existence if (avsFile.Clip.AudioSamplesCount == 0) { throw new ApplicationException("Can't find audio stream!"); } // Calculate Size in Bytes long totalSizeInBytes = avsFile.Clip.AudioSamplesCount * avsFile.Clip.AudioBytesPerSample * avsFile.Clip.AudioChannelsCount; // Define format type tag // 1 for int, 3 for float int formatTypeTag = 1; if (avsFile.Clip.AudioSampleType == AvsAudioSampleType.FLOAT) { formatTypeTag = 3; } using (var process = new Process()) { // Create the ProcessStartInfo object ProcessStartInfo info = new ProcessStartInfo { // Command line arguments, to be passed to encoder // {0} means output file name // {1} means samplerate in Hz // {2} means bits per sample // {3} means channel count // {4} means samplecount // {5} means size in bytes // {6} means format (1 int, 3 float) // {7} means target bitrate Arguments = string.Format( audioEncoder.ExecutableArguments, outputFileName, avsFile.Clip.AudioSampleRate, avsFile.Clip.AudioBitsPerSample, avsFile.Clip.AudioChannelsCount, avsFile.Clip.AudioSamplesCount, totalSizeInBytes, formatTypeTag, mediaAnalyzeInfo.TargetAudioBitrate ), FileName = audioEncoder.EncoderFileName, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true }; process.StartInfo = info; Debug.WriteLine(info.Arguments); // Start the process process.Start(); // TODO: Revisit that //process.PriorityClass = m_processPriority; // Read the Standard output character by character Task.Run(() => process.ReadStreamPerCharacter(true, new Action <Process, string>((p, str) => Debug.WriteLine(str)))); // Read the Standard error character by character Task.Run(() => process.ReadStreamPerCharacter(false, new Action <Process, string>((p, str) => Debug.WriteLine(str)))); try { using (Stream processInputStream = process.StandardInput.BaseStream) { // Check if we need to write WAV Header if (audioEncoder.WriteHeader) { logAction?.Invoke($"Audio encoding: {mediaAnalyzeInfo.Filename} Writing header data to encoder's StdIn..."); WriteHeader(audioEncoder.HeaderType, processInputStream, avsFile, totalSizeInBytes, settings.ChannelMask, formatTypeTag); } logAction?.Invoke($"Audio encoding: {mediaAnalyzeInfo.Filename} Writing PCM data to encoder's StdIn..."); // Calculate the frame buffer total size int frameBufferTotalSize = MAX_SAMPLES_PER_ONCE * avsFile.Clip.AudioChannelsCount * avsFile.Clip.AudioBitsPerSample / 8; // Allocate the frame buffer byte[] frameBuffer = new byte[frameBufferTotalSize]; // Get the handle for the frame buffer GCHandle bufferHandle = GCHandle.Alloc(frameBuffer, GCHandleType.Pinned); try { // Set a current frame sample indicator int currentFrameSample = 0; // Start passing the audio frames to the encoder's standard input stream while (currentFrameSample < avsFile.Clip.AudioSamplesCount) { // Check for unexpected process exit if (process != null && process.HasExited) { throw new ApplicationException($"Unexpected encoder termination with exit code: {process.ExitCode}"); } // Calculate how many frame samples to read int framesSamplesToRead = Math.Min((int)(avsFile.Clip.AudioSamplesCount - currentFrameSample), MAX_SAMPLES_PER_ONCE); int bytesRead = framesSamplesToRead * avsFile.Clip.AudioBytesPerSample * avsFile.Clip.AudioChannelsCount; // Read the audio frame samples and copy them to the frame buffer avsFile.ReadAudioSamples(bufferHandle.AddrOfPinnedObject(), currentFrameSample, framesSamplesToRead); // Calculate the current progress double progress = ((double)currentFrameSample / (double)avsFile.Clip.AudioSamplesCount) * 100.0; progressAction?.Invoke($"Progress {progress:#0.00}%"); // Write the frame samples to the encoder's standard input stream processInputStream.Write(frameBuffer, 0, bytesRead); processInputStream.Flush(); // Advance the current frame sample indicator currentFrameSample += framesSamplesToRead; // Signal the OS to run other threads in our time slice Thread.Yield(); } } finally { // Free the frame buffer handle bufferHandle.Free(); } } if (process != null) { logAction?.Invoke($"Audio encoding: {mediaAnalyzeInfo.Filename} Finalizing encoder"); // Wait for the process to exit process.WaitForExit(); // Debug write the exit code Debug.WriteLine($"Exit code: {process.ExitCode}"); } } finally { // Sanity check for non exited process if (process != null && !process.HasExited) { // Kill the process process.Kill(); // Wait for the process to exit process.WaitForExit(); // Debug write the exit code Debug.WriteLine($"Exit code: {process.ExitCode}"); } } // Return the process exit code return(process?.ExitCode ?? 0); } } }
private void AnalyzeVideoFileInternal( MediaAnalyzeFileRequest request, Func <double, double> targetFunction, MediaAnalyzeActions actions ) { // Sanity checks if (request.MaxAllowedHeight > request.MaxAllowedWidth) { throw new ArgumentException(nameof(request), $"{nameof(request.MaxAllowedWidth)} must be always greater than {nameof(request.MaxAllowedHeight)}!"); } actions.SetCurrentFileAction(request.MediaFile); using (gMediaInfo mi = new gMediaInfo(request.MediaFile)) { if (mi == null) { actions.LogErrorAction($"ERROR! {request.MediaFile}"); return; } MediaAnalyzeInfo result = new MediaAnalyzeInfo { Filename = request.MediaFile, Size = new FileInfo(request.MediaFile).Length, NeedsVideoReencode = false, NeedsAudioReencode = false }; // Get first General track var generalTrack = mi?.GeneralTracks?.FirstOrDefault(); if (generalTrack == null) { actions.LogErrorAction($"ERROR! {request.MediaFile}"); return; } // Get more info result.FileExtension = generalTrack.FileExtension; result.FileContainerFormat = generalTrack.Format; // Get first video track var videoTrack = mi?.VideoTracks?.FirstOrDefault(); if (videoTrack == null) { actions.LogErrorAction($"ERROR! {request.MediaFile}"); return; } // Check if we have valid video track info if (int.TryParse(videoTrack.Width, out int width) && int.TryParse(videoTrack.Height, out int height) && ( int.TryParse(videoTrack.BitRate, out int bitrate) || (videoTrack.BitRate.Contains("/") && int.TryParse(videoTrack.BitRate.Substring(videoTrack.BitRate.IndexOf("/") + 1), out bitrate)) || int.TryParse(videoTrack.BitRateNominal, out bitrate) || (videoTrack.BitRateNominal.Contains("/") && int.TryParse(videoTrack.BitRateNominal.Substring(videoTrack.BitRate.IndexOf("/") + 1), out bitrate)) ) ) { MediaAnalyzeVideoInfo videoResult = new MediaAnalyzeVideoInfo(); // Check for pixel aspect ration if (videoTrack.PixelAspectRatio.TryParseDecimal(out decimal pixelAspectRatio)) { // Check if pixel aspect ration is not equal to 1 if (pixelAspectRatio > 1.0m) { // Recalculate width based on the pixel aspect ration width = Convert.ToInt32(Math.Ceiling(width * pixelAspectRatio)); } } videoResult.Width = width; videoResult.Height = height; videoResult.Bitrate = bitrate; videoResult.CodecID = videoTrack.CodecID; videoResult.Size = long.TryParse(videoTrack.StreamSize, out long streamSize) ? streamSize : default; videoResult.Length = long.TryParse(videoTrack.Duration, out long videoDuration) ? videoDuration : default; // Get the video FrameRate Mode videoResult.FrameRateMode = videoTrack.FrameRateMode.ToLower().Equals("vfr") ? VideoFrameRateMode.VFR : VideoFrameRateMode.CFR; videoResult.ChromaSubsampling = videoTrack.ChromaSubsampling; videoResult.ColorSpace = videoTrack.ColorSpace; videoResult.Rotation = videoTrack.Rotation; result.VideoInfo = videoResult; } else { actions.LogErrorAction($"ERROR! {videoTrack.Width}x{videoTrack.Height} : {videoTrack.BitRate} : {videoTrack.CodecID} : {request.MediaFile}"); return; } // Get audio tracks var audioTracks = mi?.AudioTracks; // Get audio track var audioTrack = audioTracks?.FirstOrDefault(); // Check if we have valid audio track info if (audioTrack != null && int.TryParse(audioTrack.Channels, out int audioChannels) && (int.TryParse(audioTrack.BitRate, out int audioBitrate) || int.TryParse(audioTrack.BitRateNominal, out audioBitrate))) { MediaAnalyzeAudioInfo audioResult = new MediaAnalyzeAudioInfo(); audioResult.Channels = audioChannels; audioResult.Bitrate = audioBitrate; audioResult.Codec = audioTrack.FormatString; audioResult.Size = long.TryParse(audioTrack.StreamSize, out long audioSize) ? audioSize : default; audioResult.Length = long.TryParse(audioTrack.Duration, out long audioDuration) ? audioDuration : default; result.AudioInfo = audioResult; } // Check if we need to re encode the video track bool isCandidateForVideoReencode = IsCandidateForVideoReencode(width, height, bitrate, request.MaxAllowedWidth, request.MaxAllowedHeight, request.BitratePercentageThreshold, targetFunction, out int targetBitrate, out int targetWidth, out int targetHeight); if (isCandidateForVideoReencode) { // We only care for lower target bitrate and bitrate greater than the min allowed bitrate! if (targetBitrate < bitrate && targetBitrate > request.MinAllowedBitrate) { // Check if the gain percentage is worth the reencode double gainPercentage = Math.Abs(((double)(targetBitrate - bitrate) / (double)bitrate) * 100.0); if (gainPercentage >= request.GainPercentageThreshold) { // Set that Video needs reencode result.NeedsVideoReencode = true; result.TargetVideoBitrate = targetBitrate; result.TargetVideoWidth = targetWidth; result.TargetVideoHeight = targetHeight; _reEncodeFiles++; actions.UpdateProgressAction(_reEncodeFiles, _totalFiles); actions.HandleMediaForReencodeAction(result); // Check for no audio, or more than one audio if (audioTracks == null || !audioTracks.Any() || audioTracks.Count() > 1) { // No audio tracks, nothing to do here return; } // Sanity check, we should have an AudioInfo if (result?.AudioInfo == null) { // No audio info found, nothing to do here return; } // Check if we need to re encode the audio track bool isWindowsMedia = result.FileContainerFormat.ToLower().Trim().Equals("windows media"); bool isCandidateForAudioReencode = IsCandidateForAudioReencode(isWindowsMedia, result.AudioInfo.Channels, result.AudioInfo.Bitrate, out int targetAudioBitrate); if (isCandidateForAudioReencode) { result.NeedsAudioReencode = true; result.TargetAudioBitrate = targetAudioBitrate; } } } } } }
private async Task <string> EncodeMediaInfoAsync(MediaAnalyzeInfo mediaInfo) { if (mediaInfo == null) { txtMediaInfo.Clear(); return(""); } // Sanity check if (!mediaInfo.NeedsVideoReencode && !mediaInfo.NeedsAudioReencode) { return(""); } // Log EncodeLog($"Start Encoding: {mediaInfo.Filename}"); txtMediaInfo.Text = GetMediaInfoAnalysis(mediaInfo); string videoOutputFileName = ""; // Encode video if (mediaInfo.NeedsVideoReencode) { EncodeLog($"Video Encoding: {mediaInfo.Filename}..."); X264VideoEncoderService videoEncoderService = ServiceFactory.GetService <X264VideoEncoderService>(); int res = await Task.Run(() => videoEncoderService.Encode( mediaInfo, @"E:\Programs\MeGUI\tools\x264\x264.exe", new Action <string>((log) => EncodeLog(log)), new Action <string>((progress) => EncodeProgress(progress)), out videoOutputFileName) ); if (res != 0) { EncodeLog($"Video Encoder failed for {mediaInfo.Filename}! Exit code : {res}"); return(""); } } string audioOutputFileName = ""; // Encode Audio if (mediaInfo.NeedsAudioReencode) { EncodeLog($"Audio Encoding: {mediaInfo.Filename}..."); AudioEncoderService audioEncoderService = ServiceFactory.GetService <AudioEncoderService>(); NeroAacAudioEncoder audioEncoder = new NeroAacAudioEncoder(@"E:\Programs\MeGUI\tools\eac3to\neroAacEnc.exe"); DefaultAudioEncoderSettings audioEncoderSettings = new DefaultAudioEncoderSettings(-1, "m4a"); int res = await Task.Run(() => audioEncoderService.Encode( mediaInfo, audioEncoder, audioEncoderSettings, new Action <string>((log) => EncodeLog(log)), new Action <string>((progress) => EncodeProgress(progress)), out audioOutputFileName) ); if (res != 0) { EncodeLog($"Audio Encoder failed for {mediaInfo.Filename}! Exit code : {res}"); return(""); } } // Mux final video! EncodeLog($"Muxing: {mediaInfo.Filename}..."); DefaultMuxerSettings muxerSettings = new DefaultMuxerSettings( videoOutputFileName, mediaInfo.NeedsAudioReencode ? audioOutputFileName : mediaInfo.Filename, "mkv" ); MkvMergeMuxer muxer = new MkvMergeMuxer(@"C:\Program Files\MKVToolNix\mkvmerge.exe"); MkvMergeMuxerService mkvMergeMuxerService = new MkvMergeMuxerService(); string muxedFilename = ""; await Task.Run(() => mkvMergeMuxerService.Mux( muxer, muxerSettings, new Action <string>((log) => EncodeLog(log)), new Action <string>((progress) => EncodeProgress(progress)), out muxedFilename) ); return(muxedFilename); }
public string CreateAviSynthVideoScript(MediaAnalyzeInfo mediaInfo, bool overWriteScriptFile = true) { if (mediaInfo == null) { throw new ArgumentNullException(nameof(mediaInfo)); } if (string.IsNullOrWhiteSpace(mediaInfo.Filename)) { throw new ArgumentException("No filename was provided!", nameof(mediaInfo.Filename)); } // Get the AVS script filename string avsScriptFilename = $"{mediaInfo.Filename}.video.avs"; // Check if we need to create a new script file if (!overWriteScriptFile) { avsScriptFilename = avsScriptFilename.GetNewFileName(); } StringBuilder avsScriptBuilder = new StringBuilder(); // Decide on the Source filter //============================= string fileContainerFormat = mediaInfo.FileContainerFormat.Trim().ToLower(); // Get the Source Service IAviSynthVideoSourceService sourceService = _aviSynthSourceFactory.GetAviSynthSourceService(fileContainerFormat); avsScriptBuilder.AppendLine(sourceService.GetAviSynthVideoSource(mediaInfo.Filename, false)); // Decide what to do with VFR // Note: Windows Media files may report CFR frame rate mode, but in reality they are VFR inside //============================= if (fileContainerFormat.Equals("windows media") || mediaInfo.VideoInfo.FrameRateMode == VideoFrameRateMode.VFR) { // Create timecodes file var timecodesFileName = _timeCodesProviderService.GetTimecodesFileName(mediaInfo.Filename); // Read timecodes file var videoFrameList = _timeCodesParserService.ParseTimeCodes(timecodesFileName); // Create the VFR to CFR AviSynth script var timeCodesAviSynthScript = _aviSynthVfrToCfrConversionService.GetConvertVfrToCfrScript(videoFrameList, new List <VideoFrameSection>()); // Append it to the main script avsScriptBuilder.AppendLine(timeCodesAviSynthScript); } // Decide if we need resize //============================= if (mediaInfo.TargetVideoWidth != mediaInfo.VideoInfo.Width || mediaInfo.TargetVideoHeight != mediaInfo.VideoInfo.Height) { avsScriptBuilder.AppendLine($"Lanczos4resize({mediaInfo.TargetVideoWidth}, {mediaInfo.TargetVideoHeight})"); } // Decide if we need rotation //============================= if (!string.IsNullOrWhiteSpace(mediaInfo.VideoInfo.Rotation)) { // check if it's a valid rotation number (degrees) if (mediaInfo.VideoInfo.Rotation.PrepareStringForNumericParse().TryParseDecimal(out decimal rotation)) { // Check if the degrees are valid if (rotation % 90 == 0) { // Check if it's a negative number bool isNegative = mediaInfo.VideoInfo.Rotation.Contains("-"); // Determine turn command string turnCommand = isNegative ? "turnLeft()" : "turnRight()"; // Get number of 90 degrees rotations int numberOfRotations = Convert.ToInt32(rotation / 90.0m); for (int i = 0; i < numberOfRotations; i++) { avsScriptBuilder.AppendLine(turnCommand); } } } } // Decide if we need colorspace conversion //============================= if (!mediaInfo.VideoInfo.ColorSpace.Trim().ToLower().Equals("yv12")) { avsScriptBuilder.AppendLine("ConvertToYV12()"); } // Write the file using (StreamWriter sw = new StreamWriter(avsScriptFilename, false, Encoding.GetEncoding(1253))) { sw.Write(avsScriptBuilder.ToString()); } return(avsScriptFilename); }
public string CreateAviSynthAudioScript(MediaAnalyzeInfo mediaInfo, bool overWriteScriptFile = true, IAviSynthAudioSourceService audioSourceService = null) { if (mediaInfo == null) { throw new ArgumentNullException(nameof(mediaInfo)); } if (string.IsNullOrWhiteSpace(mediaInfo.Filename)) { throw new ArgumentException("No filename was provided!", nameof(mediaInfo.Filename)); } // Get the AVS script filename string avsScriptFilename = $"{mediaInfo.Filename}.audio.avs"; // Check if we need to create a new script file if (!overWriteScriptFile) { avsScriptFilename = avsScriptFilename.GetNewFileName(); } StringBuilder avsScriptBuilder = new StringBuilder(); IAviSynthAudioSourceService sourceService; // Check if no audio source service was provided if (audioSourceService == null) { // Use AviSynthLWLibavAudioSourceService Source filter to get the audio //============================= // Currently it has a bug in the latest versions that do not produce clips with correct audio length // Last good working version: r920-20161216 // Use FFMS2 till then which seems to produce correct results // UPDATE: LSMASH 20200322 fixes the audio issues, switch to AviSynthLWLibavAudioSourceService // UPDATE: LSMASH still seems to have problems with some Windows Meadia Audio, so use FFMS2 for those files // UPDATE: FFMS2 also struggles with those particular audio formats, switch to DirectShowSource string fileContainerFormat = mediaInfo.FileContainerFormat.Trim().ToLower(); if (fileContainerFormat.Equals("windows media")) { //sourceService = ServiceFactory.GetService<AviSynthFfms2AudioSourceService>(); sourceService = ServiceFactory.GetService <AviSynthDirectShowAudioSourceService>(); } else { sourceService = ServiceFactory.GetService <AviSynthLWLibavAudioSourceService>(); } } else { sourceService = audioSourceService; } avsScriptBuilder.AppendLine(sourceService.GetAviSynthAudioSource(mediaInfo.Filename, -1, false)); // Write the file using (StreamWriter sw = new StreamWriter(avsScriptFilename, false, Encoding.GetEncoding(1253))) { sw.Write(avsScriptBuilder.ToString()); } return(avsScriptFilename); }