public static string GetExtensionForProfile(VCProfile profile, bool includeDot = true)
        {
            HBContainer container = HandBrakeEncoderHelpers.GetContainer(profile.ContainerName);

            if (container == null)
            {
                throw new ArgumentException("Could not find container with name " + profile.ContainerName, nameof(profile));
            }

            string extension;

            if (container.DefaultExtension == "mkv")
            {
                extension = "mkv";
            }
            else if (container.DefaultExtension == "mp4" && profile.PreferredExtension == VCOutputExtension.Mp4)
            {
                extension = "mp4";
            }
            else
            {
                extension = "m4v";
            }

            return(includeDot ? "." + extension : extension);
        }
Example #2
0
        private void RefreshCopyMaskChoices()
        {
            List <CopyMaskChoiceViewModel> oldChoices = new List <CopyMaskChoiceViewModel>(this.copyMaskChoices.Items);

            this.copyMaskChoices.Edit(copyMaskChoicesInnerList =>
            {
                copyMaskChoicesInnerList.Clear();

                HBContainer container = HandBrakeEncoderHelpers.GetContainer(this.EncodingWindowViewModel.Profile.ContainerName);
                foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders)
                {
                    if ((encoder.CompatibleContainers & container.Id) > 0 && encoder.IsPassthrough && encoder.ShortName != AudioEncodingViewModel.AutoPassthroughEncoder)
                    {
                        bool enabled = true;
                        string codec = encoder.ShortName.Substring(5);
                        CopyMaskChoiceViewModel oldChoice = oldChoices.FirstOrDefault(choice => choice.Codec == codec);
                        if (oldChoice != null)
                        {
                            enabled = oldChoice.Enabled;
                        }

                        copyMaskChoicesInnerList.Add(new CopyMaskChoiceViewModel(codec, enabled));
                    }
                }
            });
        }
        public SubtitleDialogViewModel(Subtitles currentSubtitles)
        {
            this.container = Encoders.GetContainer(this.presetsViewModel.SelectedPreset.Preset.EncodingProfile.ContainerName);

            this.sourceSubtitles = new ObservableCollection <SourceSubtitleViewModel>();
            this.srtSubtitles    = new ObservableCollection <SrtSubtitleViewModel>();

            if (currentSubtitles != null)
            {
                if (!currentSubtitles.SourceSubtitles.Any(s => s.TrackNumber == 0))
                {
                    this.sourceSubtitles.Add(
                        new SourceSubtitleViewModel(
                            this,
                            new SourceSubtitle
                    {
                        TrackNumber = 0,
                        BurnedIn    = false,
                        Forced      = false,
                        Default     = false
                    }));
                }

                foreach (SourceSubtitle subtitle in currentSubtitles.SourceSubtitles)
                {
                    this.sourceSubtitles.Add(new SourceSubtitleViewModel(this, subtitle.Clone())
                    {
                        Selected = true
                    });
                }

                foreach (SrtSubtitle subtitle in currentSubtitles.SrtSubtitles)
                {
                    this.srtSubtitles.Add(new SrtSubtitleViewModel(this, subtitle.Clone()));
                }
            }

            // Fill in remaining unselected source subtitles
            foreach (Subtitle subtitle in this.mainViewModel.SelectedTitle.Subtitles)
            {
                if (!currentSubtitles.SourceSubtitles.Any(s => s.TrackNumber == subtitle.TrackNumber))
                {
                    var newSubtitle = new SourceSubtitle
                    {
                        TrackNumber = subtitle.TrackNumber,
                        Default     = false,
                        Forced      = false,
                        BurnedIn    = false
                    };

                    this.sourceSubtitles.Add(new SourceSubtitleViewModel(this, newSubtitle));
                }
            }

            this.sourceSubtitles.CollectionChanged += this.SourceCollectionChanged;
            this.srtSubtitles.CollectionChanged    += this.SrtCollectionChanged;

            this.UpdateBoxes();
        }
