// -------------------------------------------------------------------------------------------------------------------- // // 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 HandBrake.App.Core.Utilities; using HandBrake.Interop.Interop; using HandBrake.Interop.Interop.Interfaces.Model; using HandBrake.Interop.Interop.Interfaces.Model.Encoders; using HandBrakeWPF.Commands; using HandBrakeWPF.Model.Audio; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Encode.Model.Models; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.ViewModels.Interfaces; using HandBrakeWPF.Views; /// /// 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 readonly IWindowManager windowManager; private BindingList availableLanguages; private AudioBehaviours audioBehaviours; /// /// Initializes a new instance of the class. /// public AudioDefaultsViewModel(IWindowManager windowManager) { this.windowManager = windowManager; this.AudioBehaviours = new AudioBehaviours(); this.SelectedAvailableToMove = new BindingList(); this.SelectedLanguagesToMove = new BindingList(); this.AvailableLanguages = new BindingList(); this.AudioEncoders = new List(HandBrakeEncoderHelpers.AudioEncoders) { HBAudioEncoder.None }; this.SampleRates = new ObservableCollection { "Auto" }; foreach (var item in HandBrakeEncoderHelpers.AudioSampleRates) { this.SampleRates.Add(item.Name); } this.Title = Resources.AudioViewModel_AudioDefaults; BindingList data = new BindingList(); foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders.Where(s => s.IsPassthru && !s.IsAutoPassthru)) { data.Add(new AudioFallbackWrapper(encoder)); } this.PassthruEncoders = data; this.RemoveTrackCommand = new SimpleRelayCommand(this.RemoveTrack, null); } #region Properties public ListboxDeleteCommand DeleteCommand => new ListboxDeleteCommand(); public OutputFormat OutputFormat { get; private set; } /// /// 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 SelectedLanguages. /// public BindingList SelectedAvailableToMove { get; private set; } /// /// Gets SelectedLanguages. /// public BindingList SelectedLanguagesToMove { get; private set; } public BindingList PassthruEncoders { get; private set; } /// /// Gets or sets the audio encoder fallback. /// public HBAudioEncoder AudioEncoderFallback { get { return this.audioBehaviours.AudioFallbackEncoder; } set { if (value == this.audioBehaviours.AudioFallbackEncoder) { return; } foreach (var item in this.BehaviourTracks) { item.SetFallbackEncoder(value); } this.audioBehaviours.AudioFallbackEncoder = value; this.NotifyOfPropertyChange(() => this.AudioEncoderFallback); } } public SimpleRelayCommand RemoveTrackCommand { get; } #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(() => this.AvailableLanguages); } } /// /// Gets or sets AudioEncoders. /// public IEnumerable AudioEncoders { get; set; } /// /// Gets or sets SampleRates. /// public IList SampleRates { get; set; } public IList TrackNamingBehaviours { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } #endregion #region Public Methods /// /// Add a new behaviour track. /// public void AddTrack() { this.BehaviourTracks.Add(new AudioBehaviourTrack(this.AudioEncoderFallback)); foreach (var item in this.BehaviourTracks) { item.SetFallbackEncoder(this.AudioEncoderFallback); } } /// /// 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 (Language item in copiedList) { this.AudioBehaviours.SelectedLanguages.Add(item); } this.UpdateAvailableLanguages(); } } /// /// Audio List Move Right /// public void LanguageMoveLeft() { if (this.SelectedLanguagesToMove.Count > 0) { List copiedList = this.SelectedLanguagesToMove.ToList(); foreach (Language item in copiedList) { this.AudioBehaviours.SelectedLanguages.Remove(item); } } this.UpdateAvailableLanguages(); } /// /// Audio List Clear all selected languages /// public void LanguageClearAll() { this.AudioBehaviours.SelectedLanguages.Clear(); this.UpdateAvailableLanguages(); } #endregion #region Methods public void Setup(AudioBehaviours behaviours, OutputFormat outputFormat) { // Reset this.IsApplied = false; this.AudioBehaviours = new AudioBehaviours(); this.AvailableLanguages.Clear(); foreach (Language item in HandBrakeLanguagesHelper.AllLanguagesWithAny) { this.AvailableLanguages.Add(item); } this.OutputFormat = outputFormat; if (behaviours != null) { this.AudioBehaviours.SelectedBehaviour = behaviours.SelectedBehaviour; this.AudioBehaviours.SelectedTrackDefaultBehaviour = behaviours.SelectedTrackDefaultBehaviour; this.AudioBehaviours.AllowedPassthruOptions = behaviours.AllowedPassthruOptions; this.AudioBehaviours.AudioFallbackEncoder = behaviours.AudioFallbackEncoder; foreach (var encoder in this.PassthruEncoders) { encoder.IsEnabled = false; if (behaviours.AllowedPassthruOptions.Contains(encoder.Encoder)) { encoder.IsEnabled = true; } } foreach (AudioBehaviourTrack item in behaviours.BehaviourTracks) { this.BehaviourTracks.Add(new AudioBehaviourTrack(item)); } this.NotifyOfPropertyChange(() => this.BehaviourTracks); foreach (Language selectedItem in behaviours.SelectedLanguages) { this.AudioBehaviours.SelectedLanguages.Add(selectedItem); } this.UpdateAvailableLanguages(); this.AudioBehaviours.AudioTrackNamePassthru = behaviours.AudioTrackNamePassthru; this.AudioBehaviours.AudioAutomaticNamingBehavior = behaviours.AudioAutomaticNamingBehavior; } this.CorrectAudioEncoders(this.OutputFormat); this.NotifyOfPropertyChange(() => this.PassthruEncoders); this.NotifyOfPropertyChange(() => this.AudioEncoderFallback); } /// /// The refresh task. /// public void RefreshTask(OutputFormat outputFormat) { this.OutputFormat = outputFormat; this.NotifyOfPropertyChange(() => this.AudioEncoders); this.NotifyOfPropertyChange(() => this.OutputFormat); this.CorrectAudioEncoders(this.OutputFormat); } public void LaunchHelp() { Process.Start("explorer.exe", "https://handbrake.fr/docs/en/latest/advanced/audio-subtitle-defaults.html"); } #endregion public bool ShowWindow() { this.IsApplied = false; this.windowManager.ShowDialog(this); return this.IsApplied; } public void Cancel() { this.IsApplied = false; this.TryClose(); } public void Save() { this.audioBehaviours.AllowedPassthruOptions = this.PassthruEncoders.Where(s => s.IsEnabled).Select(s => s.Encoder).ToList(); this.IsApplied = true; this.TryClose(true); } private void CorrectAudioEncoders(OutputFormat outputFormat) { if (outputFormat == OutputFormat.Mp4 && this.AudioEncoderFallback != null && !this.AudioEncoderFallback.SupportsMP4) { this.AudioEncoderFallback = HandBrakeEncoderHelpers.GetAudioEncoder(HBAudioEncoder.AvAac); } if (outputFormat == OutputFormat.WebM && this.AudioEncoderFallback != null && !this.AudioEncoderFallback.SupportsWebM) { this.AudioEncoderFallback = HandBrakeEncoderHelpers.GetAudioEncoder(HBAudioEncoder.Vorbis); } if (outputFormat == OutputFormat.Mp4) { foreach (AudioBehaviourTrack track in this.BehaviourTracks.Where(track => !track.Encoder.SupportsMP4)) { track.Encoder = HandBrakeEncoderHelpers.GetAudioEncoder(HBAudioEncoder.AvAac); } } if (outputFormat == OutputFormat.WebM) { foreach (AudioBehaviourTrack track in this.BehaviourTracks.Where(track => !track.Encoder.SupportsWebM)) { track.Encoder = HandBrakeEncoderHelpers.GetAudioEncoder(HBAudioEncoder.Vorbis); } } } private void UpdateAvailableLanguages() { List copiedList = this.AudioBehaviours.SelectedLanguages.ToList(); BindingList newAvailable = new BindingList(); foreach (Language lang in HandBrakeLanguagesHelper.AllLanguagesWithAny) { if (!copiedList.Contains(lang)) { newAvailable.Add(lang); } } this.AvailableLanguages = newAvailable; } } }