/// <summary> /// Initializes a new instance of the <see cref="QueueTask"/> class. /// </summary> /// <param name="task"> /// The task. /// </param> /// <param name="configuration"> /// The configuration. /// </param> /// <param name="scannedSourcePath"> /// The scanned Source Path. /// </param> public QueueTask(EncodeTask task, HBConfiguration configuration, string scannedSourcePath) { this.Task = task; this.Configuration = configuration; this.Status = QueueItemStatus.Waiting; this.ScannedSourcePath = scannedSourcePath; }
/// <summary> /// The create audio. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Audio"/>. /// </returns> private static Audio CreateAudio(EncodeTask job) { Audio audio = new Audio(); List<uint> copyMaskList = new List<uint>(); if (job.AllowedPassthruOptions.AudioAllowAACPass) copyMaskList.Add(NativeConstants.HB_ACODEC_AAC_PASS); if (job.AllowedPassthruOptions.AudioAllowAC3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_AC3_PASS); if (job.AllowedPassthruOptions.AudioAllowDTSHDPass) copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_HD_PASS); if (job.AllowedPassthruOptions.AudioAllowDTSPass) copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_PASS); if (job.AllowedPassthruOptions.AudioAllowEAC3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_EAC3_PASS); if (job.AllowedPassthruOptions.AudioAllowFlacPass) copyMaskList.Add(NativeConstants.HB_ACODEC_FLAC_PASS); if (job.AllowedPassthruOptions.AudioAllowMP3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_MP3_PASS); if (job.AllowedPassthruOptions.AudioAllowTrueHDPass) copyMaskList.Add(NativeConstants.HB_ACODEC_TRUEHD_PASS); audio.CopyMask = copyMaskList.ToArray(); HBAudioEncoder audioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper<AudioEncoder>.GetShortName(job.AllowedPassthruOptions.AudioEncoderFallback)); audio.FallbackEncoder = audioEncoder.Id; audio.AudioList = new List<Interop.Json.Encode.AudioTrack>(); foreach (AudioTrack item in job.AudioTracks) { HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(ApplicationServices.Utilities.Converters.GetCliAudioEncoder(item.Encoder)); Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder); HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(EnumHelper<Mixdown>.GetShortName(item.MixDown)); Validate.NotNull(mixdown, "Unrecognized audio mixdown:" + item.MixDown); HBRate sampleRate = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(s => s.Name == item.SampleRate.ToString(CultureInfo.InvariantCulture)); HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack audioTrack = new HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack { Track = (item.Track.HasValue ? item.Track.Value : 0) - 1, DRC = item.DRC, Encoder = encoder.Id, Gain = item.Gain, Mixdown = mixdown.Id, NormalizeMixLevel = false, Samplerate = sampleRate != null ? sampleRate.Rate : 0, Name = item.TrackName, }; if (!item.IsPassthru) { if (item.EncoderRateType == AudioEncoderRateType.Quality) { audioTrack.Quality = item.Quality; } if (item.EncoderRateType == AudioEncoderRateType.Bitrate) { audioTrack.Bitrate = item.Bitrate; } } audio.AudioList.Add(audioTrack); } return audio; }
/* * TODO: * 1. OpenCL and HWD Support * 2. Rotate Support */ /// <summary> /// The create. /// </summary> /// <param name="job"> /// The encode job. /// </param> /// <param name="configuration"> /// The configuration. /// </param> /// <returns> /// The <see cref="JsonEncodeObject"/>. /// </returns> internal static JsonEncodeObject Create(EncodeTask job, HBConfiguration configuration) { JsonEncodeObject encode = new JsonEncodeObject { SequenceID = 0, Audio = CreateAudio(job), Destination = CreateDestination(job), Filters = CreateFilter(job), PAR = CreatePAR(job), Metadata = CreateMetaData(job), Source = CreateSource(job, configuration), Subtitle = CreateSubtitle(job), Video = CreateVideo(job, configuration) }; return encode; }
/// <summary> /// Edit a Queue Task /// </summary> /// <param name="task"> /// The task. /// </param> public void EditQueueJob(EncodeTask task) { // Rescan the source to make sure it's still valid this.queueEditTask = task; this.scanService.Scan(task.Source, task.Title, QueueEditAction, HBConfigurationFactory.Create()); }
/// <summary> /// Get an EncodeJob model for a LibHB Encode. /// </summary> /// <param name="task"> /// The task. /// </param> /// <returns> /// An Interop.EncodeJob model. /// </returns> public static EncodeJob GetEncodeJob(QueueTask task) { // Sanity Checking if (task == null || task.Task == null) { return(null); } // The current Job Configuration EncodeTask work = task.Task; // Which will be converted to this EncodeJob Model. EncodeJob job = new EncodeJob(); EncodingProfile profile = new EncodingProfile(); job.EncodingProfile = profile; profile.Anamorphic = work.Anamorphic; profile.AudioEncodings = new List <AudioEncoding>(); job.ChosenAudioTracks = new List <int>(); foreach (AudioTrack track in work.AudioTracks) { AudioEncoding newTrack = new AudioEncoding { Bitrate = track.Bitrate, Drc = track.DRC, Gain = track.Gain, Encoder = Converters.GetCliAudioEncoder(track.Encoder), InputNumber = track.Track.HasValue ? track.Track.Value : 0, Mixdown = Converters.GetCliMixDown(track.MixDown), SampleRateRaw = GetSampleRateRaw(track.SampleRate), }; profile.AudioEncodings.Add(newTrack); if (track.Track != null) { job.ChosenAudioTracks.Add(track.Track.Value); } } profile.Cropping = new Cropping { Top = work.Cropping.Top, Bottom = work.Cropping.Bottom, Left = work.Cropping.Left, Right = work.Cropping.Right }; profile.CroppingType = CroppingType.Custom; // TODO deal with this better profile.CustomDecomb = work.CustomDecomb; profile.CustomDeinterlace = work.CustomDeinterlace; profile.CustomDenoise = work.CustomDenoise; profile.CustomDetelecine = work.CustomDetelecine; profile.Deblock = work.Deblock; profile.Decomb = work.Decomb; profile.Deinterlace = work.Deinterlace; profile.Denoise = work.Denoise; profile.Detelecine = work.Detelecine; profile.DisplayWidth = work.DisplayWidth.HasValue ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString()) : 0; profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0; profile.Grayscale = work.Grayscale; profile.Height = work.Height.HasValue ? work.Height.Value : 0; profile.IPod5GSupport = work.IPod5GSupport; profile.IncludeChapterMarkers = work.IncludeChapterMarkers; profile.KeepDisplayAspect = work.KeepDisplayAspect; profile.LargeFile = work.LargeFile; profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0; profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0; profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16; profile.Optimize = work.OptimizeMP4; switch (work.OutputFormat) { case OutputFormat.Mp4: case OutputFormat.M4V: profile.OutputFormat = Container.Mp4; break; case OutputFormat.Mkv: profile.OutputFormat = Container.Mkv; break; } profile.ConstantFramerate = work.FramerateMode == FramerateMode.CFR; profile.PixelAspectX = work.PixelAspectX; profile.PixelAspectY = work.PixelAspectY; switch (work.OutputFormat) { case OutputFormat.Mp4: profile.PreferredExtension = OutputExtension.Mp4; break; case OutputFormat.M4V: profile.PreferredExtension = OutputExtension.M4v; break; } profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0; profile.UseDisplayWidth = true; profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0; profile.VideoEncodeRateType = work.VideoEncodeRateType; profile.VideoEncoder = Converters.GetVideoEncoder(work.VideoEncoder); profile.Width = work.Width.HasValue ? work.Width.Value : 0; profile.X264Options = work.AdvancedEncoderOptions; if (work.PointToPointMode == PointToPointMode.Chapters) { job.ChapterStart = work.StartPoint; job.ChapterEnd = work.EndPoint; } job.Angle = work.Angle; job.EncodingProfile = profile; if (work.PointToPointMode == PointToPointMode.Frames) { job.FramesEnd = work.EndPoint; job.FramesStart = work.StartPoint; } job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList(); job.UseDefaultChapterNames = work.IncludeChapterMarkers; job.OutputPath = work.Destination; switch (work.PointToPointMode) { case PointToPointMode.Chapters: job.RangeType = VideoRangeType.Chapters; break; case PointToPointMode.Seconds: job.RangeType = VideoRangeType.Seconds; break; case PointToPointMode.Frames: job.RangeType = VideoRangeType.Frames; break; } if (work.PointToPointMode == PointToPointMode.Seconds) { job.SecondsEnd = work.EndPoint; job.SecondsStart = work.StartPoint; } job.SourcePath = work.Source; // job.SourceType = work.Type; job.Title = work.Title; // Subtitles job.Subtitles = new Subtitles { SourceSubtitles = new List <SourceSubtitle>(), SrtSubtitles = new List <SrtSubtitle>() }; foreach (SubtitleTrack track in work.SubtitleTracks) { if (track.IsSrtSubtitle) { job.Subtitles.SrtSubtitles.Add( new SrtSubtitle { CharacterCode = track.SrtCharCode, Default = track.Default, FileName = track.SrtFileName, LanguageCode = track.SrtLang, Offset = track.SrtOffset }); } else { if (track.SourceTrack != null) { job.Subtitles.SourceSubtitles.Add( new SourceSubtitle { BurnedIn = track.Burned, Default = track.Default, Forced = track.Forced, TrackNumber = track.SourceTrack.TrackNumber }); } } } return(job); }
private static string VideoSettingsQuery(EncodeTask task, double x264CqStep) { string query = string.Empty; switch (task.VideoEncoder) { case VideoEncoder.FFMpeg: query += " -e ffmpeg"; break; case VideoEncoder.X264: query += " -e x264"; break; case VideoEncoder.Theora: query += " -e theora"; break; default: query += " -e x264"; break; } switch (task.VideoEncodeRateType) { case VideoEncodeRateMode.ConstantQuality: if (task.VideoBitrate.HasValue) { query += string.Format(" -b {0}", task.VideoBitrate.Value); } break; case VideoEncodeRateMode.AverageBitrate: double value; switch (task.VideoEncoder) { case VideoEncoder.FFMpeg: value = 31 - (task.Quality - 1); query += string.Format(" -q {0}", value.ToString(new CultureInfo("en-US"))); break; case VideoEncoder.X264: CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); value = 51 - (task.Quality * x264CqStep); value = Math.Round(value, 2); query += string.Format(" -q {0}", value.ToString(culture)); break; case VideoEncoder.Theora: value = task.Quality; query += string.Format(" -q {0}", value.ToString(new CultureInfo("en-US"))); break; } break; } if (task.TwoPass) { query += " -2 "; } if (task.TurboFirstPass) { query += " -T "; } if (task.Framerate.HasValue) { query += string.Format(" -r {0}", task.Framerate); } switch (task.FramerateMode) { case FramerateMode.CFR: query += " --cfr"; break; case FramerateMode.VFR: query += " --vfr"; break; case FramerateMode.PFR: query += " --pfr"; break; default: query += " --vfr"; break; } return(query); }
/// <summary> /// Setup this window for a new source /// </summary> /// <param name="title"> /// The title. /// </param> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetSource(Title title, Preset preset, EncodeTask task) { this.Task = task; }
/// <summary> /// The create subtitle. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="HandBrake.ApplicationServices.Interop.Json.Encode.Subtitles"/>. /// </returns> private static Subtitles CreateSubtitle(EncodeTask job) { Subtitles subtitle = new Subtitles { Search = new SubtitleSearch { Enable = false, Default = false, Burn = false, Forced = false }, SubtitleList = new List<SubtitleList>() }; foreach (SubtitleTrack item in job.SubtitleTracks) { if (!item.IsSrtSubtitle) { // Handle Foreign Audio Search if (item.SourceTrack.TrackNumber == 0) { subtitle.Search.Enable = true; subtitle.Search.Burn = item.Burned; subtitle.Search.Default = item.Default; subtitle.Search.Forced = item.Forced; } else { SubtitleList track = new SubtitleList { Burn = item.Burned, Default = item.Default, Forced = item.Forced, ID = item.SourceTrack.TrackNumber, Track = (item.SourceTrack.TrackNumber - 1) }; subtitle.SubtitleList.Add(track); } } else { SubtitleList track = new SubtitleList { Track = -1, // Indicates SRT Default = item.Default, Offset = item.SrtOffset, Burn = item.Burned, SRT = new SRT { Filename = item.SrtPath, Codeset = item.SrtCharCode, Language = item.SrtLang } }; subtitle.SubtitleList.Add(track); } } return subtitle; }
private static string X264Query(EncodeTask task) { return(string.IsNullOrEmpty(task.AdvancedEncoderOptions) ? string.Empty : string.Format(" -x {0}", task.AdvancedEncoderOptions)); }
/// <summary> /// Setup this tab for the specified preset. /// </summary> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetPreset(Preset preset, EncodeTask task) { this.Task = task; // Handle built-in presets. if (preset.IsBuildIn) { preset.PictureSettingsMode = PresetPictureSettingsMode.Custom; } // Setup the Picture Sizes switch (preset.PictureSettingsMode) { default: case PresetPictureSettingsMode.Custom: case PresetPictureSettingsMode.SourceMaximum: // Anamorphic Mode this.SelectedAnamorphicMode = preset.Task.Anamorphic; // Modulus if (preset.Task.Modulus.HasValue) { this.SelectedModulus = preset.Task.Modulus; } // Set the Maintain Aspect ratio. this.MaintainAspectRatio = preset.Task.KeepDisplayAspect; // Set the Maximum so libhb can correctly manage the size. if (preset.PictureSettingsMode == PresetPictureSettingsMode.SourceMaximum) { this.MaxWidth = this.sourceResolution.Width; this.MaxHeight = this.sourceResolution.Height; } else { this.MaxWidth = preset.Task.MaxWidth ?? this.sourceResolution.Width; this.MaxHeight = preset.Task.MaxHeight ?? this.sourceResolution.Height; } // Set the width, then check the height doesn't breach the max height and correct if necessary. int width = this.GetModulusValue(this.GetRes((this.sourceResolution.Width - this.CropLeft - this.CropRight), preset.Task.MaxWidth)); this.Width = width; // If we have a max height, make sure we havn't breached it. int height = this.GetModulusValue(this.GetRes((this.sourceResolution.Height - this.CropTop - this.CropBottom), preset.Task.MaxHeight)); if (preset.Task.MaxHeight.HasValue && this.Height > preset.Task.MaxHeight.Value) { this.Height = height; } break; case PresetPictureSettingsMode.None: // Do Nothing except reset the Max Width/Height this.MaxWidth = this.sourceResolution.Width; this.MaxHeight = this.sourceResolution.Height; this.SelectedAnamorphicMode = preset.Task.Anamorphic; break; } // Custom Anamorphic if (preset.Task.Anamorphic == Anamorphic.Custom) { this.DisplayWidth = preset.Task.DisplayWidth != null?int.Parse(preset.Task.DisplayWidth.ToString()) : 0; this.ParWidth = preset.Task.PixelAspectX; this.ParHeight = preset.Task.PixelAspectY; } // Cropping if (preset.Task.HasCropping) { this.IsCustomCrop = true; this.CropLeft = preset.Task.Cropping.Left; this.CropRight = preset.Task.Cropping.Right; this.CropTop = preset.Task.Cropping.Top; this.CropBottom = preset.Task.Cropping.Bottom; } else { this.IsCustomCrop = false; } this.NotifyOfPropertyChange(() => this.Task); this.UpdateVisibileControls(); }
/// <summary> /// The create filter. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Filters"/>. /// </returns> private static Filters CreateFilter(EncodeTask job) { Filters filter = new Filters { FilterList = new List<Filter>(), Grayscale = job.Grayscale }; // Detelecine if (job.Detelecine != Detelecine.Off) { Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DETELECINE, Settings = job.CustomDetelecine }; filter.FilterList.Add(filterItem); } // Decomb if (job.Decomb != Decomb.Off) { string options; if (job.Decomb == Decomb.Fast) { options = "7:2:6:9:1:80"; } else if (job.Decomb == Decomb.Bob) { options = "455"; } else { options = job.CustomDecomb; } Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DECOMB, Settings = options }; filter.FilterList.Add(filterItem); } // Deinterlace if (job.Deinterlace != Deinterlace.Off) { string options; if (job.Deinterlace == Deinterlace.Fast) { options = "0"; } else if (job.Deinterlace == Deinterlace.Slow) { options = "1"; } else if (job.Deinterlace == Deinterlace.Slower) { options = "3"; } else if (job.Deinterlace == Deinterlace.Bob) { options = "15"; } else { options = job.CustomDeinterlace; } Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEINTERLACE, Settings = options }; filter.FilterList.Add(filterItem); } // VFR / CFR int fm = job.FramerateMode == FramerateMode.CFR ? 1 : job.FramerateMode == FramerateMode.PFR ? 2 : 0; IntPtr frameratePrt = Marshal.StringToHGlobalAnsi(job.Framerate.ToString()); // TODO check culture int vrate = HBFunctions.hb_video_framerate_get_from_name(frameratePrt); int? num = null; int? den = null; if (vrate > 0) { num = 27000000; den = vrate; } string framerateString = num.HasValue ? string.Format("{0}:{1}:{2}", fm, num, den) : string.Format("{0}", fm); // filter_cfr, filter_vrate.num, filter_vrate.den Filter framerateShaper = new Filter { ID = (int)hb_filter_ids.HB_FILTER_VFR, Settings = framerateString }; filter.FilterList.Add(framerateShaper); // Deblock if (job.Deblock >= 5) { Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEBLOCK, Settings = job.Deblock.ToString() }; filter.FilterList.Add(filterItem); } // Denoise if (job.Denoise != Denoise.Off) { hb_filter_ids id = job.Denoise == Denoise.hqdn3d ? hb_filter_ids.HB_FILTER_HQDN3D : hb_filter_ids.HB_FILTER_NLMEANS; string settings; if (!string.IsNullOrEmpty(job.CustomDenoise)) { settings = job.CustomDenoise; } else { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings((int)id, job.DenoisePreset.ToString().ToLower().Replace(" ", string.Empty), job.DenoiseTune.ToString().ToLower().Replace(" ", string.Empty)); settings = Marshal.PtrToStringAnsi(settingsPtr); } Filter filterItem = new Filter { ID = (int)id, Settings = settings }; filter.FilterList.Add(filterItem); } // CropScale Filter Filter cropScale = new Filter { ID = (int)hb_filter_ids.HB_FILTER_CROP_SCALE, Settings = string.Format( "{0}:{1}:{2}:{3}:{4}:{5}", job.Width, job.Height, job.Cropping.Top, job.Cropping.Bottom, job.Cropping.Left, job.Cropping.Right) }; filter.FilterList.Add(cropScale); // Rotate /* TODO NOT SUPPORTED YET. */ return filter; }
public DeinterlaceFilterItem(EncodeTask currentTask, Action triggerTabChanged) { this.triggerTabChanged = triggerTabChanged; this.CurrentTask = currentTask; this.SelectedDeinterlaceFilter = DeinterlaceFilter.Off; }
/// <summary> /// Setup this tab for the specified preset. /// </summary> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetPreset(Preset preset, EncodeTask task) { this.Task = task; this.Task.IncludeChapterMarkers = preset.Task.IncludeChapterMarkers; this.NotifyOfPropertyChange(() => this.Task); }
public PadFilter(EncodeTask currentTask, Action triggerTabChanged) { this.triggerTabChanged = triggerTabChanged; this.CurrentTask = currentTask; }
public void UpdateTask(EncodeTask task) { this.CurrentTask = task; }
/// <summary> /// Add the encode settings to the preset /// </summary> /// <param name="xmlWriter"> /// The xml writer. /// </param> /// <param name="parsed"> /// The parsed. /// </param> /// <param name="preset"> /// The preset. /// </param> /// <param name="build"> /// The build. /// </param> private static void AddEncodeSettings(XmlTextWriter xmlWriter, EncodeTask parsed, Preset preset, string build) { AddBooleanElement(xmlWriter, "AudioAllowAACPass", parsed.AllowedPassthruOptions.AudioAllowAACPass); AddBooleanElement(xmlWriter, "AudioAllowAC3Pass", parsed.AllowedPassthruOptions.AudioAllowAC3Pass); AddBooleanElement(xmlWriter, "AudioAllowDTSHDPass", parsed.AllowedPassthruOptions.AudioAllowDTSHDPass); AddBooleanElement(xmlWriter, "AudioAllowDTSPass", parsed.AllowedPassthruOptions.AudioAllowDTSPass); AddBooleanElement(xmlWriter, "AudioAllowMP3Pass", parsed.AllowedPassthruOptions.AudioAllowMP3Pass); // TODO Update AddEncodeElement(xmlWriter, "AudioEncoderFallback", "string", EnumHelper <AudioEncoder> .GetDisplay(parsed.AllowedPassthruOptions.AudioEncoderFallback)); AddBooleanElement(xmlWriter, "ChapterMarkers", parsed.IncludeChapterMarkers); AddEncodeElement(xmlWriter, "Default", "integer", "0"); AddEncodeElement(xmlWriter, "FileFormat", "string", (parsed.OutputFormat == OutputFormat.Mp4) ? "MP4 file" : "MKV file"); // TODO AddBooleanElement(xmlWriter, "Folder", false); AddEncodeElement(xmlWriter, "Mp4HttpOptimize", "integer", parsed.OptimizeMP4 ? "1" : "0"); AddEncodeElement(xmlWriter, "Mp4iPodCompatible", "integer", parsed.IPod5GSupport ? "1" : "0"); AddEncodeElement(xmlWriter, "PictureAutoCrop", "integer", "1"); // Filters AddEncodeElement(xmlWriter, "PictureDeblock", "integer", parsed.Deblock.ToString()); AddBooleanElement(xmlWriter, "PictureDecombDeinterlace", parsed.Decomb != Decomb.Off); AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", parsed.Decomb == Decomb.Custom ? parsed.CustomDecomb : string.Empty); AddEncodeElement(xmlWriter, "PictureDecomb", "integer", ((int)parsed.Decomb).ToString()); AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", parsed.Deinterlace == Deinterlace.Custom ? parsed.CustomDeinterlace : string.Empty); AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", ((int)parsed.Deinterlace).ToString()); AddEncodeElement(xmlWriter, "PictureDenoiseFilter", "string", parsed.Denoise.ToString().ToLower()); AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", parsed.DenoisePreset == DenoisePreset.Custom ? parsed.CustomDenoise : string.Empty); AddEncodeElement(xmlWriter, "PictureDenoisePreset", "string", parsed.DenoisePreset.ToString().ToLower()); if (parsed.Denoise == Denoise.NLMeans) { AddEncodeElement(xmlWriter, "PictureDenoiseTune", "string", parsed.DenoiseTune.ToString().ToLower()); } AddEncodeElement(xmlWriter, "PictureDetelecine", "integer", ((int)parsed.Detelecine).ToString()); AddEncodeElement(xmlWriter, "PictureDetelecineCustom", "string", parsed.Detelecine == Detelecine.Custom ? parsed.CustomDecomb : string.Empty); // Picture Settings AddEncodeElement(xmlWriter, "PictureHeight", "integer", parsed.MaxHeight.HasValue ? parsed.MaxHeight.Value.ToString() : parsed.Height.HasValue?parsed.Height.Value.ToString() : "0"); AddEncodeElement(xmlWriter, "PictureKeepRatio", "integer", parsed.KeepDisplayAspect ? "1" : "0"); AddEncodeElement(xmlWriter, "PictureModulus", "integer", parsed.Modulus.ToString()); AddEncodeElement(xmlWriter, "PicturePAR", "integer", ((int)parsed.Anamorphic).ToString()); AddEncodeElement(xmlWriter, "PictureLeftCrop", "integer", parsed.Cropping.Left.ToString()); AddEncodeElement(xmlWriter, "PictureRightCrop", "integer", parsed.Cropping.Right.ToString()); AddEncodeElement(xmlWriter, "PictureTopCrop", "integer", parsed.Cropping.Top.ToString()); AddEncodeElement(xmlWriter, "PictureBottomCrop", "integer", parsed.Cropping.Bottom.ToString()); AddEncodeElement(xmlWriter, "PictureWidth", "integer", parsed.MaxWidth.HasValue ? parsed.MaxWidth.Value.ToString() : parsed.Width.HasValue?parsed.Width.Value.ToString() : "0"); // Preset Information AddEncodeElement(xmlWriter, "PresetBuildNumber", "string", build); AddEncodeElement(xmlWriter, "PresetDescription", "string", "No Description"); AddEncodeElement(xmlWriter, "PresetName", "string", preset.Name); AddEncodeElement(xmlWriter, "Type", "integer", "1"); // 1 is user preset, 0 is built in // Preset Settings AddEncodeElement(xmlWriter, "UsesMaxPictureSettings", "integer", (parsed.MaxWidth != 0 || parsed.MaxHeight != 0) ? "1" : "0"); AddEncodeElement(xmlWriter, "UsesPictureFilters", "integer", "1"); AddEncodeElement(xmlWriter, "UsesPictureSettings", "integer", "1"); // Video Settings AddEncodeElement(xmlWriter, "VideoAvgBitrate", "string", parsed.VideoBitrate.ToString()); AddEncodeElement(xmlWriter, "VideoEncoder", "string", EnumHelper <VideoEncoder> .GetDisplay(parsed.VideoEncoder)); AddEncodeElement(xmlWriter, "VideoFramerate", "string", parsed.Framerate == null ? "Same as source" : parsed.Framerate.ToString()); AddEncodeElement(xmlWriter, "VideoFramerateMode", "string", parsed.FramerateMode.ToString().ToLower()); AddBooleanElement(xmlWriter, "VideoGrayScale", parsed.Grayscale); AddEncodeElement(xmlWriter, "VideoQualitySlider", "real", parsed.Quality.ToString()); if (parsed.VideoPreset != null) { AddEncodeElement(xmlWriter, "VideoPreset", "string", parsed.VideoPreset.ShortName); } if (parsed.VideoLevel != null) { AddEncodeElement(xmlWriter, "VideoLevel", "string", parsed.VideoLevel.ShortName); } if (parsed.VideoProfile != null) { AddEncodeElement(xmlWriter, "VideoProfile", "string", parsed.VideoProfile.ShortName); } if (parsed.VideoTunes != null) { AddEncodeElement(xmlWriter, "VideoTune", "string", parsed.VideoTunes.Aggregate(string.Empty, (current, item) => string.IsNullOrEmpty(current) ? item.ShortName : "," + item.ShortName)); } AddEncodeElement(xmlWriter, "VideoOptionExtra", "string", parsed.ExtraAdvancedArguments); AddEncodeElement(xmlWriter, "x264UseAdvancedOptions", "integer", parsed.ShowAdvancedTab ? "1" : "0"); int videoQualityType = 0; if (parsed.VideoBitrate != null) { videoQualityType = 1; } else if (parsed.Quality != null) { videoQualityType = 2; } AddEncodeElement(xmlWriter, "VideoQualityType", "integer", videoQualityType.ToString()); AddEncodeElement(xmlWriter, "VideoTargetSize", "string", string.Empty); AddEncodeElement(xmlWriter, "VideoTurboTwoPass", "integer", parsed.TurboFirstPass ? "1" : "0"); AddEncodeElement(xmlWriter, "VideoTwoPass", "integer", parsed.TwoPass ? "1" : "0"); // x264 string AddEncodeElement(xmlWriter, "x264Option", "string", parsed.AdvancedEncoderOptions); }
private static string AudioSettingsQuery(EncodeTask task) { string query = string.Empty; List <AudioTrack> audioTracks = task.AudioTracks; List <int> tracks = new List <int>(); List <AudioEncoder> codecs = new List <AudioEncoder>(); List <Mixdown> mixdowns = new List <Mixdown>(); List <double> samplerates = new List <double>(); List <int> bitrates = new List <int>(); List <double> drcs = new List <double>(); // No Audio if (audioTracks.Count == 0) { query += " -a none "; } // Gather information about each audio track and store them in the declared lists. foreach (AudioTrack track in audioTracks) { tracks.Add(track.Track); // Audio Codec (-E) codecs.Add(track.Encoder); // Audio Mixdown (-6) mixdowns.Add(track.MixDown); // Sample Rate (-R) samplerates.Add(track.SampleRate); // Audio Bitrate (-B) bitrates.Add(track.Bitrate); // DRC (-D) drcs.Add(track.DRC); } // Audio Track (-a) string audioItems = string.Empty; bool firstLoop = true; foreach (int item in tracks) { if (firstLoop) { audioItems = item.ToString(); firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -a " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Audio Codec (-E) foreach (AudioEncoder item in codecs) { if (firstLoop) { audioItems = Converters.GetCliAudioEncoder(item); firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -E " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Audio Mixdown (-6) foreach (Mixdown item in mixdowns) { if (firstLoop) { audioItems = Converters.GetCliMixDown(item); firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -6 " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Sample Rate (-R) foreach (double item in samplerates) { if (firstLoop) { audioItems = item.ToString(); firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -R " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Audio Bitrate (-B) foreach (int item in bitrates) { if (firstLoop) { audioItems = item.ToString(); firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -B " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // DRC (-D) foreach (var itm in drcs) { string item = itm.ToString(new CultureInfo("en-US")); if (firstLoop) { audioItems = item; firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -D " + audioItems; } return(query); }
/// <summary> /// Setup this window for a new source /// </summary> /// <param name="source"> /// The source. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetSource(Source source, Title title, Preset preset, EncodeTask task) { this.currentTitle = title; this.Task = task; this.scannedSource = source; if (title != null) { // Set cached info this.sourceParValues = title.ParVal; this.sourceResolution = title.Resolution; // Update the cropping values, preffering those in the presets. if (!preset.Task.HasCropping) { this.Task.Cropping.Top = title.AutoCropDimensions.Top; this.Task.Cropping.Bottom = title.AutoCropDimensions.Bottom; this.Task.Cropping.Left = title.AutoCropDimensions.Left; this.Task.Cropping.Right = title.AutoCropDimensions.Right; this.IsCustomCrop = false; } else { this.Task.Cropping.Left = preset.Task.Cropping.Left; this.Task.Cropping.Right = preset.Task.Cropping.Right; this.Task.Cropping.Top = preset.Task.Cropping.Top; this.Task.Cropping.Bottom = preset.Task.Cropping.Bottom; this.IsCustomCrop = true; } if (preset.PictureSettingsMode == PresetPictureSettingsMode.None) { // We have no instructions, so simply set it to the source. this.Task.Width = this.GetModulusValue(this.sourceResolution.Width - this.CropLeft - this.CropRight); this.MaintainAspectRatio = true; } else { // Set the Max Width / Height available to the user controls if (this.sourceResolution.Width < this.MaxWidth) { this.MaxWidth = this.sourceResolution.Width; } else if (this.sourceResolution.Width > this.MaxWidth) { this.MaxWidth = preset.Task.MaxWidth ?? this.sourceResolution.Width; } if (this.sourceResolution.Height < this.MaxHeight) { this.MaxHeight = this.sourceResolution.Height; } else if (this.sourceResolution.Height > this.MaxHeight) { this.MaxHeight = preset.Task.MaxHeight ?? this.sourceResolution.Height; } // Set the Width, and Maintain Aspect ratio. That should calc the Height for us. if (this.SelectedAnamorphicMode == Anamorphic.None) { this.Task.Width = preset.Task.Width ?? (this.MaxWidth - this.CropLeft - this.CropRight); // Note: This will be auto-corrected in the property if it's too large. } else { this.Task.Width = preset.Task.Width ?? this.MaxWidth; } // If our height is too large, let it downscale the width for us by setting the height to the lower value. if (!this.MaintainAspectRatio && this.Height > this.MaxHeight) { this.Task.Height = this.MaxHeight; } } // Set Screen Controls this.SourceInfo = string.Format( "{0}x{1}, PAR: {2}/{3}", title.Resolution.Width, title.Resolution.Height, title.ParVal.Width, title.ParVal.Height); this.RecaulcatePictureSettingsProperties(ChangedPictureField.Width); } this.NotifyOfPropertyChange(() => this.Task); }
/// <summary> /// Function which generates the filename and path automatically based on /// the Source Name, DVD title and DVD Chapters /// </summary> /// <param name="task"> /// The task. /// </param> /// <param name="sourceOrLabelName"> /// The Source or Label Name /// </param> /// <returns> /// The Generated FileName /// </returns> public static string AutoName(EncodeTask task, string sourceOrLabelName) { IUserSettingService userSettingService = IoC.Get<IUserSettingService>(); if (task.Destination == null) { task.Destination = string.Empty; } string autoNamePath = string.Empty; if (task.Title != 0) { // Get the Source Name and remove any invalid characters string sourceName = Path.GetInvalidFileNameChars().Aggregate(sourceOrLabelName, (current, character) => current.Replace(character.ToString(), string.Empty)); // Remove Underscores if (userSettingService.GetUserSetting<bool>(UserSettingConstants.AutoNameRemoveUnderscore)) sourceName = sourceName.Replace("_", " "); if (userSettingService.GetUserSetting<bool>(UserSettingConstants.RemovePunctuation)) { sourceName = sourceName.Replace("-", string.Empty); sourceName = sourceName.Replace(",", string.Empty); sourceName = sourceName.Replace(".", string.Empty); } // Switch to "Title Case" if (userSettingService.GetUserSetting<bool>(UserSettingConstants.AutoNameTitleCase)) sourceName = sourceName.ToTitleCase(); // Get the Selected Title Number string dvdTitle = task.Title.ToString(); // Get the Chapter Start and Chapter End Numbers string chapterStart = task.StartPoint.ToString(); string chapterFinish = task.EndPoint.ToString(); string combinedChapterTag = chapterStart; if (chapterFinish != chapterStart && chapterFinish != string.Empty) combinedChapterTag = chapterStart + "-" + chapterFinish; /* * File Name */ string destinationFilename; if (userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNameFormat) != string.Empty) { destinationFilename = userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNameFormat); destinationFilename = destinationFilename.Replace("{source}", sourceName) .Replace(Constants.Title, dvdTitle) .Replace(Constants.Chapters, combinedChapterTag) .Replace(Constants.Date, DateTime.Now.Date.ToShortDateString().Replace('/', '-')) .Replace(Constants.Time, DateTime.Now.ToString("HH:mm")); if (task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality) { destinationFilename = destinationFilename.Replace(Constants.Quality, task.Quality.ToString()); destinationFilename = destinationFilename.Replace(Constants.Bitrate, string.Empty); } else { destinationFilename = destinationFilename.Replace(Constants.Bitrate, task.VideoBitrate.ToString()); destinationFilename = destinationFilename.Replace(Constants.Quality, string.Empty); } } else destinationFilename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag; /* * File Extension */ if (task.OutputFormat == OutputFormat.Mp4) { switch (userSettingService.GetUserSetting<int>(UserSettingConstants.UseM4v)) { case 0: // Automatic destinationFilename += task.IncludeChapterMarkers || task.RequiresM4v ? ".m4v" : ".mp4"; break; case 1: // Always MP4 destinationFilename += ".mp4"; break; case 2: // Always M4V destinationFilename += ".m4v"; break; } } else if (task.OutputFormat == OutputFormat.Mkv) destinationFilename += ".mkv"; /* * File Destination Path */ // If there is an auto name path, use it... if (userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNamePath).Trim().StartsWith("{source_path}") && !string.IsNullOrEmpty(task.Source)) { string savedPath = userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNamePath).Trim().Replace("{source_path}\\", string.Empty).Replace("{source_path}", string.Empty); string directory = Directory.Exists(task.Source) ? task.Source : Path.GetDirectoryName(task.Source); string requestedPath = Path.Combine(directory, savedPath); autoNamePath = Path.Combine(requestedPath, destinationFilename); if (autoNamePath == task.Source) { // Append out_ to files that already exist or is the source file autoNamePath = Path.Combine(Path.GetDirectoryName(task.Source), "output_" + destinationFilename); } } else if (userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNamePath).Contains("{source_folder_name}") && !string.IsNullOrEmpty(task.Source)) { // Second Case: We have a Path, with "{source_folder}" in it, therefore we need to replace it with the folder name from the source. string path = Path.GetDirectoryName(task.Source); if (!string.IsNullOrEmpty(path)) { string[] filesArray = path.Split(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); string sourceFolder = filesArray[filesArray.Length - 1]; autoNamePath = Path.Combine(userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNamePath).Replace("{source_folder_name}", sourceFolder), destinationFilename); } } else if (!task.Destination.Contains(Path.DirectorySeparatorChar.ToString())) { // Third case: If the destination box doesn't already contain a path, make one. if (userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNamePath).Trim() != string.Empty && userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNamePath).Trim() != "Click 'Browse' to set the default location") { autoNamePath = Path.Combine(userSettingService.GetUserSetting<string>(UserSettingConstants.AutoNamePath), destinationFilename); } else // ...otherwise, output to the source directory autoNamePath = null; } else // Otherwise, use the path that is already there. { // Use the path and change the file extension to match the previous destination autoNamePath = Path.Combine(Path.GetDirectoryName(task.Destination), destinationFilename); } } return autoNamePath; }
/// <summary> /// Start with a LibHb EncodeJob Object /// </summary> /// <param name="task"> /// The task. /// </param> /// <param name="configuration"> /// The configuration. /// </param> public void Start(EncodeTask task, HBConfiguration configuration) { try { // Setup this.startTime = DateTime.Now; this.currentTask = task; this.currentConfiguration = configuration; // Create a new HandBrake instance // Setup the HandBrake Instance HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged; HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged; this.instance = HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity); this.instance.EncodeCompleted += this.InstanceEncodeCompleted; this.instance.EncodeProgress += this.InstanceEncodeProgress; // Sanity Checking and Setup if (this.IsEncoding) { throw new Exception("HandBrake is already encoding."); } this.IsEncoding = true; this.SetupLogging(); // Verify the Destination Path Exists, and if not, create it. this.VerifyEncodeDestinationPath(task); ServiceLogMessage("Starting Encode ..."); // Get an EncodeJob object for the Interop Library instance.StartEncode(EncodeFactory.Create(task, configuration)); // Fire the Encode Started Event this.InvokeEncodeStarted(System.EventArgs.Empty); // Set the Process Priority switch (configuration.ProcessPriority) { case "Realtime": Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime; break; case "High": Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; break; case "Above Normal": Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.AboveNormal; break; case "Normal": Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Normal; break; case "Low": Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Idle; break; default: Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal; break; } } catch (Exception exc) { this.IsEncoding = false; ServiceLogMessage("Failed to start encoding ..." + Environment.NewLine + exc); this.InvokeEncodeCompleted(new EventArgs.EncodeCompletedEventArgs(false, exc, "Unable to start encoding", task.Source)); } }
/// <summary> /// Create the PAR object /// </summary> /// <param name="job"> /// The Job /// </param> /// <returns> /// The produced PAR object. /// </returns> private static PAR CreatePAR(EncodeTask job) { return new PAR { Num = job.PixelAspectX, Den = job.PixelAspectY }; }
/// <summary> /// Setup this tab for the specified preset. /// </summary> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetPreset(Preset preset, EncodeTask task) { this.Task.PropertyChanged -= this.Task_PropertyChanged; this.Task = task; this.Task.PropertyChanged += this.Task_PropertyChanged; this.AdvancedOptionsString = preset.Task.AdvancedEncoderOptions; if (task.ShowAdvancedTab && task.VideoEncoder == VideoEncoder.X264) { this.ShowX264AdvancedOptions = true; this.NotifyOfPropertyChange(() => ShowX264AdvancedOptions); } }
/// <summary> /// Update all the UI controls based on the encode task passed in. /// </summary> /// <param name="task"> /// The task. /// </param> public void UpdateTask(EncodeTask task) { this.Task = task; this.NotifyOfPropertyChange(() => Task.AudioTracks); this.NotifyOfPropertyChange(() => this.Task); }
private static string SubtitlesQuery(EncodeTask task) { // TODO return(string.Empty); }
/// <summary> /// Encode and play a sample /// </summary> public void Play() { try { this.IsEncoding = true; if (File.Exists(this.CurrentlyPlaying)) File.Delete(this.CurrentlyPlaying); } catch (Exception) { this.IsEncoding = false; this.errorService.ShowMessageBox("Unable to delete previous preview file. You may need to restart the application.", Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); } if (this.Task == null || string.IsNullOrEmpty(Task.Source)) { this.errorService.ShowMessageBox("You must first scan a source and setup your encode before creating a preview.", Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); return; } EncodeTask encodeTask = new EncodeTask(this.Task) { PreviewEncodeDuration = this.Duration, PreviewEncodeStartAt = this.SelectedPreviewImage, PointToPointMode = PointToPointMode.Preview }; // Filename handling. if (string.IsNullOrEmpty(encodeTask.Destination)) { string filename = Path.ChangeExtension(Path.GetTempFileName(), encodeTask.OutputFormat == OutputFormat.Mkv ? "m4v" : "mkv"); encodeTask.Destination = filename; this.CurrentlyPlaying = filename; } else { string directory = Path.GetDirectoryName(encodeTask.Destination) ?? string.Empty; string filename = Path.GetFileNameWithoutExtension(encodeTask.Destination); string extension = Path.GetExtension(encodeTask.Destination); string previewFilename = string.Format("{0}_preview{1}", filename, extension); string previewFullPath = Path.Combine(directory, previewFilename); encodeTask.Destination = previewFullPath; this.CurrentlyPlaying = previewFullPath; } // Setup the encode task as a preview encode encodeTask.IsPreviewEncode = true; encodeTask.PreviewEncodeStartAt = this.SelectedPreviewImage; // TODO 0 and 1 mean the same. Need to fix this as it knocks the video out of sync with the still preview. encodeTask.PreviewEncodeDuration = this.Duration; QueueTask task = new QueueTask(encodeTask, HBConfigurationFactory.Create(), this.ScannedSource.ScanPath); ThreadPool.QueueUserWorkItem(this.CreatePreview, task); }
/// <summary> /// Generate the Command Line Arguments for the Picture Settings tab /// </summary> /// <param name="task"> /// The encode task. /// </param> /// <returns> /// A Cli Query as a string /// </returns> private static string PictureSettingsQuery(EncodeTask task) { string query = string.Empty; if (task.Anamorphic != Anamorphic.Strict) { if (task.MaxWidth.HasValue) { query += string.Format(" -X {0}", task.MaxWidth); } else if (task.Width.HasValue && task.Width != 0) { query += string.Format(" -w {0}", task.Width); } if (task.MaxWidth.HasValue) { query += string.Format(" -Y {0}", task.MaxHeight); } else if (task.Height.HasValue && task.Height != 0) { query += string.Format(" -l {0}", task.Height); } } if (task.HasCropping) { query += string.Format(" --crop {0}:{1}:{2}:{3}", task.Cropping.Top, task.Cropping.Bottom, task.Cropping.Left, task.Cropping.Right); } switch (task.Anamorphic) { case Anamorphic.Strict: query += " --strict-anamorphic "; break; case Anamorphic.Loose: query += " --loose-anamorphic "; break; case Anamorphic.Custom: query += " --custom-anamorphic "; if (task.DisplayWidth.HasValue) { query += " --display-width " + task.DisplayWidth + " "; } if (task.KeepDisplayAspect) { query += " --keep-display-aspect "; } if (!task.KeepDisplayAspect) { query += string.Format(" --pixel-aspect {0}:{1}", task.PixelAspectX, task.PixelAspectY); } break; } if (task.Modulus.HasValue) { query += " --modulus " + task.Modulus; } return(query); }
/// <summary> /// Update all the UI controls based on the encode task passed in. /// </summary> /// <param name="task"> /// The task. /// </param> public void UpdateTask(EncodeTask task) { this.Task = task; this.SetEncoder(task.VideoEncoder); this.AdvancedOptionsString = task.AdvancedEncoderOptions; }
/// <summary> /// Generate the Command Line Arguments for the Filters Tab /// </summary> /// <param name="task"> /// The encode task. /// </param> /// <returns> /// A Cli Query as a string /// </returns> private static string FiltersQuery(EncodeTask task) { string query = string.Empty; switch (task.Detelecine) // DeTelecine { case Detelecine.Off: query += string.Empty; break; case Detelecine.Default: query += " --detelecine"; break; case Detelecine.Custom: query += string.Format(" --detelecine=\"{0}\"", task.CustomDetelecine); break; default: query += string.Empty; break; } switch (task.Decomb) // Decomb { case Decomb.Off: query += string.Empty; break; case Decomb.Default: query += " --decomb"; break; case Decomb.Custom: query += string.Format(" --decomb=\"{0}\"", task.CustomDecomb); break; case Decomb.Fast: query += " --decomb=\"fast\""; break; case Decomb.Bob: query += " --decomb=\"bob\""; break; default: query += string.Empty; break; } switch (task.Deinterlace) // DeInterlace { case Deinterlace.Fast: query += " --deinterlace=\"fast\""; break; case Deinterlace.Slow: query += " --deinterlace=\"slow\""; break; case Deinterlace.Slower: query += " --deinterlace=\"slower\""; break; case Deinterlace.Custom: query += string.Format(" --deinterlace=\"{0}\"", task.CustomDeinterlace); break; case Deinterlace.Bob: query += " --deinterlace=\"bob\""; break; default: query += string.Empty; break; } switch (task.Denoise) // Denoise { case Denoise.Weak: query += " --denoise=\"weak\""; break; case Denoise.Medium: query += " --denoise=\"medium\""; break; case Denoise.Strong: query += " --denoise=\"strong\""; break; case Denoise.Custom: query += string.Format(" --denoise=\"{0}\"", task.CustomDenoise); break; default: query += string.Empty; break; } if (task.Deblock != 0) { query += string.Format(" --deblock={0}", task.Deblock); } if (task.Grayscale) { query += " -g "; } return(query); }
/// <summary> /// Takes in a query which can be in any order and parses it. /// All varibles are then set so they can be used elsewhere. /// </summary> /// <param name="input">A ClI Query</param> /// <returns>A Parsed Query</returns> public static EncodeTask Parse(string input) { var parsed = new EncodeTask(); #region Regular Expressions // Source Match title = Regex.Match(input, @"-t ([0-9]*)"); Match chapters = Regex.Match(input, @"-c ([0-9-]*)"); // Output Settings Match format = Regex.Match(input, @"-f ([a-zA-Z0-9]*)"); Match grayscale = Regex.Match(input, @" -g"); Match largerMp4 = Regex.Match(input, @" -4"); Match ipodAtom = Regex.Match(input, @" -I"); // Picture Settings Tab Match width = Regex.Match(input, @"-w ([0-9]*)"); Match height = Regex.Match(input, @"-l ([0-9]*)"); Match maxWidth = Regex.Match(input, @"-X ([0-9]*)"); Match maxHeight = Regex.Match(input, @"-Y ([0-9]*)"); Match crop = Regex.Match(input, @"--crop ([0-9]*):([0-9]*):([0-9]*):([0-9]*)"); Match looseAnamorphic = Regex.Match(input, @"--loose-anamorphic"); Match strictAnamorphic = Regex.Match(input, @"--strict-anamorphic"); Match customAnamorphic = Regex.Match(input, @"--custom-anamorphic"); Match keepDisplayAsect = Regex.Match(input, @"--keep-display-aspect"); Match displayWidth = Regex.Match(input, @"--display-width ([0-9]*)"); Match pixelAspect = Regex.Match(input, @"--pixel-aspect ([0-9]*):([0-9]*)"); Match modulus = Regex.Match(input, @"--modulus ([0-9]*)"); // Picture Settings - Filters Match decomb = Regex.Match(input, @" --decomb"); Match decombValue = Regex.Match(input, @" --decomb=\""([a-zA-Z0-9.:]*)\"""); Match deinterlace = Regex.Match(input, @"--deinterlace=\""([a-zA-Z0-9.:]*)\"""); Match denoise = Regex.Match(input, @"--denoise=\""([a-zA-Z0-9.:]*)\"""); Match deblock = Regex.Match(input, @"--deblock=([0-9:]*)"); Match detelecine = Regex.Match(input, @"--detelecine"); Match detelecineValue = Regex.Match(input, @" --detelecine=\""([a-zA-Z0-9.:]*)\"""); // Video Settings Tab Match videoEncoder = Regex.Match(input, @"-e ([a-zA-Z0-9]*)"); Match videoFramerate = Regex.Match(input, @"-r ([0-9.]*)"); Match videoBitrate = Regex.Match(input, @"-b ([0-9]*)"); Match videoQuality = Regex.Match(input, @"-q ([0-9.]*)"); Match twoPass = Regex.Match(input, @" -2"); Match turboFirstPass = Regex.Match(input, @" -T"); Match optimizeMP4 = Regex.Match(input, @" -O"); Match pfr = Regex.Match(input, @" --pfr"); Match vfr = Regex.Match(input, @" --vfr"); Match cfr = Regex.Match(input, @" --cfr"); // Audio Settings Tab Match noAudio = Regex.Match(input, @"-a none"); Match audioTracks = Regex.Match(input, @"-a ([0-9,]*)"); Match audioTrackMixes = Regex.Match(input, @"-6 ([0-9a-zA-Z,]*)"); Match audioEncoders = Regex.Match(input, @"-E ([a-zA-Z0-9+,:]*)"); Match audioBitrates = Regex.Match(input, @"-B ([0-9a-zA-Z,]*)"); // Auto = a-z Match audioSampleRates = Regex.Match(input, @"-R ([0-9a-zA-Z.,]*)"); // Auto = a-z Match drcValues = Regex.Match(input, @"-D ([0-9.,]*)"); // Chapters Tab Match chapterMarkers = Regex.Match(input, @" -m"); Match chapterMarkersFileMode = Regex.Match(input, @"--markers"); // Advanced Tab Match advanced = Regex.Match(input, @"-x ([.,/a-zA-Z0-9=:-]*)"); #endregion #region Set Varibles try { #region Source Tab if (title.Success) { parsed.Title = int.Parse(title.ToString().Replace("-t ", string.Empty)); } if (chapters.Success) { parsed.PointToPointMode = PointToPointMode.Chapters; string[] actTitles = chapters.ToString().Replace("-c ", string.Empty).Split('-'); parsed.StartPoint = int.Parse(actTitles[0]); if (actTitles.Length > 1) { parsed.EndPoint = int.Parse(actTitles[1]); } if ((parsed.StartPoint == 1) && (parsed.EndPoint == 0)) { parsed.EndPoint = parsed.StartPoint; } } #endregion #region Output Settings if (format.Success) { parsed.OutputFormat = Converters.GetFileFormat(format.Groups[1].ToString()); } parsed.LargeFile = largerMp4.Success; parsed.IPod5GSupport = ipodAtom.Success; parsed.OptimizeMP4 = optimizeMP4.Success; #endregion #region Picture Tab if (width.Success) { parsed.Width = int.Parse(width.Groups[0].Value.Replace("-w ", string.Empty)); } if (height.Success) { parsed.Height = int.Parse(height.Groups[0].Value.Replace("-l ", string.Empty)); } if (maxWidth.Success) { parsed.MaxWidth = int.Parse(maxWidth.Groups[0].Value.Replace("-X ", string.Empty)); } if (maxHeight.Success) { parsed.MaxHeight = int.Parse(maxHeight.Groups[0].Value.Replace("-Y ", string.Empty)); } if (crop.Success) { try { string values = crop.ToString().Replace("--crop ", string.Empty); string[] actCropValues = values.Split(':'); parsed.Cropping = new Cropping( int.Parse(actCropValues[0]), int.Parse(actCropValues[1]), int.Parse(actCropValues[2]), int.Parse(actCropValues[3])); } catch (Exception) { // No need to do anything. } } if (strictAnamorphic.Success) { parsed.Anamorphic = Anamorphic.Strict; } else if (looseAnamorphic.Success) { parsed.Anamorphic = Anamorphic.Loose; } else if (customAnamorphic.Success) { parsed.Anamorphic = Anamorphic.Custom; } else { parsed.Anamorphic = Anamorphic.None; } parsed.KeepDisplayAspect = keepDisplayAsect.Success; if (displayWidth.Success) { parsed.DisplayWidth = double.Parse(displayWidth.Groups[0].Value.Replace("--display-width ", string.Empty), Culture); } if (pixelAspect.Success) { parsed.PixelAspectX = int.Parse(pixelAspect.Groups[1].Value.Replace("--pixel-aspect ", string.Empty)); } if (pixelAspect.Success && pixelAspect.Groups.Count >= 3) { parsed.PixelAspectY = int.Parse(pixelAspect.Groups[2].Value.Replace("--pixel-aspect ", string.Empty)); } if (modulus.Success) { parsed.Modulus = int.Parse(modulus.Groups[0].Value.Replace("--modulus ", string.Empty)); } #endregion #region Filters parsed.Decomb = Decomb.Off; if (decomb.Success) { parsed.Decomb = Decomb.Default; if (decombValue.Success) { parsed.CustomDecomb = decombValue.ToString().Replace("--decomb=", string.Empty).Replace("\"", string.Empty); } } parsed.Deinterlace = Deinterlace.Off; if (deinterlace.Success) { switch (deinterlace.ToString().Replace("--deinterlace=", string.Empty).Replace("\"", string.Empty).ToLower()) { case "fast": parsed.Deinterlace = Deinterlace.Fast; break; case "slow": parsed.Deinterlace = Deinterlace.Slow; break; case "slower": parsed.Deinterlace = Deinterlace.Slower; break; case "slowest": parsed.Deinterlace = Deinterlace.Slowest; break; default: parsed.Deinterlace = Deinterlace.Custom; parsed.CustomDeinterlace = deinterlace.ToString().Replace("--deinterlace=", string.Empty).Replace("\"", string.Empty).ToLower(); break; } } parsed.Denoise = Denoise.Off; if (denoise.Success) { switch (denoise.ToString().Replace("--denoise=", string.Empty).Replace("\"", string.Empty)) { case "weak": parsed.Denoise = Denoise.Weak; break; case "medium": parsed.Denoise = Denoise.Medium; break; case "strong": parsed.Denoise = Denoise.Strong; break; default: parsed.Denoise = Denoise.Custom; parsed.CustomDenoise = denoise.ToString().Replace("--denoise=", string.Empty).Replace("\"", string.Empty); break; } } parsed.Deblock = 0; if (deblock.Success) { int dval; int.TryParse(deblock.ToString().Replace("--deblock=", string.Empty), out dval); parsed.Deblock = dval; } parsed.Detelecine = Detelecine.Off; if (detelecine.Success) { parsed.Detelecine = Detelecine.Default; if (detelecineValue.Success) { parsed.CustomDetelecine = detelecineValue.ToString().Replace("--detelecine=", string.Empty).Replace("\"", string.Empty); parsed.Detelecine = Detelecine.Custom; } } #endregion #region Video Settings Tab parsed.VideoEncoder = Converters.GetVideoEncoder(videoEncoder.ToString().Replace("-e ", string.Empty)); if (videoFramerate.Success) { double fps; double.TryParse(videoFramerate.Groups[1].ToString(), out fps); parsed.Framerate = fps; } if (pfr.Success) { parsed.FramerateMode = FramerateMode.PFR; } else if (cfr.Success) { parsed.FramerateMode = FramerateMode.CFR; } else { parsed.FramerateMode = FramerateMode.VFR; // Default to VFR } parsed.Grayscale = grayscale.Success; parsed.TwoPass = twoPass.Success; parsed.TurboFirstPass = turboFirstPass.Success; if (videoBitrate.Success) { parsed.VideoEncodeRateType = VideoEncodeRateMode.AverageBitrate; parsed.VideoBitrate = int.Parse(videoBitrate.ToString().Replace("-b ", string.Empty)); } if (videoQuality.Success) { float quality = float.Parse(videoQuality.ToString().Replace("-q ", string.Empty), Culture); parsed.Quality = quality; } #endregion #region Audio Tab // Find out how many tracks we need to add by checking how many encoders or audio tracks are selected. int encoderCount = 0; if (audioEncoders.Success) { string[] audioDataCounters = audioEncoders.ToString().Replace("-E ", string.Empty).Split(','); encoderCount = audioDataCounters.Length; } // Get the data from the regular expression results string[] trackData = null; string[] trackMixes = null; string[] trackEncoders = null; string[] trackBitrates = null; string[] trackSamplerates = null; string[] trackDRCvalues = null; if (audioTracks.Success) { trackData = audioTracks.ToString().Replace("-a ", string.Empty).Split(','); } if (audioTrackMixes.Success) { trackMixes = audioTrackMixes.ToString().Replace("-6 ", string.Empty).Split(','); } if (audioEncoders.Success) { trackEncoders = audioEncoders.ToString().Replace("-E ", string.Empty).Split(','); } if (audioBitrates.Success) { trackBitrates = audioBitrates.ToString().Replace("-B ", string.Empty).Split(','); } if (audioSampleRates.Success) { trackSamplerates = audioSampleRates.ToString().Replace("-R ", string.Empty).Split(','); } if (drcValues.Success) { trackDRCvalues = drcValues.ToString().Replace("-D ", string.Empty).Split(','); } // Create new Audio Track Classes and store them in the ArrayList List <AudioTrack> allAudioTrackInfo = new List <AudioTrack>(); for (int x = 0; x < encoderCount; x++) { AudioTrack track = new AudioTrack(); if (trackData != null) { if (trackData.Length >= (x + 1)) // Audio Track { track.Track = int.Parse(trackData[x].Trim()); } } if (trackMixes != null) { if (trackMixes.Length >= (x + 1)) // Audio Mix { track.MixDown = Converters.GetAudioMixDown(Converters.GetMixDown(trackMixes[x].Trim())); } } if (trackEncoders != null) { if (trackEncoders.Length >= (x + 1)) // Audio Mix { track.Encoder = Converters.GetAudioEncoderFromCliString(trackEncoders[x].Trim()); } } if (trackBitrates != null) { if (trackBitrates.Length >= (x + 1)) // Audio Encoder { track.Bitrate = int.Parse(trackBitrates[x].Trim() == "auto" ? "0" : trackBitrates[x].Trim()); } } if (trackSamplerates != null) { if (trackSamplerates.Length >= (x + 1)) // Audio SampleRate { track.SampleRate = double.Parse(trackSamplerates[x].Replace("Auto", "0").Trim(), Culture); } } if (trackDRCvalues != null) { if (trackDRCvalues.Length >= (x + 1)) // Audio DRC Values { track.DRC = double.Parse(trackDRCvalues[x].Trim(), Culture); } } allAudioTrackInfo.Add(track); } parsed.AudioTracks = allAudioTrackInfo; #endregion #region Chapters Tab if (chapterMarkersFileMode.Success || chapterMarkers.Success) { parsed.IncludeChapterMarkers = true; } #endregion #region Advanced and other if (advanced.Success) { parsed.AdvancedEncoderOptions = advanced.ToString().Replace("-x ", string.Empty); } #endregion } catch (Exception exc) { throw new Exception("An error has occured in the QueryParser Utility.", exc); } #endregion return(parsed); }
/// <summary> /// Generate the Command Line Arguments for the Video Settings Tab /// </summary> /// <param name="task"> /// The encode task. /// </param> /// <returns> /// A Cli Query as a string /// </returns> private static string VideoSettingsQuery(EncodeTask task) { string query = string.Empty; switch (task.VideoEncoder) { case VideoEncoder.FFMpeg: query += " -e ffmpeg4"; break; case VideoEncoder.FFMpeg2: query += " -e ffmpeg2"; break; case VideoEncoder.X264: query += " -e x264"; break; case VideoEncoder.Theora: query += " -e theora"; break; default: query += " -e x264"; break; } switch (task.VideoEncodeRateType) { case VideoEncodeRateType.AverageBitrate: if (task.VideoBitrate.HasValue) { query += string.Format(" -b {0}", task.VideoBitrate.Value); } break; case VideoEncodeRateType.ConstantQuality: double value; switch (task.VideoEncoder) { case VideoEncoder.FFMpeg: case VideoEncoder.FFMpeg2: query += string.Format(" -q {0}", task.Quality.Value.ToString(CultureInfo.InvariantCulture)); break; case VideoEncoder.X264: query += string.Format(" -q {0}", task.Quality.Value.ToString(CultureInfo.InvariantCulture)); break; case VideoEncoder.Theora: query += string.Format(" -q {0}", task.Quality.Value.ToString(CultureInfo.InvariantCulture)); break; } break; } if (task.TwoPass) { query += " -2 "; } if (task.TurboFirstPass) { query += " -T "; } if (task.Framerate.HasValue) { query += string.Format(" -r {0}", task.Framerate); } switch (task.FramerateMode) { case FramerateMode.CFR: query += " --cfr"; break; case FramerateMode.VFR: query += " --vfr"; break; case FramerateMode.PFR: query += " --pfr"; break; default: query += " --vfr"; break; } return(query); }
/// <summary> /// Setup this tab for the specified preset. /// </summary> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetPreset(Preset preset, EncodeTask task) { this.Task = task; if (preset == null || preset.Task == null) { return; } this.SelectedVideoEncoder = preset.Task.VideoEncoder; this.SelectedFramerate = preset.Task.Framerate.HasValue ? preset.Task.Framerate.Value.ToString(CultureInfo.InvariantCulture) : SameAsSource; this.IsConstantQuantity = preset.Task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality; switch (preset.Task.FramerateMode) { case FramerateMode.CFR: this.IsConstantFramerate = true; break; case FramerateMode.VFR: this.IsVariableFramerate = true; this.ShowPeakFramerate = false; break; case FramerateMode.PFR: this.IsPeakFramerate = true; this.ShowPeakFramerate = true; break; } double cqStep = userSettingService.GetUserSetting <double>(UserSettingConstants.X264Step); double rfValue = 0; this.SetQualitySliderBounds(); switch (this.SelectedVideoEncoder) { case VideoEncoder.FFMpeg: case VideoEncoder.FFMpeg2: if (preset.Task.Quality.HasValue) { int cq; int.TryParse(preset.Task.Quality.Value.ToString(CultureInfo.InvariantCulture), out cq); this.RF = 32 - cq; } break; case VideoEncoder.X264: double multiplier = 1.0 / cqStep; if (preset.Task.Quality.HasValue) { rfValue = preset.Task.Quality.Value * multiplier; } this.RF = this.QualityMax - (int)Math.Round(rfValue, 0); break; case VideoEncoder.Theora: if (preset.Task.Quality.HasValue) { this.RF = (int)preset.Task.Quality.Value; } break; } this.Task.TwoPass = preset.Task.TwoPass; this.Task.TurboFirstPass = preset.Task.TurboFirstPass; this.Task.VideoBitrate = preset.Task.VideoBitrate; this.NotifyOfPropertyChange(() => this.Task); if (preset.Task != null) { this.SetEncoder(preset.Task.VideoEncoder); this.X264PresetValue = preset.Task.VideoEncoder == VideoEncoder.X264 ? (int)preset.Task.X264Preset : (int)x264Preset.Medium; this.H264Profile = preset.Task.VideoEncoder == VideoEncoder.X264 ? preset.Task.H264Profile : x264Profile.None; this.X264Tune = preset.Task.VideoEncoder == VideoEncoder.X264 ? preset.Task.X264Tune : x264Tune.None; this.H264Level = preset.Task.VideoEncoder == VideoEncoder.X264 ? preset.Task.H264Level : "Auto"; this.FastDecode = preset.Task.VideoEncoder == VideoEncoder.X264 && preset.Task.FastDecode; this.ExtraArguments = preset.Task.ExtraAdvancedArguments; this.UseAdvancedTab = !string.IsNullOrEmpty(preset.Task.AdvancedEncoderOptions) && this.ShowAdvancedTab; } }
/// <summary> /// Generate the Command Line Arguments for the Audio Settings Tab /// </summary> /// <param name="task"> /// The encode task. /// </param> /// <returns> /// A Cli Query as a string /// </returns> private static string AudioSettingsQuery(EncodeTask task) { string query = string.Empty; ObservableCollection <AudioTrack> audioTracks = task.AudioTracks; List <int> tracks = new List <int>(); List <AudioEncoder> codecs = new List <AudioEncoder>(); List <Mixdown> mixdowns = new List <Mixdown>(); List <double> samplerates = new List <double>(); List <int> bitrates = new List <int>(); List <double> drcs = new List <double>(); List <double> gains = new List <double>(); // No Audio if (audioTracks.Count == 0) { query += " -a none "; } // Gather information about each audio track and store them in the declared lists. foreach (AudioTrack track in audioTracks) { if (track.Track == null) { continue; } tracks.Add(track.Track.Value); // Audio Codec (-E) codecs.Add(track.Encoder); // Audio Mixdown (-6) mixdowns.Add(track.IsPassthru ? Mixdown.None : track.MixDown); // Sample Rate (-R) samplerates.Add(track.IsPassthru ? 0 : track.SampleRate); // Audio Bitrate (-B) bitrates.Add(track.IsPassthru ? 0 : track.Bitrate); // DRC (-D) drcs.Add(track.IsPassthru ? 0 : track.DRC); // Gain (--gain) gains.Add(track.IsPassthru ? 0 : track.Gain); } // Audio Track (-a) string audioItems = string.Empty; bool firstLoop = true; foreach (int item in tracks) { if (firstLoop) { audioItems = item.ToString(); firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -a " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Audio Codec (-E) foreach (AudioEncoder item in codecs) { if (firstLoop) { audioItems = Converters.GetCliAudioEncoder(item); firstLoop = false; } else { audioItems += "," + Converters.GetCliAudioEncoder(item); } } if (audioItems.Trim() != String.Empty) { query += " -E " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Audio Mixdown (-6) foreach (Mixdown item in mixdowns) { if (firstLoop) { audioItems = Converters.GetCliMixDown(item); firstLoop = false; } else { audioItems += "," + Converters.GetCliMixDown(item); } } if (audioItems.Trim() != String.Empty) { query += " -6 " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Sample Rate (-R) foreach (double item in samplerates) { string add = (item == 0.0) ? "Auto" : item.ToString(); if (firstLoop) { audioItems = add; firstLoop = false; } else { audioItems += "," + add; } } if (audioItems.Trim() != String.Empty) { query += " -R " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // Audio Bitrate (-B) foreach (int item in bitrates) { if (firstLoop) { audioItems = item.ToString(); firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -B " + audioItems; } firstLoop = true; audioItems = string.Empty; // Reset for another pass. // DRC (-D) foreach (var itm in drcs) { string item = itm.ToString(new CultureInfo("en-US")); if (firstLoop) { audioItems = item; firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " -D " + audioItems; } audioItems = string.Empty; // Reset for another pass. firstLoop = true; // Gain (--gain) foreach (var itm in gains) { string item = itm.ToString(new CultureInfo("en-US")); if (firstLoop) { audioItems = item; firstLoop = false; } else { audioItems += "," + item; } } if (audioItems.Trim() != String.Empty) { query += " --gain " + audioItems; } // Passthru Settings if (task.AllowedPassthruOptions != null && task.AllowedPassthruOptions.IsEnabled) { string fallbackEncoders = string.Empty; if (task.AllowedPassthruOptions.AudioAllowAACPass) { fallbackEncoders += "aac"; } if (task.AllowedPassthruOptions.AudioAllowAC3Pass) { fallbackEncoders += string.IsNullOrEmpty(fallbackEncoders) ? "ac3" : ",ac3"; } if (task.AllowedPassthruOptions.AudioAllowDTSHDPass) { fallbackEncoders += string.IsNullOrEmpty(fallbackEncoders) ? "dtshd" : ",dtshd"; } if (task.AllowedPassthruOptions.AudioAllowDTSPass) { fallbackEncoders += string.IsNullOrEmpty(fallbackEncoders) ? "dts" : ",dts"; } if (task.AllowedPassthruOptions.AudioAllowMP3Pass) { fallbackEncoders += string.IsNullOrEmpty(fallbackEncoders) ? "mp3" : ",mp3"; } if (!string.IsNullOrEmpty(fallbackEncoders)) { query += string.Format(" --audio-copy-mask {0}", fallbackEncoders); } query += string.Format(" --audio-fallback {0}", Converters.GetCliAudioEncoder(task.AllowedPassthruOptions.AudioEncoderFallback)); } return(query); }
/// <summary> /// Setup this tab for the specified preset. /// </summary> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetPreset(Preset preset, EncodeTask task) { this.Task.PropertyChanged -= this.Task_PropertyChanged; this.Task = task; this.Task.PropertyChanged += this.Task_PropertyChanged; this.AdvancedOptionsString = preset.Task.AdvancedEncoderOptions; }
/// <summary> /// Generate the Command Line Arguments for the Subtitles Tab /// </summary> /// <param name="task"> /// The encode task. /// </param> /// <returns> /// A Cli Query as a string /// </returns> private static string SubtitlesQuery(EncodeTask task) { string query = string.Empty; if (task.SubtitleTracks.Count != 0) { // BitMap and CC's string subtitleTracks = String.Empty; string subtitleForced = String.Empty; string subtitleBurn = String.Empty; string subtitleDefault = String.Empty; // SRT string srtFile = String.Empty; string srtCodeset = String.Empty; string srtOffset = String.Empty; string srtLang = String.Empty; string srtDefault = String.Empty; int srtCount = 0; int subCount = 0; // Languages IDictionary <string, string> langMap = LanguageUtilities.MapLanguages(); foreach (SubtitleTrack item in task.SubtitleTracks) { string itemToAdd; if (item.IsSrtSubtitle) // We have an SRT file { srtCount++; // SRT track id. srtLang += srtLang == string.Empty ? langMap[item.SrtLang] : "," + langMap[item.SrtLang]; srtCodeset += srtCodeset == string.Empty ? item.SrtCharCode : "," + item.SrtCharCode; if (item.Default) { srtDefault = srtCount.ToString(); } itemToAdd = item.SrtPath; srtFile += srtFile == string.Empty ? itemToAdd : "," + itemToAdd; itemToAdd = item.SrtOffset.ToString(); srtOffset += srtOffset == string.Empty ? itemToAdd : "," + itemToAdd; } else // We have Bitmap or CC { subCount++; // Find --subtitle <string> if (item.SourceTrack.SubtitleType == SubtitleType.ForeignAudioSearch) { itemToAdd = "scan"; } else { string[] tempSub = item.Track.Split(' '); itemToAdd = tempSub[0]; } subtitleTracks += subtitleTracks == string.Empty ? itemToAdd : "," + itemToAdd; // Find --subtitle-forced if (item.Forced) { subtitleForced += subtitleForced == string.Empty ? subCount.ToString() : "," + subCount; } // Find --subtitle-burn if (item.Burned) { subtitleBurn = subCount.ToString(); } // Find --subtitle-default if (item.Default) { subtitleDefault = subCount.ToString(); } } } // Build The CLI Subtitles Query if (subtitleTracks != string.Empty) { query += " --subtitle " + subtitleTracks; if (subtitleForced != string.Empty) { query += " --subtitle-forced=" + subtitleForced; } if (subtitleBurn != string.Empty) { query += " --subtitle-burn=" + subtitleBurn; } if (subtitleDefault != string.Empty) { query += " --subtitle-default=" + subtitleDefault; } } if (srtFile != string.Empty) // SRTs { query += " --srt-file " + "\"" + srtFile + "\""; if (srtCodeset != string.Empty) { query += " --srt-codeset " + srtCodeset; } if (srtOffset != string.Empty) { query += " --srt-offset " + srtOffset; } if (srtLang != string.Empty) { query += " --srt-lang " + srtLang; } if (srtDefault != string.Empty) { query += " --srt-default=" + srtDefault; } } } return(query); }
/// <summary> /// Get a Preview image for the current job and preview number. /// </summary> /// <param name="job"> /// The job. /// </param> /// <param name="preview"> /// The preview. /// </param> /// <param name="configuraiton"> /// The configuraiton. /// </param> /// <returns> /// The <see cref="BitmapImage"/>. /// </returns> public BitmapImage GetPreview(EncodeTask job, int preview, HBConfiguration configuraiton) { if (this.instance == null) { return null; } BitmapImage bitmapImage = null; try { PreviewSettings settings = new PreviewSettings(job); bitmapImage = this.instance.GetPreview(settings, preview); } catch (AccessViolationException e) { Console.WriteLine(e); } return bitmapImage; }
/// <summary> /// Add the encode settings to the preset /// </summary> /// <param name="xmlWriter"> /// The xml writer. /// </param> /// <param name="parsed"> /// The parsed. /// </param> /// <param name="preset"> /// The preset. /// </param> /// <param name="build"> /// The build. /// </param> private static void AddEncodeSettings(XmlTextWriter xmlWriter, EncodeTask parsed, Preset preset, string build) { AddEncodeElement(xmlWriter, "AudioAllowAACPass", "integer", getNullBoolValue(parsed.AllowedPassthruOptions.AudioAllowAACPass)); AddEncodeElement(xmlWriter, "AudioAllowAC3Pass", "integer", getNullBoolValue(parsed.AllowedPassthruOptions.AudioAllowAC3Pass)); AddEncodeElement(xmlWriter, "AudioAllowDTSHDPass", "integer", getNullBoolValue(parsed.AllowedPassthruOptions.AudioAllowDTSHDPass)); AddEncodeElement(xmlWriter, "AudioAllowDTSPass", "integer", getNullBoolValue(parsed.AllowedPassthruOptions.AudioAllowDTSPass)); AddEncodeElement(xmlWriter, "AudioAllowMP3Pass", "integer", getNullBoolValue(parsed.AllowedPassthruOptions.AudioAllowMP3Pass)); AddEncodeElement(xmlWriter, "AudioEncoderFallback", "string", EnumHelper <AudioEncoder> .GetDisplay(parsed.AllowedPassthruOptions.AudioEncoderFallback)); AddEncodeElement(xmlWriter, "ChapterMarkers", "integer", parsed.IncludeChapterMarkers ? "1" : "0"); AddEncodeElement(xmlWriter, "Default", "integer", "0"); AddEncodeElement(xmlWriter, "FileFormat", "string", (parsed.OutputFormat == OutputFormat.Mp4 || parsed.OutputFormat == OutputFormat.M4V) ? "MP4 file" : "MKV file"); AddBooleanElement(xmlWriter, "Folder", false); AddEncodeElement(xmlWriter, "Mp4HttpOptimize", "integer", parsed.OptimizeMP4 ? "1" : "0"); AddEncodeElement(xmlWriter, "Mp4LargeFile", "integer", parsed.LargeFile ? "1" : "0"); AddEncodeElement(xmlWriter, "Mp4iPodCompatible", "integer", parsed.IPod5GSupport ? "1" : "0"); AddEncodeElement(xmlWriter, "PictureAutoCrop", "integer", "1"); AddEncodeElement(xmlWriter, "PictureBottomCrop", "integer", parsed.Cropping.Bottom.ToString()); // Filters AddEncodeElement(xmlWriter, "PictureDeblock", "integer", parsed.Deblock.ToString()); switch (parsed.Decomb) { case Decomb.Off: AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "0"); AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", string.Empty); break; case Decomb.Default: AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "2"); AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", string.Empty); break; case Decomb.Fast: AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "3"); AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", string.Empty); break; case Decomb.Bob: AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "4"); AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", string.Empty); break; case Decomb.Custom: AddEncodeElement(xmlWriter, "PictureDecomb", "integer", "1"); AddEncodeElement(xmlWriter, "PictureDecombCustom", "string", parsed.CustomDecomb); break; } AddEncodeElement(xmlWriter, "PictureDecombDeinterlace", "integer", parsed.Decomb != Decomb.Off ? "0" : "1"); switch (parsed.Deinterlace) { case Deinterlace.Off: AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "0"); AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty); break; case Deinterlace.Fast: AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "2"); AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty); break; case Deinterlace.Slow: AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "3"); AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty); break; case Deinterlace.Slower: AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "4"); AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty); break; case Deinterlace.Bob: AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "5"); AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", string.Empty); break; case Deinterlace.Custom: AddEncodeElement(xmlWriter, "PictureDeinterlace", "integer", "1"); AddEncodeElement(xmlWriter, "PictureDeinterlaceCustom", "string", parsed.CustomDeinterlace); break; } switch (parsed.Denoise) { case Denoise.Off: AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "0"); AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty); break; case Denoise.Weak: AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "2"); AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty); break; case Denoise.Medium: AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "3"); AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty); break; case Denoise.Strong: AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "4"); AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", string.Empty); break; case Denoise.Custom: AddEncodeElement(xmlWriter, "PictureDenoise", "integer", "1"); AddEncodeElement(xmlWriter, "PictureDenoiseCustom", "string", parsed.CustomDenoise); break; } int detelecine = 0; switch (parsed.Detelecine) { case Detelecine.Off: detelecine = 0; break; case Detelecine.Default: detelecine = 2; break; case Detelecine.Custom: detelecine = 1; break; } AddEncodeElement(xmlWriter, "PictureDetelecine", "integer", detelecine.ToString()); AddEncodeElement(xmlWriter, "PictureDetelecineCustom", "string", detelecine == 1 ? parsed.CustomDecomb : string.Empty); // Picture Settings AddEncodeElement(xmlWriter, "PictureHeight", "integer", parsed.Height.ToString()); AddEncodeElement(xmlWriter, "PictureKeepRatio", "integer", parsed.KeepDisplayAspect ? "1" : "0"); AddEncodeElement(xmlWriter, "PictureLeftCrop", "integer", parsed.Cropping.Left.ToString()); AddEncodeElement(xmlWriter, "PictureModulus", "integer", parsed.Modulus.ToString()); AddEncodeElement(xmlWriter, "PicturePAR", "integer", ((int)parsed.Anamorphic).ToString()); AddEncodeElement(xmlWriter, "PictureRightCrop", "integer", parsed.Cropping.Right.ToString()); AddEncodeElement(xmlWriter, "PictureTopCrop", "integer", parsed.Cropping.Top.ToString()); AddEncodeElement(xmlWriter, "PictureWidth", "integer", parsed.Width.ToString()); // Preset Information AddEncodeElement(xmlWriter, "PresetBuildNumber", "string", build); AddEncodeElement(xmlWriter, "PresetDescription", "string", "No Description"); AddEncodeElement(xmlWriter, "PresetName", "string", preset.Name); AddEncodeElement(xmlWriter, "Type", "integer", "1"); // 1 is user preset, 0 is built in // Preset Settings AddEncodeElement(xmlWriter, "UsesMaxPictureSettings", "integer", (parsed.MaxWidth != 0 || parsed.MaxHeight != 0) ? "1" : "0"); AddEncodeElement(xmlWriter, "UsesPictureFilters", "integer", "1"); AddEncodeElement(xmlWriter, "UsesPictureSettings", "integer", "2"); // Video Settings AddEncodeElement(xmlWriter, "VideoAvgBitrate", "string", parsed.VideoBitrate.ToString()); AddEncodeElement(xmlWriter, "VideoEncoder", "string", EnumHelper <VideoEncoder> .GetDisplay(parsed.VideoEncoder)); AddEncodeElement(xmlWriter, "VideoFramerate", "string", parsed.Framerate == null ? "Same as source" : parsed.Framerate.ToString()); AddEncodeElement(xmlWriter, "VideoFramerateMode", "string", parsed.FramerateMode.ToString().ToLower()); AddEncodeElement(xmlWriter, "VideoGrayScale", "integer", parsed.Grayscale ? "1" : "0"); AddEncodeElement(xmlWriter, "VideoQualitySlider", "real", parsed.Quality.ToString()); AddEncodeElement(xmlWriter, "h264Level", "string", parsed.H264Level); AddEncodeElement(xmlWriter, "x264OptionExtra", "string", parsed.AdvancedEncoderOptions); AddEncodeElement(xmlWriter, "x264Preset", "string", parsed.X264Preset.ToString().ToLower()); AddEncodeElement(xmlWriter, "h264Profile", "string", parsed.H264Profile.ToString().ToLower()); string tune = parsed.X264Tune.ToString().ToLower(); if (parsed.FastDecode) { tune = tune == "none" ? "fastdecode" : tune + ",fastdecode"; } AddEncodeElement(xmlWriter, "x264Tune", "string", tune); AddEncodeElement(xmlWriter, "x264UseAdvancedOptions", "integer", parsed.ShowAdvancedTab ? "1" : "0"); AddEncodeElement(xmlWriter, "QsvPreset", "string", parsed.QsvPreset.ToString()); int videoQualityType = 0; if (parsed.VideoBitrate != null) { videoQualityType = 1; } else if (parsed.Quality != null) { videoQualityType = 2; } AddEncodeElement(xmlWriter, "VideoQualityType", "integer", videoQualityType.ToString()); AddEncodeElement(xmlWriter, "VideoTargetSize", "string", string.Empty); AddEncodeElement(xmlWriter, "VideoTurboTwoPass", "integer", parsed.TurboFirstPass ? "1" : "0"); AddEncodeElement(xmlWriter, "VideoTwoPass", "integer", parsed.TwoPass ? "1" : "0"); // x264 string AddEncodeElement(xmlWriter, "x264Option", "string", parsed.AdvancedEncoderOptions); }
/// <summary> /// Setup this window for a new source /// </summary> /// <param name="source"> /// The source. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetSource(Source source, Title title, Preset preset, EncodeTask task) { this.CurrentTask = task; }
public void SetSource(Source scannedSource, Title selectedTitle, Preset currentPreset, EncodeTask encodeTask) { this.Source = scannedSource; this.CurrentTitle = selectedTitle; this.Task = encodeTask; this.UpdateDisplayedInfo(); this.SetPreviewControlVisibility(); }
/// <summary> /// The create destination. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Destination"/>. /// </returns> private static Destination CreateDestination(EncodeTask job) { Destination destination = new Destination { File = job.Destination, Mp4Options = new Mp4Options { IpodAtom = job.IPod5GSupport, Mp4Optimize = job.OptimizeMP4 }, ChapterMarkers = job.IncludeChapterMarkers, Mux = HBFunctions.hb_container_get_from_name(job.OutputFormat == OutputFormat.Mp4 ? "av_mp4" : "av_mkv"), // TODO tidy up. ChapterList = new List<ChapterList>() }; if (job.IncludeChapterMarkers) { foreach (ChapterMarker item in job.ChapterNames) { ChapterList chapter = new ChapterList { Name = item.ChapterName }; destination.ChapterList.Add(chapter); } } return destination; }
/// <summary> /// Setup this tab for the specified preset. /// </summary> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetPreset(Preset preset, EncodeTask task) { this.Task = task; this.currentPreset = preset; // Audio Behaviours this.SetupLanguages(preset); if (preset != null && preset.Task != null) { this.Task.AllowedPassthruOptions = new AllowedPassthru(preset.Task.AllowedPassthruOptions); this.SetupTracks(); } this.NotifyOfPropertyChange(() => this.Task); }
/// <summary> /// The create meta data. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Interop.Json.Encode.MetaData"/>. /// </returns> private static MetaData CreateMetaData(EncodeTask job) { MetaData metaData = new MetaData(); /* TODO NOT SUPPORTED YET. */ return metaData; }
/// <summary> /// Set the Source Title /// </summary> /// <param name="source"> /// The source. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetSource(Source source, Title title, Preset preset, EncodeTask task) { this.SourceTracks = title.AudioTracks; // Only reset the audio tracks if we have none, or if the task is null. if (this.Task == null) { this.SetPreset(preset, task); } // If there are no source tracks, clear the list, otherwise try to Auto-Select the correct tracks if (this.SourceTracks == null || !this.SourceTracks.Any()) { this.Task.AudioTracks.Clear(); } else { this.SetupTracks(); } // Force UI Updates this.NotifyOfPropertyChange(() => this.Task); }
/// <summary> /// The create source. /// </summary> /// <param name="job"> /// The job. /// </param> /// <param name="configuration"> /// The configuration. /// </param> /// <returns> /// The <see cref="Source"/>. /// </returns> private static Source CreateSource(EncodeTask job, HBConfiguration configuration) { Range range = new Range(); switch (job.PointToPointMode) { case PointToPointMode.Chapters: range.Type = "chapter"; range.End = job.EndPoint; range.Start = job.StartPoint; break; case PointToPointMode.Seconds: range.Type = "time"; range.Start = job.StartPoint * 90000; range.End = (job.EndPoint - job.StartPoint) * 90000; break; case PointToPointMode.Frames: range.Type = "frame"; range.Start = job.StartPoint; range.End = job.EndPoint; break; case PointToPointMode.Preview: range.Type = "preview"; range.Start = job.PreviewEncodeStartAt; range.SeekPoints = configuration.PreviewScanCount; range.End = job.PreviewEncodeDuration * 90000; break; } Source source = new Source { Title = job.Title, Range = range, Angle = job.Angle, Path = job.Source, }; return source; }
/// <summary> /// The create video. /// </summary> /// <param name="job"> /// The job. /// </param> /// <param name="configuration"> /// The configuration. /// </param> /// <returns> /// The <see cref="Video"/>. /// </returns> private static Video CreateVideo(EncodeTask job, HBConfiguration configuration) { Video video = new Video(); HBVideoEncoder videoEncoder = HandBrakeEncoderHelpers.VideoEncoders.FirstOrDefault(e => e.ShortName == ApplicationServices.Utilities.Converters.GetVideoEncoder(job.VideoEncoder)); Validate.NotNull(videoEncoder, "Video encoder " + job.VideoEncoder + " not recognized."); if (videoEncoder != null) { video.Encoder = videoEncoder.Id; } string advancedOptions = job.ShowAdvancedTab ? job.AdvancedEncoderOptions : string.Empty; if (!string.IsNullOrEmpty(advancedOptions)) { video.Options = advancedOptions; } else { video.Level = job.VideoLevel != null ? job.VideoLevel.ShortName : null; video.Options = job.ExtraAdvancedArguments; video.Preset = job.VideoPreset != null ? job.VideoPreset.ShortName : null; video.Profile = job.VideoProfile != null ? job.VideoProfile.ShortName : null; } if (job.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality) video.Quality = job.Quality; if (job.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate) { video.Bitrate = job.VideoBitrate; video.TwoPass = job.TwoPass; video.Turbo = job.TurboFirstPass; } if (job.VideoTunes != null && job.VideoTunes.Count > 0) { foreach (var item in job.VideoTunes) { video.Tune += string.IsNullOrEmpty(video.Tune) ? item.ShortName : "," + item.ShortName; } } video.OpenCL = configuration.ScalingMode == VideoScaler.BicubicCl; video.HWDecode = configuration.EnableDxva; video.QSV.Decode = !configuration.DisableQuickSyncDecoding; return video; }
/// <summary> /// Redraw the Queue window with the latest information about HandBrakes status /// </summary> private void RedrawQueue() { if (InvokeRequired) { BeginInvoke(new UpdateHandler(RedrawQueue)); return; } list_queue.Items.Clear(); ReadOnlyCollection <QueueTask> theQueue = queue.QueueManager.Queue; foreach (QueueTask queueItem in theQueue) { string qItem = queueItem.Query; EncodeTask parsed = QueryParserUtility.Parse(qItem); // Get the DVD Title string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString(); // Get the DVD Chapters string chapters; if (parsed.StartPoint == 0) { chapters = "Auto"; } else { chapters = parsed.StartPoint.ToString(); if (parsed.EndPoint != 0) { chapters = chapters + " - " + parsed.EndPoint; } } ListViewItem item = new ListViewItem { Tag = queueItem, Text = EnumHelper <QueueItemStatus> .GetDescription(queueItem.Status) }; item.SubItems.Add(title); item.SubItems.Add(chapters); // Chapters item.SubItems.Add(queueItem.Source); // Source item.SubItems.Add(queueItem.Destination); // Destination item.SubItems.Add(EnumHelper <VideoEncoder> .GetDisplay(parsed.VideoEncoder)); // Display The Audio Track Information string audio = string.Empty; foreach (AudioTrack track in parsed.AudioTracks) { if (audio != string.Empty) { audio += ", " + EnumHelper <AudioEncoder> .GetDisplay(track.Encoder); } else { audio = EnumHelper <AudioEncoder> .GetDisplay(track.Encoder); } } item.SubItems.Add(audio); // Audio list_queue.Items.Add(item); } }
/// <summary> /// The create audio. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Audio"/>. /// </returns> private static Audio CreateAudio(EncodeTask job) { Audio audio = new Audio(); List<uint> copyMaskList = new List<uint>(); if (job.AllowedPassthruOptions.AudioAllowAACPass) copyMaskList.Add(NativeConstants.HB_ACODEC_AAC_PASS); if (job.AllowedPassthruOptions.AudioAllowAC3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_AC3_PASS); if (job.AllowedPassthruOptions.AudioAllowDTSHDPass) copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_HD_PASS); if (job.AllowedPassthruOptions.AudioAllowDTSPass) copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_PASS); if (job.AllowedPassthruOptions.AudioAllowEAC3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_EAC3_PASS); if (job.AllowedPassthruOptions.AudioAllowFlacPass) copyMaskList.Add(NativeConstants.HB_ACODEC_FLAC_PASS); if (job.AllowedPassthruOptions.AudioAllowMP3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_MP3_PASS); if (job.AllowedPassthruOptions.AudioAllowTrueHDPass) copyMaskList.Add(NativeConstants.HB_ACODEC_TRUEHD_PASS); audio.CopyMask = copyMaskList.ToArray(); HBAudioEncoder audioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper<AudioEncoder>.GetShortName(job.AllowedPassthruOptions.AudioEncoderFallback)); audio.FallbackEncoder = audioEncoder.Id; audio.AudioList = new List<AudioList>(); foreach (AudioTrack item in job.AudioTracks) { HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(ApplicationServices.Utilities.Converters.GetCliAudioEncoder(item.Encoder) ); Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder); HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(ApplicationServices.Utilities.Converters.GetCliMixDown(item.MixDown)); Validate.NotNull(mixdown, "Unrecognized audio mixdown:" + ApplicationServices.Utilities.Converters.GetCliMixDown(item.MixDown)); AudioList audioTrack = new AudioList { Track = (item.Track.HasValue ? item.Track.Value : 0) - 1, DRC = item.DRC, Encoder = encoder.Id, Gain = item.Gain, Mixdown = mixdown.Id, NormalizeMixLevel = false, Samplerate = GetSampleRateRaw(item.SampleRate), Name = item.TrackName, }; if (!item.IsPassthru) { // TODO Impiment Quality and Compression. We only support bitrate right now. //if (item.EncodeRateType == AudioEncodeRateType.Quality) //{ // audioTrack.Quality = item.Quality; //} //if (item.EncodeRateType == AudioEncodeRateType.Compression) //{ // audioTrack.CompressionLevel = item.Compression; //} //if (item.EncodeRateType == AudioEncodeRateType.Bitrate) // { audioTrack.Bitrate = item.Bitrate; // } } audio.AudioList.Add(audioTrack); } return audio; }
/// <summary> /// Get an EncodeJob model for a LibHB Encode. /// </summary> /// <param name="task"> /// The task. /// </param> /// <param name="configuration"> /// The configuration. /// </param> /// <returns> /// An Interop.EncodeJob model. /// </returns> public static EncodeJob GetEncodeJob(EncodeTask task, HBConfiguration configuration) { // The current Job Configuration EncodeTask work = task; // Which will be converted to this EncodeJob Model. EncodeJob job = new EncodeJob(); // Audio Settings job.AudioEncodings = new List <AudioEncoding>(); foreach (AudioTrack track in work.AudioTracks) { AudioEncoding newTrack = new AudioEncoding { Bitrate = track.Bitrate, Drc = track.DRC, Gain = track.Gain, Encoder = Converters.GetCliAudioEncoder(track.Encoder), InputNumber = track.Track.HasValue ? track.Track.Value : 0, Mixdown = Converters.GetCliMixDown(track.MixDown), SampleRateRaw = GetSampleRateRaw(track.SampleRate), EncodeRateType = AudioEncodeRateType.Bitrate, Name = track.TrackName, IsPassthru = track.IsPassthru, }; job.AudioEncodings.Add(newTrack); } // Title Settings job.OutputPath = work.Destination; job.SourcePath = work.Source; job.Title = work.Title; // job.SourceType = work.Type; switch (work.PointToPointMode) { case PointToPointMode.Chapters: job.RangeType = VideoRangeType.Chapters; break; case PointToPointMode.Seconds: job.RangeType = VideoRangeType.Seconds; break; case PointToPointMode.Frames: job.RangeType = VideoRangeType.Frames; break; case PointToPointMode.Preview: job.RangeType = VideoRangeType.Preview; break; } if (work.PointToPointMode == PointToPointMode.Seconds) { job.SecondsEnd = work.EndPoint; job.SecondsStart = work.StartPoint; } if (work.PointToPointMode == PointToPointMode.Chapters) { job.ChapterStart = work.StartPoint; job.ChapterEnd = work.EndPoint; } if (work.PointToPointMode == PointToPointMode.Frames) { job.FramesEnd = work.EndPoint; job.FramesStart = work.StartPoint; } if (work.PointToPointMode == PointToPointMode.Preview) { job.StartAtPreview = work.PreviewEncodeStartAt.HasValue ? work.PreviewEncodeStartAt.Value + 1 : 1; job.SecondsEnd = work.PreviewEncodeDuration.HasValue ? work.PreviewEncodeDuration.Value : 30; job.SeekPoints = configuration.PreviewScanCount; } job.Angle = work.Angle; // Output Settings job.IPod5GSupport = work.IPod5GSupport; job.Optimize = work.OptimizeMP4; switch (work.OutputFormat) { case OutputFormat.Mp4: job.ContainerName = "av_mp4"; // TODO make part of enum. break; case OutputFormat.Mkv: job.ContainerName = "av_mkv"; // TODO make part of enum. break; } // Picture Settings job.Anamorphic = work.Anamorphic; job.Cropping = new Cropping { Top = work.Cropping.Top, Bottom = work.Cropping.Bottom, Left = work.Cropping.Left, Right = work.Cropping.Right }; job.DisplayWidth = work.DisplayWidth.HasValue ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString()) : 0; job.PixelAspectX = work.PixelAspectX; job.PixelAspectY = work.PixelAspectY; job.Height = work.Height.HasValue ? work.Height.Value : 0; job.KeepDisplayAspect = work.KeepDisplayAspect; job.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0; job.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0; job.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16; job.UseDisplayWidth = true; job.Width = work.Width.HasValue ? work.Width.Value : 0; // Filter Settings job.CustomDecomb = work.CustomDecomb; job.CustomDeinterlace = work.CustomDeinterlace; job.CustomDenoise = work.CustomDenoise; job.DenoisePreset = work.DenoisePreset.ToString().ToLower().Replace(" ", string.Empty); job.DenoiseTune = work.DenoiseTune.ToString().ToLower().Replace(" ", string.Empty); job.CustomDetelecine = work.CustomDetelecine; if (work.Deblock > 4) { job.Deblock = work.Deblock; } job.Decomb = work.Decomb; job.Deinterlace = work.Deinterlace; job.Denoise = work.Denoise; job.Detelecine = work.Detelecine; job.Grayscale = work.Grayscale; // Video Settings job.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0; job.ConstantFramerate = work.FramerateMode == FramerateMode.CFR; job.PeakFramerate = work.FramerateMode == FramerateMode.PFR; job.Quality = work.Quality.HasValue ? work.Quality.Value : 0; job.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0; job.VideoEncodeRateType = work.VideoEncodeRateType; job.VideoEncoder = Converters.GetVideoEncoder(work.VideoEncoder); job.TwoPass = work.TwoPass; job.TurboFirstPass = work.TurboFirstPass; if (work.VideoEncoder == VideoEncoder.X264 || work.VideoEncoder == VideoEncoder.X265 || work.VideoEncoder == VideoEncoder.QuickSync) { job.VideoPreset = work.VideoPreset.ShortName; job.VideoProfile = work.VideoProfile.ShortName; job.VideoLevel = work.VideoLevel.ShortName; if (work.VideoEncoder != VideoEncoder.QuickSync) { job.VideoTunes = new List <string>(); foreach (var item in work.VideoTunes) { job.VideoTunes.Add(item.ShortName); } } } // Chapter Markers job.IncludeChapterMarkers = work.IncludeChapterMarkers; job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList(); job.UseDefaultChapterNames = work.IncludeChapterMarkers; // Advanced Settings job.VideoOptions = work.ShowAdvancedTab ? work.AdvancedEncoderOptions : work.ExtraAdvancedArguments; // Subtitles job.Subtitles = new Subtitles { SourceSubtitles = new List <SourceSubtitle>(), SrtSubtitles = new List <SrtSubtitle>() }; foreach (SubtitleTrack track in work.SubtitleTracks) { if (track.IsSrtSubtitle) { job.Subtitles.SrtSubtitles.Add( new SrtSubtitle { CharacterCode = track.SrtCharCode, Default = track.Default, FileName = track.SrtPath, LanguageCode = track.SrtLang, Offset = track.SrtOffset, BurnedIn = track.Burned }); } else { if (track.SourceTrack != null) { job.Subtitles.SourceSubtitles.Add( new SourceSubtitle { BurnedIn = track.Burned, Default = track.Default, Forced = track.Forced, TrackNumber = track.SourceTrack.TrackNumber }); } } } return(job); }
/// <summary> /// Get a Preview image for the current job and preview number. /// </summary> /// <param name="job"> /// The job. /// </param> /// <param name="preview"> /// The preview. /// </param> /// <param name="configuraiton"> /// The configuraiton. /// </param> /// <returns> /// The <see cref="BitmapImage"/>. /// </returns> public BitmapImage GetPreview(EncodeTask job, int preview, HBConfiguration configuraiton) { if (this.instance == null) { return null; } BitmapImage bitmapImage = null; try { PreviewSettings settings = new PreviewSettings { Cropping = new Cropping(job.Cropping), MaxWidth = job.MaxWidth ?? 0, MaxHeight = job.MaxHeight ?? 0, KeepDisplayAspect = job.KeepDisplayAspect, TitleNumber = job.Title, Anamorphic = job.Anamorphic, Modulus = job.Modulus, Width = job.Width ?? 0, Height = job.Height ?? 0, PixelAspectX = job.PixelAspectX, PixelAspectY = job.PixelAspectY }; bitmapImage = this.instance.GetPreview(settings, preview); } catch (AccessViolationException e) { Console.WriteLine(e); } return bitmapImage; }
/// <summary> /// Update all the UI controls based on the encode task passed in. /// </summary> /// <param name="encodeTask"> /// The task. /// </param> public void UpdateTask(EncodeTask encodeTask) { this.Task = encodeTask; }
/// <summary> /// The update preview frame. /// </summary> /// <param name="task"> /// The task. /// </param> /// <param name="scannedSource"> /// The scanned Source. /// </param> public void UpdatePreviewFrame(EncodeTask task, Source scannedSource) { this.Task = task; this.UpdatePreviewFrame(); this.DisplayName = "Picture Preview"; this.Title = Properties.Resources.Preview; this.ScannedSource = scannedSource; }
/// <summary> /// Setup the window after a scan. /// </summary> /// <param name="source"> /// The source. /// </param> /// <param name="selectedTitle"> /// The selected title. /// </param> /// <param name="currentPreset"> /// The Current preset /// </param> /// <param name="encodeTask"> /// The task. /// </param> public void SetSource(Source source, Title selectedTitle, Preset currentPreset, EncodeTask encodeTask) { this.Task = encodeTask; }
/// <summary> /// Setup this window for a new source /// </summary> /// <param name="source"> /// The source. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="preset"> /// The preset. /// </param> /// <param name="task"> /// The task. /// </param> public void SetSource(Source source, Title title, Preset preset, EncodeTask task) { this.Task = task; this.NotifyOfPropertyChange(() => this.AdvancedOptionsString); }
/// <summary> /// Set the selected preset /// </summary> /// <param name="preset"> /// The preset. /// </param> /// <param name="encodeTask"> /// The task. /// </param> public void SetPreset(Preset preset, EncodeTask encodeTask) { this.Task = encodeTask; }
/// <summary> /// Verify the Encode Destination path exists and if not, create it. /// </summary> /// <param name="task"> /// The task. /// </param> /// <exception cref="Exception"> /// If the creation fails, an exception is thrown. /// </exception> protected void VerifyEncodeDestinationPath(EncodeTask task) { // Make sure the path exists, attempt to create it if it doesn't try { string path = Directory.GetParent(task.Destination).ToString(); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } catch (Exception exc) { throw new GeneralApplicationException( "Unable to create directory for the encoded output.", "Please verify that you have a valid path.", exc); } }
/// <summary> /// Takes in a query which can be in any order and parses it. /// All varibles are then set so they can be used elsewhere. /// </summary> /// <param name="input">A ClI Query</param> /// <returns>A Parsed Query</returns> public static EncodeTask Parse(string input) { var parsed = new EncodeTask(); #region Regular Expressions // Source Match title = Regex.Match(input, @"-t ([0-9]+)"); Match chapters = Regex.Match(input, @"-c ([0-9-]+)"); // Output Settings Match format = Regex.Match(input, @"-f ([a-zA-Z0-9]+)"); Match grayscale = Regex.Match(input, @" -g"); Match ipodAtom = Regex.Match(input, @" -I"); // Picture Settings Tab Match width = Regex.Match(input, @"-w ([0-9]+)"); Match height = Regex.Match(input, @"-l ([0-9]+)"); Match maxWidth = Regex.Match(input, @"-X ([0-9]+)"); Match maxHeight = Regex.Match(input, @"-Y ([0-9]+)"); Match crop = Regex.Match(input, @"--crop ([0-9]*):([0-9]*):([0-9]*):([0-9]*)"); Match looseAnamorphic = Regex.Match(input, @"--loose-anamorphic"); Match strictAnamorphic = Regex.Match(input, @"--strict-anamorphic"); Match customAnamorphic = Regex.Match(input, @"--custom-anamorphic"); Match keepDisplayAsect = Regex.Match(input, @"--keep-display-aspect"); Match displayWidth = Regex.Match(input, @"--display-width ([0-9]*)"); Match pixelAspect = Regex.Match(input, @"--pixel-aspect ([0-9]*):([0-9]*)"); Match modulus = Regex.Match(input, @"--modulus ([0-9]*)"); // Picture Settings - Filters Match decomb = Regex.Match(input, @" --decomb"); Match decombValue = Regex.Match(input, @" --decomb=([a-zA-Z0-9.:""\\]*)"); Match deinterlace = Regex.Match(input, @"--deinterlace=\""([a-zA-Z0-9.:]*)\"""); Match denoise = Regex.Match(input, @"--denoise=\""([a-zA-Z0-9.:]*)\"""); Match deblock = Regex.Match(input, @"--deblock=([0-9:]*)"); Match detelecine = Regex.Match(input, @"--detelecine"); Match detelecineValue = Regex.Match(input, @" --detelecine=\""([a-zA-Z0-9.:]*)\"""); // Video Settings Tab Match videoEncoder = Regex.Match(input, @"-e ([a-zA-Z0-9]+)"); Match videoFramerate = Regex.Match(input, @"-r ([0-9.]+)"); Match videoBitrate = Regex.Match(input, @"-b ([0-9]+)"); Match videoQuality = Regex.Match(input, @"-q ([0-9.]+)"); Match twoPass = Regex.Match(input, @" -2"); Match turboFirstPass = Regex.Match(input, @" -T"); Match optimizeMP4 = Regex.Match(input, @" -O"); Match pfr = Regex.Match(input, @" --pfr"); Match cfr = Regex.Match(input, @" --cfr"); // Audio Settings Tab Match audioTrackMixes = Regex.Match(input, @"-6 ([0-9a-zA-Z,]+)"); Match audioEncoders = Regex.Match(input, @"-E ([a-zA-Z0-9+,:\*]+)"); Match audioBitrates = Regex.Match(input, @"-B ([0-9a-zA-Z,]+)"); // Auto = a-z Match audioSampleRates = Regex.Match(input, @"-R ([0-9a-zA-Z.,]+)"); // Auto = a-z Match drcValues = Regex.Match(input, @"-D ([0-9.,]+)"); Match gainValues = Regex.Match(input, @"--gain=([0-9.,-]+)"); Match fallbackEncoder = Regex.Match(input, @"--audio-fallback([a-zA-Z0-9:=\s ]*)"); Match allowedPassthru = Regex.Match(input, @"--audio-copy-mask([a-zA-Z0-9:,=\s ]*)"); // Chapters Tab Match chapterMarkers = Regex.Match(input, @" -m"); Match chapterMarkersFileMode = Regex.Match(input, @"--markers"); // Advanced Tab Match advanced = Regex.Match(input, @"-x ([.,/a-zA-Z0-9=:-]*)"); Match x264Preset = Regex.Match(input, @"--x264-preset([=a-zA-Z0-9\s ]*)"); Match x264Tune = Regex.Match(input, @"--x264-tune([=,a-zA-Z0-9\s ]*)"); Match h264Profile = Regex.Match(input, @"--h264-profile([=a-zA-Z0-9\s ]*)"); Match x264Profile = Regex.Match(input, @"--x264-profile([=a-zA-Z0-9\s ]*)"); Match h264Level = Regex.Match(input, @"--h264-level([=a-zA-Z0-9.\s ]*)"); Match x265Profile = Regex.Match(input, @"--x265-profile([=a-zA-Z0-9\s ]*)"); Match x265Tune = Regex.Match(input, @"--x265-tune([=,a-zA-Z0-9\s ]*)"); Match x265Preset = Regex.Match(input, @"--x265-preset([=a-zA-Z0-9\s ]*)"); #endregion #region Set Varibles try { #region Source Tab if (title.Success) { parsed.Title = int.Parse(title.ToString().Replace("-t ", string.Empty)); } if (chapters.Success) { parsed.PointToPointMode = PointToPointMode.Chapters; string[] actTitles = chapters.ToString().Replace("-c ", string.Empty).Split('-'); parsed.StartPoint = int.Parse(actTitles[0]); if (actTitles.Length > 1) { parsed.EndPoint = int.Parse(actTitles[1]); } if ((parsed.StartPoint == 1) && (parsed.EndPoint == 0)) { parsed.EndPoint = parsed.StartPoint; } } #endregion #region Output Settings if (format.Success) { parsed.OutputFormat = Converters.GetFileFormat(format.Groups[1].ToString()); } parsed.IPod5GSupport = ipodAtom.Success; parsed.OptimizeMP4 = optimizeMP4.Success; #endregion #region Picture Tab if (width.Success) { parsed.Width = int.Parse(width.Groups[0].Value.Replace("-w ", string.Empty)); } if (height.Success) { parsed.Height = int.Parse(height.Groups[0].Value.Replace("-l ", string.Empty)); } if (maxWidth.Success) { parsed.MaxWidth = int.Parse(maxWidth.Groups[0].Value.Replace("-X ", string.Empty)); } if (maxHeight.Success) { parsed.MaxHeight = int.Parse(maxHeight.Groups[0].Value.Replace("-Y ", string.Empty)); } if (crop.Success) { try { string values = crop.ToString().Replace("--crop ", string.Empty); string[] actCropValues = values.Split(':'); parsed.Cropping = new Cropping( int.Parse(actCropValues[0]), int.Parse(actCropValues[1]), int.Parse(actCropValues[2]), int.Parse(actCropValues[3])); parsed.HasCropping = true; } catch (Exception) { parsed.Cropping = null; parsed.HasCropping = false; // No need to do anything. } } if (strictAnamorphic.Success) { parsed.Anamorphic = Anamorphic.Strict; } else if (looseAnamorphic.Success) { parsed.Anamorphic = Anamorphic.Loose; } else if (customAnamorphic.Success) { parsed.Anamorphic = Anamorphic.Custom; } else { parsed.Anamorphic = Anamorphic.None; } parsed.KeepDisplayAspect = keepDisplayAsect.Success; if (displayWidth.Success) { parsed.DisplayWidth = double.Parse(displayWidth.Groups[0].Value.Replace("--display-width ", string.Empty), Culture); } if (pixelAspect.Success) { parsed.PixelAspectX = int.Parse(pixelAspect.Groups[1].Value.Replace("--pixel-aspect ", string.Empty)); } if (pixelAspect.Success && pixelAspect.Groups.Count >= 3) { parsed.PixelAspectY = int.Parse(pixelAspect.Groups[2].Value.Replace("--pixel-aspect ", string.Empty)); } if (modulus.Success) { parsed.Modulus = int.Parse(modulus.Groups[0].Value.Replace("--modulus ", string.Empty)); } #endregion #region Filters parsed.Decomb = Decomb.Off; if (decomb.Success) { parsed.Decomb = Decomb.Default; if (decombValue.Success) { string value = decombValue.ToString().Replace("--decomb=", string.Empty).Replace("\"", string.Empty).Trim(); if (value == "bob") { parsed.Decomb = Decomb.Bob; } else if (value == "fast") { parsed.Decomb = Decomb.Fast; } else { parsed.CustomDecomb = value; parsed.Decomb = parsed.CustomDecomb == "7:2:6:9:1:80" ? Decomb.Fast : Decomb.Custom; } } } parsed.Deinterlace = Deinterlace.Off; if (deinterlace.Success) { switch (deinterlace.ToString().Replace("--deinterlace=", string.Empty).Replace("\"", string.Empty).ToLower()) { case "fast": parsed.Deinterlace = Deinterlace.Fast; break; case "slow": parsed.Deinterlace = Deinterlace.Slow; break; case "slower": parsed.Deinterlace = Deinterlace.Slower; break; case "bob": parsed.Deinterlace = Deinterlace.Bob; break; default: parsed.Deinterlace = Deinterlace.Custom; parsed.CustomDeinterlace = deinterlace.ToString().Replace("--deinterlace=", string.Empty).Replace("\"", string.Empty).ToLower(); break; } } parsed.Denoise = Denoise.Off; if (denoise.Success) { switch (denoise.ToString().Replace("--denoise=", string.Empty).Replace("\"", string.Empty)) { case "weak": parsed.Denoise = Denoise.Weak; break; case "medium": parsed.Denoise = Denoise.Medium; break; case "strong": parsed.Denoise = Denoise.Strong; break; default: parsed.Denoise = Denoise.Custom; parsed.CustomDenoise = denoise.ToString().Replace("--denoise=", string.Empty).Replace("\"", string.Empty); break; } } parsed.Deblock = 0; if (deblock.Success) { int dval; int.TryParse(deblock.ToString().Replace("--deblock=", string.Empty), out dval); parsed.Deblock = dval; } parsed.Detelecine = Detelecine.Off; if (detelecine.Success) { parsed.Detelecine = Detelecine.Default; if (detelecineValue.Success) { parsed.CustomDetelecine = detelecineValue.ToString().Replace("--detelecine=", string.Empty).Replace("\"", string.Empty); parsed.Detelecine = Detelecine.Custom; } } #endregion #region Video Settings Tab parsed.VideoEncoder = videoEncoder.Success ? Converters.GetVideoEncoder(videoEncoder.ToString().Replace("-e ", string.Empty)) : VideoEncoder.FFMpeg; if (videoFramerate.Success) { double fps; double.TryParse(videoFramerate.Groups[1].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out fps); parsed.Framerate = fps; } if (pfr.Success) { parsed.FramerateMode = FramerateMode.PFR; } else if (cfr.Success) { parsed.FramerateMode = FramerateMode.CFR; } else { parsed.FramerateMode = FramerateMode.VFR; // Default to VFR } parsed.Grayscale = grayscale.Success; parsed.TwoPass = twoPass.Success; parsed.TurboFirstPass = turboFirstPass.Success; if (videoBitrate.Success) { parsed.VideoEncodeRateType = VideoEncodeRateType.AverageBitrate; parsed.VideoBitrate = int.Parse(videoBitrate.ToString().Replace("-b ", string.Empty)); } if (videoQuality.Success) { float quality = float.Parse(videoQuality.ToString().Replace("-q ", string.Empty), Culture); parsed.Quality = quality; parsed.VideoEncodeRateType = VideoEncodeRateType.ConstantQuality; } #endregion #region Audio Tab // Find out how many tracks we need to add by checking how many encoders or audio tracks are selected. int encoderCount = 0; if (audioEncoders.Success) { string[] audioDataCounters = audioEncoders.ToString().Replace("-E ", string.Empty).Split(','); encoderCount = audioDataCounters.Length; } // Get the data from the regular expression results string[] trackMixes = null; string[] trackEncoders = null; string[] trackBitrates = null; string[] trackSamplerates = null; string[] trackDRCvalues = null; string[] trackGainValues = null; if (audioTrackMixes.Success) { trackMixes = audioTrackMixes.ToString().Replace("-6 ", string.Empty).Split(','); } if (audioEncoders.Success) { trackEncoders = audioEncoders.ToString().Replace("-E ", string.Empty).Split(','); } if (audioBitrates.Success) { trackBitrates = audioBitrates.ToString().Replace("-B ", string.Empty).Split(','); } if (audioSampleRates.Success) { trackSamplerates = audioSampleRates.ToString().Replace("-R ", string.Empty).Split(','); } if (drcValues.Success) { trackDRCvalues = drcValues.ToString().Replace("-D ", string.Empty).Split(','); } if (gainValues.Success) { trackGainValues = gainValues.ToString().Replace("--gain=", string.Empty).Split(','); } // Create new Audio Track Classes and store them in the ArrayList ObservableCollection <AudioTrack> allAudioTrackInfo = new ObservableCollection <AudioTrack>(); for (int x = 0; x < encoderCount; x++) { AudioTrack track = new AudioTrack(); if (trackMixes != null) { if (trackMixes.Length >= (x + 1)) // Audio Mix { track.MixDown = Converters.GetAudioMixDown(Converters.GetMixDown(trackMixes[x].Trim())); } } if (trackEncoders != null) { if (trackEncoders.Length >= (x + 1)) // Audio Mix { track.Encoder = Converters.GetAudioEncoderFromCliString(trackEncoders[x].Trim()); } } if (trackBitrates != null) { if (trackBitrates.Length >= (x + 1)) // Audio Encoder { track.Bitrate = int.Parse(trackBitrates[x].Trim() == "auto" ? "0" : trackBitrates[x].Trim()); } } if (trackSamplerates != null) { if (trackSamplerates.Length >= (x + 1)) // Audio SampleRate { track.SampleRate = double.Parse(trackSamplerates[x].Replace("Auto", "0").Trim(), Culture); } } if (trackDRCvalues != null) { if (trackDRCvalues.Length >= (x + 1)) // Audio DRC Values { track.DRC = double.Parse(trackDRCvalues[x].Trim(), Culture); } } if (trackGainValues != null) { if (trackGainValues.Length >= (x + 1)) // Audio DRC Values { track.Gain = int.Parse(trackGainValues[x].Trim()); } } allAudioTrackInfo.Add(track); } parsed.AudioTracks = allAudioTrackInfo; if (fallbackEncoder.Success) { parsed.AllowedPassthruOptions.AudioEncoderFallback = Converters.GetAudioEncoderFromCliString(fallbackEncoder.Groups[1].ToString().Trim()); } if (allowedPassthru.Success) { string[] allowedEncoders = allowedPassthru.Groups[1].ToString().Trim().Split(','); parsed.AllowedPassthruOptions.AudioAllowAACPass = allowedEncoders.Contains("aac"); parsed.AllowedPassthruOptions.AudioAllowAC3Pass = allowedEncoders.Contains("ac3"); parsed.AllowedPassthruOptions.AudioAllowDTSHDPass = allowedEncoders.Contains("dtshd"); parsed.AllowedPassthruOptions.AudioAllowDTSPass = allowedEncoders.Contains("dts"); parsed.AllowedPassthruOptions.AudioAllowMP3Pass = allowedEncoders.Contains("mp3"); } #endregion #region Chapters Tab if (chapterMarkersFileMode.Success || chapterMarkers.Success) { parsed.IncludeChapterMarkers = true; } #endregion #region Advanced and other if (advanced.Success) { parsed.AdvancedEncoderOptions = advanced.ToString().Replace("-x ", string.Empty); } if (x264Preset.Success) { parsed.X264Preset = Converters.Getx264PresetFromCli(x264Preset.ToString().Replace("--x264-preset", string.Empty).Replace("=", string.Empty).Trim()); } if (h264Profile.Success) { parsed.H264Profile = Converters.Getx264ProfileFromCli(h264Profile.ToString().Replace("--h264-profile", string.Empty).Replace("=", string.Empty).Trim()); } if (x264Profile.Success) { parsed.H264Profile = Converters.Getx264ProfileFromCli(x264Profile.ToString().Replace("--x264-profile", string.Empty).Replace("=", string.Empty).Trim()); } if (h264Level.Success) { parsed.H264Level = h264Level.ToString().Replace("--h264-level", string.Empty).Replace("=", string.Empty).Trim(); } if (x264Tune.Success) { string tuneOptions = x264Tune.ToString().Replace("--x264-tune", string.Empty).Replace("=", string.Empty).Trim(); parsed.FastDecode = tuneOptions.Contains("fastdecode"); // Remove these options. They are not in the dropdown. tuneOptions = tuneOptions.Replace("fastdecode", string.Empty).Replace( ",", string.Empty); parsed.X264Tune = Converters.Getx264TuneFromCli(tuneOptions); } if (x265Preset.Success) { parsed.X265Preset = Converters.Getx265PresetFromCli(x265Preset.ToString().Replace("--x265-preset", string.Empty).Replace("=", string.Empty).Trim()); } if (h264Profile.Success) { parsed.H265Profile = Converters.Getx265ProfileFromCli(h264Profile.ToString().Replace("--h265-profile", string.Empty).Replace("=", string.Empty).Trim()); } if (x265Profile.Success) { parsed.H265Profile = Converters.Getx265ProfileFromCli(x265Profile.ToString().Replace("--x265-profile", string.Empty).Replace("=", string.Empty).Trim()); } if (x265Tune.Success) { string tuneOptions = x265Tune.ToString().Replace("--x265-tune", string.Empty).Replace("=", string.Empty).Trim(); parsed.FastDecode = tuneOptions.Contains("fastdecode"); // Remove these options. They are not in the dropdown. tuneOptions = tuneOptions.Replace("fastdecode", string.Empty).Replace( ",", string.Empty); parsed.X265Tune = Converters.Getx265TuneFromCli(tuneOptions); } #endregion } catch (Exception exc) { throw new Exception("An error has occured in the QueryParser Utility.", exc); } #endregion return(parsed); }