Example #4
0
        private void RefreshEncoderChoices(string containerName, EncoderChoicesRefreshSource refreshSource)
        {
            HBContainer container = HandBrakeEncoderHelpers.GetContainer(containerName);

            HBVideoEncoder oldEncoder = null;

            if (this.selectedEncoder != null)
            {
                oldEncoder = this.selectedEncoder.Encoder;
            }

            this.encoderChoices = new List <VideoEncoderViewModel>();

            foreach (HBVideoEncoder encoder in HandBrakeEncoderHelpers.VideoEncoders)
            {
                if ((encoder.CompatibleContainers & container.Id) > 0)
                {
                    this.EncoderChoices.Add(new VideoEncoderViewModel {
                        Encoder = encoder
                    });
                }
            }

            this.RaisePropertyChanged(nameof(this.EncoderChoices));

            HBVideoEncoder targetEncoder;

            switch (refreshSource)
            {
            case EncoderChoicesRefreshSource.ContainerChange:
                targetEncoder = oldEncoder;
                break;

            case EncoderChoicesRefreshSource.ProfileChange:
                targetEncoder = HandBrakeEncoderHelpers.GetVideoEncoder(this.Profile.VideoEncoder);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(refreshSource), refreshSource, null);
            }

            this.selectedEncoder = this.EncoderChoices.FirstOrDefault(e => e.Encoder == targetEncoder);

            if (this.selectedEncoder == null)
            {
                this.selectedEncoder = this.EncoderChoices[0];
            }

            // If it's a container change we need to commit the new encoder change.
            if (refreshSource == EncoderChoicesRefreshSource.ContainerChange && this.selectedEncoder.Encoder != oldEncoder)
            {
                this.UpdateProfileProperty(nameof(this.Profile.VideoEncoder), this.selectedEncoder.Encoder.ShortName, raisePropertyChanged: false);
                this.SetDefaultQuality();
            }

            this.RaisePropertyChanged(nameof(this.SelectedEncoder));
        }
        public void UpdateWarningVisibility()
        {
            bool        textSubtitleVisible = false;
            VCProfile   profile             = this.presetsViewModel.SelectedPreset.Preset.EncodingProfile;
            HBContainer profileContainer    = Encoders.GetContainer(profile.ContainerName);

            if (profileContainer.DefaultExtension == "mp4" && profile.PreferredExtension == VCOutputExtension.Mp4)
            {
                foreach (SourceSubtitleViewModel sourceVM in this.SourceSubtitles)
                {
                    if (sourceVM.Selected && sourceVM.SubtitleName.Contains("(Text)"))
                    {
                        textSubtitleVisible = true;
                        break;
                    }
                }
            }

            this.TextSubtitleWarningVisibile = textSubtitleVisible;

            bool anyBurned   = false;
            int  totalTracks = 0;

            foreach (SourceSubtitleViewModel sourceVM in this.SourceSubtitles)
            {
                if (sourceVM.Selected)
                {
                    totalTracks++;
                    if (sourceVM.BurnedIn)
                    {
                        anyBurned = true;
                    }
                }
            }

            foreach (SrtSubtitleViewModel srtVM in this.SrtSubtitles)
            {
                totalTracks++;
                if (srtVM.BurnedIn)
                {
                    anyBurned = true;
                }
            }

            this.BurnedOverlapWarningVisible = anyBurned && totalTracks > 1;
        }
Example #6
0
        private void RefreshFallbackEncoderChoices()
        {
            if (this.EncodingWindowViewModel.Profile == null)
            {
                return;
            }

            HBContainer    container  = HandBrakeEncoderHelpers.GetContainer(this.EncodingWindowViewModel.Profile.ContainerName);
            HBAudioEncoder oldEncoder = null;

            if (this.audioEncoderFallback != null)
            {
                oldEncoder = this.audioEncoderFallback.Encoder;
            }

            this.fallbackEncoderChoices = new List <AudioEncoderViewModel>();

            this.FallbackEncoderChoices.Add(new AudioEncoderViewModel {
                Encoder = HandBrakeEncoderHelpers.GetAudioEncoder("none")
            });

            foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders)
            {
                if ((encoder.CompatibleContainers & container.Id) > 0 && !encoder.IsPassthrough)
                {
                    this.FallbackEncoderChoices.Add(new AudioEncoderViewModel {
                        Encoder = encoder
                    });
                }
            }

            this.RaisePropertyChanged(nameof(this.FallbackEncoderChoices));

            this.audioEncoderFallback = this.FallbackEncoderChoices.FirstOrDefault(e => e.Encoder == oldEncoder);

            if (this.audioEncoderFallback == null)
            {
                this.audioEncoderFallback = this.FallbackEncoderChoices[1];
            }

            this.RaisePropertyChanged(nameof(this.AudioEncoderFallback));
        }
Example #7
0
        public static string GetExtensionForProfile(VCProfile profile, bool includeDot = true)
        {
            HBContainer container = Encoders.GetContainer(profile.ContainerName);

            string extension;

            if (container.DefaultExtension == "mkv")
            {
                extension = "mkv";
            }
            else if (container.DefaultExtension == "mp4" && profile.PreferredExtension == VCOutputExtension.Mp4)
            {
                extension = "mp4";
            }
            else
            {
                extension = "m4v";
            }

            return(includeDot ? "." + extension : extension);
        }
