public ConversionTaskMonitorTasksListForm(List<MonitorJobOptions> monitorTasks, ConversionJobOptions cjo) { InitializeComponent(); _monitorTasks = monitorTasks; _cjo = cjo; }
/// <summary> /// Returns the final extension for the file to be converted /// </summary> /// <param name="conversionOptions">Conversion Options</param> /// <returns>Extension as specified in the Conversion Profile</returns> public static string GetConversionExtension(ConversionJobOptions conversionOptions) { Ini ini = new Ini(GlobalDefs.ProfileFile); string orderSetting = ini.ReadString(conversionOptions.profile, "order", "").ToLower().Trim(); if (!orderSetting.Contains("mencoder")) orderSetting = orderSetting.Replace("me","mencoder"); if (!orderSetting.Contains("handbrake")) orderSetting = orderSetting.Replace("hb", "handbrake"); if (!orderSetting.Contains("ffmpeg")) orderSetting = orderSetting.Replace("ff", "ffmpeg"); string[] tool = orderSetting.Split(','); // We can check the first tool since all tools will lead to the same final extension string extension = ini.ReadString(conversionOptions.profile, tool[0] + "-ext", "").ToLower().Trim(); string remuxTo = ini.ReadString(conversionOptions.profile, tool[0] + "-remuxto", "").ToLower().Trim(); if (!string.IsNullOrEmpty(remuxTo)) { if (remuxTo[0] != '.') remuxTo = "." + remuxTo; // Just in case someone does something dumb like forget the leading "." return remuxTo; } else { if (extension[0] != '.') extension = "." + extension; // Just in case someone does something dumb like forget the leading "." return extension; } }
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 }
public RemuxMCERecording(ConversionJobOptions cjo, JobStatus jobStatus, Log jobLog) { _jobStatus = jobStatus; _jobLog = jobLog; _RecordingFile = cjo.sourceVideo; _destinationPath = cjo.workingPath; _requestedAudioLanguage = cjo.audioLanguage; _tivoMAKKey = cjo.tivoMAKKey; if (Util.FilePaths.CleanExt(_RecordingFile) == ".ts") // Handle TS files difference since they will have the same namess _RemuxedFile = Path.Combine(_destinationPath, Path.GetFileNameWithoutExtension(_RecordingFile) + "-REMUXED.ts"); else _RemuxedFile = Path.Combine(_destinationPath, Path.GetFileNameWithoutExtension(_RecordingFile) + ".ts"); // Read various profile parameters Ini configProfileIni = new Ini(GlobalDefs.ProfileFile); _useRemuxsupp = configProfileIni.ReadBoolean(cjo.profile, "UseWTVRemuxsupp", false); // Some videos fail with FFMPEG remuxing and Mencoder encoding (use remuxsupp for remuxing there) _jobLog.WriteEntry(this, "Force Remuxsupp (UseWTVRemuxsupp) : " + _useRemuxsupp.ToString(), Log.LogEntryType.Debug); _forceWTVStreamsRemuxing = configProfileIni.ReadBoolean(cjo.profile, "ForceWTVStreamsRemuxing", false); // Use Streams remuxing for DVRMS and WTV files _jobLog.WriteEntry(this, "Force Streams Remuxing (ForceWTVStreamsRemuxing) : " + _forceWTVStreamsRemuxing.ToString(), Log.LogEntryType.Debug); _allowH264CopyRemuxing = configProfileIni.ReadBoolean(cjo.profile, "AllowH264CopyRemuxing", true); // Allow H.264 files to be remuxed into TS without recoding to MPEG2 _jobLog.WriteEntry(this, "Allow H264 Copy Remuxing (AllowH264CopyRemuxing) (default: true) : " + _allowH264CopyRemuxing.ToString(), Log.LogEntryType.Debug); _allowAllCopyRemuxing = configProfileIni.ReadBoolean(cjo.profile, "AllowAllCopyRemuxing", false); // Allow any video codec to be remuxed into TS without recoding to MPEG2 _jobLog.WriteEntry(this, "Allow All Video codec formats Copy Remuxing (AllowAllCopyRemuxing) (default: false) : " + _allowAllCopyRemuxing.ToString(), Log.LogEntryType.Debug); // Get the media info for the recording file once for the entire operation to reuse _jobLog.WriteEntry(this, "Reading Recording file " + _RecordingFile + " media information", Log.LogEntryType.Debug); _RecordingFileMediaInfo = new FFmpegMediaInfo(_RecordingFile, _jobStatus, _jobLog); // Check for donator version of Comskip Comskip checkComskip = new Comskip(MCEBuddyConf.GlobalMCEConfig.GeneralOptions.comskipPath, _jobLog); // Check if we are using a mpeg4 video and allowing h264 video codec for commercial skipping purposes if (_allowH264CopyRemuxing) { if (_mpeg4Codecs.Any(s => s.Contains(_RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec.ToLower()))) { if (cjo.commercialRemoval == CommercialRemovalOptions.Comskip) { if (checkComskip.IsDonator) _jobLog.WriteEntry(this, "AllowH264CopyRemuxing will run fast for commercial detection, using donator version of Comskip", Log.LogEntryType.Information); else _jobLog.WriteEntry(this, "AllowH264CopyRemuxing is SLOW with the bundled Comskip. Use ShowAnalyzer or Comskip Donator version (http://www.comskip.org) to speed up commercial detection. Codec detected -> " + _RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec, Log.LogEntryType.Warning); } } } // Check if we are using an unsupported codec and copying to TS format if (_allowAllCopyRemuxing) if (!_supportedCodecs.Any(s => s.Contains(_RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec.ToLower()))) // Check if we using any of the default supported codecs _jobLog.WriteEntry(this, "AllowAllCopyRemuxing is enabled and an unsupported codec in the source video is detected. Some underlying programs may not work with this codec. Codec detected -> " + _RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec, Log.LogEntryType.Warning); }
public CredentialsForm(ConversionJobOptions cjo) { InitializeComponent(); options = cjo; domainNameTxt.Text = cjo.domainName; userNameTxt.Text = cjo.userName; passwordTxt.Text = confirmPasswordTxt.Text = cjo.password; fallbackToSourceChk.Checked = cjo.fallbackToSourcePath; }
/// <summary> /// Extract the metadata from the video file (WTV/DVRMS/MP4/MKV/AVI/TS XML) and supplement with information downloaded from TVDB and MovieDB /// </summary> /// <param name="cjo">Conversion job options</param> /// <param name="disableDownloadSeriesDetails">(Optional) True if you want to override adn disable the DownloadSeriesDetails option from TVDB/MovieDB</param> public VideoMetaData(ConversionJobOptions cjo, JobStatus jobStatus, Log jobLog, bool disableDownloadSeriesDetails = false) { _videoFileName = cjo.sourceVideo; _downloadSeriesDetails = (cjo.downloadSeriesDetails && !disableDownloadSeriesDetails); // special case, if want to override it _downloadBannerFile = (cjo.downloadBanner && !disableDownloadSeriesDetails); _jobStatus = jobStatus; _jobLog = jobLog; _metadataCorrections = cjo.metadataCorrections; _tivoMAKKey = cjo.tivoMAKKey; _profile = cjo.profile; _taskName = cjo.taskName; _forceShowType = cjo.forceShowType; _prioritizeMatchDate = cjo.prioritizeOriginalBroadcastDateMatch; }
public Scanner(ConversionJobOptions conversionOptions, string videoFileName, bool useShowAnalyzer, float duration, JobStatus jobStatus, Log jobLog) : base(conversionOptions.profile, videoFileName, duration, "", 0, jobStatus, jobLog) { _videoFileName = videoFileName; _useShowAnalyzer = useShowAnalyzer; _jobStatus = jobStatus; _jobLog = jobLog; _profile = conversionOptions.profile; _convOptions = conversionOptions; _customComskipPath = MCEBuddyConf.GlobalMCEConfig.GeneralOptions.comskipPath; if (!String.IsNullOrWhiteSpace(_customComskipPath)) _jobLog.WriteEntry(this, "Using Custom Comskip Path -> " + MCEBuddyConf.GlobalMCEConfig.GeneralOptions.comskipPath, Log.LogEntryType.Information); }
/// <summary> /// Clones the current object and returns a new instance of the object /// </summary> /// <returns>New clone object</returns> public ConversionJobOptions Clone() { ConversionJobOptions clone = (ConversionJobOptions)this.MemberwiseClone(); if (metadataCorrections != null) { clone.metadataCorrections = new MetadataCorrectionOptions[metadataCorrections.Length]; for (int i = 0; i < metadataCorrections.Length; i++) { clone.metadataCorrections[i] = this.metadataCorrections[i].Clone(); // Clone this object as MemberwiseClone only does a shallow copy } } return(clone); }
private bool _newTask = false; // Are we creating a new task public ConversionTaskForm(MCEBuddyConf mceOptions, string taskName) { InitializeComponent(); maxWidthBar.Maximum = _resolutions.Length - 1; _advGrpSize = advancedSettings.Size; // Store the value _mceOptions = mceOptions; _cjo = _mceOptions.GetConversionTaskByName(taskName); // First get the new scale using (Graphics g = this.CreateGraphics()) { float _scale = g.DpiX / 96; // Get the system DPI (font scaling) _advancedBoxCollapsedSize = (int)(_advancedBoxCollapsedSize * _scale); } }
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 } }
public ConversionJob(ConversionJobOptions conversionJobOptions, VideoMetaData metaData) { _conversionOptions = conversionJobOptions; // First thing to do _metaData = metaData; // Save the metadata if present _originalFileNameBackup = _conversionOptions.sourceVideo; // This is what we use to report to the world what we're working on, _sourceVideo may change under certain conditions below if (String.IsNullOrEmpty(_conversionOptions.destinationPath)) _conversionOptions.destinationPath = Path.GetDirectoryName(_conversionOptions.sourceVideo); // No dest path = convert in place _jobStatus = new JobStatus(); _jobStatus.SourceFile = _conversionOptions.sourceVideo; _jobStatus.TaskName = _conversionOptions.taskName; // Read various engine parameters _maxConcurrentJobs = MCEBuddyConf.GlobalMCEConfig.GeneralOptions.maxConcurrentJobs; _spaceCheck = MCEBuddyConf.GlobalMCEConfig.GeneralOptions.spaceCheck; _subtitleSegmentOffset = MCEBuddyConf.GlobalMCEConfig.GeneralOptions.subtitleSegmentOffset; // Read various profile parameters Ini configProfileIni = new Ini(GlobalDefs.ProfileFile); // Profile only parameters _preConversionCommercialRemover = configProfileIni.ReadBoolean(_conversionOptions.profile, "PreConversionCommercialRemover", false); // Check if the user wants to remove commercials before the actual conversion in which case we always return false - i.e. remove commercial during remux stage _copyLOGFile = configProfileIni.ReadBoolean(_conversionOptions.profile, "CopyLogFile", false); // Check if the user wants to save the log file generated by Comskip _copyPropertiesFile = configProfileIni.ReadBoolean(_conversionOptions.profile, "CopyPropertiesFile", false); // Check if the user wants to save the properties file for SageTV metadata if (configProfileIni.ReadString(_conversionOptions.profile, "AutoDeinterlace", "default") == "default") _autoDeinterlace = _conversionOptions.autoDeInterlace; else _autoDeinterlace = configProfileIni.ReadBoolean(_conversionOptions.profile, "AutoDeinterlace", false); if (_conversionOptions.renameOnly) _commercialSkipCut = true; //no cutting if we are renaming only else if (configProfileIni.ReadString(_conversionOptions.profile, "CommercialSkipCut", "default") == "default") _commercialSkipCut = _conversionOptions.commercialSkipCut; else _commercialSkipCut = configProfileIni.ReadBoolean(_conversionOptions.profile, "CommercialSkipCut", false); }
/// <summary> /// Reads the settings from the conversion job options and populates the form /// </summary> private void ReadSettings(ConversionJobOptions cjo) { monitorTaskNameMatchChk.Checked = !(cjo.monitorTaskNames == null); // If we have a list then check the box startTrim.Text = cjo.startTrim.ToString(); startTrimChk.Checked = (cjo.startTrim != 0); endTrim.Text = cjo.endTrim.ToString(); endTrimChk.Checked = (cjo.endTrim != 0); makKey.Text = cjo.tivoMAKKey; insertTopChk.Checked = cjo.insertQueueTop; string extractCCOpts = cjo.extractCC; if (String.IsNullOrEmpty(extractCCOpts)) { extractCCAdvOpts.Enabled = extractCCAdvOpts.Checked = false; ccField.Enabled = ccChannel.Enabled = false; ccOffset.Enabled = false; ccField.Text = ccChannel.Text = "1"; // Populate some default values } else if (extractCCOpts == "default") { extractCCAdvOpts.Enabled = true; extractCCAdvOpts.Checked = false; ccOffset.Enabled = true; ccField.Enabled = ccChannel.Enabled = false; ccField.Text = ccChannel.Text = "1"; // Populate some default values } else { string[] ccOpts = extractCCOpts.Split(','); // Field,Channel extractCCAdvOpts.Enabled = extractCCAdvOpts.Checked = true; ccOffset.Enabled = ccField.Enabled = ccChannel.Enabled = true; ccField.Text = ccOpts[0]; // MCEBuddy doesn't support 12/both configuration ccChannel.Text = ccOpts[1]; } ccOffset.Text = cjo.ccOffset.ToString(CultureInfo.InvariantCulture); if (cjo.audioOffset == 0) { audioOffsetChk.Checked = audioOffset.Enabled = false; audioOffset.Text = ""; } else { audioOffsetChk.Checked = audioOffset.Enabled = true; audioOffset.Text = cjo.audioOffset.ToString(CultureInfo.InvariantCulture); } if (String.IsNullOrWhiteSpace(cjo.FPS)) { frameRateChk.Checked = frameRate.Enabled = false; frameRate.Text = ""; } else { frameRateChk.Checked = frameRate.Enabled = true; frameRate.Text = cjo.FPS; } embedSrtChaptersChk.Checked = cjo.embedSubtitlesChapters; skipHistoryChk.Checked = cjo.checkReprocessingHistory; // First skipReprocessChk.Checked = cjo.skipReprocessing; // Second autoIncFilenameChk.Checked = cjo.autoIncrementFilename; xmlChk.Checked = cjo.extractXML; writeMetadataChk.Checked = cjo.writeMetadata; disableCroppingChk.Checked = cjo.disableCropping; downloadSeriesChk.Checked = cjo.downloadSeriesDetails; // First seriesButton.Enabled = downloadSeriesChk.Checked; // Second skipCopyChk.Checked = cjo.skipCopyBackup; skipRemuxChk.Checked = cjo.skipRemuxing; forceShowTypeCbo.Text = cjo.forceShowType.ToString(); drmFilterCbo.Text = cjo.metaDRMSelection.ToString(); ignoreCopyProtectionChk.Checked = cjo.ignoreCopyProtection; drcChk.Checked = cjo.drc; hardwareEncodingChk.Checked = cjo.preferHardwareEncoding; tempFldrPath.Text = cjo.workingPath; //Temp folder path if (cjo.commercialRemoval != CommercialRemovalOptions.None) // Only if commercial detection is enabled, we check for commercial skip cutting { commercialSkipCutChk.Enabled = true; commercialSkipCutChk.Checked = cjo.commercialSkipCut; } else { commercialSkipCutChk.Enabled = commercialSkipCutChk.Checked = false; } comskipINIPath.Text = cjo.comskipIni; if (cjo.commercialRemoval == CommercialRemovalOptions.Comskip) // Comskip comskipINIPath.Enabled = comskipIniCmd.Enabled = true; else comskipINIPath.Enabled = comskipIniCmd.Enabled = false; // RENAME ONLY CHECK - DISABLE OTHER CONTROLS: Do these in the end since they control other check boxes if (cjo.renameOnly) frameRateChk.Enabled = audioOffsetChk.Enabled = audioOffset.Enabled = startTrimChk.Enabled = startTrim.Enabled = endTrimChk.Enabled = endTrim.Enabled = disableCroppingChk.Enabled = commercialSkipCutChk.Enabled = drcChk.Enabled = embedSrtChaptersChk.Enabled = writeMetadataChk.Enabled = hardwareEncodingChk.Enabled = ignoreCopyProtectionChk.Enabled = false; else drmFilterCbo.Enabled = false; }
public ConversionTaskExpertSettingsForm(List<MonitorJobOptions> monitorTasks, ConversionJobOptions cjo) { InitializeComponent(); _cjo = cjo; _monitorTasks = monitorTasks; }
/// <summary> /// Writes the settings from the form to the Conversion Job Options /// </summary> private void WriteSettings(ConversionJobOptions cjo) { cjo.ignoreCopyProtection = ignoreCopyProtectionChk.Checked; cjo.skipCopyBackup = skipCopyChk.Checked; cjo.skipRemuxing = skipRemuxChk.Checked; cjo.skipReprocessing = skipReprocessChk.Checked; cjo.autoIncrementFilename = autoIncFilenameChk.Checked; cjo.checkReprocessingHistory = skipHistoryChk.Checked; cjo.comskipIni = comskipINIPath.Text; cjo.downloadSeriesDetails = downloadSeriesChk.Checked; cjo.forceShowType = (ShowType)forceShowTypeCbo.SelectedIndex; cjo.metaDRMSelection = (DRMType)drmFilterCbo.SelectedIndex; cjo.extractXML = xmlChk.Checked; cjo.writeMetadata = writeMetadataChk.Checked; cjo.insertQueueTop = insertTopChk.Checked; cjo.disableCropping = disableCroppingChk.Checked; cjo.drc = drcChk.Checked; cjo.preferHardwareEncoding = hardwareEncodingChk.Checked; cjo.embedSubtitlesChapters = embedSrtChaptersChk.Checked; cjo.tivoMAKKey = makKey.Text; cjo.workingPath = tempFldrPath.Text.Trim(); cjo.enabled = true; // By default tasks are enabled if (!monitorTaskNameMatchChk.Checked) cjo.monitorTaskNames = null; // clear it if the box is unchecked cjo.commercialSkipCut = commercialSkipCutChk.Checked; if (startTrimChk.Checked && startTrim.Text != "") int.TryParse(startTrim.Text, out cjo.startTrim); else cjo.startTrim = 0; if (endTrimChk.Checked && endTrim.Text != "") int.TryParse(endTrim.Text, out cjo.endTrim); else cjo.endTrim = 0; if (extractCCAdvOpts.Enabled == false) cjo.extractCC = ""; else if (extractCCAdvOpts.Checked == false) cjo.extractCC = "default"; else cjo.extractCC = ccField.Text + "," + ccChannel.Text; // Field,Channel double.TryParse(ccOffset.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.ccOffset); if (audioOffsetChk.Checked == false) cjo.audioOffset = 0; else double.TryParse(audioOffset.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.audioOffset); if (frameRateChk.Checked == false) cjo.FPS = ""; else cjo.FPS = frameRate.Text.Trim(); }
static int Main(string[] args) { MCEBuddyConf.GlobalMCEConfig = new MCEBuddyConf(GlobalDefs.ConfigFile); // Read the settings for global objects ConversionJobOptions cjo = new ConversionJobOptions(); // Start with an empty project cjo.workingPath = Environment.CurrentDirectory; // Set the default path to here Log.AppLog = new Log(Log.LogDestination.Console); // Redirect to console all output Log.LogLevel = Log.LogEntryType.Debug; // Print all messages string currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); Log.AppLog.WriteEntry("", "\r\nRemux TiVO file using DirectShow streams and TiVODecode as fallback", Log.LogEntryType.Debug); Log.AppLog.WriteEntry("", "This file remuxes a TiVO file into a TS file.\r\nIf TiVO Desktop is installed, it will try to use the TiVO DirectShow filter to decrypt and then use FFMPEG.exe to remux the streams into a TS file.\r\nAs a fallback it will try to use TiVODecode.exe to decrypt and remux into a TS file.", Log.LogEntryType.Debug); Log.AppLog.WriteEntry("", "Copyright (c) Ramit Bhalla, Build Version : " + currentVersion, Log.LogEntryType.Debug); Log.AppLog.WriteEntry("", "Build Date : " + System.IO.File.GetLastWriteTime(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug); Log.AppLog.WriteEntry("", "", Log.LogEntryType.Debug); try { switch (args.Length) // HACK - bad coding but efficient :) { case 4: // GOOD SECTION cjo.audioLanguage = args[3]; Log.AppLog.WriteEntry("", "RemuxTiVOStreams Audio Langage Code : " + cjo.audioLanguage, Log.LogEntryType.Debug); goto case 3; case 3: cjo.tivoMAKKey = args[2]; Log.AppLog.WriteEntry("", "RemuxTiVOStreams MAK : " + cjo.tivoMAKKey, Log.LogEntryType.Debug); goto case 2; case 2: if (!String.IsNullOrWhiteSpace(args[1])) // If it's empty use the current directory cjo.workingPath = args[1]; Log.AppLog.WriteEntry("", "RemuxTiVOStreams Temp Path : " + cjo.workingPath, Log.LogEntryType.Debug); goto case 1; case 1: if (String.IsNullOrWhiteSpace(args[0])) goto default; // Bad usage cjo.sourceVideo = args[0]; if (String.IsNullOrWhiteSpace(Path.GetDirectoryName(cjo.sourceVideo))) cjo.sourceVideo = Path.Combine(Environment.CurrentDirectory, cjo.sourceVideo); // If the video doesn't have a path, it's in the current directory Log.AppLog.WriteEntry("", "RemuxTiVOStreams Source File : " + cjo.sourceVideo, Log.LogEntryType.Debug); break; case 0: // NO GOOD SECTION goto default; default: Log.AppLog.WriteEntry("", "\r\nRemuxTiVOStreams Invalid Input", Log.LogEntryType.Debug); Usage(); return -1; // Bad usage } } catch (Exception e) { Log.AppLog.WriteEntry("", "\r\nRemuxTiVOStreams Invalid Input Error -> " + e.ToString() + "\r\n", Log.LogEntryType.Error); Usage(); return -1; // Bad usage } Log.AppLog.WriteEntry("", "\r\nRemuxTiVOStreams trying to Remux TiVO file\r\n", Log.LogEntryType.Debug); try { RemuxMCERecording remuxTivo = new RemuxMCERecording(cjo, new JobStatus(), Log.AppLog); if (remuxTivo.RemuxTiVO()) { Log.AppLog.WriteEntry("", "\r\nRemuxTiVOStreams Successful!!", Log.LogEntryType.Debug); return 0; // we good here } else { Log.AppLog.WriteEntry("", "\r\nRemuxTiVOStreams Failed!!", Log.LogEntryType.Debug); return -2; // too bad } } catch (Exception e1) { Log.AppLog.WriteEntry("", "\r\nRemuxTiVOStreams Crashed with Error -> " + e1.ToString() + "\r\n", Log.LogEntryType.Error); return -3; // We bugged out } }
/// <summary> /// Writes the settings to the cjo object /// </summary> /// <param name="save">True if you want to save the settings to the Global MCE object</param> private void WriteSettings(ConversionJobOptions cjo, bool save) { cjo.taskName = taskNameTxt.Text.Trim(); cjo.profile = profileCbo.SelectedItem.ToString(); cjo.destinationPath = destinationPathTxt.Text; cjo.addToiTunes = addiTunesChk.Checked; cjo.addToWMP = addToWMPChk.Checked; int.TryParse(maxWidthTxt.Text.ToString(), out cjo.maxWidth); cjo.encoderSelectBestAudioTrack = singleAudioTrackChk.Checked; cjo.volumeMultiplier = RangeValToVolume(volumeBar.Value); cjo.qualityMultiplier = RangeValToQuality(qualityBar.Value); cjo.commercialRemoval = (CommercialRemovalOptions)detectAdsCbo.SelectedIndex; cjo.renameBySeries = renameBySeriesChk.Checked; cjo.altRenameBySeries = altRenameBySeriesChk.Checked; cjo.renameOnly = renameOnlyChk.Checked; cjo.fileSelection = fileMatchTxt.Text; cjo.metaShowSelection = metaShowMatchTxt.Text; cjo.metaNetworkSelection = metaNetworkMatchTxt.Text; cjo.audioLanguage = ISO639_3.GetLanguageCode(langBox.Text); cjo.stereoAudio = !multiChannelAudioChk.Checked; cjo.autoDeInterlace = autoDeinterlaceChk.Checked; cjo.enabled = true; // By default tasks are enabled switch (metaShowTypeCbo.SelectedIndex) { case 1: cjo.metaShowTypeSelection = ShowType.Movie; break; case 2: cjo.metaShowTypeSelection = ShowType.Series; break; case 3: cjo.metaShowTypeSelection = ShowType.Sports; break; case 0: default: cjo.metaShowTypeSelection = ShowType.Default; break; } if (detectAdsCbo.SelectedIndex == 0) // Write this only if commercial detection is enabled, default is false cjo.commercialSkipCut = false; if (customReNamingChk.Checked && customFileRenamePattern.Text != "") cjo.customRenameBySeries = customFileRenamePattern.Text; else cjo.customRenameBySeries = ""; if (extractCC.Checked == false) cjo.extractCC = ""; // SANITY CHECKS: if ((detectAdsCbo.SelectedIndex != 0) && renameOnlyChk.Checked) // If we are naming only, then we need to ensure CommercialSkipCut is enabled if commercial detection is enabled cjo.commercialSkipCut = true; if (save) // Are we asked to save them _mceOptions.AddOrUpdateConversionTask(cjo, false); }
/// <summary> /// Generates a new name and path for a file using the metadata and options provided /// </summary> /// <param name="conversionOptions">Conversion job options</param> /// <param name="metaData">Metadata for video file</param> /// <param name="originalFileName">Full path and name for original video file</param> /// <param name="renamedFileExt">File extension for the renamed file</param> /// <param name="newFileName">Will contain the name of the renamed file if successful</param> /// <param name="subDestinationPath">Will contain the path of the renamed file if successful</param> /// <param name="jobLog">JobLog</param> /// <returns>True if rename was successful, false if there was no rename</returns> public static bool GetRenameByMetadata(ConversionJobOptions conversionOptions, VideoMetaData metaData, string originalFileName, string renamedFileExt, out string newFileName, out string subDestinationPath, Log jobLog) { newFileName = subDestinationPath = ""; if (metaData != null) { if ((conversionOptions.renameBySeries) & (!String.IsNullOrEmpty(metaData.MetaData.Title))) { string title = metaData.MetaData.Title; string subTitle = metaData.MetaData.SubTitle; //Get the date field string date; if (metaData.MetaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { date = metaData.MetaData.RecordedDateTime.ToLocalTime().ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); } else { DateTime dt = Util.FileIO.GetFileCreationTime(originalFileName); if (dt > GlobalDefs.NO_BROADCAST_TIME) { date = dt.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry("Cannot get recorded date and time, using current date and time", Log.LogEntryType.Warning); date = DateTime.Now.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); } } // Build the new file name, check which naming convention we are using if (!String.IsNullOrEmpty(conversionOptions.customRenameBySeries)) { jobLog.WriteEntry("Custom Renaming Command -> " + conversionOptions.customRenameBySeries, Log.LogEntryType.Debug); try { CustomRename.CustomRenameFilename(conversionOptions.customRenameBySeries, ref newFileName, ref subDestinationPath, originalFileName, metaData.MetaData, jobLog); newFileName = newFileName.Replace(@"\\", @"\"); newFileName += renamedFileExt; } catch (Exception e) { jobLog.WriteEntry("Error in file naming format detected, fallback to default naming convention.\r\nError : " + e.ToString(), Log.LogEntryType.Warning); // We had an invalid format newFileName = ""; // Reset since we had an error so fall back can work subDestinationPath = ""; // Reset path for failure } } else if (conversionOptions.altRenameBySeries) // Alternate renaming pattern { // ALTERNATE MC COMPATIBLE --> SHOWNAME/SEASON XX/SXXEYY-EPISODENAME.ext if ((metaData.MetaData.Season > 0) && (metaData.MetaData.Episode > 0)) { newFileName += "S" + metaData.MetaData.Season.ToString("00", System.Globalization.CultureInfo.InvariantCulture) + "E" + metaData.MetaData.Episode.ToString("00", System.Globalization.CultureInfo.InvariantCulture); if (subTitle != "") newFileName += "-" + subTitle; } else { jobLog.WriteEntry("No Season and Episode information available, using show name", Log.LogEntryType.Warning); // if there is not season episode name available newFileName = title; if (subTitle != "") newFileName += "-" + subTitle; else newFileName += "-" + date + " " + DateTime.Now.ToString("HH:MM", System.Globalization.CultureInfo.InvariantCulture); } newFileName = newFileName.Replace(@"\\", @"\"); newFileName += renamedFileExt; // Create the directory structure subDestinationPath += metaData.MetaData.Title; if ((metaData.MetaData.Season > 0)) subDestinationPath += "\\Season " + metaData.MetaData.Season.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } if (newFileName == "") // this is our default/fallback option { // STANDARD --> SHOWNAME/SHOWNAME-SXXEYY-EPISODENAME<-RECORDDATE>.ext // Record date is used where there is no season and episode info newFileName = title; if ((metaData.MetaData.Season > 0) && (metaData.MetaData.Episode > 0)) { newFileName += "-" + "S" + metaData.MetaData.Season.ToString("00", System.Globalization.CultureInfo.InvariantCulture) + "E" + metaData.MetaData.Episode.ToString("00", System.Globalization.CultureInfo.InvariantCulture); if (subTitle != "") newFileName += "-" + subTitle; } else { jobLog.WriteEntry("No Season and Episode information available, using episode name/record date", Log.LogEntryType.Warning); // if there is not season episode name available if (subTitle != "") newFileName += "-" + subTitle; else newFileName += "-" + date + " " + DateTime.Now.ToString("HH:MM", System.Globalization.CultureInfo.InvariantCulture); // Backup to create a unique name if season/episode is not available } newFileName = newFileName.Replace(@"\\", @"\"); newFileName += renamedFileExt; // Create the directory structure subDestinationPath += metaData.MetaData.Title; } subDestinationPath = Util.FilePaths.RemoveIllegalFilePathChars(subDestinationPath); // clean it up newFileName = Util.FilePaths.RemoveIllegalFileNameChars(newFileName); // clean it up return true; // We have a new name and path } else jobLog.WriteEntry("Skipping Renaming by Series details", Log.LogEntryType.Information); } else jobLog.WriteEntry("Renaming by Series, no Metadata", Log.LogEntryType.Warning); return false; // No new name }
private void ReadConversionSettings(Ini configIni) { // Read the Conversion Tasks string[] conversionRecords = configIni.ReadString("Engine", "Tasks", "").Split(','); foreach (string conversionRecord in conversionRecords) { if (String.IsNullOrEmpty(conversionRecord)) continue; ConversionJobOptions cjo = new ConversionJobOptions(); cjo.taskName = conversionRecord; cjo.profile = configIni.ReadString(conversionRecord, "Profile", ""); cjo.destinationPath = configIni.ReadString(conversionRecord, "DestinationPath", ""); CheckPathEnding(ref cjo.destinationPath); cjo.workingPath = configIni.ReadString(conversionRecord, "WorkingPath", ""); CheckPathEnding(ref cjo.workingPath); cjo.fallbackToSourcePath = configIni.ReadBoolean(conversionRecord, "FallbackDestination", false); cjo.autoIncrementFilename = configIni.ReadBoolean(conversionRecord, "AutoIncrementFilename", false); cjo.skipReprocessing = configIni.ReadBoolean(conversionRecord, "SkipReprocessing", false); cjo.checkReprocessingHistory = configIni.ReadBoolean(conversionRecord, "CheckReprocessingHistory", false); cjo.addToiTunes = configIni.ReadBoolean(conversionRecord, "AddToiTunesLibrary", false); cjo.addToWMP = configIni.ReadBoolean(conversionRecord, "AddToWMPLibrary", false); cjo.maxWidth = configIni.ReadInteger(conversionRecord, "MaxWidth", 720); cjo.FPS = configIni.ReadString(conversionRecord, "FPS", ""); cjo.renameBySeries = configIni.ReadBoolean(conversionRecord, "RenameBySeries", true); cjo.altRenameBySeries = configIni.ReadBoolean(conversionRecord, "AltRenameBySeries", false); cjo.customRenameBySeries = configIni.ReadString(conversionRecord, "CustomRenameBySeries", ""); cjo.renameOnly = configIni.ReadBoolean(conversionRecord, "RenameOnly", false); cjo.fileSelection = configIni.ReadString(conversionRecord, "FileSelection", ""); cjo.metaShowSelection = configIni.ReadString(conversionRecord, "MetaSelection", ""); cjo.metaNetworkSelection = configIni.ReadString(conversionRecord, "MetaChannelSelection", ""); string monitorNameList = configIni.ReadString(conversionRecord, "MonitorTaskNames", ""); if (String.IsNullOrWhiteSpace(monitorNameList)) cjo.monitorTaskNames = null; // list should be empty if nothing is there else cjo.monitorTaskNames = monitorNameList.Split(','); cjo.audioLanguage = configIni.ReadString(conversionRecord, "AudioLanguage", ""); string audioOffsetStr = configIni.ReadString(conversionRecord, "AudioOffset", "0"); double.TryParse(audioOffsetStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.audioOffset); cjo.drc = configIni.ReadBoolean(conversionRecord, "DRC", true); cjo.stereoAudio = configIni.ReadBoolean(conversionRecord, "StereoAudio", true); cjo.encoderSelectBestAudioTrack = configIni.ReadBoolean(conversionRecord, "EncoderSelectBestAudioTrack", true); cjo.autoDeInterlace = configIni.ReadBoolean(conversionRecord, "AutoDeInterlace", true); cjo.preferHardwareEncoding = configIni.ReadBoolean(conversionRecord, "PreferHardwareEncoding", true); cjo.startTrim = configIni.ReadInteger(conversionRecord, "StartTrim", 0); cjo.endTrim = configIni.ReadInteger(conversionRecord, "EndTrim", 0); cjo.insertQueueTop = configIni.ReadBoolean(conversionRecord, "InsertQueueTop", false); cjo.extractXML = configIni.ReadBoolean(conversionRecord, "ExtractXML", false); cjo.writeMetadata = configIni.ReadBoolean(conversionRecord, "WriteMetadata", true); cjo.disableCropping = configIni.ReadBoolean(conversionRecord, "DisableCropping", false); cjo.commercialSkipCut = configIni.ReadBoolean(conversionRecord, "TaskCommercialSkipCut", false); cjo.skipCopyBackup = configIni.ReadBoolean(conversionRecord, "SkipCopyBackup", false); cjo.skipRemuxing = configIni.ReadBoolean(conversionRecord, "SkipRemux", false); cjo.ignoreCopyProtection = configIni.ReadBoolean(conversionRecord, "IgnoreCopyProtection", false); cjo.tivoMAKKey = configIni.ReadString(conversionRecord, "TiVOMAKKey", ""); cjo.downloadSeriesDetails = configIni.ReadBoolean(conversionRecord, "DownloadSeriesDetails", true); cjo.downloadBanner = configIni.ReadBoolean(conversionRecord, "DownloadBanner", true); cjo.enabled = configIni.ReadBoolean(conversionRecord, "Enabled", true); cjo.extractCC = configIni.ReadString(conversionRecord, "ExtractCC", ""); cjo.embedSubtitlesChapters = configIni.ReadBoolean(conversionRecord, "EmbedSubtitlesChapters", false); cjo.prioritizeOriginalBroadcastDateMatch = configIni.ReadBoolean(conversionRecord, "PrioritizeOriginalBroadcastDateMatch", false); string ccOffsetStr = configIni.ReadString(conversionRecord, "CCOffset", GlobalDefs.DefaultCCOffset); double.TryParse(ccOffsetStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.ccOffset); string qualityMultiplierStr = configIni.ReadString(conversionRecord, "QualityMultiplier", "1"); double.TryParse(qualityMultiplierStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.qualityMultiplier); if (cjo.qualityMultiplier <= 0.01) cjo.qualityMultiplier = 0.01F; if (cjo.qualityMultiplier > 4) cjo.qualityMultiplier = 4F; string volumeMultiplierStr = configIni.ReadString(conversionRecord, "VolumeMultiplier", "0"); double.TryParse(volumeMultiplierStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.volumeMultiplier); if (cjo.volumeMultiplier <= -20) cjo.volumeMultiplier = -20F; //-10db minimum if (cjo.volumeMultiplier > 60) cjo.volumeMultiplier = 60F; //30db max string metaShowType = configIni.ReadString(conversionRecord, "MetaShowTypeSelection", ShowType.Default.ToString()); if (String.Compare(metaShowType, ShowType.Movie.ToString(), true) == 0) cjo.metaShowTypeSelection = ShowType.Movie; else if (String.Compare(metaShowType, ShowType.Series.ToString(), true) == 0) cjo.metaShowTypeSelection = ShowType.Series; else if (String.Compare(metaShowType, ShowType.Sports.ToString(), true) == 0) cjo.metaShowTypeSelection = ShowType.Sports; else cjo.metaShowTypeSelection = ShowType.Default; string drmType = configIni.ReadString(conversionRecord, "MetaDRMTypeSelection", DRMType.All.ToString()); if (String.Compare(drmType, DRMType.Protected.ToString(), true) == 0) cjo.metaDRMSelection = DRMType.Protected; else if (String.Compare(drmType, DRMType.Unprotected.ToString(), true) == 0) cjo.metaDRMSelection = DRMType.Unprotected; else cjo.metaDRMSelection = DRMType.All; string showType = configIni.ReadString(conversionRecord, "ForceShowType", ShowType.Default.ToString()); if (String.Compare(showType, ShowType.Movie.ToString(), true) == 0) cjo.forceShowType = ShowType.Movie; else if (String.Compare(showType, ShowType.Series.ToString(), true) == 0) cjo.forceShowType = ShowType.Series; else if (String.Compare(showType, ShowType.Sports.ToString(), true) == 0) cjo.forceShowType = ShowType.Sports; else cjo.forceShowType = ShowType.Default; string commercialRemovalStr = configIni.ReadString(conversionRecord, "CommercialRemoval", CommercialRemovalOptions.Comskip.ToString()); if (String.Compare(commercialRemovalStr, CommercialRemovalOptions.Comskip.ToString(), true) == 0) cjo.commercialRemoval = CommercialRemovalOptions.Comskip; else if (String.Compare(commercialRemovalStr, CommercialRemovalOptions.ShowAnalyzer.ToString(), true) == 0) cjo.commercialRemoval = CommercialRemovalOptions.ShowAnalyzer; else cjo.commercialRemoval = CommercialRemovalOptions.None; cjo.comskipIni = configIni.ReadString(conversionRecord, "ComskipINI", ""); cjo.domainName = configIni.ReadString(conversionRecord, "DomainName", ""); cjo.userName = configIni.ReadString(conversionRecord, "UserName", "Guest"); cjo.password = configIni.ReadString(conversionRecord, "Password", ""); if (!String.IsNullOrEmpty(cjo.password)) cjo.password = Crypto.Decrypt(cjo.password); // Password is kept as encrypted int metaCorrectionsCount = configIni.ReadInteger(conversionRecord, "MetaCorrectionsCount", 0); if (metaCorrectionsCount < 1) cjo.metadataCorrections = null; else { cjo.metadataCorrections = new ConversionJobOptions.MetadataCorrectionOptions[metaCorrectionsCount]; for (int i = 0; i < metaCorrectionsCount; i++) // The entries are kept in their own section, easier to manage { cjo.metadataCorrections[i] = new ConversionJobOptions.MetadataCorrectionOptions(); cjo.metadataCorrections[i].originalTitle = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "OriginalTitle" + i.ToString(), ""); cjo.metadataCorrections[i].correctedTitle = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "CorrectedTitle" + i.ToString(), ""); cjo.metadataCorrections[i].tvdbSeriesId = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "TVDBSeriesId" + i.ToString(), ""); cjo.metadataCorrections[i].imdbSeriesId = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "IMDBSeriesId" + i.ToString(), ""); } } mceBuddyConfSettings.conversionTasks.Add(cjo); // Add the Monitor Task object } }
/// <summary> /// Update a Conversion Task or Add to the list if not found (by Name), optionally write to file /// </summary> /// <param name="cjo">Conversion job options</param> /// <param name="write">Write to configuration file immediately</param> public void AddOrUpdateConversionTask(ConversionJobOptions cjo, bool write) { int index = mceBuddyConfSettings.conversionTasks.FindIndex(item => item.taskName == cjo.taskName); // Clone it, to avoid conflict if (index < 0) // new task, cannot find it mceBuddyConfSettings.conversionTasks.Add(cjo.Clone()); else mceBuddyConfSettings.conversionTasks[index] = cjo.Clone(); if (write) WriteConversionSettings(configIni); }
/// <summary> /// Matches the various types of metadata from the recording (after extracting) to the conversion job options /// This function is thread safe /// </summary> /// <returns>Null if there is a metadata filter mismatch, else returns the recording metadata object</returns> private VideoMetaData MetadataMatchFilters(ConversionJobOptions cjo) { // Extract the metadata VideoMetaData metaData = ExtractMetadata(cjo); Log.AppLog.WriteEntry(this, "Checking Metadata for File -> " + cjo.sourceVideo + ", Conversion Task ->" + cjo.taskName, Log.LogEntryType.Debug); // Check the filename matching filters Log.AppLog.WriteEntry(this, "File >" + Path.GetFileName(cjo.sourceVideo) + "<, checking filename filter >" + cjo.fileSelection + "<", Log.LogEntryType.Debug); if (!String.IsNullOrWhiteSpace(cjo.fileSelection)) { if (!Util.Text.WildcardRegexPatternMatch(Path.GetFileName(cjo.sourceVideo), cjo.fileSelection)) { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match Filename meta data pattern", Log.LogEntryType.Debug); return null; } } // Check for the Showname match filters Log.AppLog.WriteEntry(this, "Show >" + metaData.MetaData.Title + "<, checking for showname filter >" + cjo.metaShowSelection + "<", Log.LogEntryType.Debug); if (!String.IsNullOrEmpty(cjo.metaShowSelection)) { if (!Util.Text.WildcardRegexPatternMatch(metaData.MetaData.Title, cjo.metaShowSelection)) { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match Showname meta data pattern", Log.LogEntryType.Debug); return null; } } // Check for the Network name match filters Log.AppLog.WriteEntry(this, "Network >" + metaData.MetaData.Network + "<, checking for network/channel filter >" + cjo.metaNetworkSelection + "<", Log.LogEntryType.Debug); if (!String.IsNullOrEmpty(cjo.metaNetworkSelection)) { if (!Util.Text.WildcardRegexPatternMatch(metaData.MetaData.Network, cjo.metaNetworkSelection)) { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match Network/Channel meta data pattern", Log.LogEntryType.Debug); return null; } } // Check for the Show type match filters Log.AppLog.WriteEntry(this, "IsSports >" + metaData.MetaData.IsSports.ToString() + "<, IsMovie >" + metaData.MetaData.IsMovie.ToString() + "<, checking for show type filter >" + cjo.metaShowTypeSelection.ToString() + "<", Log.LogEntryType.Debug); switch (cjo.metaShowTypeSelection) { case ShowType.Movie: // Asked to only process movies if (!metaData.MetaData.IsMovie) // Show is NOT a Movie { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match Show Type Movie meta data pattern", Log.LogEntryType.Debug); return null; } break; case ShowType.Series: // Asked to only process Series if (metaData.MetaData.IsMovie || metaData.MetaData.IsSports) // Show is NOT a series { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match Show Type Series meta data pattern", Log.LogEntryType.Debug); return null; } break; case ShowType.Sports: // Asked to only process Sports if (!metaData.MetaData.IsSports) // Show is NOT a series { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match Show Type Series meta data pattern", Log.LogEntryType.Debug); return null; } break; case ShowType.Default: default: break; // nothing to do here, no matching required } // Check for the DRM type match filters if (cjo.renameOnly) // Only works with Rename Only { Log.AppLog.WriteEntry(this, "Is CopyProtected >" + metaData.MetaData.CopyProtected.ToString() + "<, checking for DRM type filter >" + cjo.metaDRMSelection.ToString() + "<", Log.LogEntryType.Debug); switch (cjo.metaDRMSelection) { case DRMType.Protected: // Asked to only process only copy protected files if (!metaData.MetaData.CopyProtected) // Show is NOT copy protected { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match DRM Type Protected meta data pattern", Log.LogEntryType.Debug); return null; } break; case DRMType.Unprotected: // Asked to only process only un protected if (metaData.MetaData.CopyProtected) // Show is copy protected { Log.AppLog.WriteEntry(this, "File " + Path.GetFileName(cjo.sourceVideo) + " did not match DRM Type UnProtected meta data pattern", Log.LogEntryType.Debug); return null; } break; case DRMType.All: default: break; // nothing to do here, no matching required } } // ALL DONE - CLEARED ALL MATCHES return metaData; }
/// <summary> /// Reads the settings from the conversion job options and populates the form /// </summary> /// <param name="cjo">Refernce to a cjo object, will create a new object if it is null</param> private void ReadSettings(ref ConversionJobOptions cjo) { // Load the languages list for (int i = 0; i < ISO639_3.ISOLanguageCodesLength; i++) { if (!langBox.Items.Contains(ISO639_3.ISOLanguageCodes[i, 2])) langBox.Items.Add(ISO639_3.ISOLanguageCodes[i, 2]); } profileCbo.Items.Clear(); // We need to clear the list and start over other the "-----" getting messed up foreach (string[] profileSummary in GlobalDefs.profilesSummary) { profileCbo.Items.Add(profileSummary[0]); // Name of profile } if (cjo != null) { taskNameTxt.Text = cjo.taskName; if (!_newTask) taskNameTxt.ReadOnly = true; // Mark read only for an existing task string profile = cjo.profile; if (profileCbo.Items.Contains(profile)) { profileCbo.SelectedItem = profile; } else { MessageBox.Show(Localise.GetPhrase("Cannot find selected profile in profiles.conf"), Localise.GetPhrase("Profile Error"), MessageBoxButtons.OK, MessageBoxIcon.Error); profileCbo.SelectedIndex = 0; } destinationPathTxt.Text = cjo.destinationPath; string newPath = Util.Net.GetUNCPath(destinationPathTxt.Text); if (newPath != destinationPathTxt.Text) destinationPathTxt.Text = newPath; setConnectionCredentials.Enabled = (Net.IsUNCPath(newPath)); maxWidthTxt.Text = cjo.maxWidth.ToString(System.Globalization.CultureInfo.InvariantCulture); double qualityMultiplier = cjo.qualityMultiplier; qualityBar.Value = QualityToRange(qualityMultiplier); UpdateQualityLabel(); double volumeMultiplier = cjo.volumeMultiplier; volumeBar.Value = VolumeToRange(volumeMultiplier); UpdateVolumeLabel(); singleAudioTrackChk.Checked = cjo.encoderSelectBestAudioTrack; detectAdsCbo.SelectedIndex = (int) cjo.commercialRemoval; fileMatchTxt.Text = cjo.fileSelection; metaShowMatchTxt.Text = cjo.metaShowSelection; metaNetworkMatchTxt.Text = cjo.metaNetworkSelection; switch (cjo.metaShowTypeSelection) { case ShowType.Movie: metaShowTypeCbo.SelectedIndex = 1; break; case ShowType.Series: metaShowTypeCbo.SelectedIndex = 2; break; case ShowType.Sports: metaShowTypeCbo.SelectedIndex = 3; break; case ShowType.Default: default: metaShowTypeCbo.SelectedIndex = 0; break; // No show type meta selection } langBox.Text = ISO639_3.GetLanguageName(cjo.audioLanguage); string extractCCOpts = cjo.extractCC; if (String.IsNullOrEmpty(extractCCOpts)) extractCC.Checked = false; else extractCC.Checked = true; multiChannelAudioChk.Checked = !cjo.stereoAudio; autoDeinterlaceChk.Checked = cjo.autoDeInterlace; addiTunesChk.Checked = cjo.addToiTunes; addToWMPChk.Checked = cjo.addToWMP; // Do these in the end since they control other check boxes renameOnlyChk.Checked = cjo.renameOnly; altRenameBySeriesChk.Checked = cjo.altRenameBySeries; string renamePattern = cjo.customRenameBySeries; if (renamePattern != "") { customReNamingChk.Checked = true; customFileRenamePattern.Text = renamePattern; } renameBySeriesChk.Checked = cjo.renameBySeries; // Last one to be set } else { cjo = new ConversionJobOptions(); _newTask = true; // this is a new task and will remain until we hit OK profileCbo.SelectedIndex = 0; // profile detectAdsCbo.SelectedIndex = 1; // Comskip langBox.Text = ISO639_3.GetLanguageName(""); UpdateVolumeLabel(); UpdateQualityLabel(); cjo.preferHardwareEncoding = cjo.downloadSeriesDetails = cjo.downloadBanner = cjo.writeMetadata = cjo.encoderSelectBestAudioTrack = cjo.drc = true; double.TryParse(GlobalDefs.DefaultCCOffset, System.Globalization.NumberStyles.Float, CultureInfo.InvariantCulture, out cjo.ccOffset); metaShowTypeCbo.SelectedIndex = 0; // All shows } CheckNetDrive(false); // No pop up while reading }
/// <summary> /// Gets the name of the destination (expected) conversion file along with full path after checking for renaming options /// </summary> /// <param name="conversionOptions">Conversion Options</param> /// <param name="metaData">Video MetaData</param> /// <param name="originalFileName">Original filename and Path</param> /// <returns>Destination (expected converted) filename and path</returns> public static string GetDestinationFilename(ConversionJobOptions conversionOptions, VideoMetaData metaData, string originalFileName, Log jobLog) { string newFileName, subDestinationPath; // TODO: Do we need to ignore filename auto increment here? if (!CustomRename.GetRenameByMetadata(conversionOptions, metaData, originalFileName, Transcode.Convert.GetConversionExtension(conversionOptions), out newFileName, out subDestinationPath, jobLog)) // Get the new filename and path { // If there is no renaming occuring then the converted video will have the same name as the original video, but the extension may be different newFileName = Path.GetFileNameWithoutExtension(originalFileName) + Transcode.Convert.GetConversionExtension(conversionOptions); // Original Filename + extension of the converted file } // Check if there is a File Rename command in the profile and adjust the filename accordingly string renameExt = GetRenameFileExtension(conversionOptions.profile); if (!String.IsNullOrWhiteSpace(renameExt)) newFileName = Path.GetFileNameWithoutExtension(newFileName) + renameExt; // Original Filename + new renamed extension of the converted file return Path.Combine(conversionOptions.destinationPath, subDestinationPath, newFileName); }
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; }
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); }
private VideoMetaData ExtractMetadata(ConversionJobOptions cjo) { // Extract the video metadata first - we DO NOT download the information now since // 1. This will hang the thread and we have a queue lock already here, so the GUI will hang // 2. We dont' need the additional information, the information about Filename, Show and Network are already available in existing metadata is not overwritten/supplemented by internet data Log.AppLog.WriteEntry("Extracting metadata from file " + cjo.sourceVideo, Log.LogEntryType.Information); VideoMetaData metaData = new VideoMetaData(cjo, new JobStatus(), Log.AppLog, true); // Do NOT download internet information metaData.Extract(true); // Ignore the suspend since we have a Queue lock right now otherwise the engine will hang if the user pauses return metaData; }