public static SourceTitle GetFeatureTitle(List <SourceTitle> titles, int hbFeatureTitle) { // If the feature title is supplied, find it in the list. if (hbFeatureTitle > 0) { SourceTitle featureTitle = titles.FirstOrDefault(title => title.Index == hbFeatureTitle); if (featureTitle != null) { return(featureTitle); } } // Select the first title within 80% of the duration of the longest title. double maxSeconds = titles.Max(title => title.Duration.ToSpan().TotalSeconds); foreach (SourceTitle title in titles) { if (title.Duration.ToSpan().TotalSeconds >= maxSeconds * .8) { return(title); } } return(titles[0]); }
private void RefreshImageSize() { var previewVM = this.DataContext as QueueTitlesWindowViewModel; if (previewVM.SelectedTitles.Count != 1) { return; } double widthPixels, heightPixels; SourceTitle title = previewVM.SelectedTitles[0].Title; if (title.Geometry.PAR.Num > title.Geometry.PAR.Den) { widthPixels = title.Geometry.Width * ((double)title.Geometry.PAR.Num / title.Geometry.PAR.Den); heightPixels = title.Geometry.Height; } else { widthPixels = title.Geometry.Width; heightPixels = title.Geometry.Height * ((double)title.Geometry.PAR.Den / title.Geometry.PAR.Num); } ImageUtilities.UpdatePreviewHolderSize(this.previewImage, this.previewImageHolder, widthPixels, heightPixels, showOneToOneWhenSmaller: true); }
/// <summary> /// Starts an encode, given a VidCoder job and some extra data. /// </summary> /// <param name="job">The VidCoder job to run.</param> /// <param name="previewNumber">The preview number to run.</param> /// <param name="previewSeconds">The number of seconds the preview should be.</param> /// <param name="defaultChapterNameFormat">The default format for chapter names.</param> public void StartEncode( VCJob job, int previewNumber, int previewSeconds, string defaultChapterNameFormat) { this.StartEncodeInternal( job.SourcePath, job.Title, scanObject => { SourceTitle encodeTitle = scanObject.TitleList.FirstOrDefault(title => title.Index == job.Title); if (encodeTitle != null) { JsonEncodeFactory factory = new JsonEncodeFactory(ServiceLocator.Current.GetInstance <ILogger>()); JsonEncodeObject encodeObject = factory.CreateJsonObject( job, encodeTitle, defaultChapterNameFormat, previewNumber, previewSeconds, this.passedPreviewCount); return(JsonConvert.SerializeObject(encodeObject, JsonSettings.HandBrakeJsonSerializerSettings)); } else { return(null); } }); }
/// <summary> /// Replace arguments with the given job information. /// </summary> /// <param name="nameFormat">The name format to use.</param> /// <param name="picker">The picker.</param> /// <param name="jobViewModel">The job to pick information from.</param> /// <returns>The string with arguments replaced.</returns> public string ReplaceArguments(string nameFormat, Picker picker, EncodeJobViewModel jobViewModel) { // The jobViewModel might have null VideoSource and VideoSourceMetadata from an earlier version < 4.17. VCJob job = jobViewModel.Job; SourceTitle title = jobViewModel.VideoSource?.Titles.Single(t => t.Index == job.Title); string sourceName = jobViewModel.VideoSourceMetadata != null ? jobViewModel.VideoSourceMetadata.Name : string.Empty; TimeSpan titleDuration = title?.Duration.ToSpan() ?? TimeSpan.Zero; int chapterCount = title?.ChapterList.Count ?? 0; bool hasMultipleTitles = jobViewModel.VideoSource != null && jobViewModel.VideoSource.Titles.Count > 1; return(this.ReplaceArguments( job.SourcePath, sourceName, job.Title, titleDuration, job.RangeType, job.ChapterStart, job.ChapterEnd, chapterCount, TimeSpan.FromSeconds(job.SecondsStart), TimeSpan.FromSeconds(job.SecondsEnd), job.FramesStart, job.FramesEnd, nameFormat, hasMultipleTitles, picker)); }
public static List <InfoLineViewModel> GetResolutionInfoLines(SourceTitle title) { var previewLines = new List <InfoLineViewModel>(); if (title == null) { return(previewLines); } string inputStorageResolutionString = title.Geometry.Width + " x " + title.Geometry.Height; if (title.Geometry.PAR.Num == title.Geometry.PAR.Den) { previewLines.Add(new InfoLineViewModel(EncodingRes.ResolutionLabel, inputStorageResolutionString)); } else { previewLines.Add(new InfoLineViewModel(EncodingRes.StorageResolutionLabel, inputStorageResolutionString)); previewLines.Add(new InfoLineViewModel(EncodingRes.PixelAspectRatioLabel, CreateParDisplayString(title.Geometry.PAR.Num, title.Geometry.PAR.Den))); double pixelAspectRatio = ((double)title.Geometry.PAR.Num) / title.Geometry.PAR.Den; double displayWidth = title.Geometry.Width * pixelAspectRatio; int displayWidthRounded = (int)Math.Round(displayWidth); string displayResolutionString = displayWidthRounded + " x " + title.Geometry.Height; previewLines.Add(new InfoLineViewModel(EncodingRes.DisplayResolutionLabel, displayResolutionString)); } return(previewLines); }
public RawPreviewData GetPreview(PreviewSettings settings, int previewNumber, bool deinterlace) { SourceTitle title = this.Titles.TitleList.FirstOrDefault(t => t.Index == settings.TitleNumber); // Create the Expected Output Geometry details for libhb. hb_geometry_settings_s uiGeometry = new hb_geometry_settings_s { crop = new[] { settings.Cropping.Top, settings.Cropping.Bottom, settings.Cropping.Left, settings.Cropping.Right }, itu_par = 0, keep = (int)AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH + (settings.KeepDisplayAspect ? 0x04 : 0), // TODO Keep Width? maxWidth = settings.MaxWidth, maxHeight = settings.MaxHeight, mode = (int)(hb_anamorphic_mode_t)settings.Anamorphic, modulus = settings.Modulus ?? 16, geometry = new hb_geometry_s { height = settings.Height, width = settings.Width, par = settings.Anamorphic != Anamorphic.Custom && settings.Anamorphic != Anamorphic.Automatic ? new hb_rational_t { den = title.Geometry.PAR.Den, num = title.Geometry.PAR.Num } : new hb_rational_t { den = settings.PixelAspectY, num = settings.PixelAspectX } } }; // Fetch the image data from LibHb IntPtr resultingImageStuct = hbFunctions.hb_get_preview2(this.Handle, settings.TitleNumber, previewNumber, ref uiGeometry, deinterlace ? 1 : 0); hb_image_s image = InteropUtilities.ToStructureFromPtr <hb_image_s>(resultingImageStuct); // Copy the filled image buffer to a managed array. int stride_width = image.plane[0].stride; int stride_height = image.plane[0].height_stride; int imageBufferSize = stride_width * stride_height; // int imageBufferSize = outputWidth * outputHeight * 4; byte[] managedBuffer = new byte[imageBufferSize]; Marshal.Copy(image.plane[0].data, managedBuffer, 0, imageBufferSize); RawPreviewData preview = new RawPreviewData(managedBuffer, stride_width, stride_height, image.width, image.height); // Close the image so we don't leak memory. IntPtr nativeJobPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(nativeJobPtrPtr, resultingImageStuct); hbFunctions.hb_image_close(nativeJobPtrPtr); Marshal.FreeHGlobal(nativeJobPtrPtr); return(preview); }
public static TimeSpan GetChapterRangeDuration(this SourceTitle title, int startChapter, int endChapter) { if (startChapter > endChapter || endChapter > title.ChapterList.Count || startChapter < 1) { return(TimeSpan.Zero); } TimeSpan rangeTime = TimeSpan.Zero; for (int i = startChapter; i <= endChapter; i++) { rangeTime += title.ChapterList[i - 1].Duration.ToSpan(); } return(rangeTime); }
public Task StartEncodeAsync( VCJob job, IAppLogger logger, bool preview, int previewNumber, int previewSeconds, double overallSelectedLengthSeconds) { this.logger = logger; this.StartEncodeInternal( job.SourcePath, job.Title, scanObject => { SourceTitle encodeTitle = scanObject.TitleList.FirstOrDefault(title => title.Index == job.Title); if (encodeTitle != null) { JsonEncodeFactory factory = new JsonEncodeFactory(logger); JsonEncodeObject jsonEncodeObject = factory.CreateJsonObject( job, encodeTitle, EncodingRes.DefaultChapterName, preview ? previewNumber : -1, previewSeconds, Config.PreviewCount); return(JsonConvert.SerializeObject(jsonEncodeObject, JsonSettings.HandBrakeJsonSerializerSettings)); } else { return(null); } }); return(Task.CompletedTask); }
public static string GetDisplayString(this SourceTitle title) { if (title == null) { return(string.Empty); } string playlistPortion = string.Empty; if (title.Type == (int)TitleType.Bluray) { playlistPortion = FormattableString.Invariant($" {title.Playlist:d5}.MPLS"); } int hours, minutes, seconds; if (title.Duration != null) { hours = title.Duration.Hours; minutes = title.Duration.Minutes; seconds = title.Duration.Seconds; } else { hours = 0; minutes = 0; seconds = 0; } return(string.Format( CultureInfo.CurrentCulture, "{0}{1} ({2:00}:{3:00}:{4:00})", title.Index, playlistPortion, hours, minutes, seconds)); }
public static PreviewSettings CreatePreviewSettings(this VCProfile profile, SourceTitle title) { VCCropping cropping = JsonEncodeFactory.GetCropping(profile, title); // HB doesn't expect us to give it a 0 width and height so we need to guard against that int sanitizedWidth = profile.Width > 0 ? profile.Width : title.Geometry.Width - cropping.Left - cropping.Right; int sanitizedHeight = profile.Height > 0 ? profile.Height : title.Geometry.Height - cropping.Top - cropping.Bottom; return(new PreviewSettings { Anamorphic = EnumConverter.Convert <VCAnamorphic, Anamorphic>(profile.Anamorphic), Cropping = JsonEncodeFactory.GetCropping(profile, title).GetHbCropping(), Width = sanitizedWidth, Height = sanitizedHeight, MaxWidth = profile.MaxWidth, MaxHeight = profile.MaxHeight, KeepDisplayAspect = profile.KeepDisplayAspect, Modulus = profile.Modulus, PixelAspectX = 1, PixelAspectY = 1, TitleNumber = title.Index }); }
public static PreviewSettings CreatePreviewSettings(this VCProfile profile, SourceTitle title) { VCCropping cropping = JsonEncodeFactory.GetCropping(profile, title); var outputSize = JsonEncodeFactory.GetOutputSize(profile, title); int width = outputSize.ScaleWidth; int height = outputSize.ScaleHeight; return(new PreviewSettings { Anamorphic = EnumConverter.Convert <VCAnamorphic, Anamorphic>(profile.Anamorphic), Cropping = cropping.GetHbCropping(), Width = width, Height = height, MaxWidth = width, MaxHeight = height, KeepDisplayAspect = true, Modulus = profile.Modulus, PixelAspectX = 1, PixelAspectY = 1, TitleNumber = title.Index }); }
public void SetChosenTracks(List <int> chosenAudioTracks, SourceTitle selectedTitle) { DispatchUtilities.Invoke(() => { int previousIndex = this.TargetStreamIndex; this.targetStreams.Clear(); this.targetStreams.Add(new TargetStreamViewModel { Text = CommonRes.All }); int shownStreams = Math.Max(previousIndex, chosenAudioTracks.Count); for (int i = 0; i < shownStreams; i++) { string details = null; if (i < chosenAudioTracks.Count && selectedTitle != null) { details = selectedTitle.AudioList[chosenAudioTracks[i] - 1].Description; } this.targetStreams.Add( new TargetStreamViewModel { Text = string.Format(CommonRes.StreamChoice, (i + 1)), TrackDetails = details }); } // Set to -1, then back to real index in order to force a refresh on the ComboBox this.targetStreamIndex = -1; this.RaisePropertyChanged(nameof(this.TargetStreamIndex)); this.targetStreamIndex = previousIndex; this.RaisePropertyChanged(nameof(this.TargetStreamIndex)); }); }
public static int GetEstimatedFrames(this SourceTitle title) { return((int)Math.Ceiling(title.Duration.ToSpan().TotalSeconds *title.FrameRate.ToDouble())); }
public bool IsDeathCert() => SourceMedium.Contains("Official Document") && SourceTitle.ToUpper().IndexOf(DEATHCERT, StringComparison.Ordinal) >= 0;
public bool IsCensusCert() => SourceMedium.Equals("Official Document") && SourceTitle.ToUpper().IndexOf(CENSUSCERT, StringComparison.Ordinal) >= 0;
public static (int chapterStart, int chapterEnd) GetChapterRange(Picker picker, SourceTitle title) { int chapterStart = picker.ChapterRangeStart ?? 1; int chapterEnd = picker.ChapterRangeEnd ?? title.ChapterList.Count; if (chapterStart > title.ChapterList.Count) { chapterStart = title.ChapterList.Count; } if (chapterEnd > title.ChapterList.Count) { chapterEnd = title.ChapterList.Count; } // If start is greater than end, swap them. if (chapterStart > chapterEnd) { int temp = chapterStart; chapterStart = chapterEnd; chapterEnd = temp; } return(chapterStart, chapterEnd); }
public bool IsMarriageCert() => SourceMedium.Contains("Official Document") && SourceTitle.ToUpper().IndexOf(MARRIAGECERT, StringComparison.Ordinal) >= 0;
public SourceTitleViewModel(SourceTitle title) { this.Title = title; }
public MemoryStream GetPreview(PreviewSettings settings, int previewNumber, bool deinterlace) { SourceTitle title = this.Titles.TitleList.FirstOrDefault(t => t.Index == settings.TitleNumber); // Create the Expected Output Geometry details for libhb. hb_geometry_settings_s uiGeometry = new hb_geometry_settings_s { crop = new[] { settings.Cropping.Top, settings.Cropping.Bottom, settings.Cropping.Left, settings.Cropping.Right }, itu_par = 0, keep = (int)AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH + (settings.KeepDisplayAspect ? 0x04 : 0), // TODO Keep Width? maxWidth = settings.MaxWidth, maxHeight = settings.MaxHeight, mode = (int)(hb_anamorphic_mode_t)settings.Anamorphic, modulus = settings.Modulus ?? 16, geometry = new hb_geometry_s { height = settings.Height, width = settings.Width, par = settings.Anamorphic != Anamorphic.Custom ? new hb_rational_t { den = title.Geometry.PAR.Den, num = title.Geometry.PAR.Num } : new hb_rational_t { den = settings.PixelAspectY, num = settings.PixelAspectX } } }; // Fetch the image data from LibHb IntPtr resultingImageStuct = HBFunctions.hb_get_preview2(this.hbHandle, settings.TitleNumber, previewNumber, ref uiGeometry, deinterlace ? 1 : 0); hb_image_s image = InteropUtilities.ToStructureFromPtr <hb_image_s>(resultingImageStuct); // Copy the filled image buffer to a managed array. int stride_width = image.plane[0].stride; int stride_height = image.plane[0].height_stride; int imageBufferSize = stride_width * stride_height; // int imageBufferSize = outputWidth * outputHeight * 4; byte[] managedBuffer = new byte[imageBufferSize]; Marshal.Copy(image.plane[0].data, managedBuffer, 0, imageBufferSize); var bitmap = new Bitmap(image.width, image.height); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, image.width, image.height), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb); IntPtr ptr = bitmapData.Scan0; // Pointer to the first pixel. for (int i = 0; i < image.height; i++) { try { Marshal.Copy(managedBuffer, i * stride_width, ptr, stride_width); ptr = IntPtr.Add(ptr, image.width * 4); } catch (Exception exc) { Debug.WriteLine(exc); // In theory, this will allow a partial image display if this happens. TODO add better logging of this. } } bitmap.UnlockBits(bitmapData); // Close the image so we don't leak memory. IntPtr nativeJobPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(nativeJobPtrPtr, resultingImageStuct); HBFunctions.hb_image_close(nativeJobPtrPtr); Marshal.FreeHGlobal(nativeJobPtrPtr); // Converts Bitmap into MemoryStream for transport. var memoryStream = new MemoryStream(); try { bitmap.Save(memoryStream, ImageFormat.Bmp); } finally { bitmap.Dispose(); } return(memoryStream); }
public BitmapImage GetPreview(PreviewSettings settings, int previewNumber) { SourceTitle title = this.Titles.TitleList.FirstOrDefault(t => t.Index == settings.TitleNumber); Validate.NotNull(title, "GetPreview: Title should not have been null. This is probably a bug."); // Create the Expected Output Geometry details for libhb. hb_geometry_settings_s uiGeometry = new hb_geometry_settings_s { crop = new[] { settings.Cropping.Top, settings.Cropping.Bottom, settings.Cropping.Left, settings.Cropping.Right }, itu_par = 0, keep = (int)AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH + (settings.KeepDisplayAspect ? 0x04 : 0), // TODO Keep Width? maxWidth = settings.MaxWidth, maxHeight = settings.MaxHeight, mode = (int)(hb_anamorphic_mode_t)settings.Anamorphic, modulus = settings.Modulus ?? 16, geometry = new hb_geometry_s { height = settings.Height, width = settings.Width, par = settings.Anamorphic != Anamorphic.Custom ? new hb_rational_t { den = title.Geometry.PAR.Den, num = title.Geometry.PAR.Num } : new hb_rational_t { den = settings.PixelAspectY, num = settings.PixelAspectX } } }; // Sanitize the input. Geometry resultGeometry = AnamorphicFactory.CreateGeometry(settings, new SourceVideoInfo(new Size(title.Geometry.Width, title.Geometry.Height), new Size(title.Geometry.PAR.Num, title.Geometry.PAR.Den))); int width = resultGeometry.Width * resultGeometry.PAR.Num / resultGeometry.PAR.Den; int height = resultGeometry.Height; uiGeometry.geometry.width = width; uiGeometry.geometry.height = height; uiGeometry.geometry.par.num = settings.PixelAspectX; uiGeometry.geometry.par.den = settings.PixelAspectY; // Fetch the image data from LibHb IntPtr resultingImageStuct = HBFunctions.hb_get_preview2(this.hbHandle, settings.TitleNumber, previewNumber, ref uiGeometry, 0); hb_image_s image = InteropUtilities.ToStructureFromPtr <hb_image_s>(resultingImageStuct); // Copy the filled image buffer to a managed array. int stride_width = image.plane[0].stride; int stride_height = image.plane[0].height_stride; int imageBufferSize = stride_width * stride_height; // int imageBufferSize = outputWidth * outputHeight * 4; byte[] managedBuffer = new byte[imageBufferSize]; Marshal.Copy(image.plane[0].data, managedBuffer, 0, imageBufferSize); var bitmap = new Bitmap(width, height); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb); IntPtr ptr = bitmapData.Scan0; // Pointer to the first pixel. for (int i = 0; i < image.height; i++) { try { Marshal.Copy(managedBuffer, i * stride_width, ptr, stride_width); ptr = IntPtr.Add(ptr, width * 4); } catch (Exception exc) { Debug.WriteLine(exc); // In theory, this will allow a partial image display if this happens. TODO add better logging of this. } } bitmap.UnlockBits(bitmapData); // Close the image so we don't leak memory. IntPtr nativeJobPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(nativeJobPtrPtr, resultingImageStuct); HBFunctions.hb_image_close(nativeJobPtrPtr); Marshal.FreeHGlobal(nativeJobPtrPtr); // Create a Bitmap Image for display. using (var memoryStream = new MemoryStream()) { try { bitmap.Save(memoryStream, ImageFormat.Bmp); } finally { bitmap.Dispose(); } var wpfBitmap = new BitmapImage(); wpfBitmap.BeginInit(); wpfBitmap.CacheOption = BitmapCacheOption.OnLoad; wpfBitmap.StreamSource = memoryStream; wpfBitmap.EndInit(); wpfBitmap.Freeze(); return(wpfBitmap); } }
public bool isMarriageCert() { return(SourceMedium.Contains("Official Document") && SourceTitle.ToUpper().IndexOf(MARRIAGECERT) >= 0); }
public QueueTitlesWindowViewModel() { this.main = StaticResolver.Resolve <MainViewModel>(); this.PickersService = StaticResolver.Resolve <PickersService>(); this.windowManager = StaticResolver.Resolve <IWindowManager>(); this.titleStartOverrideEnabled = Config.QueueTitlesUseTitleOverride; this.titleStartOverride = Config.QueueTitlesTitleOverride; this.nameOverrideEnabled = Config.QueueTitlesUseNameOverride; this.nameOverride = Config.QueueTitlesNameOverride; this.RefreshTitles(); this.main.WhenAnyValue(x => x.SourceData) .Skip(1) .Subscribe(_ => { this.RefreshTitles(); }); this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectEnabled) .Skip(1) .Subscribe(_ => { this.SetSelectedFromRange(); }); this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectStartMinutes) .Skip(1) .Subscribe(_ => { this.SetSelectedFromRange(); }); this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectEndMinutes) .Skip(1) .Subscribe(_ => { this.SetSelectedFromRange(); }); this.SelectedTitles.CollectionChanged += (sender, args) => { this.RaisePropertyChanged(nameof(this.TitleDetailsVisible)); if (this.SelectedTitles.Count == 1) { SourceTitle title = this.SelectedTitles[0].Title; // Do preview var previewProfile = new VCProfile { CustomCropping = true, Cropping = new VCCropping(), VideoEncoder = "x264", AudioEncodings = new List <AudioEncoding>() }; this.PreviewImage = BitmapUtilities.ConvertToBitmapImage(BitmapUtilities.ConvertByteArrayToBitmap(this.main.ScanInstance.GetPreview(previewProfile.CreatePreviewSettings(title), 2, deinterlace: false))); this.RaisePropertyChanged(nameof(this.TitleText)); } }; }
public AudioEncodingViewModel(AudioEncoding audioEncoding, SourceTitle selectedTitle, List <int> chosenAudioTracks, AudioPanelViewModel audioPanelVM) { this.initializing = true; this.audioPanelVM = audioPanelVM; this.targetStreams = new ObservableCollection <TargetStreamViewModel>(); this.targetStreamIndex = audioEncoding.InputNumber; this.SetChosenTracks(chosenAudioTracks, selectedTitle); this.audioEncoders = new List <AudioEncoderViewModel>(); this.mixdownChoices = new List <MixdownViewModel>(); this.RefreshEncoderChoices(); this.presetChangeSubscription = this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(profile => { this.containerSubscription?.Dispose(); this.containerSubscription = profile.WhenAnyValue(x => x.ContainerName) .Skip(1) .Subscribe(_ => { this.RefreshEncoderChoices(isContainerChange: true); }); this.audioPanelVM.SuppressProfileEdits = true; this.RefreshEncoderChoices(); this.audioPanelVM.SuppressProfileEdits = false; }); HBAudioEncoder hbAudioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(audioEncoding.Encoder); if (hbAudioEncoder.IsPassthrough) { this.selectedAudioEncoder = this.audioEncoders[0]; this.selectedPassthrough = audioEncoding.Encoder; } else { this.selectedAudioEncoder = this.audioEncoders.Skip(1).FirstOrDefault(e => e.Encoder.ShortName == audioEncoding.Encoder); this.selectedPassthrough = "copy"; } if (this.selectedAudioEncoder == null) { this.selectedAudioEncoder = this.audioEncoders[1]; } this.RefreshMixdownChoices(); this.RefreshBitrateChoices(); this.RefreshSampleRateChoices(); this.SelectMixdown(HandBrakeEncoderHelpers.GetMixdown(audioEncoding.Mixdown)); this.sampleRate = audioEncoding.SampleRateRaw; if (!this.HBAudioEncoder.SupportsQuality) { this.encodeRateType = AudioEncodeRateType.Bitrate; } else { this.encodeRateType = audioEncoding.EncodeRateType; } this.audioQuality = audioEncoding.Quality; if (audioEncoding.Compression >= 0) { this.audioCompression = audioEncoding.Compression; } else { this.audioCompression = this.HBAudioEncoder.DefaultCompression; } this.selectedBitrate = this.BitrateChoices.SingleOrDefault(b => b.Bitrate == audioEncoding.Bitrate); if (this.selectedBitrate == null) { this.selectedBitrate = this.BitrateChoices.First(); } this.gain = audioEncoding.Gain; this.drc = audioEncoding.Drc; this.passthroughIfPossible = audioEncoding.PassthroughIfPossible; this.name = audioEncoding.Name; // EncoderSettingsVisible this.WhenAnyValue(x => x.SelectedAudioEncoder, x => x.SelectedPassthrough, (audioEncoder, passthrough) => { if (audioEncoder == null) { return(false); } if (passthrough == null) { return(false); } return(!GetHBAudioEncoder(audioEncoder, passthrough).IsPassthrough); }).ToProperty(this, x => x.EncoderSettingsVisible, out this.encoderSettingsVisible); // AudioCompressionVisible this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { return(!audioEncoder.IsPassthrough && audioEncoder.Encoder.SupportsCompression); }).ToProperty(this, x => x.AudioCompressionVisible, out this.audioCompressionVisible); // PassthroughIfPossibleVisible this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(false); } if (HandBrakeEncoderHelpers.AudioEncoders.Any(e => e.Id == (NativeConstants.HB_ACODEC_PASS_FLAG | audioEncoder.Encoder.Id))) { return(true); } return(audioEncoder.Encoder.ShortName.ToLowerInvariant().Contains("aac") || audioEncoder.Encoder.ShortName.ToLowerInvariant().Contains("mp3")); }).ToProperty(this, x => x.PassthroughIfPossibleVisible, out this.passthroughIfPossibleVisible); // BitrateVisible this.WhenAnyValue( x => x.SelectedAudioEncoder, x => x.EncoderSettingsVisible, x => x.SelectedMixdown, x => x.EncodeRateType, (audioEncoder, encoderSettingsVisible, mixdown, encodeRateType) => { if (audioEncoder.IsPassthrough) { return(false); } if (encoderSettingsVisible && mixdown != null && encodeRateType == AudioEncodeRateType.Bitrate) { // We only need to find out if the bitrate limits exist, so pass in some normal values for sample rate and mixdown. BitrateLimits bitrateLimits = HandBrakeEncoderHelpers.GetBitrateLimits(audioEncoder.Encoder, 48000, HandBrakeEncoderHelpers.GetMixdown("dpl2")); return(bitrateLimits.High > 0); } return(false); }).ToProperty(this, x => x.BitrateVisible, out this.bitrateVisible); // BitrateLabelVisible this.WhenAnyValue(x => x.BitrateVisible, x => x.SelectedAudioEncoder, (bitrateVisible, audioEncoder) => { return(!audioEncoder.IsPassthrough && bitrateVisible && !audioEncoder.Encoder.SupportsQuality); }).ToProperty(this, x => x.BitrateLabelVisible, out this.bitrateLabelVisible); // AudioQualityVisible this.WhenAnyValue(x => x.SelectedAudioEncoder, x => x.EncodeRateType, (audioEncoder, encodeRateType) => { return(!audioEncoder.IsPassthrough && audioEncoder.Encoder.SupportsQuality && encodeRateType == AudioEncodeRateType.Quality); }).ToProperty(this, x => x.AudioQualityVisible, out this.audioQualityVisible); // AudioQualityRadioVisible this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { return(!audioEncoder.IsPassthrough && audioEncoder.Encoder.SupportsQuality); }).ToProperty(this, x => x.AudioQualityRadioVisible, out this.audioQualityRadioVisible); // AudioQualityMinimum this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(0); } return(Math.Round(audioEncoder.Encoder.QualityLimits.Low, RangeRoundDigits)); }).ToProperty(this, x => x.AudioQualityMinimum, out this.audioQualityMinimum); // AudioQualityMaximum this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(0); } return(Math.Round(audioEncoder.Encoder.QualityLimits.High, RangeRoundDigits)); }).ToProperty(this, x => x.AudioQualityMaximum, out this.audioQualityMaximum); // AudioQualityGranularity this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(0); } return(Math.Round(audioEncoder.Encoder.QualityLimits.Granularity, RangeRoundDigits)); }).ToProperty(this, x => x.AudioQualityGranularity, out this.audioQualityGranularity); // AudioQualityToolTip this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(string.Empty); } string directionSentence; if (audioEncoder.Encoder.QualityLimits.Ascending) { directionSentence = EncodingRes.AscendingQualityToolTip; } else { directionSentence = EncodingRes.DescendingQualityToolTip; } return(string.Format( EncodingRes.AudioQualityToolTip, directionSentence, audioEncoder.Encoder.QualityLimits.Low, audioEncoder.Encoder.QualityLimits.High)); }).ToProperty(this, x => x.AudioQualityToolTip, out this.audioQualityToolTip); // AudioCompressionMinimum this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(0); } return(Math.Round(audioEncoder.Encoder.CompressionLimits.Low, RangeRoundDigits)); }).ToProperty(this, x => x.AudioCompressionMinimum, out this.audioCompressionMinimum); // AudioCompressionMaximum this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(0); } return(Math.Round(audioEncoder.Encoder.CompressionLimits.High, RangeRoundDigits)); }).ToProperty(this, x => x.AudioCompressionMaximum, out this.audioCompressionMaximum); // AudioCompressionGranularity this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(0); } return(Math.Round(audioEncoder.Encoder.CompressionLimits.Granularity, RangeRoundDigits)); }).ToProperty(this, x => x.AudioCompressionGranularity, out this.audioCompressionGranularity); // AudioCompressionToolTip this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { if (audioEncoder.IsPassthrough) { return(string.Empty); } string directionSentence; if (audioEncoder.Encoder.QualityLimits.Ascending) { directionSentence = EncodingRes.AscendingCompressionToolTip; } else { directionSentence = EncodingRes.DescendingCompressionToolTip; } return(string.Format( EncodingRes.AudioCompressionToolTip, directionSentence, audioEncoder.Encoder.CompressionLimits.Low, audioEncoder.Encoder.CompressionLimits.High)); }).ToProperty(this, x => x.AudioCompressionToolTip, out this.audioCompressionToolTip); // PassthroughChoicesVisible this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder => { return(audioEncoder.IsPassthrough); }).ToProperty(this, x => x.PassthroughChoicesVisible, out this.passthroughChoicesVisible); this.selectedTitleSubscription = this.main.WhenAnyValue(x => x.SelectedTitle) .Skip(1) .Subscribe(_ => { this.RefreshFromNewInput(); }); this.audioTrackChangedSubscription = this.main.AudioTracks.Connect().WhenAnyPropertyChanged().Subscribe(_ => { this.RefreshFromNewInput(); }); Config.Observables.ShowAudioTrackNameField.ToProperty(this, x => x.NameVisible, out this.nameVisible); this.initializing = false; }
public Title CreateTitle(SourceTitle title, int mainFeature) { Title converted = new Title { TitleNumber = title.Index, Duration = new TimeSpan(0, title.Duration.Hours, title.Duration.Minutes, title.Duration.Seconds), Resolution = new Size(title.Geometry.Width, title.Geometry.Height), AngleCount = title.AngleCount, ParVal = new Size(title.Geometry.PAR.Num, title.Geometry.PAR.Den), AutoCropDimensions = new Cropping { Top = title.Crop[0], Bottom = title.Crop[1], Left = title.Crop[2], Right = title.Crop[3] }, Fps = ((double)title.FrameRate.Num) / title.FrameRate.Den, SourceName = title.Path, MainTitle = mainFeature == title.Index, Playlist = title.Type == 1 ? string.Format(" {0:d5}.MPLS", title.Playlist).Trim() : null, FramerateNumerator = title.FrameRate.Num, FramerateDenominator = title.FrameRate.Den, Type = title.Type }; int currentTrack = 1; foreach (SourceChapter chapter in title.ChapterList) { string chapterName = !string.IsNullOrEmpty(chapter.Name) ? chapter.Name : string.Empty; converted.Chapters.Add(new Chapter(currentTrack, chapterName, new TimeSpan(chapter.Duration.Hours, chapter.Duration.Minutes, chapter.Duration.Seconds))); currentTrack++; } int currentAudioTrack = 1; foreach (SourceAudioTrack track in title.AudioList) { converted.AudioTracks.Add(new Audio(currentAudioTrack, track.Language, track.LanguageCode, track.Description, track.Codec, track.SampleRate, track.BitRate, track.ChannelLayout, track.Name)); currentAudioTrack++; } int currentSubtitleTrack = 1; foreach (SourceSubtitleTrack track in title.SubtitleList) { SubtitleType convertedType = new SubtitleType(); switch (track.Source) { case 0: convertedType = SubtitleType.VobSub; break; case 4: convertedType = SubtitleType.UTF8Sub; break; case 5: convertedType = SubtitleType.TX3G; break; case 6: convertedType = SubtitleType.SSA; break; case 1: convertedType = SubtitleType.SRT; break; case 2: convertedType = SubtitleType.CC; break; case 3: convertedType = SubtitleType.CC; break; case 7: convertedType = SubtitleType.PGS; break; } bool canBurn = HBFunctions.hb_subtitle_can_burn(track.Source) > 0; bool canSetForcedOnly = HBFunctions.hb_subtitle_can_force(track.Source) > 0; converted.Subtitles.Add(new Subtitle(track.Source, currentSubtitleTrack, track.Language, track.LanguageCode, convertedType, canBurn, canSetForcedOnly, track.Name)); currentSubtitleTrack++; } SourceMetadata metadata = title.MetaData; if (title.MetaData != null) { converted.Metadata = new Metadata( metadata.AlbumArtist, metadata.Album, metadata.Artist, metadata.Comment, metadata.Composer, metadata.Description, metadata.Genre, metadata.LongDescription, metadata.Name, metadata.ReleaseDate); } return(converted); }
public TitleSelectionViewModel(SourceTitle title, QueueTitlesWindowViewModel titlesDialogVM) { this.Title = title; this.titlesDialogVM = titlesDialogVM; }
public bool isCensusCert() { return(SourceMedium.Equals("Official Document") && SourceTitle.ToUpper().IndexOf(CENSUSCERT) >= 0); }
public QueueTitlesWindowViewModel() { this.main = Ioc.Get <MainViewModel>(); this.PickersService = Ioc.Get <PickersService>(); this.windowManager = Ioc.Get <IWindowManager>(); this.selectedTitles = new ReactiveList <TitleSelectionViewModel>(); this.titleStartOverrideEnabled = Config.QueueTitlesUseTitleOverride; this.titleStartOverride = Config.QueueTitlesTitleOverride; this.nameOverrideEnabled = Config.QueueTitlesUseNameOverride; this.nameOverride = Config.QueueTitlesNameOverride; this.titles = new ReactiveList <TitleSelectionViewModel>(); this.RefreshTitles(); this.Play = ReactiveCommand.Create(MvvmUtilities.CreateConstantObservable(Players.Installed.Count > 0)); this.Play.Subscribe(_ => this.PlayImpl()); this.AddToQueue = ReactiveCommand.Create(); this.AddToQueue.Subscribe(_ => this.AddToQueueImpl()); this.main.WhenAnyValue(x => x.SourceData) .Skip(1) .Subscribe(_ => { this.RefreshTitles(); }); this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectEnabled) .Skip(1) .Subscribe(_ => { this.SetSelectedFromRange(); }); this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectStartMinutes) .Skip(1) .Subscribe(_ => { this.SetSelectedFromRange(); }); this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectEndMinutes) .Skip(1) .Subscribe(_ => { this.SetSelectedFromRange(); }); this.selectedTitles.CountChanged .Select(count => count == 1) .ToProperty(this, x => x.TitleDetailsVisible, out this.titleDetailsVisible, initialValue: false); this.selectedTitles.CollectionChanged += (sender, args) => { if (this.selectedTitles.Count == 1) { SourceTitle title = this.selectedTitles[0].Title; // Do preview var previewProfile = new VCProfile { CustomCropping = true, Cropping = new VCCropping(), VideoEncoder = "x264", AudioEncodings = new List <AudioEncoding>() }; var previewJob = new VCJob { RangeType = VideoRangeType.All, Title = title.Index, EncodingProfile = previewProfile }; this.PreviewImage = this.main.ScanInstance.GetPreview(previewProfile.CreatePreviewSettings(title), 2); this.RaisePropertyChanged(nameof(this.TitleText)); } }; }
public bool isDeathCert() { return(SourceMedium.Contains("Official Document") && SourceTitle.ToUpper().IndexOf(DEATHCERT) >= 0); }