Example #8
0
        private void RefreshEncoderChoices(string containerName, bool applyDefaults)
        {
            HBContainer container = Encoders.GetContainer(containerName);

            HBVideoEncoder oldEncoder = null;

            if (this.selectedEncoder != null)
            {
                oldEncoder = this.selectedEncoder.Encoder;
            }

            this.encoderChoices = new List <VideoEncoderViewModel>();

            foreach (HBVideoEncoder encoder in Encoders.VideoEncoders)
            {
                if ((encoder.CompatibleContainers & container.Id) > 0)
                {
                    this.EncoderChoices.Add(new VideoEncoderViewModel {
                        Encoder = encoder
                    });
                }
            }

            this.RaisePropertyChanged(() => this.EncoderChoices);

            this.selectedEncoder = this.EncoderChoices.FirstOrDefault(e => e.Encoder == oldEncoder);

            if (this.selectedEncoder == null)
            {
                this.selectedEncoder = this.EncoderChoices[0];
            }

            if (this.selectedEncoder.Encoder != oldEncoder)
            {
                RefreshEncoderSettings(applyDefaults);
                this.NotifyEncoderChanged();
            }

            this.RaisePropertyChanged(() => this.SelectedEncoder);
        }
Example #9
0
        private void RefreshFallbackEncoderChoices()
        {
            if (this.EncodingViewModel.EncodingProfile == null)
            {
                return;
            }

            HBContainer    container  = Encoders.GetContainer(this.EncodingViewModel.EncodingProfile.ContainerName);
            HBAudioEncoder oldEncoder = null;

            if (this.selectedFallbackEncoder != null)
            {
                oldEncoder = this.selectedFallbackEncoder.Encoder;
            }

            this.fallbackEncoderChoices = new List <AudioEncoderViewModel>();

            foreach (HBAudioEncoder encoder in Encoders.AudioEncoders)
            {
                if ((encoder.CompatibleContainers & container.Id) > 0 && !encoder.IsPassthrough)
                {
                    this.FallbackEncoderChoices.Add(new AudioEncoderViewModel {
                        Encoder = encoder
                    });
                }
            }

            this.RaisePropertyChanged(() => this.FallbackEncoderChoices);

            this.selectedFallbackEncoder = this.FallbackEncoderChoices.FirstOrDefault(e => e.Encoder == oldEncoder);

            if (this.selectedFallbackEncoder == null)
            {
                this.selectedFallbackEncoder = this.FallbackEncoderChoices[0];
            }

            this.RaisePropertyChanged(() => this.SelectedFallbackEncoder);
        }
        public ContainerPanelViewModel(EncodingWindowViewModel encodingWindowViewModel)
            : base(encodingWindowViewModel)
        {
            this.AutomaticChange = true;

            this.RegisterProfileProperties();

            this.containerChoices = new List <ComboChoice>();
            foreach (HBContainer hbContainer in HandBrakeEncoderHelpers.Containers)
            {
                this.containerChoices.Add(new ComboChoice(hbContainer.ShortName, hbContainer.DefaultExtension.ToUpperInvariant()));
            }

            this.WhenAnyValue(
                x => x.ContainerName,
                containerName =>
            {
                HBContainer container = HandBrakeEncoderHelpers.GetContainer(containerName);
                return(container.DefaultExtension == "mp4");
            })
            .ToProperty(this, x => x.ShowMp4Choices, out this.showMp4Choices);

            this.AutomaticChange = false;
        }
        public EncodingWindowViewModel()
        {
            this.AutomaticChange = true;

            this.RegisterProfileProperties();

            this.containerChoices = new List <ComboChoice>();
            foreach (HBContainer hbContainer in HandBrakeEncoderHelpers.Containers)
            {
                this.containerChoices.Add(new ComboChoice(hbContainer.ShortName, hbContainer.DefaultExtension.ToUpperInvariant()));
            }

            this.WhenAnyValue(
                x => x.ContainerName,
                containerName =>
            {
                HBContainer container = HandBrakeEncoderHelpers.GetContainer(containerName);
                return(container.DefaultExtension == "mp4");
            })
            .ToProperty(this, x => x.ShowMp4Choices, out this.showMp4Choices);

            this.PresetsService.WhenAnyValue(x => x.SelectedPreset.DisplayNameWithStar)
            .ToProperty(this, x => x.WindowTitle, out this.windowTitle);

            this.PresetsService.WhenAnyValue(
                x => x.SelectedPreset.Preset.IsBuiltIn,
                x => x.SelectedPreset.Preset.IsQueue,
                (isBuiltIn, isQueue) =>
            {
                return(!isBuiltIn && !isQueue);
            })
            .ToProperty(this, x => x.SaveRenameButtonsVisible, out this.saveRenameButtonsVisible);

            this.PresetsService.WhenAnyValue(
                x => x.SelectedPreset.Preset.IsBuiltIn,
                x => x.SelectedPreset.Preset.IsModified,
                x => x.SelectedPreset.Preset.IsQueue,
                (isBuiltIn, isModified, isQueue) =>
            {
                return(!isBuiltIn && !isModified && !isQueue);
            })
            .ToProperty(this, x => x.DeleteButtonVisible, out this.deleteButtonVisible);

            this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.IsBuiltIn)
            .ToProperty(this, x => x.IsBuiltIn, out this.isBuiltIn);


            this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile)
            .Subscribe(encodingProfile =>
            {
                if (!encodingProfile.UseAdvancedTab && this.SelectedTabIndex == AdvancedVideoTabIndex)
                {
                    this.SelectedTabIndex = VideoTabIndex;
                }
            });


            this.TogglePresetPanel = ReactiveCommand.Create();
            this.TogglePresetPanel.Subscribe(_ => this.TogglePresetPanelImpl());

            this.Save = ReactiveCommand.Create(this.WhenAnyValue(x => x.IsBuiltIn, isBuiltIn => !isBuiltIn));
            this.Save.Subscribe(_ => this.SaveImpl());

            this.SaveAs = ReactiveCommand.Create();
            this.SaveAs.Subscribe(_ => this.SaveAsImpl());

            this.Rename = ReactiveCommand.Create(this.WhenAnyValue(x => x.IsBuiltIn, isBuiltIn => !isBuiltIn));
            this.Rename.Subscribe(_ => this.RenameImpl());

            this.DeletePreset = ReactiveCommand.Create(this.PresetsService.WhenAnyValue(
                                                           x => x.SelectedPreset.Preset.IsBuiltIn,
                                                           x => x.SelectedPreset.Preset.IsModified,
                                                           (isBuiltIn, isModified) =>
            {
                return(!isBuiltIn || isModified);
            }));
            this.DeletePreset.Subscribe(_ => this.DeletePresetImpl());

            this.SizingPanelViewModel       = new SizingPanelViewModel(this);
            this.VideoFiltersPanelViewModel = new VideoFiltersPanelViewModel(this);
            this.VideoPanelViewModel        = new VideoPanelViewModel(this);
            this.AudioPanelViewModel        = new AudioPanelViewModel(this);
            this.AdvancedPanelViewModel     = new AdvancedPanelViewModel(this);

            this.presetPanelOpen = Config.EncodingListPaneOpen;

            this.selectedTabIndex = Config.EncodingDialogLastTab;

            this.AutomaticChange = false;
        }
