private string _srtFile = ""; // Subtitle file public ConvertWithFfmpeg(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan, string srtFile) : base(conversionOptions, tool, videoFile, jobStatus, jobLog, commercialScan) { passLog = Path.Combine(_workingPath, "MCEBuddy2Pass.log"); // Name of passlog file //Check if MEncoder EDL Removal has been disabled at conversion time Ini ini = new Ini(GlobalDefs.ProfileFile); if(ini.ReadBoolean(conversionOptions.profile, tool + "-SubtitleBurn", false)) _srtFile = srtFile; // Save the SRT file info otherwise skip it }
private const double DRC = 0.8; // Dynamic Range Compression to 80% public ConvertWithMencoder(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan) : base(conversionOptions, tool, videoFile, jobStatus, jobLog, commercialScan) { //Check if MEncoder EDL Removal has been disabled at conversion time Ini ini = new Ini(GlobalDefs.ProfileFile); mEncoderEDLSkip = ini.ReadBoolean(conversionOptions.profile, "MEncoderEDLSkip", false); _extractCC = conversionOptions.extractCC; if (!String.IsNullOrEmpty(_extractCC)) // If Closed Caption extraction is enabled, we don't use cut EDL using Mencoder during encoding, Mencoder has a bug which causes it to cut out of sync with the EDL file which throws the CC out of sync, it will be cut separately { _jobLog.WriteEntry(this, Localise.GetPhrase("Closed Captions Enabled, skipping EDL cutting during encoding"), Log.LogEntryType.Information); mEncoderEDLSkip = true; } if ((_startTrim != 0) || (_endTrim != 0)) // If trimming is enabled skip cutting using EDL otherwise MEncoder messes it up { _jobLog.WriteEntry(this, Localise.GetPhrase("Trimming Enabled, skipping EDL cutting during encoding"), Log.LogEntryType.Information); mEncoderEDLSkip = true; } }
public ConvertWithHandbrake(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan) : base(conversionOptions, tool, videoFile, jobStatus, jobLog, commercialScan) { // Check if we have hardware encoding support available on the system Handbrake hb = new Handbrake(jobLog); hardwareEncodingAvailable = hb.QuickSyncEncodingAvailable; //Check if the profiles is setup for Hardware encoding, if so don't adjust hardware encoding options Ini ini = new Ini(GlobalDefs.ProfileFile); bool profileHardwareEncoding = ini.ReadBoolean(conversionOptions.profile, tool + "-UsingHardwareEncoding", false); if (_preferHardwareEncoding && profileHardwareEncoding) { _jobLog.WriteEntry(this, "Hardware enabled handbrake profile, disabling auto hardware encoder adjustments", Log.LogEntryType.Debug); _preferHardwareEncoding = false; // Don't change any settings, this profile is already setup for hardware encoding } // Check if we are using any of the h264 codecs, only then can we use hardware encoder for H264 if (_preferHardwareEncoding && !h264Encoders.Any((new FFMpegMEncoderParams(_videoParams)).ParameterValue("-e").ToLower().Equals)) { _jobLog.WriteEntry(this, "Cannot find h264 encoder, disabling auto hardware h264 encoder adjustments", Log.LogEntryType.Debug); _preferHardwareEncoding = false; // Don't use hardware encoder since this isn't a h264 profile } }
private string _renameConvertedFileWithOriginalName = ""; // Keep track incase of filename conflict protected ConvertBase(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan) : base (true) { //Setup log and status _jobStatus = jobStatus; _jobLog = jobLog; //Set the destination paths _workingPath = conversionOptions.workingPath; Util.FilePaths.CreateDir(_workingPath); // Check first up to see if the source video uses an unsupported combination for this profile // Container, Video Codec, Audio Codec and whether it was originally a Media Center recording or not _videoFile = videoFile; _commercialScan = commercialScan; if (CheckUnsupported(conversionOptions.profile, tool)) return; // Set the input params and get the standard settings _maxWidth = conversionOptions.maxWidth; _userQuality = conversionOptions.qualityMultiplier; _volume = conversionOptions.volumeMultiplier; _drc = conversionOptions.drc; _startTrim = conversionOptions.startTrim; _endTrim = conversionOptions.endTrim; _encoderChooseBestAudioTrack = conversionOptions.encoderSelectBestAudioTrack; _fps = conversionOptions.FPS; _preferHardwareEncoding = conversionOptions.preferHardwareEncoding; Ini ini = new Ini(GlobalDefs.ProfileFile); // Profile override parameters - if default (i.e. does not exist then use conversion options else use profile parameters) if (ini.ReadString(conversionOptions.profile, "2ChannelAudio", "default") == "default") _2ChannelAudio = conversionOptions.stereoAudio; else _2ChannelAudio = ini.ReadBoolean(conversionOptions.profile, "2ChannelAudio", false); // Fix output to 2 channels (from profile) if (ini.ReadString(conversionOptions.profile, "SkipCropping", "default") == "default") _skipCropping = conversionOptions.disableCropping; else _skipCropping = ini.ReadBoolean(conversionOptions.profile, "SkipCropping", false); // Cropping can be forced in the profile if (ini.ReadString(conversionOptions.profile, "AutoDeinterlace", "default") == "default") _autoDeInterlacing = conversionOptions.autoDeInterlace; else _autoDeInterlacing = ini.ReadBoolean(conversionOptions.profile, "AutoDeinterlace", false); if (conversionOptions.renameOnly) _commercialSkipCut = true; //no cutting if we are renaming only else if (ini.ReadString(conversionOptions.profile, "CommercialSkipCut", "default") == "default") _commercialSkipCut = conversionOptions.commercialSkipCut; else _commercialSkipCut = ini.ReadBoolean(conversionOptions.profile, "CommercialSkipCut", false); // Profile only parameters _fixedResolution = ini.ReadBoolean(conversionOptions.profile, "FixedResolution", false); _2Pass = ini.ReadBoolean(conversionOptions.profile, "2pass", false); _generalParams = ini.ReadString(conversionOptions.profile, tool + "-general", ""); _videoParams = ini.ReadString(conversionOptions.profile, tool + "-video", ""); _audioParams = ini.ReadString(conversionOptions.profile, tool + "-audio", ""); _extension = _videoFile.Extension = ini.ReadString(conversionOptions.profile, tool + "-ext", "").ToLower().Trim(); if (string.IsNullOrWhiteSpace(_extension)) // Special case copy converter if there is no specified extension, it will be using the source file extension _extension = FilePaths.CleanExt(SourceVideo); _remuxTo = _videoFile.RemuxTo = ini.ReadString(conversionOptions.profile, tool + "-remuxto", "").ToLower().Trim(); _audioDelay = ini.ReadString(conversionOptions.profile, tool + "-audiodelay", "skip").ToLower().Trim(); if (_audioDelay == "auto") // Use the audio delay specified in the file _toolAudioDelay = videoFile.AudioDelay; else if (_audioDelay != "skip") double.TryParse(_audioDelay, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out _toolAudioDelay); if (conversionOptions.audioOffset != 0) // Conversion options Audio Delay takes priority over profile Audio Delay _toolAudioDelay = conversionOptions.audioOffset; // Audio select the AC3 audio option if the source video has AC3) if (((videoFile.AudioCodec == "ac-3") || (videoFile.AudioCodec == "ac3") || (videoFile.AudioCodec != "e-ac-3") || (videoFile.AudioCodec != "eac3")) && (ini.ReadString(conversionOptions.profile, tool + "-audioac3", "") != "")) _audioParams = ini.ReadString(conversionOptions.profile, tool + "-audioac3", _audioParams); // E-AC3 test option if the source video has E-AC3 - Not required as mencoder can handle eac3 audio /* if (videoFile.AudioCodec == "e-ac-3" || _videoFile.AudioCodec != "eac3") { _audioParams = ini.ReadString(conversionOptions.profile, tool + "-audioeac3", _audioParams); if ((_audioParams == "") && (tool == "mencoder")) _audioParams = "-noaudio "; }*/ // Important to use temp name while converting - sometimes the sources files are copied to the working directory and the converted files conflict with teh original filename, compensate. E.g. TS file input, TS file output with Copy converter _convertedFile = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(SourceVideo) + "-converted" + _extension); _renameConvertedFileWithOriginalName = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(SourceVideo) + _extension); }
public ConvertWithCopy(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan) : base(conversionOptions, tool, videoFile, jobStatus, jobLog, commercialScan) { }
public bool Run(ConversionJobOptions conversionOptions, VideoInfo videoFile, Scanner commercialScan, string srtFile) { bool converted = false; Ini ini = new Ini(GlobalDefs.ProfileFile); // Dump the entire profile for debugging purposes (incase users have customized it) _jobLog.WriteEntry("Profile being used : " + conversionOptions.profile + ".\r\nProfile entries ->", Log.LogEntryType.Debug); SortedList<string, string> profileEntries = ini.GetSectionKeyValuePairs(conversionOptions.profile); foreach (string key in profileEntries.Keys) { _jobLog.WriteEntry(key + "=" + profileEntries[key], Log.LogEntryType.Debug); } string[] order = GetProfileEncoderOrder(conversionOptions.profile); foreach (string encoder in order) { switch (encoder.Trim()) { case "copy": { _jobLog.WriteEntry(this, Localise.GetPhrase("Using special case COPY for converter"), Log.LogEntryType.Information); // Special case, no real encoder, just ignore any recoding and assume the output = input file ConvertWithCopy convertWithCopy = new ConvertWithCopy(conversionOptions, "copy", videoFile, _jobStatus, _jobLog, commercialScan); if (!convertWithCopy.Unsupported) { _jobLog.WriteEntry(this, Localise.GetPhrase("Converting with COPY"), Log.LogEntryType.Information); bool ret = convertWithCopy.Convert(); if (ret) { converted = true; _convertedFile = convertWithCopy.ConvertedFile; videoFile.ConversionTool = "copy"; } else { _jobLog.WriteEntry(this, Localise.GetPhrase("COPY did not convert successfully, using fallback if configured"), Log.LogEntryType.Error); } } break; } case "mencoder": { ConvertWithMencoder convertWithMencoder = new ConvertWithMencoder(conversionOptions, "mencoder", videoFile, _jobStatus, _jobLog, commercialScan); if (!convertWithMencoder.Unsupported) { _jobLog.WriteEntry(this, Localise.GetPhrase("Converting with MEncoder"), Log.LogEntryType.Information); bool ret = convertWithMencoder.Convert(); if (ret) { converted = true; _convertedFile = convertWithMencoder.ConvertedFile; videoFile.ConversionTool = "mencoder"; } else { _jobLog.WriteEntry(this, Localise.GetPhrase("MEncoder did not convert successfully, using fallback if configured"), Log.LogEntryType.Error); } } else _jobLog.WriteEntry(this, Localise.GetPhrase("Unsupported MEncoder file formats"), Log.LogEntryType.Error); break; } case "handbrake": { ConvertWithHandbrake convertWithHandbrake = new ConvertWithHandbrake(conversionOptions, "handbrake", videoFile, _jobStatus, _jobLog, commercialScan); if (!convertWithHandbrake.Unsupported) { _jobLog.WriteEntry(this, Localise.GetPhrase("Converting with Handbrake"), Log.LogEntryType.Information); bool ret = convertWithHandbrake.Convert(); if (ret) { converted = true; _convertedFile = convertWithHandbrake.ConvertedFile; videoFile.ConversionTool = "handbrake"; } else { _jobLog.WriteEntry(this, Localise.GetPhrase("Handbrake did not convert successfully, using fallback if configured"), Log.LogEntryType.Error); } } else _jobLog.WriteEntry(this, Localise.GetPhrase("Unsupported Handbrake file formats"), Log.LogEntryType.Error); break; } case "ffmpeg": { ConvertWithFfmpeg convertWithFfmpeg = new ConvertWithFfmpeg(conversionOptions, "ffmpeg", videoFile, _jobStatus, _jobLog, commercialScan, srtFile); if (!convertWithFfmpeg.Unsupported) { _jobLog.WriteEntry(this, Localise.GetPhrase("Converting with FFMpeg"), Log.LogEntryType.Information); bool ret = convertWithFfmpeg.Convert(); if (ret) { converted = true; _convertedFile = convertWithFfmpeg.ConvertedFile; _subtitleBurned = convertWithFfmpeg.SubtitleBurned; // Right now only ffmpeg supports subtitle burning videoFile.ConversionTool = "ffmpeg"; } else { _jobLog.WriteEntry(this, Localise.GetPhrase("FFMpeg did not convert successfully, using fallback if configured"), Log.LogEntryType.Error); } } else _jobLog.WriteEntry(this, Localise.GetPhrase("Unsupported FFMpeg file formats"), Log.LogEntryType.Error); break; } default: { _jobLog.WriteEntry(Localise.GetPhrase("Unsupported converter"), Log.LogEntryType.Error); break; } } if (converted || _jobStatus.Cancelled) break; } if (!converted) _jobLog.WriteEntry(this, Localise.GetPhrase("Unable to convert file") + " " + Path.GetFileName(videoFile.SourceVideo) + " " + Localise.GetPhrase("using profile") + " " + conversionOptions.profile, Log.LogEntryType.Error); else { _jobLog.WriteEntry(this, Localise.GetPhrase("Successfully converted file") + " " + Path.GetFileName(videoFile.SourceVideo) + " " + Localise.GetPhrase("using profile") + " " + conversionOptions.profile, Log.LogEntryType.Debug); //Reset the error message incase there was a fallback conversion the suceeded _jobStatus.ErrorMsg = ""; } return converted; }