// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // The Audio Defaults View Model // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.ViewModels { using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Windows.Navigation; using HandBrake.Interop.Interop; using HandBrake.Interop.Interop.Model.Encoding; using HandBrake.Interop.Utilities; using HandBrakeWPF.Model.Audio; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Encode.Model; using HandBrakeWPF.Services.Encode.Model.Models; using HandBrakeWPF.Services.Presets.Model; using HandBrakeWPF.Utilities; using HandBrakeWPF.ViewModels.Interfaces; /// /// The Audio View Model /// /// /// TODO: /// - Support setting fallback encoder options for Passthru tracks. /// - Mixdown Dropdown should only show mixdowns for the set encoder. Not all. /// public class AudioDefaultsViewModel : ViewModelBase, IAudioDefaultsViewModel { private BindingList availableLanguages; private AudioBehaviours audioBehaviours; private EncodeTask task; #region Constructors and Destructors /// /// Initializes a new instance of the class. /// /// /// The task. /// public AudioDefaultsViewModel(EncodeTask task) { this.Task = task; this.AudioBehaviours = new AudioBehaviours(); this.SelectedAvailableToMove = new BindingList(); this.SelectedLangaugesToMove = new BindingList(); this.AvailableLanguages = new BindingList(); this.AudioEncoders = EnumHelper.GetEnumList(); this.SampleRates = new ObservableCollection { "Auto" }; foreach (var item in HandBrakeEncoderHelpers.AudioSampleRates) { this.SampleRates.Add(item.Name); } this.Setup((Preset)null, task); this.Title = Resources.AudioViewModel_AudioDefaults; } #endregion #region Properties /// /// Gets or sets the task. /// public EncodeTask Task { get { return this.task; } set { if (Equals(value, this.task)) { return; } this.task = value; this.NotifyOfPropertyChange(() => this.Task); } } /// /// Gets or sets the list of audio tracks we will use as templates for generating tracks for a given source. /// public BindingList BehaviourTracks { get { return this.AudioBehaviours.BehaviourTracks; } set { this.AudioBehaviours.BehaviourTracks = value; this.NotifyOfPropertyChange(() => this.BehaviourTracks); } } /// /// Gets the audio behaviours. /// public AudioBehaviours AudioBehaviours { get { return this.audioBehaviours; } private set { if (Equals(value, this.audioBehaviours)) { return; } this.audioBehaviours = value; this.NotifyOfPropertyChange(() => this.AudioBehaviours); } } public bool IsApplied { get; set; } /// /// Gets SelectedLangauges. /// public BindingList SelectedAvailableToMove { get; private set; } /// /// Gets SelectedLangauges. /// public BindingList SelectedLangaugesToMove { get; private set; } /// /// Gets or sets a value indicating whether audio allow m p 3 pass. /// public bool AudioAllowMP3Pass { get { return this.Task.AllowedPassthruOptions.AudioAllowMP3Pass; } set { this.task.AllowedPassthruOptions.AudioAllowMP3Pass = value; this.NotifyOfPropertyChange(() => this.AudioAllowMP3Pass); } } /// /// Gets or sets a value indicating whether audio allow aac pass. /// public bool AudioAllowAACPass { get { return this.Task.AllowedPassthruOptions.AudioAllowAACPass; } set { this.task.AllowedPassthruOptions.AudioAllowAACPass = value; this.NotifyOfPropertyChange(() => this.AudioAllowAACPass); } } /// /// Gets or sets a value indicating whether audio allow ac3 pass. /// public bool AudioAllowAC3Pass { get { return this.Task.AllowedPassthruOptions.AudioAllowAC3Pass; } set { this.task.AllowedPassthruOptions.AudioAllowAC3Pass = value; this.NotifyOfPropertyChange(() => this.AudioAllowAC3Pass); } } /// /// Gets or sets a value indicating whether audio allow eac3 pass. /// public bool AudioAllowEAC3Pass { get { return this.Task.AllowedPassthruOptions.AudioAllowEAC3Pass; } set { this.task.AllowedPassthruOptions.AudioAllowEAC3Pass = value; this.NotifyOfPropertyChange(() => this.AudioAllowEAC3Pass); } } /// /// Gets or sets a value indicating whether audio allow dts pass. /// public bool AudioAllowDTSPass { get { return this.Task.AllowedPassthruOptions.AudioAllowDTSPass; } set { this.task.AllowedPassthruOptions.AudioAllowDTSPass = value; this.NotifyOfPropertyChange(() => this.AudioAllowDTSPass); } } /// /// Gets or sets a value indicating whether audio allow dtshd pass. /// public bool AudioAllowDTSHDPass { get { return this.Task.AllowedPassthruOptions.AudioAllowDTSHDPass; } set { this.task.AllowedPassthruOptions.AudioAllowDTSHDPass = value; this.NotifyOfPropertyChange(() => this.AudioAllowDTSHDPass); } } /// /// Gets or sets a value indicating whether audio allow true hd pass. /// public bool AudioAllowTrueHDPass { get { return this.Task.AllowedPassthruOptions.AudioAllowTrueHDPass; } set { this.task.AllowedPassthruOptions.AudioAllowTrueHDPass = value; this.NotifyOfPropertyChange(() => this.AudioAllowTrueHDPass); } } /// /// Gets or sets a value indicating whether audio allow flac pass. /// public bool AudioAllowFlacPass { get { return this.Task.AllowedPassthruOptions.AudioAllowFlacPass; } set { this.task.AllowedPassthruOptions.AudioAllowFlacPass = value; this.NotifyOfPropertyChange(() => this.AudioAllowFlacPass); } } /// /// Gets or sets the audio encoder fallback. /// public AudioEncoder AudioEncoderFallback { get { return this.Task.AllowedPassthruOptions.AudioEncoderFallback; } set { if (value == this.Task.AllowedPassthruOptions.AudioEncoderFallback) { return; } this.Task.AllowedPassthruOptions.AudioEncoderFallback = value; this.NotifyOfPropertyChange(() => this.AudioEncoderFallback); } } #endregion #region Data Properties /// /// Gets the audio behaviour modes. /// public BindingList AudioBehaviourModeList { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } /// /// Gets the audio track default behaviour mode list. /// public BindingList AudioTrackDefaultBehaviourModeList { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } /// /// Gets AvailableLanguages. /// public BindingList AvailableLanguages { get { return this.availableLanguages; } private set { this.availableLanguages = value; this.NotifyOfPropertyChange("AvailableLanguages"); } } /// /// Gets or sets AudioEncoders. /// public IEnumerable AudioEncoders { get; set; } /// /// Gets or sets SampleRates. /// public IList SampleRates { get; set; } #endregion #region Public Methods /// /// Add a new behaviour track. /// public void AddTrack() { this.BehaviourTracks.AddNew(); } /// /// Clear all the behaviour tracks /// public void ClearTracks() { this.BehaviourTracks.Clear(); } /// /// Remove the Selected Track /// /// /// The track. /// public void RemoveTrack(AudioBehaviourTrack track) { this.BehaviourTracks.Remove(track); } /// /// Audio List Move Left /// public void LanguageMoveRight() { if (this.SelectedAvailableToMove.Count > 0) { List copiedList = this.SelectedAvailableToMove.ToList(); foreach (string item in copiedList) { this.AvailableLanguages.Remove(item); this.AudioBehaviours.SelectedLangauges.Add(item); } this.AvailableLanguages = new BindingList(this.AvailableLanguages.OrderBy(o => o).ToList()); } } /// /// Audio List Move Right /// public void LanguageMoveLeft() { if (this.SelectedLangaugesToMove.Count > 0) { List copiedList = this.SelectedLangaugesToMove.ToList(); foreach (string item in copiedList) { this.AudioBehaviours.SelectedLangauges.Remove(item); this.AvailableLanguages.Add(item); } } this.AvailableLanguages = new BindingList(this.AvailableLanguages.OrderBy(o => o).ToList()); } /// /// Audio List Clear all selected languages /// public void LanguageClearAll() { foreach (string item in this.AudioBehaviours.SelectedLangauges) { this.AvailableLanguages.Add(item); } this.AvailableLanguages = new BindingList(this.AvailableLanguages.OrderBy(o => o).ToList()); this.AudioBehaviours.SelectedLangauges.Clear(); } public void ResetApplied() { this.IsApplied = false; } #endregion #region Methods /// /// The setup languages. /// /// /// The preset. /// /// /// The task. /// public void Setup(Preset preset, EncodeTask task) { // Reset this.IsApplied = false; this.AudioBehaviours = new AudioBehaviours(); // Setup for this Encode Task. this.Task = task; IDictionary langList = LanguageUtilities.MapLanguages(); langList = (from entry in langList orderby entry.Key ascending select entry).ToDictionary(pair => pair.Key, pair => pair.Value); this.AvailableLanguages.Clear(); foreach (string item in langList.Keys) { this.AvailableLanguages.Add(item); } // Handle the Preset, if it's not null. if (preset == null) { return; } AudioBehaviours behaviours = preset.AudioTrackBehaviours.Clone(); if (behaviours != null) { this.AudioBehaviours.SelectedBehaviour = behaviours.SelectedBehaviour; this.AudioBehaviours.SelectedTrackDefaultBehaviour = behaviours.SelectedTrackDefaultBehaviour; foreach (AudioBehaviourTrack item in preset.AudioTrackBehaviours.BehaviourTracks) { this.BehaviourTracks.Add(new AudioBehaviourTrack(item)); } this.NotifyOfPropertyChange(() => this.BehaviourTracks); foreach (string selectedItem in behaviours.SelectedLangauges) { this.AvailableLanguages.Remove(selectedItem); this.AudioBehaviours.SelectedLangauges.Add(selectedItem); } } this.task.AllowedPassthruOptions = new AllowedPassthru(preset.Task.AllowedPassthruOptions); this.NotifyOfPropertyChange(() => this.AudioAllowMP3Pass); this.NotifyOfPropertyChange(() => this.AudioAllowAACPass); this.NotifyOfPropertyChange(() => this.AudioAllowAC3Pass); this.NotifyOfPropertyChange(() => this.AudioAllowEAC3Pass); this.NotifyOfPropertyChange(() => this.AudioAllowDTSPass); this.NotifyOfPropertyChange(() => this.AudioAllowDTSHDPass); this.NotifyOfPropertyChange(() => this.AudioAllowTrueHDPass); this.NotifyOfPropertyChange(() => this.AudioAllowFlacPass); this.NotifyOfPropertyChange(() => this.AudioEncoderFallback); } /// /// The refresh task. /// public void RefreshTask() { this.NotifyOfPropertyChange(() => this.Task); if (this.Task.OutputFormat == OutputFormat.Mp4 && (this.AudioEncoderFallback == AudioEncoder.ffflac || this.AudioEncoderFallback == AudioEncoder.ffflac24 || this.AudioEncoderFallback == AudioEncoder.Vorbis || this.AudioEncoderFallback == AudioEncoder.Opus)) { this.AudioEncoderFallback = AudioEncoder.ffaac; } if (this.Task.OutputFormat == OutputFormat.WebM && (this.AudioEncoderFallback != AudioEncoder.Opus && this.AudioEncoderFallback != AudioEncoder.Vorbis)) { this.AudioEncoderFallback = AudioEncoder.Vorbis; } if (this.Task.OutputFormat == OutputFormat.Mp4) { foreach (AudioBehaviourTrack track in this.BehaviourTracks.Where(track => track.Encoder == AudioEncoder.ffflac || track.Encoder == AudioEncoder.ffflac24 || track.Encoder == AudioEncoder.Opus || track.Encoder == AudioEncoder.Vorbis)) { track.Encoder = AudioEncoder.ffaac; } } if (this.Task.OutputFormat == OutputFormat.WebM) { foreach (AudioBehaviourTrack track in this.BehaviourTracks.Where(track => track.Encoder != AudioEncoder.Vorbis && track.Encoder != AudioEncoder.Opus)) { track.Encoder = AudioEncoder.Vorbis; } } } public void LaunchHelp() { Process.Start("https://handbrake.fr/docs/en/latest/advanced/audio-subtitle-defaults.html"); } #endregion } }