Example #12
0
        public SubtitleDialogViewModel(VCSubtitles currentSubtitles)
        {
            this.container = HandBrakeEncoderHelpers.GetContainer(this.presetsService.SelectedPreset.Preset.EncodingProfile.ContainerName);

            this.sourceSubtitles = new ReactiveList <SourceSubtitleViewModel>();
            this.srtSubtitles    = new ReactiveList <SrtSubtitleViewModel>();

            if (currentSubtitles != null)
            {
                if (!currentSubtitles.SourceSubtitles.Any(s => s.TrackNumber == 0))
                {
                    this.sourceSubtitles.Add(
                        new SourceSubtitleViewModel(
                            this,
                            new SourceSubtitle
                    {
                        TrackNumber = 0,
                        BurnedIn    = false,
                        ForcedOnly  = false,
                        Default     = false
                    }));
                }

                foreach (SourceSubtitle subtitle in currentSubtitles.SourceSubtitles)
                {
                    this.sourceSubtitles.Add(new SourceSubtitleViewModel(this, subtitle.Clone())
                    {
                        Selected = true
                    });
                }

                foreach (SrtSubtitle subtitle in currentSubtitles.SrtSubtitles)
                {
                    this.srtSubtitles.Add(new SrtSubtitleViewModel(this, subtitle.Clone()));
                }
            }

            // Fill in remaining unselected source subtitles
            for (int i = 1; i <= this.mainViewModel.SelectedTitle.SubtitleList.Count; i++)
            {
                if (!currentSubtitles.SourceSubtitles.Any(s => s.TrackNumber == i))
                {
                    var newSubtitle = new SourceSubtitle
                    {
                        TrackNumber = i,
                        Default     = false,
                        ForcedOnly  = false,
                        BurnedIn    = false
                    };

                    this.sourceSubtitles.Add(new SourceSubtitleViewModel(this, newSubtitle));
                }
            }

            // HasSourceSubtitles
            this.sourceSubtitles.CountChanged.Select(count => count > 0)
            .ToProperty(this, x => x.HasSourceSubtitles, out this.hasSourceSubtitles, initialValue: this.sourceSubtitles.Count > 0);

            // AddSourceSubtitleToolTip
            this.mainViewModel
            .WhenAnyValue(x => x.SelectedTitle)
            .Select(selectedTitle =>
            {
                if (selectedTitle == null || selectedTitle.SubtitleList.Count == 0)
                {
                    return(SubtitleRes.AddSourceNoSubtitlesToolTip);
                }

                return(null);
            })
            .ToProperty(this, x => x.AddSourceSubtitleToolTip, out this.addSourceSubtitleToolTip);

            // HasSrtSubtitles
            this.srtSubtitles.CountChanged.Select(count => count > 0)
            .ToProperty(this, x => x.HasSrtSubtitles, out this.hasSrtSubtitles, initialValue: this.srtSubtitles.Count > 0);

            this.AddSrtSubtitle = ReactiveCommand.Create();
            this.AddSrtSubtitle.Subscribe(_ => this.AddSrtSubtitleImpl());

            this.UpdateBoxes();
        }
        public AudioPanelViewModel(EncodingWindowViewModel encodingWindowViewModel)
            : base(encodingWindowViewModel)
        {
            this.audioOutputPreviews = new ReactiveList <AudioOutputPreview>();
            this.audioEncodings      = new ReactiveList <AudioEncodingViewModel>();
            this.audioEncodings.ChangeTrackingEnabled = true;

            this.fallbackEncoderChoices = new List <AudioEncoderViewModel>();

            this.audioOutputPreviews.CountChanged
            .Select(c => c > 0)
            .Subscribe(hasAudioTracks =>
            {
                this.HasAudioTracks = hasAudioTracks;
            });

            this.AddAudioEncoding = ReactiveCommand.Create();
            this.AddAudioEncoding.Subscribe(_ => this.AddAudioEncodingImpl());

            this.main.WhenAnyValue(x => x.SelectedTitle)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.NotifyAudioInputChanged();
            });

            this.main.AudioChoiceChanged += (o, e) =>
            {
                this.NotifyAudioInputChanged();
            };

            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.ContainerName)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.RefreshFallbackEncoderChoices();
                this.RefreshCopyMaskChoices();
            });

            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile)
            .Subscribe(Observer.Create((VCProfile _) =>
            {
                this.OnProfileChanged();
            }));

            // AutoPassthroughSettingsVisible
            AudioEncodingViewModel audioEncodingViewModel;

            this.audioEncodings.ItemChanged
            .Where(x => x.PropertyName == nameof(audioEncodingViewModel.SelectedAudioEncoder) || x.PropertyName == nameof(audioEncodingViewModel.SelectedPassthrough))
            .Subscribe(_ =>
            {
                this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible));
            });
            this.audioEncodings.Changed
            .Subscribe(_ =>
            {
                this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible));
            });

            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioEncoderFallback)
            .Subscribe(audioEncoderFallback =>
            {
                if (!this.userUpdatingFallbackEncoder)
                {
                    this.audioEncoderFallback = this.fallbackEncoderChoices.FirstOrDefault(c => c.Encoder.ShortName == audioEncoderFallback);
                    if (this.audioEncoderFallback == null)
                    {
                        this.audioEncoderFallback = this.fallbackEncoderChoices[0];
                    }

                    this.RaisePropertyChanged(nameof(this.AudioEncoderFallback));
                }
            });

            // Make user updates change the profile
            CopyMaskChoiceViewModel copyMaskChoiceViewModel;

            this.CopyMaskChoices.ChangeTrackingEnabled = true;
            this.CopyMaskChoices.ItemChanged
            .Where(x => x.PropertyName == nameof(copyMaskChoiceViewModel.Enabled))
            .Subscribe(_ =>
            {
                this.userUpdatingCopyMask = true;
                this.SaveCopyMasksToProfile();
                this.userUpdatingCopyMask = false;

                this.RefreshAudioPreview();
            });

            // Make profile changes update the local mask choices
            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioCopyMask)
            .Subscribe(audioCopyMask =>
            {
                if (this.userUpdatingCopyMask)
                {
                    return;
                }

                using (this.CopyMaskChoices.SuppressChangeNotifications())
                {
                    this.CopyMaskChoices.Clear();

                    HBContainer container = HandBrakeEncoderHelpers.GetContainer(this.EncodingWindowViewModel.Profile.ContainerName);
                    foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders)
                    {
                        if ((encoder.CompatibleContainers & container.Id) > 0 && encoder.IsPassthrough && encoder.ShortName != AudioEncodingViewModel.AutoPassthroughEncoder)
                        {
                            bool enabled = true;
                            string codec = encoder.ShortName.Substring(5);

                            if (audioCopyMask != null)
                            {
                                CopyMaskChoice profileMaskChoice = audioCopyMask.FirstOrDefault(choice => choice.Codec == codec);
                                if (profileMaskChoice != null)
                                {
                                    enabled = profileMaskChoice.Enabled;
                                }
                            }

                            this.CopyMaskChoices.Add(new CopyMaskChoiceViewModel(codec, enabled));
                        }
                    }
                }

                this.RefreshAudioPreview();
            });

            this.RegisterProfileProperties();
        }
