/// <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> /// 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 { // Sanity Checking and Setup if (this.IsEncoding) { throw new GeneralApplicationException("HandBrake is already encoding a file.", "Please stop the current encode. If the problem persists, please restart HandBrake.", null); } // 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 = task.IsPreviewEncode ? HandBrakeInstanceManager.GetPreviewInstance(configuration.Verbosity) : HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity); this.instance.EncodeCompleted += this.InstanceEncodeCompleted; this.instance.EncodeProgress += this.InstanceEncodeProgress; this.IsEncoding = true; this.isPreviewInstance = task.IsPreviewEncode; this.SetupLogging(task.IsPreviewEncode); // Verify the Destination Path Exists, and if not, create it. this.VerifyEncodeDestinationPath(task); this.ServiceLogMessage("Starting Encode ..."); // Get an EncodeJob object for the Interop Library this.instance.StartEncode(EncodeFactory.Create(task, configuration)); // Fire the Encode Started Event this.InvokeEncodeStarted(System.EventArgs.Empty); } catch (Exception exc) { this.IsEncoding = false; this.ServiceLogMessage("Failed to start encoding ..." + Environment.NewLine + exc); this.InvokeEncodeCompleted(new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(false, exc, "Unable to start encoding", task.Source)); } }
/// <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 = CreateFilters(job), PAR = CreatePAR(job), Metadata = CreateMetadata(job), Source = CreateSource(job, configuration), Subtitle = CreateSubtitle(job), Video = CreateVideo(job, configuration) }; return encode; }
/// <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.Start = job.StartPoint; range.End = job.EndPoint; 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> /// 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.CurrentTask = task; this.NotifyOfPropertyChange(() => this.SelectedDenoise); this.NotifyOfPropertyChange(() => this.SelectedDecomb); this.NotifyOfPropertyChange(() => this.SelectedDeInterlace); this.NotifyOfPropertyChange(() => this.SelectedDetelecine); this.NotifyOfPropertyChange(() => this.Grayscale); this.NotifyOfPropertyChange(() => this.DeblockValue); this.NotifyOfPropertyChange(() => this.SelectedSharpen); this.NotifyOfPropertyChange(() => this.SelectedSharpenPreset); this.NotifyOfPropertyChange(() => this.SelectedSharpenTune); this.NotifyOfPropertyChange(() => this.SelectedCombDetectPreset); this.NotifyOfPropertyChange(() => this.SelectedDenoisePreset); this.NotifyOfPropertyChange(() => this.SelectedDenoiseTune); this.NotifyOfPropertyChange(() => this.FlipVideo); this.NotifyOfPropertyChange(() => this.SelectedRotation); this.NotifyOfPropertyChange(() => this.CustomDecomb); this.NotifyOfPropertyChange(() => this.CustomDeinterlace); this.NotifyOfPropertyChange(() => this.CustomDetelecine); this.NotifyOfPropertyChange(() => this.CustomDenoise); this.NotifyOfPropertyChange(() => this.CustomSharpen); this.NotifyOfPropertyChange(() => this.CustomCombDetect); this.NotifyOfPropertyChange(() => this.IsDeinterlaceMode); this.NotifyOfPropertyChange(() => this.IsDecombMode); this.NotifyOfPropertyChange(() => this.IsDeinterlaceDecomb); this.NotifyOfPropertyChange(() => this.ShowDenoiseOptions); this.NotifyOfPropertyChange(() => this.ShowDenoiseCustom); this.NotifyOfPropertyChange(() => this.ShowDenoiseTune); this.NotifyOfPropertyChange(() => this.ShowDecombCustom); this.NotifyOfPropertyChange(() => this.ShowCombDetectCustom); this.NotifyOfPropertyChange(() => this.ShowDeinterlaceDecombCustom); this.NotifyOfPropertyChange(() => this.ShowDeinterlaceCustom); this.NotifyOfPropertyChange(() => this.ShowDetelecineCustom); this.NotifyOfPropertyChange(() => this.ShowSharpenCustom); this.NotifyOfPropertyChange(() => this.ShowSharpenOptions); this.NotifyOfPropertyChange(() => this.ShowSharpenTune); }
/// <summary> /// Converts a value. /// </summary> /// <returns> /// A converted value. If the method returns null, the valid null value is used. /// </returns> /// <param name="value"> /// The value produced by the binding source. /// </param> /// <param name="targetType"> /// The type of the binding target property. /// </param> /// <param name="parameter"> /// The converter parameter to use. /// </param> /// <param name="culture"> /// The culture to use in the converter. /// </param> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { EncodeTask task = value as EncodeTask; if (task != null) { string rfqp = task.VideoEncoder == VideoEncoder.X264 || task.VideoEncoder == VideoEncoder.X264_10 || task.VideoEncoder == VideoEncoder.X265 || task.VideoEncoder == VideoEncoder.X265_10 || task.VideoEncoder == VideoEncoder.X265_12 ? "RF" : "QP"; string quality = task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality ? task.Quality + rfqp : task.VideoBitrate + " kbps"; string twoPass = null; if (task.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate) { twoPass = task.TwoPass ? task.TurboFirstPass ? " (2-Pass with Turbo)" : " (2-Pass)" : string.Empty; } return string.Format("{0} - {1}{2}", EnumHelper<VideoEncoder>.GetDisplay(task.VideoEncoder), quality, twoPass); } return "Unknown"; }
/// <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.CurrentTask = task; this.NotifyOfPropertyChange(() => this.SelectedDenoise); this.NotifyOfPropertyChange(() => this.SelectedDecomb); this.NotifyOfPropertyChange(() => this.SelectedDeInterlace); this.NotifyOfPropertyChange(() => this.SelectedDetelecine); this.NotifyOfPropertyChange(() => this.Grayscale); this.NotifyOfPropertyChange(() => this.DeblockValue); this.NotifyOfPropertyChange(() => this.CustomDecomb); this.NotifyOfPropertyChange(() => this.CustomDeinterlace); this.NotifyOfPropertyChange(() => this.CustomDetelecine); this.NotifyOfPropertyChange(() => this.CustomDenoise); this.NotifyOfPropertyChange(() => this.IsDeinterlaceMode); this.NotifyOfPropertyChange(() => this.IsDecombMode); this.NotifyOfPropertyChange(() => this.IsDeinterlaceDecomb); }
public QueueTask(EncodeTask task, HBConfiguration configuration, string scannedSourcePath, Preset currentPreset, bool isPresetModified) { this.Task = task; this.Configuration = configuration; this.Status = QueueItemStatus.Waiting; this.ScannedSourcePath = scannedSourcePath; if (currentPreset != null) { this.presetKey = currentPreset.Name; if (isPresetModified) { this.presetKey = this.presetKey + " (Modified)"; } } id = id + 1; this.Id = string.Format("{0}.{1}", GeneralUtilities.ProcessId, id); this.Statistics = new QueueStats(); }
/// <summary> /// Converts a value. /// </summary> /// <returns> /// A converted value. If the method returns null, the valid null value is used. /// </returns> /// <param name="value"> /// The value produced by the binding source. /// </param> /// <param name="targetType"> /// The type of the binding target property. /// </param> /// <param name="parameter"> /// The converter parameter to use. /// </param> /// <param name="culture"> /// The culture to use in the converter. /// </param> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { EncodeTask task = value as EncodeTask; if (task != null) { string rfqp = HandBrakeEncoderHelpers.GetVideoQualityRateControlName(EnumHelper <VideoEncoder> .GetShortName(task.VideoEncoder)); string quality = task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality ? string.Format("{0} {1}", task.Quality, rfqp) : string.Format("{0} {1}", task.VideoBitrate, " kbps"); string twoPass = null; if (task.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate) { twoPass = task.TwoPass ? task.TurboFirstPass ? " (2-Pass with Turbo)" : " (2-Pass)" : string.Empty; } return(string.Format("{0} - {1}{2}", EnumHelper <VideoEncoder> .GetDisplay(task.VideoEncoder), quality, twoPass)); } return("Unknown"); }
/// <summary> /// Gets a list of audio encoders OR returns the string name of an encoder depending on the input. /// </summary> /// <param name="values"> /// The values. /// </param> /// <param name="targetType"> /// The target type. /// </param> /// <param name="parameter"> /// The parameter. /// </param> /// <param name="culture"> /// The culture. /// </param> /// <returns> /// IEnumberable AudioEncoder or String encoder name. /// </returns> public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { // TODO -> Be smarter and only show the available Passthru options. if (values.Count() == 2) { List <AudioEncoder> encoders = EnumHelper <AudioEncoder> .GetEnumList().ToList(); EncodeTask task = values[1] as EncodeTask; if (task != null && task.OutputFormat != OutputFormat.Mkv) { encoders.Remove(AudioEncoder.Vorbis); encoders.Remove(AudioEncoder.ffflac); encoders.Remove(AudioEncoder.ffflac24); encoders.Remove(AudioEncoder.FlacPassthru); } if (parameter != null && parameter.ToString() == "True") { encoders.Remove(AudioEncoder.DtsHDPassthrough); encoders.Remove(AudioEncoder.DtsPassthrough); encoders.Remove(AudioEncoder.EAc3Passthrough); encoders.Remove(AudioEncoder.AacPassthru); encoders.Remove(AudioEncoder.Ac3Passthrough); encoders.Remove(AudioEncoder.Mp3Passthru); encoders.Remove(AudioEncoder.Passthrough); encoders.Remove(AudioEncoder.TrueHDPassthrough); encoders.Remove(AudioEncoder.FlacPassthru); } return(EnumHelper <AudioEncoder> .GetEnumDisplayValuesSubset(encoders)); } if (values.Any() && values.First() != DependencyProperty.UnsetValue) { return(EnumHelper <AudioEncoder> .GetDisplay((AudioEncoder)values[0])); } return(EnumHelper <AudioEncoder> .GetDisplay(AudioEncoder.ffaac)); }
/// <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.SetRF(task.Quality); this.ShowPeakFramerate = this.IsPeakFramerate; this.NotifyOfPropertyChange(() => this.IsConstantFramerate); this.NotifyOfPropertyChange(() => this.IsConstantQuantity); this.NotifyOfPropertyChange(() => this.IsPeakFramerate); this.NotifyOfPropertyChange(() => this.IsVariableFramerate); this.NotifyOfPropertyChange(() => this.SelectedVideoEncoder); this.NotifyOfPropertyChange(() => this.SelectedFramerate); this.NotifyOfPropertyChange(() => this.QualityMax); this.NotifyOfPropertyChange(() => this.QualityMin); this.NotifyOfPropertyChange(() => this.RF); this.NotifyOfPropertyChange(() => this.DisplayRF); this.NotifyOfPropertyChange(() => this.IsLossless); this.NotifyOfPropertyChange(() => this.VideoBitrate); this.NotifyOfPropertyChange(() => this.Task.Quality); this.NotifyOfPropertyChange(() => this.Task.TwoPass); this.NotifyOfPropertyChange(() => this.Task.TurboFirstPass); this.NotifyOfPropertyChange(() => this.VideoTune); this.NotifyOfPropertyChange(() => this.VideoProfile); this.NotifyOfPropertyChange(() => this.VideoPreset); this.NotifyOfPropertyChange(() => this.VideoLevel); this.NotifyOfPropertyChange(() => this.FastDecode); this.NotifyOfPropertyChange(() => this.ExtraArguments); this.VideoTune = (task.VideoTunes != null && task.VideoTunes.Any() ? task.VideoTunes.FirstOrDefault(t => !Equals(t, VideoTune.FastDecode)) : this.VideoTunes.FirstOrDefault()) ?? VideoTune.None; HBVideoEncoder encoder = HandBrakeEncoderHelpers.VideoEncoders.FirstOrDefault(s => s.ShortName == EnumHelper <VideoEncoder> .GetShortName(this.SelectedVideoEncoder)); if (encoder != null && this.VideoPreset != null) { int index = encoder.Presets.IndexOf(this.VideoPreset.ShortName); this.VideoPresetValue = index; } }
/// <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> /// Prepare the Preset window to create a Preset Object later. /// </summary> /// <param name="task"> /// The Encode Task. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="audioBehaviours"> /// The audio Behaviours. /// </param> /// <param name="subtitleBehaviours"> /// The subtitle Behaviours. /// </param> public void Setup(EncodeTask task, Title title, AudioBehaviours audioBehaviours, SubtitleBehaviours subtitleBehaviours) { this.Preset.Task = new EncodeTask(task); this.Preset.AudioTrackBehaviours = audioBehaviours.Clone(); this.Preset.SubtitleTrackBehaviours = subtitleBehaviours.Clone(); this.selectedTitle = title; switch (task.Anamorphic) { default: this.SelectedPictureSettingMode = PresetPictureSettingsMode.Custom; if (title != null && title.Resolution != null) { this.CustomWidth = title.Resolution.Width; this.CustomHeight = title.Resolution.Height; } break; case Anamorphic.Strict: this.SelectedPictureSettingMode = PresetPictureSettingsMode.SourceMaximum; break; } }
/// <summary> /// Converts a value. /// </summary> /// <returns> /// A converted value. If the method returns null, the valid null value is used. /// </returns> /// <param name="value"> /// The value produced by the binding source. /// </param> /// <param name="targetType"> /// The type of the binding target property. /// </param> /// <param name="parameter"> /// The converter parameter to use. /// </param> /// <param name="culture"> /// The culture to use in the converter. /// </param> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { EncodeTask task = value as EncodeTask; if (task != null && (task.VideoEncoder == VideoEncoder.X264 || task.VideoEncoder == VideoEncoder.X264_10 || task.VideoEncoder == VideoEncoder.X265 || task.VideoEncoder == VideoEncoder.X265_10 || task.VideoEncoder == VideoEncoder.X265_12)) { if (task.ShowAdvancedTab) { return(task.AdvancedEncoderOptions); } VideoTune tune = task.VideoTunes.FirstOrDefault(); return(string.Format("Preset: {0}{5}Tune: {1}{5}Profile: {2}{5}Level: {3}{5}Extra Arguments: {4}{5}", task.VideoPreset != null ? task.VideoPreset.ShortName : VideoPreset.None.DisplayName, tune != null ? tune.ShortName : VideoTune.None.DisplayName, task.VideoProfile != null ? task.VideoProfile.ShortName : VideoProfile.Auto.DisplayName, task.VideoLevel != null ? task.VideoLevel.ShortName : VideoLevel.Auto.DisplayName, string.IsNullOrEmpty(task.ExtraAdvancedArguments) ? "None" : task.ExtraAdvancedArguments, Environment.NewLine)); } return(task != null ? task.AdvancedEncoderOptions : string.Empty); }
private static DateTime ObtainCreateDateObject(EncodeTask task) { var rd = task.MetaData.ReleaseDate; if (DateTime.TryParse(rd, out var d)) { return(d); } try { return(File.GetCreationTime(task.Source)); } catch (Exception e) { if (e is UnauthorizedAccessException || e is PathTooLongException || e is NotSupportedException) { // Suspect the most likely concerns trying to grab the creation date in which we would want to swallow exception. return(default(DateTime)); } throw; } }
/// <summary> /// The create filter. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Filters"/>. /// </returns> private static Filters CreateFilters(EncodeTask job) { Filters filter = new Filters { FilterList = new List <Filter>(), }; // Note, order is important. // Detelecine if (job.Detelecine != Detelecine.Off) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DETELECINE, null, null, job.CustomDetelecine); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DETELECINE, Settings = settings }; filter.FilterList.Add(filterItem); } } // Deinterlace if (job.DeinterlaceFilter == DeinterlaceFilter.Yadif) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DEINTERLACE, EnumHelper <Deinterlace> .GetShortName(job.Deinterlace), null, job.CustomDeinterlace); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken root = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEINTERLACE, Settings = root }; filter.FilterList.Add(filterItem); } } // Decomb if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DECOMB, EnumHelper <Decomb> .GetShortName(job.Decomb), null, job.CustomDecomb); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DECOMB, Settings = settings }; filter.FilterList.Add(filterItem); } } if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb || job.DeinterlaceFilter == DeinterlaceFilter.Yadif) { if (job.CombDetect != CombDetect.Off) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_COMB_DETECT, EnumHelper <CombDetect> .GetShortName(job.CombDetect), null, job.CustomCombDetect); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_COMB_DETECT, Settings = settings }; 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; IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)id, job.DenoisePreset.ToString().ToLower().Replace(" ", string.Empty), job.DenoiseTune.ToString().ToLower().Replace(" ", string.Empty), job.CustomDenoise); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)id, Settings = settings }; filter.FilterList.Add(filterItem); } } // Deblock if (job.Deblock >= 5) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DEBLOCK, null, null, string.Format("qp={0}", job.Deblock)); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEBLOCK, Settings = settings }; filter.FilterList.Add(filterItem); } } // CropScale Filter string cropSettings = string.Format("width={0}:height={1}:crop-top={2}:crop-bottom={3}:crop-left={4}:crop-right={5}", job.Width, job.Height, job.Cropping.Top, job.Cropping.Bottom, job.Cropping.Left, job.Cropping.Right); IntPtr cropSettingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_CROP_SCALE, null, null, cropSettings); string unparsedCropSettingsJson = Marshal.PtrToStringAnsi(cropSettingsPtr); if (!string.IsNullOrEmpty(unparsedCropSettingsJson)) { JToken cropSettingsJson = JObject.Parse(unparsedCropSettingsJson); Filter cropScale = new Filter { ID = (int)hb_filter_ids.HB_FILTER_CROP_SCALE, Settings = cropSettingsJson }; filter.FilterList.Add(cropScale); } // Grayscale if (job.Grayscale) { Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_GRAYSCALE, Settings = null }; filter.FilterList.Add(filterItem); } // Rotate if (job.Rotation != 0 || job.FlipVideo) { string rotateSettings = string.Format("angle={0}:hflip={1}", job.Rotation, job.FlipVideo ? "1" : "0"); IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_ROTATE, null, null, rotateSettings); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_ROTATE, Settings = settings }; filter.FilterList.Add(filterItem); } } // Framerate shaping filter int fm = job.FramerateMode == FramerateMode.CFR ? 1 : job.FramerateMode == FramerateMode.PFR ? 2 : 0; int?num = null, den = null; if (job.Framerate != null) { IntPtr frameratePrt = Marshal.StringToHGlobalAnsi(job.Framerate.Value.ToString(CultureInfo.InvariantCulture)); int vrate = HBFunctions.hb_video_framerate_get_from_name(frameratePrt); if (vrate > 0) { num = 27000000; den = vrate; } } string framerateString = num.HasValue ? string.Format("mode={0}:rate={1}/{2}", fm, num, den) : string.Format("mode={0}", fm); // filter_cfr, filter_vrate.num, filter_vrate.den IntPtr framerateSettingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_VFR, null, null, framerateString); string unparsedFramerateJson = Marshal.PtrToStringAnsi(framerateSettingsPtr); if (!string.IsNullOrEmpty(unparsedFramerateJson)) { JToken framerateSettings = JObject.Parse(unparsedFramerateJson); Filter framerateShaper = new Filter { ID = (int)hb_filter_ids.HB_FILTER_VFR, Settings = framerateSettings }; filter.FilterList.Add(framerateShaper); } return(filter); }
/// <summary> /// The create subtitle. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="HandBrake.ApplicationServices.Interop.Json.Encode.Subtitles"/>. /// </returns> private static Subtitle CreateSubtitle(EncodeTask job) { Subtitles subtitle = new Subtitles { Search = new SubtitleSearch { Enable = false, Default = false, Burn = false, Forced = false }, SubtitleList = new List <HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack>() }; 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 { HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack track = new HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack { Burn = item.Burned, Default = item.Default, Forced = item.Forced, ID = item.SourceTrack.TrackNumber, Track = (item.SourceTrack.TrackNumber - 1) }; subtitle.SubtitleList.Add(track); } } else { HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack track = new HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack { 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); }
/// <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; } // Set the Max Width / Height available to the user controls. // Preset Max is null for None / SourceMax this.MaxWidth = preset.Task.MaxWidth ?? this.sourceResolution.Width; if (this.sourceResolution.Width < this.MaxWidth) { this.MaxWidth = this.sourceResolution.Width; } this.MaxHeight = preset.Task.MaxHeight ?? this.sourceResolution.Height; if (this.sourceResolution.Height < this.MaxHeight) { this.MaxHeight = this.sourceResolution.Height; } // Set the W/H if (preset.PictureSettingsMode == PresetPictureSettingsMode.None) { this.Task.Width = this.GetModulusValue(this.sourceResolution.Width - this.CropLeft - this.CropRight); this.Task.Height = this.GetModulusValue(this.sourceResolution.Height - this.CropTop - this.CropBottom); } else if (preset.PictureSettingsMode == PresetPictureSettingsMode.SourceMaximum) { this.Task.Width = this.GetModulusValue(this.sourceResolution.Width - this.CropLeft - this.CropRight); this.Task.Height = this.GetModulusValue(this.sourceResolution.Height - this.CropTop - this.CropBottom); this.MaintainAspectRatio = preset.Task.KeepDisplayAspect; } else { // Custom // Set the Width, and Maintain Aspect ratio. That should calc the Height for us. this.Task.Width = this.GetModulusValue(this.sourceResolution.Width - this.CropLeft - this.CropRight); if (this.SelectedAnamorphicMode != Anamorphic.Loose) { this.Task.Height = this.GetModulusValue(this.sourceResolution.Height - this.CropTop - this.CropBottom); } } // 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); // Force a re-calc. This will handle MaxWidth / Height corrections. this.RecaulcatePictureSettingsProperties(ChangedPictureField.Width); } this.NotifyOfPropertyChange(() => this.Task); }
/// <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> /// 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 || MP4Helper.RequiresM4v(task) ? ".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> /// Update this preset. /// The given parameters should be copy-constructed. /// </summary> /// <param name="task"> /// The task. /// </param> /// <param name="audioBehaviours"> /// The audio behaviours. /// </param> /// <param name="subtitleBehaviours"> /// The subtitle behaviours. /// </param> public void Update(EncodeTask task, AudioBehaviours audioBehaviours, SubtitleBehaviours subtitleBehaviours) { // Copy over Max Width / Height for the following picture settings modes. if (this.PictureSettingsMode == PresetPictureSettingsMode.Custom || this.PictureSettingsMode == PresetPictureSettingsMode.SourceMaximum) { task.MaxWidth = this.Task.MaxWidth; task.MaxHeight = this.Task.MaxHeight; } this.Task = task; this.AudioTrackBehaviours = new AudioBehaviours(audioBehaviours); this.SubtitleTrackBehaviours = new SubtitleBehaviours(subtitleBehaviours); }
/// <summary> /// The create filter. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Filters"/>. /// </returns> private static Filters CreateFilters(EncodeTask job) { Filters filter = new Filters { FilterList = new List<Filter>(), }; // Note, order is important. // Detelecine if (job.Detelecine != Detelecine.Off) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DETELECINE, null, null, job.CustomDetelecine); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DETELECINE, Settings = settings }; filter.FilterList.Add(filterItem); } } // Deinterlace if (job.DeinterlaceFilter == DeinterlaceFilter.Yadif) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DEINTERLACE, EnumHelper<Deinterlace>.GetShortName(job.Deinterlace), null, job.CustomDeinterlace); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken root = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEINTERLACE, Settings = root }; filter.FilterList.Add(filterItem); } } // Decomb if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DECOMB, EnumHelper<Decomb>.GetShortName(job.Decomb), null, job.CustomDecomb); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DECOMB, Settings = settings }; filter.FilterList.Add(filterItem); } } if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb || job.DeinterlaceFilter == DeinterlaceFilter.Yadif) { if (job.CombDetect != CombDetect.Off) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_COMB_DETECT, EnumHelper<CombDetect>.GetShortName(job.CombDetect), null, job.CustomCombDetect); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_COMB_DETECT, Settings = settings }; 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; IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)id, job.DenoisePreset.ToString().ToLower().Replace(" ", string.Empty), job.DenoiseTune.ToString().ToLower().Replace(" ", string.Empty), job.CustomDenoise); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)id, Settings = settings }; filter.FilterList.Add(filterItem); } } // Deblock if (job.Deblock >= 5) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DEBLOCK, null, null, string.Format("qp={0}", job.Deblock)); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEBLOCK, Settings = settings }; filter.FilterList.Add(filterItem); } } // CropScale Filter string cropSettings = string.Format("width={0}:height={1}:crop-top={2}:crop-bottom={3}:crop-left={4}:crop-right={5}", job.Width, job.Height, job.Cropping.Top, job.Cropping.Bottom, job.Cropping.Left, job.Cropping.Right); IntPtr cropSettingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_CROP_SCALE, null, null, cropSettings); string unparsedCropSettingsJson = Marshal.PtrToStringAnsi(cropSettingsPtr); if (!string.IsNullOrEmpty(unparsedCropSettingsJson)) { JToken cropSettingsJson = JObject.Parse(unparsedCropSettingsJson); Filter cropScale = new Filter { ID = (int)hb_filter_ids.HB_FILTER_CROP_SCALE, Settings = cropSettingsJson }; filter.FilterList.Add(cropScale); } // Grayscale if (job.Grayscale) { Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_GRAYSCALE, Settings = null }; filter.FilterList.Add(filterItem); } // Rotate if (job.Rotation != 0 || job.FlipVideo) { string rotateSettings = string.Format("angle={0}:hflip={1}", job.Rotation, job.FlipVideo ? "1" : "0"); IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_ROTATE, null, null, rotateSettings); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_ROTATE, Settings = settings }; filter.FilterList.Add(filterItem); } } // Framerate shaping filter int fm = job.FramerateMode == FramerateMode.CFR ? 1 : job.FramerateMode == FramerateMode.PFR ? 2 : 0; int? num = null, den = null; if (job.Framerate != null) { IntPtr frameratePrt = Marshal.StringToHGlobalAnsi(job.Framerate.Value.ToString(CultureInfo.InvariantCulture)); int vrate = HBFunctions.hb_video_framerate_get_from_name(frameratePrt); if (vrate > 0) { num = 27000000; den = vrate; } } string framerateString = num.HasValue ? string.Format("mode={0}:rate={1}/{2}", fm, num, den) : string.Format("mode={0}", fm); // filter_cfr, filter_vrate.num, filter_vrate.den IntPtr framerateSettingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_VFR, null, null, framerateString); string unparsedFramerateJson = Marshal.PtrToStringAnsi(framerateSettingsPtr); if (!string.IsNullOrEmpty(unparsedFramerateJson)) { JToken framerateSettings = JObject.Parse(unparsedFramerateJson); Filter framerateShaper = new Filter { ID = (int)hb_filter_ids.HB_FILTER_VFR, Settings = framerateSettings }; filter.FilterList.Add(framerateShaper); } return filter; }
/// <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.Task); if (preset != null) { this.IncludeChapterMarkers = preset.Task.IncludeChapterMarkers; } this.sourceChaptersList = title.Chapters; this.SetSourceChapters(title.Chapters); }
/// <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); }
/// <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.SetRF(task.Quality); this.ShowPeakFramerate = this.IsPeakFramerate; this.NotifyOfPropertyChange(() => this.IsConstantFramerate); this.NotifyOfPropertyChange(() => this.IsConstantQuantity); this.NotifyOfPropertyChange(() => this.IsPeakFramerate); this.NotifyOfPropertyChange(() => this.IsVariableFramerate); this.NotifyOfPropertyChange(() => this.SelectedVideoEncoder); this.NotifyOfPropertyChange(() => this.SelectedFramerate); this.NotifyOfPropertyChange(() => this.QualityMax); this.NotifyOfPropertyChange(() => this.QualityMin); this.NotifyOfPropertyChange(() => this.RF); this.NotifyOfPropertyChange(() => this.DisplayRF); this.NotifyOfPropertyChange(() => this.IsLossless); this.NotifyOfPropertyChange(() => this.VideoBitrate); this.NotifyOfPropertyChange(() => this.Task.Quality); this.NotifyOfPropertyChange(() => this.Task.TwoPass); this.NotifyOfPropertyChange(() => this.Task.TurboFirstPass); this.NotifyOfPropertyChange(() => this.VideoTune); this.NotifyOfPropertyChange(() => this.VideoProfile); this.NotifyOfPropertyChange(() => this.VideoPreset); this.NotifyOfPropertyChange(() => this.VideoLevel); this.NotifyOfPropertyChange(() => this.FastDecode); this.NotifyOfPropertyChange(() => this.ExtraArguments); this.VideoTune = (task.VideoTunes != null && task.VideoTunes.Any() ? task.VideoTunes.FirstOrDefault(t => !Equals(t, VideoTune.FastDecode)) : this.VideoTunes.FirstOrDefault()) ?? VideoTune.None; HBVideoEncoder encoder = HandBrakeEncoderHelpers.VideoEncoders.FirstOrDefault(s => s.ShortName == EnumHelper<VideoEncoder>.GetShortName(this.SelectedVideoEncoder)); if (encoder != null && this.VideoPreset != null) { int index = encoder.Presets.IndexOf(this.VideoPreset.ShortName); this.VideoPresetValue = index; } }
/// <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; int cropHeight = this.Task.Cropping.Top + this.Task.Cropping.Bottom; this.Task.Height = (preset.Task.Height ?? this.MaxHeight) - cropHeight; } // 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> /// 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(() => this.Task.AudioTracks); this.NotifyOfPropertyChange(() => this.Task); }
/// <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> /// 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.AudioDefaultsViewModel.Setup(preset, task); if (preset != null && preset.Task != null) { this.SetupTracks(); } this.NotifyOfPropertyChange(() => this.Task); }
private static string GetAutonamePath(IUserSettingService userSettingService, EncodeTask task, string sourceName) { string autoNamePath = string.Empty; // 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); autoNamePath = Path.Combine(directory, savedPath); } else { autoNamePath = userSettingService.GetUserSetting <string>(UserSettingConstants.AutoNamePath).Trim(); } if (userSettingService.GetUserSetting <string>(UserSettingConstants.AutoNamePath).Contains("{source}") && !string.IsNullOrEmpty(task.Source)) { sourceName = Path.GetInvalidPathChars().Aggregate(sourceName, (current, character) => current.Replace(character.ToString(), string.Empty)); autoNamePath = autoNamePath.Replace("{source}", sourceName); } 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 = userSettingService.GetUserSetting <string>(UserSettingConstants.AutoNamePath).Replace("{source_folder_name}", sourceFolder); } } // Fallback to the users "Videos" folder. if (string.IsNullOrEmpty(autoNamePath) || autoNamePath == Resources.OptionsView_SetDefaultLocationOutputFIle) { autoNamePath = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos); } return(autoNamePath); }
/// <summary> /// Function which generates the filename and path automatically based on /// the Source Name, DVD title and DVD Chapters /// </summary> public static string AutoName(EncodeTask task, string sourceOrLabelName, Preset presetName) { IUserSettingService userSettingService = IoC.Get <IUserSettingService>(); if (task.Destination == null) { task.Destination = 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; } // Local method to check if we have a creation time in the meta data. If not, fall back to source file creation time. DateTime obtainCreateDateObject() { var rd = task.MetaData.ReleaseDate; if (DateTime.TryParse(rd, out var d)) { return(d); } try { return(File.GetCreationTime(task.Source)); } catch (Exception e) { if (e is UnauthorizedAccessException || e is PathTooLongException || e is NotSupportedException) { // Suspect the most likely concerns trying to grab the creation date in which we would want to swallow exception. return(default(DateTime)); } throw e; } } var creationDateTime = obtainCreateDateObject(); string createDate = creationDateTime.Date.ToShortDateString().Replace('/', '-'); string createTime = creationDateTime.ToString("HH-mm"); /* * Generate the full path and filename */ string destinationFilename = GenerateDestinationFileName(task, userSettingService, sourceName, dvdTitle, combinedChapterTag, createDate, createTime); string autoNamePath = GetAutonamePath(userSettingService, task, sourceName); string finalPath = Path.Combine(autoNamePath, destinationFilename); autoNamePath = CheckAndHandleFilenameCollisions(finalPath, destinationFilename, task, userSettingService); return(autoNamePath); } return(string.Empty); }
/// <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(() => this.Task.IncludeChapterMarkers); this.NotifyOfPropertyChange(() => this.Task.ChapterNames); }
/// <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); this.ServiceLogMessage("Starting Encode ..."); // Get an EncodeJob object for the Interop Library this.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; this.ServiceLogMessage("Failed to start encoding ..." + Environment.NewLine + exc); this.InvokeEncodeCompleted(new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(false, exc, "Unable to start encoding", task.Source)); } }
/// <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.CurrentTask = task; if (preset != null) { // Properties this.SelectedDenoise = preset.Task.Denoise; this.SelectedDecomb = preset.Task.Decomb; this.SelectedDeInterlace = preset.Task.Deinterlace; this.SelectedDetelecine = preset.Task.Detelecine; this.Grayscale = preset.Task.Grayscale; this.DeblockValue = preset.Task.Deblock == 0 ? 4 : preset.Task.Deblock; this.SelectedDenoisePreset = preset.Task.DenoisePreset; this.SelectedDenoiseTune = preset.Task.DenoiseTune; // Custom Values this.CustomDecomb = preset.Task.CustomDecomb; this.CustomDeinterlace = preset.Task.CustomDeinterlace; this.CustomDetelecine = preset.Task.CustomDetelecine; this.CustomDenoise = preset.Task.CustomDenoise; } else { // Default everything to off this.SelectedDenoise = Denoise.Off; this.SelectedDecomb = Decomb.Off; this.SelectedDeInterlace = Deinterlace.Off; this.SelectedDetelecine = Detelecine.Off; this.Grayscale = false; this.DeblockValue = 0; } }
/// <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); }
/// <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.CurrentTask = task; this.NotifyOfPropertyChange(() => this.SelectedDenoise); this.NotifyOfPropertyChange(() => this.SelectedDecomb); this.NotifyOfPropertyChange(() => this.SelectedDeInterlace); this.NotifyOfPropertyChange(() => this.SelectedDetelecine); this.NotifyOfPropertyChange(() => this.Grayscale); this.NotifyOfPropertyChange(() => this.DeblockValue); this.NotifyOfPropertyChange(() => this.CustomDecomb); this.NotifyOfPropertyChange(() => this.CustomDeinterlace); this.NotifyOfPropertyChange(() => this.CustomDetelecine); this.NotifyOfPropertyChange(() => this.CustomDenoise); }
/// <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> /// 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> /// 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; } // Cropping if (preset.Task.HasCropping) { this.IsCustomCrop = true; 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.NotifyOfPropertyChange(() => this.CropLeft); this.NotifyOfPropertyChange(() => this.CropRight); this.NotifyOfPropertyChange(() => this.CropTop); this.NotifyOfPropertyChange(() => this.CropBottom); } else { this.IsCustomCrop = false; } // 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 { int presetWidth = preset.Task.MaxWidth ?? this.sourceResolution.Width; int presetHeight = preset.Task.MaxHeight ?? this.sourceResolution.Height; this.MaxWidth = presetWidth <= this.sourceResolution.Width ? presetWidth : this.sourceResolution.Width; this.MaxHeight = presetHeight <= this.sourceResolution.Height ? presetHeight : 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), this.MaxWidth)); int height = this.GetModulusValue(this.GetRes((this.sourceResolution.Height - this.CropTop - this.CropBottom), this.MaxHeight)); // Set the backing fields to avoid triggering recalulation until both are set. this.Task.Width = width; this.Task.Height = height; // Trigger a Recalc this.RecaulcatePictureSettingsProperties(ChangedPictureField.Width); // Update the UI this.NotifyOfPropertyChange(() => this.Width); this.NotifyOfPropertyChange(() => this.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; if (this.Width > this.MaxWidth) { // Trigger a Recalc this.Task.Width = this.GetModulusValue(this.GetRes((this.sourceResolution.Width - this.CropLeft - this.CropRight), this.MaxWidth)); this.RecaulcatePictureSettingsProperties(ChangedPictureField.Width); } 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; } this.NotifyOfPropertyChange(() => this.Task); this.UpdateVisibileControls(); }
/// <summary> /// The create subtitle. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="HandBrake.ApplicationServices.Interop.Json.Encode.Subtitles"/>. /// </returns> private static Subtitle CreateSubtitle(EncodeTask job) { Subtitles subtitle = new Subtitles { Search = new SubtitleSearch { Enable = false, Default = false, Burn = false, Forced = false }, SubtitleList = new List<HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack>() }; 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 { HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack track = new HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack { Burn = item.Burned, Default = item.Default, Forced = item.Forced, ID = item.SourceTrack.TrackNumber, Track = (item.SourceTrack.TrackNumber - 1) }; subtitle.SubtitleList.Add(track); } } else { HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack track = new HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack { 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; }
/// <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 = 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 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 <HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack>(); foreach (AudioTrack item in job.AudioTracks) { HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(item.Encoder)); Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder); HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(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 != null ? mixdown.Id : -1, NormalizeMixLevel = false, Samplerate = sampleRate != null ? sampleRate.Rate : 0, Name = !string.IsNullOrEmpty(item.TrackName) ? item.TrackName : null, }; 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); }
/// <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, Preset presetName) { 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)); string sanitisedPresetName = presetName != null ? Path.GetInvalidFileNameChars().Aggregate(presetName.Name, (current, character) => current.Replace(character.ToString(), string.Empty)) : 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")) .Replace(Constants.Preset, sanitisedPresetName); 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 || MP4Helper.RequiresM4v(task) ? ".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; }
private static string GenerateDestinationFileName(EncodeTask task, IUserSettingService userSettingService, string sourceName, string dvdTitle, string combinedChapterTag, string createDate, string createTime) { string destinationFilename; if (userSettingService.GetUserSetting <string>(UserSettingConstants.AutoNameFormat) != string.Empty) { destinationFilename = userSettingService.GetUserSetting <string>(UserSettingConstants.AutoNameFormat); destinationFilename = destinationFilename .RegexReplace(Constants.Source, sourceName) .RegexReplace(Constants.Title, dvdTitle) .RegexReplace(Constants.Chapters, combinedChapterTag) .RegexReplace(Constants.Date, DateTime.Now.Date.ToShortDateString().Replace('/', '-')) .RegexReplace(Constants.Time, DateTime.Now.ToString("HH-mm")) .RegexReplace(Constants.CretaionDate, createDate) .RegexReplace(Constants.CreationTime, createTime); 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 ((Mp4Behaviour)userSettingService.GetUserSetting <int>(UserSettingConstants.UseM4v)) { case Mp4Behaviour.Auto: // Automatic destinationFilename += task.IncludeChapterMarkers || MP4Helper.RequiresM4v(task) ? ".m4v" : ".mp4"; break; case Mp4Behaviour.MP4: // Always MP4 destinationFilename += ".mp4"; break; case Mp4Behaviour.M4V: // Always M4V destinationFilename += ".m4v"; break; } } else if (task.OutputFormat == OutputFormat.Mkv) { destinationFilename += ".mkv"; } else if (task.OutputFormat == OutputFormat.WebM) { destinationFilename += ".webm"; } return(destinationFilename); }
/// <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 }; }
private static string CheckAndHandleFilenameCollisions(string autoNamePath, string destinationFilename, EncodeTask task, IUserSettingService userSettingService) { AutonameFileCollisionBehaviour behaviour = (AutonameFileCollisionBehaviour)userSettingService.GetUserSetting <int>(UserSettingConstants.AutonameFileCollisionBehaviour); string prefix = string.Empty, postfix = string.Empty; switch (behaviour) { case AutonameFileCollisionBehaviour.Postfix: postfix = userSettingService.GetUserSetting <string>(UserSettingConstants.AutonameFilePrePostString); break; case AutonameFileCollisionBehaviour.Prefix: prefix = userSettingService.GetUserSetting <string>(UserSettingConstants.AutonameFilePrePostString); break; } string extension = Path.GetExtension(destinationFilename); string filenameWithoutExt = Path.GetFileNameWithoutExtension(destinationFilename); if (behaviour != AutonameFileCollisionBehaviour.AppendNumber) { if (autoNamePath?.ToLower() == task.Source?.ToLower()) { autoNamePath = Path.Combine(Path.GetDirectoryName(autoNamePath), prefix + filenameWithoutExt + postfix + extension); int counter = 0; while (File.Exists(autoNamePath)) { counter = counter + 1; string appendedNumber = string.Format("({0})", counter); autoNamePath = Path.Combine(Path.GetDirectoryName(autoNamePath), prefix + filenameWithoutExt + postfix + appendedNumber + extension); } } } else { int counter = 0; while (File.Exists(autoNamePath)) { counter = counter + 1; string appendedNumber = string.Format("({0})", counter); autoNamePath = Path.Combine(Path.GetDirectoryName(autoNamePath), filenameWithoutExt + appendedNumber + extension); } } return(autoNamePath); }
/// <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; }
/// <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<Chapter>() }; if (job.IncludeChapterMarkers) { foreach (ChapterMarker item in job.ChapterNames) { Chapter chapter = new Chapter { 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; 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; } this.SetRF(preset.Task.Quality); this.TwoPass = preset.Task.TwoPass; this.TurboFirstPass = preset.Task.TurboFirstPass; this.VideoBitrate = preset.Task.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate ? preset.Task.VideoBitrate : null; this.NotifyOfPropertyChange(() => this.Task); if (preset.Task != null) { this.HandleEncoderChange(preset.Task.VideoEncoder); HBVideoEncoder encoder = HandBrakeEncoderHelpers.VideoEncoders.FirstOrDefault(s => s.ShortName == EnumHelper <VideoEncoder> .GetShortName(preset.Task.VideoEncoder)); if (encoder != null) { if (preset.Task.VideoEncoder == VideoEncoder.X264 || preset.Task.VideoEncoder == VideoEncoder.X264_10 || preset.Task.VideoEncoder == VideoEncoder.X265 || preset.Task.VideoEncoder == VideoEncoder.X265_10 || preset.Task.VideoEncoder == VideoEncoder.X265_12 || preset.Task.VideoEncoder == VideoEncoder.QuickSync || preset.Task.VideoEncoder == VideoEncoder.QuickSyncH265) { this.VideoLevel = preset.Task.VideoLevel != null?preset.Task.VideoLevel.Clone() : this.VideoLevels.FirstOrDefault(); this.VideoProfile = preset.Task.VideoProfile != null?preset.Task.VideoProfile.Clone() : this.VideoProfiles.FirstOrDefault(); this.VideoPresetValue = preset.Task.VideoPreset != null?this.VideoPresets.IndexOf(preset.Task.VideoPreset) : 0; this.FastDecode = preset.Task.VideoTunes != null && preset.Task.VideoTunes.Contains(VideoTune.FastDecode); this.VideoTune = (preset.Task.VideoTunes != null && preset.Task.VideoTunes.Any() ? preset.Task.VideoTunes.FirstOrDefault(t => !Equals(t, VideoTune.FastDecode)) : this.VideoTunes.FirstOrDefault()) ?? VideoTune.None; } } this.ExtraArguments = preset.Task.ExtraAdvancedArguments; this.UseAdvancedTab = (!string.IsNullOrEmpty(preset.Task.AdvancedEncoderOptions) && this.ShowAdvancedTab) || preset.Task.ShowAdvancedTab; } }
/// <summary> /// The create meta data. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Metadata"/>. /// </returns> private static Metadata CreateMetadata(EncodeTask job) { Metadata metaData = new Metadata(); if (job.MetaData != null) { metaData.Artist = job.MetaData.Artist; metaData.AlbumArtist = job.MetaData.AlbumArtist; metaData.Comment = job.MetaData.Comment; metaData.Composer = job.MetaData.Composer; metaData.Description = job.MetaData.Description; metaData.Genre = job.MetaData.Genre; metaData.LongDescription = job.MetaData.LongDescription; metaData.Name = job.MetaData.Name; metaData.ReleaseDate = job.MetaData.ReleaseDate; } return metaData; }
/// <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(() => this.Width); this.NotifyOfPropertyChange(() => this.Height); this.NotifyOfPropertyChange(() => this.SelectedAnamorphicMode); this.NotifyOfPropertyChange(() => this.SelectedModulus); }
/// <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.Start = job.StartPoint; range.End = job.EndPoint; 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; }
private static string GetAutonamePath(IUserSettingService userSettingService, EncodeTask task, string destinationFilename) { string autoNamePath = string.Empty; // 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); } 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> /// 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 == EnumHelper<VideoEncoder>.GetShortName(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.VideoTunes != null && job.VideoTunes.Count > 0) { foreach (var item in job.VideoTunes) { video.Tune += string.IsNullOrEmpty(video.Tune) ? item.ShortName : "," + item.ShortName; } } } 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; } video.OpenCL = configuration.ScalingMode == VideoScaler.BicubicCl; video.QSV.Decode = SystemInfo.IsQsvAvailable && !configuration.DisableQuickSyncDecoding; return video; }
/// <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; } this.SetRF(preset.Task.Quality); this.TwoPass = preset.Task.TwoPass; this.TurboFirstPass = preset.Task.TurboFirstPass; this.Task.VideoBitrate = preset.Task.VideoBitrate; this.NotifyOfPropertyChange(() => this.Task); if (preset.Task != null) { this.HandleEncoderChange(preset.Task.VideoEncoder); HBVideoEncoder encoder = HandBrakeEncoderHelpers.VideoEncoders.FirstOrDefault(s => s.ShortName == EnumHelper<VideoEncoder>.GetShortName(preset.Task.VideoEncoder)); if (encoder != null) { if (preset.Task.VideoEncoder == VideoEncoder.X264 || preset.Task.VideoEncoder == VideoEncoder.X265 || preset.Task.VideoEncoder == VideoEncoder.QuickSync) { this.VideoLevel = preset.Task.VideoLevel != null ? preset.Task.VideoLevel.Clone() : this.VideoLevels.FirstOrDefault(); this.VideoProfile = preset.Task.VideoProfile != null ? preset.Task.VideoProfile.Clone() : this.VideoProfiles.FirstOrDefault(); this.VideoPresetValue = preset.Task.VideoPreset != null ? this.VideoPresets.IndexOf(preset.Task.VideoPreset) : 0; this.FastDecode = preset.Task.VideoTunes != null && preset.Task.VideoTunes.Contains(VideoTune.FastDecode); this.VideoTune = (preset.Task.VideoTunes != null && preset.Task.VideoTunes.Any() ? preset.Task.VideoTunes.FirstOrDefault(t => !Equals(t, VideoTune.FastDecode)) : this.VideoTunes.FirstOrDefault()) ?? VideoTune.None; } } this.ExtraArguments = preset.Task.ExtraAdvancedArguments; this.UseAdvancedTab = !string.IsNullOrEmpty(preset.Task.AdvancedEncoderOptions) && this.ShowAdvancedTab; } }
/// <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<HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack>(); foreach (AudioTrack item in job.AudioTracks) { HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper<AudioEncoder>.GetShortName(item.Encoder)); Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder); HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(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 != null ? mixdown.Id : -1, 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; }
/// <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; }
/// <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(() => this.Task.SubtitleTracks); this.NotifyOfPropertyChange(() => this.Task); }
/// <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.SetRF(task.Quality); this.NotifyOfPropertyChange(() => this.IsConstantFramerate); this.NotifyOfPropertyChange(() => this.IsConstantQuantity); this.NotifyOfPropertyChange(() => this.IsPeakFramerate); this.NotifyOfPropertyChange(() => this.IsVariableFramerate); this.NotifyOfPropertyChange(() => this.SelectedVideoEncoder); this.NotifyOfPropertyChange(() => this.SelectedFramerate); this.NotifyOfPropertyChange(() => this.QualityMax); this.NotifyOfPropertyChange(() => this.QualityMin); this.NotifyOfPropertyChange(() => this.RF); this.NotifyOfPropertyChange(() => this.DisplayRF); this.NotifyOfPropertyChange(() => this.IsLossless); this.NotifyOfPropertyChange(() => this.Task.VideoBitrate); this.NotifyOfPropertyChange(() => this.Task.Quality); this.NotifyOfPropertyChange(() => this.Task.TwoPass); this.NotifyOfPropertyChange(() => this.Task.TurboFirstPass); this.NotifyOfPropertyChange(() => this.VideoTune); this.NotifyOfPropertyChange(() => this.VideoProfile); this.NotifyOfPropertyChange(() => this.VideoProfile); this.NotifyOfPropertyChange(() => this.VideoLevel); this.NotifyOfPropertyChange(() => this.FastDecode); this.NotifyOfPropertyChange(() => this.ExtraArguments); }