private bool FixAudioDelay() { string encoderParams; _jobStatus.PercentageComplete = 100; //all good to start with _jobStatus.ETA = ""; if (_videoFile.AudioDelaySet || _toolAudioDelay == 0) return true; //It's already been done (probably by mencoder) or been requested to skip // Check if the converted file has Audio AND Video streams (if one is missing, then skip this step) FFmpegMediaInfo ffmpegInfo = new FFmpegMediaInfo(_convertedFile, _jobStatus, _jobLog); if (!ffmpegInfo.Success || ffmpegInfo.ParseError) { _jobStatus.PercentageComplete = 0; // if the file wasn't completely converted the percentage will be low so no worries _jobStatus.ErrorMsg = "Fix AudioSync getting mediainfo Failed for " + _convertedFile; _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error); return false; } if ((ffmpegInfo.MediaInfo.VideoInfo.Stream == -1) || (ffmpegInfo.AudioTracks < 1)) { _jobLog.WriteEntry(this, "Fix audiosync, No video or no audio track detected - skipping audio sync", Log.LogEntryType.Warning); return true; } double audioDelay = _toolAudioDelay; if (audioDelay != 0) { _jobLog.WriteEntry(this, ("Fixing Audio Delay, Detected :") + " " + _videoFile.AudioDelay.ToString(System.Globalization.CultureInfo.InvariantCulture) + ", Manual Adj : " + _toolAudioDelay.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Information); string ext = FilePaths.CleanExt(_convertedFile); string fixedFile = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(_convertedFile) + "_AVFIX" + FilePaths.CleanExt(_convertedFile)); FileIO.TryFileDelete(fixedFile); _jobStatus.CurrentAction = Localise.GetPhrase("Correcting audio delay"); switch (ext) { case ".wmv": _jobLog.WriteEntry(this, ("Using ASFBin to correct audio sync for extension ") + ext, Log.LogEntryType.Debug); encoderParams = " -i " + Util.FilePaths.FixSpaces(_convertedFile) + " -adelay " + audioDelay.ToString(System.Globalization.CultureInfo.InvariantCulture) + " -o " + Util.FilePaths.FixSpaces(fixedFile) + " -y"; ASFBin asfBin = new ASFBin(encoderParams, _jobStatus, _jobLog); asfBin.Run(); if (!asfBin.Success || (FileIO.FileSize(fixedFile) <= 0)) { _jobStatus.ErrorMsg = "Fixing Audio Delay for WMV failed"; _jobLog.WriteEntry(this, ("Fixing Audio Delay for WMV failed"), Log.LogEntryType.Error); _jobStatus.PercentageComplete = 0; return false; } break; case ".avi": _jobLog.WriteEntry(this, ("Using Mencoder to correct audio sync for extension ") + ext, Log.LogEntryType.Debug); encoderParams = Util.FilePaths.FixSpaces(_convertedFile) + " -oac copy -ovc copy -ni -delay " + (-1 * audioDelay).ToString(System.Globalization.CultureInfo.InvariantCulture) + " -o " + Util.FilePaths.FixSpaces(fixedFile.ToString(System.Globalization.CultureInfo.InvariantCulture)); // avoid using threads since we are copying to increase stability _jobLog.WriteEntry(this, "Fixing Audio Delay using MEncoder with Parameters: " + encoderParams, Log.LogEntryType.Debug); Mencoder mencoderAVI = new Mencoder(encoderParams, _jobStatus, _jobLog, false); mencoderAVI.Run(); if (!mencoderAVI.Success) // something failed or was incomplete, do not check for % completion as Mencoder looks fro success criteria { _jobStatus.PercentageComplete = 0; _jobStatus.ErrorMsg = ("Fix AudioSync failed for") + " " + ext; _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error); return false; } break; default: _jobLog.WriteEntry(this, ("Using FFMPEG to correct audio sync for extension ") + ext, Log.LogEntryType.Debug); if (audioDelay > 0) // Map same file as 2 inputs, shift and take the audio in one and take the video from the other { encoderParams = "-y -i " + Util.FilePaths.FixSpaces(_convertedFile) + " -ss " + audioDelay.ToString(System.Globalization.CultureInfo.InvariantCulture) +" -i " + Util.FilePaths.FixSpaces(_convertedFile) + " -map 1:v -map 0:a -acodec copy -vcodec copy"; _jobLog.WriteEntry(this, "Fixing +ve Audio Delay using FFMPEG", Log.LogEntryType.Debug); } // if audio is behind the video skip seconds from the 2nd input file and remap to ouput (keeping the audio shift positive) else { encoderParams = "-y -ss " + (audioDelay * -1).ToString(System.Globalization.CultureInfo.InvariantCulture) + " -i " + Util.FilePaths.FixSpaces(_convertedFile) + " -i " + Util.FilePaths.FixSpaces(_convertedFile) + " -map 1:v -map 0:a -acodec copy -vcodec copy"; _jobLog.WriteEntry(this, "Fixing -ve Audio Delay using FFMPEG", Log.LogEntryType.Debug); } encoderParams += " " + Util.FilePaths.FixSpaces(fixedFile); if (!FFmpeg.FFMpegExecuteAndHandleErrors(encoderParams, _jobStatus, _jobLog, Util.FilePaths.FixSpaces(fixedFile))) // Do not check for % completion since FFMPEG doesn't always report a % for this routine for some reason { _jobStatus.PercentageComplete = 0; // if the file wasn't completely converted the percentage will be low so no worries _jobStatus.ErrorMsg = "Fix AudioSync Failed for " + ext; _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error); return false; } break; } try { _jobLog.WriteEntry(this, ("Fix Audio Delay trying to move fixed file"), Log.LogEntryType.Information); FileIO.TryFileDelete(_convertedFile); File.Move(fixedFile, _convertedFile); } catch (Exception e) { _jobLog.WriteEntry(this, ("Unable to move audio sync corrected file") + " " + fixedFile + "\r\nError : " + e.ToString(), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Unable to move audio sync file"; _jobStatus.PercentageComplete = 0; return false; } _jobLog.WriteEntry(this, ("Finished Audio Delay Correction, file size [KB]") + " " + (FileIO.FileSize(_convertedFile) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug); } else _jobLog.WriteEntry(this, ("Fix Audio Delay, net correction 0, skipping correction"), Log.LogEntryType.Information); return true; }
protected override bool ConvertWithTool() { Mencoder me; //Check if threads are specified else add multithreaded decoding, lavdopts supports a max of 8 threads if (String.IsNullOrWhiteSpace(ParameterSubValue("-lavdopts", "threads"))) { ParameterSubValueReplaceOrInsert("-lavdopts", "threads", "=" + Math.Min(8, Environment.ProcessorCount).ToString(System.Globalization.CultureInfo.InvariantCulture)); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding decoding threaded support for") + " " + Environment.ProcessorCount + " Processors", Log.LogEntryType.Information); } else _jobLog.WriteEntry(this, Localise.GetPhrase("Decoding threaded support enabled within profile parameters"), Log.LogEntryType.Debug); //Check for use of threads with lavcopts and add multithreaded support if not there, max 8 threads supported if (ParameterValue("-ovc") == "lavc") { if (String.IsNullOrWhiteSpace(ParameterSubValue("-lavcopts", "threads"))) { ParameterSubValueReplaceOrInsert("-lavcopts", "threads", "=" + Math.Min(8, Environment.ProcessorCount).ToString(System.Globalization.CultureInfo.InvariantCulture)); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding lavc threaded support for") + " " + Environment.ProcessorCount + " Processors", Log.LogEntryType.Information); } else _jobLog.WriteEntry(this, Localise.GetPhrase("lavc threaded support present"), Log.LogEntryType.Debug); } //Check for use of threads with x264encopts and add auto multithreaded support if not there, 0 threads = auto if (ParameterValue("-ovc") == "x264") { if(String.IsNullOrWhiteSpace(ParameterSubValue("-x264encopts", "threads"))) { ParameterSubValueReplaceOrInsert("-x264encopts", "threads", "=0"); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding x264enc auto threaded support"), Log.LogEntryType.Information); } else _jobLog.WriteEntry(this, Localise.GetPhrase("x264enc threaded support present"), Log.LogEntryType.Debug); } //Check for use of threads with xvidencopts and add auto multithreaded support if not there, 0 Thread = Auto if (ParameterValue("-ovc") == "xvidenc") { if (String.IsNullOrWhiteSpace(ParameterSubValue("-xvidencopts", "threads"))) { ParameterSubValueReplaceOrInsert("-xvidencopts", "threads", "=0"); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding xvidenc threaded support for") + " " + Environment.ProcessorCount + " Processors", Log.LogEntryType.Information); } else _jobLog.WriteEntry(this, Localise.GetPhrase("xvidenc threaded support present"), Log.LogEntryType.Debug); } if (_2Pass == true) { string param = ""; string subPararm = ""; if (ParameterValue("x264encopts") != "") { param = "-x264encopts"; subPararm = "pass"; } else if (ParameterValue("xvidencopts") != "") { param = "-xvidencopts"; subPararm = "pass"; } else if (ParameterValue("lavcopts") != "") { param = "-lavcopts"; subPararm = "vpass"; } if (param != "") { // 1s Pass string baseParam = _cmdParams; string passLog = Path.Combine(_workingPath, "MCEBuddy2Pass.log"); ParameterSubValueReplaceOrInsert(param, subPararm, "=1"); ParameterSubValueReplaceOrInsert(param, "turbo", ""); ParameterValueReplace("-o", "NUL"); _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file - Pass 1"); me = new Mencoder(_cmdParams + " -passlogfile " + Util.FilePaths.FixSpaces(passLog), _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder Pass 1 conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder Pass 1 conversion failed"; return false; } // 2nd Pass _cmdParams = baseParam; ParameterSubValueReplaceOrInsert(param, subPararm, "=2"); _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file - Pass 2"); me = new Mencoder(_cmdParams + " -passlogfile " + Util.FilePaths.FixSpaces(passLog), _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder Pass 2 conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder Pass 2 conversion failed"; return false; } } else { _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file"); me = new Mencoder(_cmdParams, _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder 2 pass no param conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder 2 pass no param conversion failed"; return false; } } } else { _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file"); me = new Mencoder(_cmdParams, _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder conversion failed"; return false; } } return (me.Success); }
/// <summary> /// Backup remove commercials from MP4 using MEncoder, not the best, limited in many ways /// </summary> private void CutMP4Alternate() { string tempFile = CutFileName(_uncutVideo, 0, 0); // TODO: Need to add support for non AAC Audio Codecs // Refer to: http://forum.videohelp.com/threads/337215-Mencoder-not-copying-aac-to-mp4?p=2140000 // and http://www.mplayerhq.hu/DOCS/codecs-status.html#ac // Do not use -hr-edl-seek as it doesn't work well with -ovc copy // lavdopts supports a max of 8 threads // avoid using threads, stablity - only copying here string mencoderParams = Util.FilePaths.FixSpaces(_uncutVideo) + " -of lavf -ovc copy -oac copy"; //Set fafmttag based on the type of audio codec of converted file (currently supported aac, ac3, eac3) _jobLog.WriteEntry(this, Localise.GetPhrase("Trying to reading converted file Audio information"), Log.LogEntryType.Information); string audioCodec = ""; FFmpegMediaInfo ffmpegStreamInfo = new FFmpegMediaInfo(_uncutVideo, _jobStatus, _jobLog); if (ffmpegStreamInfo.Success && !ffmpegStreamInfo.ParseError) { // Converted file should contain only 1 audio stream audioCodec = ffmpegStreamInfo.MediaInfo.AudioInfo[0].AudioCodec; _jobLog.WriteEntry(this, Localise.GetPhrase("Found AudioCodec") + " " + audioCodec, Log.LogEntryType.Information); if (String.IsNullOrEmpty(audioCodec)) _jobLog.WriteEntry(this, Localise.GetPhrase("Audio codec information is blank, will try to continue without it"), Log.LogEntryType.Warning); } else _jobLog.WriteEntry(this, Localise.GetPhrase("Cannot read Audio codec information, will try to continue without it"), Log.LogEntryType.Warning); switch (audioCodec) { case "aac": _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate found AAC Audio Codec"), Log.LogEntryType.Information); mencoderParams += @" -fafmttag 0x706D"; break; case "ac3": case "ac-3": _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate found AC3 Audio Codec"), Log.LogEntryType.Information); mencoderParams += @" -fafmttag 0x2000"; break; case "e-ac-3": _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate found E-AC3 Audio Codec"), Log.LogEntryType.Information); mencoderParams += @" -fafmttag 0x33434145"; break; case "mp3": _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate found mp3 Audio Codec"), Log.LogEntryType.Information); mencoderParams += @" -fafmttag 0x55"; break; case "flac": _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate found flac Audio Codec"), Log.LogEntryType.Information); mencoderParams += @" -fafmttag 0xF1AC"; break; case "mp1": case "mp2": _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate found mp2 Audio Codec"), Log.LogEntryType.Information); mencoderParams += @" -fafmttag 0x50"; break; default: _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate could not identify Audio Codec, DEFAULTING TO AAC - please check video file and audio encoder type"), Log.LogEntryType.Warning); mencoderParams += @" -fafmttag 0x706D"; break; } mencoderParams += " -edl " + Util.FilePaths.FixSpaces(EDLFile) + " -o " + Util.FilePaths.FixSpaces(tempFile); _jobStatus.CurrentAction = Localise.GetPhrase("Merging commercial free segments into new video"); _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate: Merging commercial free segments into new video"), Log.LogEntryType.Information); Mencoder mencoder = new Mencoder(mencoderParams, _jobStatus, _jobLog, false); mencoder.Run(); if (!mencoder.Success || (Util.FileIO.FileSize(tempFile) <= 0)) // do not check for % success here since sometimes it does not show complete number { _jobStatus.ErrorMsg = "CutMP4Alternate Commercial cutting failed"; _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate Commercial cutting failed"), Log.LogEntryType.Error); _jobStatus.PercentageComplete = 0; return; } _jobLog.WriteEntry(this, Localise.GetPhrase("CutMP4Alternate trying to replace file") + " Output : " + _uncutVideo + " Temp : " + tempFile, Log.LogEntryType.Debug); RenameAndMoveFile(tempFile); }
protected override bool ConvertWithTool() { Mencoder me; //Check if threads are specified else add multithreaded decoding, lavdopts supports a max of 8 threads if (String.IsNullOrWhiteSpace(ParameterSubValue("-lavdopts", "threads"))) { ParameterSubValueReplaceOrInsert("-lavdopts", "threads", "=" + Math.Min(8, Environment.ProcessorCount).ToString(System.Globalization.CultureInfo.InvariantCulture)); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding decoding threaded support for") + " " + Environment.ProcessorCount + " Processors", Log.LogEntryType.Information); } else { _jobLog.WriteEntry(this, Localise.GetPhrase("Decoding threaded support enabled within profile parameters"), Log.LogEntryType.Debug); } //Check for use of threads with lavcopts and add multithreaded support if not there, max 8 threads supported if (ParameterValue("-ovc") == "lavc") { if (String.IsNullOrWhiteSpace(ParameterSubValue("-lavcopts", "threads"))) { ParameterSubValueReplaceOrInsert("-lavcopts", "threads", "=" + Math.Min(8, Environment.ProcessorCount).ToString(System.Globalization.CultureInfo.InvariantCulture)); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding lavc threaded support for") + " " + Environment.ProcessorCount + " Processors", Log.LogEntryType.Information); } else { _jobLog.WriteEntry(this, Localise.GetPhrase("lavc threaded support present"), Log.LogEntryType.Debug); } } //Check for use of threads with x264encopts and add auto multithreaded support if not there, 0 threads = auto if (ParameterValue("-ovc") == "x264") { if (String.IsNullOrWhiteSpace(ParameterSubValue("-x264encopts", "threads"))) { ParameterSubValueReplaceOrInsert("-x264encopts", "threads", "=0"); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding x264enc auto threaded support"), Log.LogEntryType.Information); } else { _jobLog.WriteEntry(this, Localise.GetPhrase("x264enc threaded support present"), Log.LogEntryType.Debug); } } //Check for use of threads with xvidencopts and add auto multithreaded support if not there, 0 Thread = Auto if (ParameterValue("-ovc") == "xvidenc") { if (String.IsNullOrWhiteSpace(ParameterSubValue("-xvidencopts", "threads"))) { ParameterSubValueReplaceOrInsert("-xvidencopts", "threads", "=0"); _jobLog.WriteEntry(this, Localise.GetPhrase("Adding xvidenc threaded support for") + " " + Environment.ProcessorCount + " Processors", Log.LogEntryType.Information); } else { _jobLog.WriteEntry(this, Localise.GetPhrase("xvidenc threaded support present"), Log.LogEntryType.Debug); } } if (_2Pass == true) { string param = ""; string subPararm = ""; if (ParameterValue("x264encopts") != "") { param = "-x264encopts"; subPararm = "pass"; } else if (ParameterValue("xvidencopts") != "") { param = "-xvidencopts"; subPararm = "pass"; } else if (ParameterValue("lavcopts") != "") { param = "-lavcopts"; subPararm = "vpass"; } if (param != "") { // 1s Pass string baseParam = _cmdParams; string passLog = Path.Combine(_workingPath, "MCEBuddy2Pass.log"); ParameterSubValueReplaceOrInsert(param, subPararm, "=1"); ParameterSubValueReplaceOrInsert(param, "turbo", ""); ParameterValueReplace("-o", "NUL"); _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file - Pass 1"); me = new Mencoder(_cmdParams + " -passlogfile " + Util.FilePaths.FixSpaces(passLog), _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder Pass 1 conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder Pass 1 conversion failed"; return(false); } // 2nd Pass _cmdParams = baseParam; ParameterSubValueReplaceOrInsert(param, subPararm, "=2"); _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file - Pass 2"); me = new Mencoder(_cmdParams + " -passlogfile " + Util.FilePaths.FixSpaces(passLog), _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder Pass 2 conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder Pass 2 conversion failed"; return(false); } } else { _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file"); me = new Mencoder(_cmdParams, _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder 2 pass no param conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder 2 pass no param conversion failed"; return(false); } } } else { _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file"); me = new Mencoder(_cmdParams, _jobStatus, _jobLog, false); me.Run(); if (!me.Success) { _jobLog.WriteEntry(this, Localise.GetPhrase("Mencoder conversion failed"), Log.LogEntryType.Error); _jobStatus.ErrorMsg = "Mencoder conversion failed"; return(false); } } return(me.Success); }
/// <summary> /// Remove commercials using Mencoder for AVI, MPG and TS (not good for TS, last backup) /// </summary> /// <param name="preConversionFilterTSAudioLanguage">True is want to filter out the audio language specified by the user while removing commercials from TS files only</param> private void CutMencoder(bool remuxedVideoFilterAudioLanguage = false) { string tempFile = CutFileName(_uncutVideo, 0, 0); string mencoderParams; bool oldVersion = false; // Some cases we want to use old version of Mencoder switch (_ext) { case ".mpg": oldVersion = true; // For MPG and TS we use old version of Mencoder // TODO: Need to figure out how to fix the audio video sync, temp fix is to use a special version of mEncoder build here // Do not use -hr-edl-seek as it doesn't work well with -ovc copy // lavdopts supports a max of 8 threads // avoid using threads, as it may cause a problem - anyways we are only copying here mencoderParams = Util.FilePaths.FixSpaces(_uncutVideo) + " -of mpeg -ovc copy -oac copy"; mencoderParams += " -edl " + Util.FilePaths.FixSpaces(EDLFile) + " -o " + Util.FilePaths.FixSpaces(tempFile); break; case ".ts": oldVersion = true; // For MPG and TS we use old version of Mencoder // TODO: Need to figure out how to fix the audio video sync, temp fix is to use a special version of mEncoder build here // Do not use -hr-edl-seek as it doesn't work well with -ovc copy // lavdopts supports a max of 8 threads // avoid using threads, as it may cause a problem - anyways we are only copying here mencoderParams = Util.FilePaths.FixSpaces(_uncutVideo) + " -of lavf -lavfopts format=mpegts -ovc copy -oac copy"; // If we are requested to filter out the selected audio language, check for it's existance and filter it if (remuxedVideoFilterAudioLanguage) { if (_remuxedVideoFileInfo.AudioPID == -1) _jobLog.WriteEntry("Cannot get audio stream selection details, copying all audio streams", Log.LogEntryType.Warning); else { _jobLog.WriteEntry("Selecting Audio Language " + _remuxedVideoFileInfo.AudioLanguage + " Audio PID " + _remuxedVideoFileInfo.AudioPID.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug); mencoderParams += " -aid " + (_remuxedVideoFileInfo.AudioPID).ToString(System.Globalization.CultureInfo.InvariantCulture); // Select the Audio track PID we had isolated earlier } } mencoderParams += " -edl " + Util.FilePaths.FixSpaces(EDLFile) + " -o " + Util.FilePaths.FixSpaces(tempFile); break; case ".avi": // TODO: bug here for AVI files, using "-mc0 -noskip" helps initially but audio out of sync after cuts - need to figure out. Try the -ni (non interleaved) option for avi files, try -idx to rebuild index for audio video // Do not use -hr-edl-seek as it doesn't work well with -ovc copy // lavdopts supports a max of 8 threads // avoid using thread to increase stability since we are only copying here mencoderParams = Util.FilePaths.FixSpaces(_uncutVideo) + " -oac copy -ovc copy -ni -edl " + Util.FilePaths.FixSpaces(EDLFile) + " -o " + Util.FilePaths.FixSpaces(tempFile); break; default: _jobLog.WriteEntry(this, Localise.GetPhrase("CutMencoder unsupported file extension") + " " + _ext, Log.LogEntryType.Error); _jobStatus.ErrorMsg = "CutMencoder unsupported file extension"; _jobStatus.PercentageComplete = 0; return; } _jobStatus.CurrentAction = Localise.GetPhrase("Merging commercial free segments into new video"); _jobLog.WriteEntry(this, Localise.GetPhrase("CutMencoder: Merging commercial free segments into new video"), Log.LogEntryType.Information); Mencoder mencoder = new Mencoder(mencoderParams, _jobStatus, _jobLog, oldVersion); mencoder.Run(); if (!mencoder.Success || (Util.FileIO.FileSize(tempFile) <= 0)) // do not check for % success here since sometimes it does not show complete number { _jobStatus.ErrorMsg = "CutMencoder Commercial cutting failed"; _jobLog.WriteEntry(this, Localise.GetPhrase("CutMencoder Commercial cutting failed"), Log.LogEntryType.Error); _jobStatus.PercentageComplete = 0; return; } _jobLog.WriteEntry(this, Localise.GetPhrase("CutMencoder trying to replace file") + " Output : " + _uncutVideo + " Temp : " + tempFile, Log.LogEntryType.Debug); RenameAndMoveFile(tempFile); }