Example #14
0
        private void RefreshEncoderChoices(bool isContainerChange = false)
        {
            HBContainer           container  = HandBrakeEncoderHelpers.GetContainer(this.presetsService.SelectedPreset.Preset.EncodingProfile.ContainerName);
            AudioEncoderViewModel oldEncoder = null;
            string oldPassthrough            = null;

            if (this.selectedAudioEncoder != null)
            {
                oldEncoder     = this.selectedAudioEncoder;
                oldPassthrough = this.selectedPassthrough;
            }

            var resourceManager = new ResourceManager(typeof(EncodingRes));

            this.audioEncoders = new List <AudioEncoderViewModel>();
            //this.audioEncoders.Add(new AudioEncoderViewModel { IsPassthrough = true });

            this.passthroughChoices = new List <ComboChoice>();
            this.passthroughChoices.Add(new ComboChoice(AutoPassthroughEncoder, EncodingRes.Passthrough_auto));

            bool anyCodecSupportsPassthrough = false;

            foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders)
            {
                if ((encoder.CompatibleContainers & container.Id) > 0)
                {
                    if (encoder.IsPassthrough)
                    {
                        if (encoder.ShortName.Contains(":"))
                        {
                            string inputCodec = encoder.ShortName.Split(':')[1];
                            string display    = resourceManager.GetString("Passthrough_" + inputCodec);

                            if (string.IsNullOrEmpty(display))
                            {
                                display = encoder.DisplayName;
                            }

                            this.passthroughChoices.Add(new ComboChoice(encoder.ShortName, display));
                        }

                        anyCodecSupportsPassthrough = true;
                    }
                    else
                    {
                        this.AudioEncoders.Add(new AudioEncoderViewModel {
                            Encoder = encoder
                        });
                    }
                }
            }

            if (anyCodecSupportsPassthrough)
            {
                this.audioEncoders.Insert(0, new AudioEncoderViewModel {
                    IsPassthrough = true
                });
            }

            this.RaisePropertyChanged(nameof(this.PassthroughChoices));
            this.RaisePropertyChanged(nameof(this.AudioEncoders));

            if (oldEncoder == null)
            {
                this.selectedAudioEncoder = this.audioEncoders[1];
            }
            else
            {
                if (oldEncoder.IsPassthrough)
                {
                    this.selectedAudioEncoder = this.audioEncoders[0];
                    this.selectedPassthrough  = oldPassthrough;
                }
                else
                {
                    this.selectedAudioEncoder = this.audioEncoders.Skip(1).FirstOrDefault(e => e.Encoder == oldEncoder.Encoder);
                    this.selectedPassthrough  = "copy";
                }
            }

            if (this.selectedAudioEncoder == null)
            {
                this.selectedAudioEncoder = this.audioEncoders[1];
            }

            // If it's a container change we need to commit the new encoder change.
            if (isContainerChange && this.selectedAudioEncoder != oldEncoder)
            {
                this.RaiseAudioEncodingChanged();
            }

            this.RaisePropertyChanged(nameof(this.SelectedAudioEncoder));
            this.RaisePropertyChanged(nameof(this.SelectedPassthrough));
        }
