Example #1
0
        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);
        }
Example #3
0
        /// <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));
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        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));
        }
Example #10
0
        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
            });
        }
Example #11
0
        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
            });
        }
Example #12
0
        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));
            });
        }
Example #13
0
 public static int GetEstimatedFrames(this SourceTitle title)
 {
     return((int)Math.Ceiling(title.Duration.ToSpan().TotalSeconds *title.FrameRate.ToDouble()));
 }
Example #14
0
 public bool IsDeathCert() => SourceMedium.Contains("Official Document") &&
 SourceTitle.ToUpper().IndexOf(DEATHCERT, StringComparison.Ordinal) >= 0;
Example #15
0
 public bool IsCensusCert() => SourceMedium.Equals("Official Document") &&
 SourceTitle.ToUpper().IndexOf(CENSUSCERT, StringComparison.Ordinal) >= 0;
Example #16
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);
        }
Example #17
0
 public bool IsMarriageCert() => SourceMedium.Contains("Official Document") &&
 SourceTitle.ToUpper().IndexOf(MARRIAGECERT, StringComparison.Ordinal) >= 0;
Example #18
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);
        }
Example #20
0
        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);
            }
        }
Example #21
0
 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));
                }
            };
        }
Example #23
0
        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);
        }
Example #25
0
 public TitleSelectionViewModel(SourceTitle title, QueueTitlesWindowViewModel titlesDialogVM)
 {
     this.Title          = title;
     this.titlesDialogVM = titlesDialogVM;
 }
Example #26
0
 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));
                }
            };
        }
Example #28
0
 public bool isDeathCert()
 {
     return(SourceMedium.Contains("Official Document") &&
            SourceTitle.ToUpper().IndexOf(DEATHCERT) >= 0);
 }