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> /// 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 }
/// <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); }
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; }