Example #15
0
        public AudioOutputPreview GetAudioPreview(AudioTrack inputTrack, AudioEncodingViewModel audioVM)
        {
            HBAudioEncoder encoder = audioVM.HBAudioEncoder;

            var outputPreviewTrack = new AudioOutputPreview
            {
                Name    = inputTrack.NoTrackDisplay,
                Encoder = encoder.DisplayName
            };

            if (encoder.IsPassthrough)
            {
                // For passthrough encodes, we need to make sure the input track is of the right type
                if (!Encoders.AudioEncoderIsCompatible(inputTrack, encoder) && encoder.ShortName != "copy")
                {
                    return(null);
                }

                HBContainer container = Encoders.GetContainer(this.Profile.ContainerName);

                if (encoder.ShortName == "copy" && (inputTrack.Codec == AudioCodec.Dts || inputTrack.Codec == AudioCodec.DtsHD) && container.DefaultExtension == "mp4")
                {
                    this.PassthroughWarningText    = EncodingRes.DtsMp4Warning;
                    this.PassthroughWarningVisible = true;

                    return(outputPreviewTrack);
                }
            }

            // Find out what the real mixdown, sample rate and bitrate will be.
            HBMixdown mixdown;
            int       sampleRate, bitrate;

            if (encoder.ShortName == "copy")
            {
                if (Encoders.AudioEncoderIsCompatible(inputTrack, encoder))
                {
                    return(outputPreviewTrack);
                }

                if (this.Profile.AudioEncoderFallback == null)
                {
                    encoder = Encoders.AudioEncoders.First(a => !a.IsPassthrough);
                }
                else
                {
                    encoder = Encoders.GetAudioEncoder(this.Profile.AudioEncoderFallback);
                }

                mixdown    = Encoders.GetDefaultMixdown(encoder, inputTrack.ChannelLayout);
                sampleRate = 0;
                bitrate    = 0;

                outputPreviewTrack.Encoder = encoder.DisplayName;
            }
            else
            {
                mixdown    = audioVM.SelectedMixdown.Mixdown;
                sampleRate = audioVM.SampleRate;
                bitrate    = audioVM.SelectedBitrate.Bitrate;
            }

            HBMixdown previewMixdown;

            previewMixdown = Encoders.SanitizeMixdown(mixdown, encoder, inputTrack.ChannelLayout);

            int previewSampleRate = sampleRate;

            if (previewSampleRate == 0)
            {
                previewSampleRate = inputTrack.SampleRate;
            }

            int previewBitrate = bitrate;

            if (previewBitrate == 0)
            {
                previewBitrate = Encoders.GetDefaultBitrate(encoder, previewSampleRate, previewMixdown);
            }
            else
            {
                previewBitrate = Encoders.SanitizeAudioBitrate(previewBitrate, encoder, previewSampleRate, previewMixdown);
            }

            outputPreviewTrack.Mixdown    = previewMixdown.DisplayName;
            outputPreviewTrack.SampleRate = DisplayConversions.DisplaySampleRate(previewSampleRate);

            if (audioVM.EncodeRateType == AudioEncodeRateType.Bitrate)
            {
                if (previewBitrate >= 0)
                {
                    outputPreviewTrack.Quality = previewBitrate + " kbps";
                }
                else
                {
                    outputPreviewTrack.Quality = string.Empty;
                }
            }
            else
            {
                outputPreviewTrack.Quality = "CQ " + audioVM.AudioQuality;
            }

            var modifiers = new List <string>();

            if (audioVM.Gain != 0)
            {
                modifiers.Add(string.Format("{0}{1} dB", audioVM.Gain > 0 ? "+" : string.Empty, audioVM.Gain));
            }

            if (audioVM.Drc != 0)
            {
                modifiers.Add("DRC " + audioVM.Drc.ToString());
            }

            outputPreviewTrack.Modifiers = string.Join(", ", modifiers);

            return(outputPreviewTrack);
        }
Example #16
0
        public AudioPanelViewModel(EncodingWindowViewModel encodingWindowViewModel)
            : base(encodingWindowViewModel)
        {
            this.fallbackEncoderChoices = new List <AudioEncoderViewModel>();

            IObservable <IChangeSet <AudioEncodingViewModel> > audioEncodingsObservable = this.audioEncodings.Connect();

            audioEncodingsObservable.Bind(this.AudioEncodingsBindable).Subscribe();

            IObservable <IChangeSet <AudioOutputPreview> > audioOutputPreviewObservable = this.audioOutputPreviews.Connect();

            audioOutputPreviewObservable.Bind(this.AudioOutputPreviewsBindable).Subscribe();

            // HasAudioTracks
            audioOutputPreviewObservable
            .Count()
            .StartWith(this.audioOutputPreviews.Count)
            .Select(c => c > 0)
            .ToProperty(this, x => x.HasAudioTracks, out this.hasAudioTracks);

            this.main.WhenAnyValue(x => x.SelectedTitle)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.NotifyAudioInputChanged();
            });

            this.main.AudioTracks
            .Connect()
            .WhenAnyPropertyChanged()
            .Subscribe(_ =>
            {
                this.NotifyAudioInputChanged();
            });

            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.ContainerName)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.RefreshFallbackEncoderChoices();
                this.RefreshCopyMaskChoices();
            });

            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile)
            .Subscribe(Observer.Create((VCProfile _) =>
            {
                this.OnProfileChanged();
            }));

            // AutoPassthroughSettingsVisible
            audioEncodingsObservable
            .WhenAnyPropertyChanged(nameof(AudioEncodingViewModel.SelectedAudioEncoder), nameof(AudioEncodingViewModel.SelectedPassthrough))
            .Subscribe(_ =>
            {
                this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible));
            });

            audioEncodingsObservable.Subscribe(changeSet =>
            {
                if (changeSet.Adds > 0 || changeSet.Removes > 0)
                {
                    this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible));
                }
            });

            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioEncoderFallback)
            .Subscribe(audioEncoderFallback =>
            {
                if (!this.userUpdatingFallbackEncoder)
                {
                    this.audioEncoderFallback = this.fallbackEncoderChoices.FirstOrDefault(c => c.Encoder.ShortName == audioEncoderFallback);
                    if (this.audioEncoderFallback == null)
                    {
                        this.audioEncoderFallback = this.fallbackEncoderChoices[0];
                    }

                    this.RaisePropertyChanged(nameof(this.AudioEncoderFallback));
                }
            });

            // Make user updates change the profile
            IObservable <IChangeSet <CopyMaskChoiceViewModel> > copyMaskChoicesObservable = this.copyMaskChoices.Connect();

            copyMaskChoicesObservable.Bind(this.CopyMaskChoicesBindable).Subscribe();
            copyMaskChoicesObservable.WhenValueChanged(choice => choice.Enabled, notifyOnInitialValue: false).Subscribe(_ =>
            {
                this.userUpdatingCopyMask = true;
                this.SaveCopyMasksToProfile();
                this.userUpdatingCopyMask = false;

                this.RefreshAudioPreview();
            });

            // Make profile changes update the local mask choices
            this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioCopyMask)
            .Subscribe(audioCopyMask =>
            {
                if (this.userUpdatingCopyMask)
                {
                    return;
                }

                this.copyMaskChoices.Edit(copyMaskChoicesInnerList =>
                {
                    copyMaskChoicesInnerList.Clear();

                    HBContainer container = HandBrakeEncoderHelpers.GetContainer(this.EncodingWindowViewModel.Profile.ContainerName);
                    foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders)
                    {
                        if ((encoder.CompatibleContainers & container.Id) > 0 && encoder.IsPassthrough && encoder.ShortName != AudioEncodingViewModel.AutoPassthroughEncoder)
                        {
                            bool enabled = true;
                            string codec = encoder.ShortName.Substring(5);

                            if (audioCopyMask != null)
                            {
                                CopyMaskChoice profileMaskChoice = audioCopyMask.FirstOrDefault(choice => choice.Codec == codec);
                                if (profileMaskChoice != null)
                                {
                                    enabled = profileMaskChoice.Enabled;
                                }
                            }

                            copyMaskChoicesInnerList.Add(new CopyMaskChoiceViewModel(codec, enabled));
                        }
                    }
                });

                this.RefreshAudioPreview();
            });

            this.RegisterProfileProperties();
        }
        private void RefreshEncoderChoices()
        {
            HBContainer           container  = Encoders.GetContainer(this.containerName);
            AudioEncoderViewModel oldEncoder = null;
            string oldPassthrough            = null;

            if (this.selectedAudioEncoder != null)
            {
                oldEncoder     = this.selectedAudioEncoder;
                oldPassthrough = this.selectedPassthrough;
            }

            var resourceManager = new ResourceManager(typeof(EncodingRes));

            this.audioEncoders = new List <AudioEncoderViewModel>();
            this.audioEncoders.Add(new AudioEncoderViewModel {
                IsPassthrough = true
            });

            this.passthroughChoices = new List <ComboChoice>();
            this.passthroughChoices.Add(new ComboChoice("copy", EncodingRes.Passthrough_any));

            foreach (HBAudioEncoder encoder in Encoders.AudioEncoders)
            {
                if ((encoder.CompatibleContainers & container.Id) > 0)
                {
                    if (encoder.IsPassthrough)
                    {
                        if (encoder.ShortName.Contains(":"))
                        {
                            string inputCodec = encoder.ShortName.Split(':')[1];
                            string display    = resourceManager.GetString("Passthrough_" + inputCodec);

                            this.passthroughChoices.Add(new ComboChoice(encoder.ShortName, display));
                        }
                    }
                    else
                    {
                        this.AudioEncoders.Add(new AudioEncoderViewModel {
                            Encoder = encoder
                        });
                    }
                }
            }

            this.RaisePropertyChanged(() => this.AudioEncoders);
            this.RaisePropertyChanged(() => this.PassthroughChoices);

            if (oldEncoder == null)
            {
                this.selectedAudioEncoder = this.audioEncoders[1];
            }
            else
            {
                if (oldEncoder.IsPassthrough)
                {
                    this.selectedAudioEncoder = this.audioEncoders[0];
                    this.selectedPassthrough  = oldPassthrough;
                }
                else
                {
                    this.selectedAudioEncoder = this.audioEncoders.Skip(1).FirstOrDefault(e => e.Encoder == oldEncoder.Encoder);
                    this.selectedPassthrough  = "copy";
                }
            }

            if (this.selectedAudioEncoder == null)
            {
                this.selectedAudioEncoder = this.audioEncoders[1];
            }

            this.RaisePropertyChanged(() => this.SelectedAudioEncoder);
            this.RaisePropertyChanged(() => this.SelectedPassthrough);
            this.RaisePropertyChanged(() => this.AutoPassthroughSettingsVisible);
        }