mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-11 17:59:17 +00:00
Code Cleanup
This commit is contained in:
@@ -24,7 +24,6 @@
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
@@ -34,7 +33,6 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -298,12 +298,12 @@ public class RegValueObject
|
||||
/// </summary>
|
||||
public RegValueObject()
|
||||
{
|
||||
root = "";
|
||||
parentkey = "";
|
||||
parentkeywithoutroot = "";
|
||||
entry = "";
|
||||
value = "";
|
||||
type = "";
|
||||
root = string.Empty;
|
||||
parentkey = string.Empty;
|
||||
parentkeywithoutroot = string.Empty;
|
||||
entry = string.Empty;
|
||||
value = string.Empty;
|
||||
type = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -317,7 +317,7 @@ public class RegValueObject
|
||||
root = GetHive(ref parentkeywithoutroot);
|
||||
entry = regValueName;
|
||||
value = regValueData;
|
||||
type = "";
|
||||
type = string.Empty;
|
||||
var tmpStringValue = value;
|
||||
type = GetRegEntryType(ref tmpStringValue, encoding);
|
||||
value = tmpStringValue;
|
||||
|
@@ -15,11 +15,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using MediaInfo;
|
||||
using QuickLook.Common.Annotations;
|
||||
using QuickLook.Common.Helpers;
|
||||
using QuickLook.Common.Plugin;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
@@ -28,330 +31,325 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
using MediaInfo;
|
||||
using QuickLook.Common.Annotations;
|
||||
using QuickLook.Common.Helpers;
|
||||
using QuickLook.Common.Plugin;
|
||||
using WPFMediaKit.DirectShow.Controls;
|
||||
using WPFMediaKit.DirectShow.MediaPlayers;
|
||||
|
||||
namespace QuickLook.Plugin.VideoViewer
|
||||
namespace QuickLook.Plugin.VideoViewer;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for UserControl1.xaml
|
||||
/// </summary>
|
||||
public partial class ViewerPanel : UserControl, IDisposable, INotifyPropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for UserControl1.xaml
|
||||
/// </summary>
|
||||
public partial class ViewerPanel : UserControl, IDisposable, INotifyPropertyChanged
|
||||
private readonly ContextObject _context;
|
||||
private BitmapSource _coverArt;
|
||||
|
||||
private bool _hasVideo;
|
||||
private bool _isPlaying;
|
||||
private bool _wasPlaying;
|
||||
private bool _shouldLoop;
|
||||
|
||||
public ViewerPanel(ContextObject context)
|
||||
{
|
||||
private readonly ContextObject _context;
|
||||
private BitmapSource _coverArt;
|
||||
InitializeComponent();
|
||||
|
||||
private bool _hasVideo;
|
||||
private bool _isPlaying;
|
||||
private bool _wasPlaying;
|
||||
private bool _shouldLoop;
|
||||
// apply global theme
|
||||
Resources.MergedDictionaries[0].MergedDictionaries.Clear();
|
||||
|
||||
public ViewerPanel(ContextObject context)
|
||||
_context = context;
|
||||
|
||||
mediaElement.MediaUriPlayer.LAVFilterDirectory =
|
||||
IntPtr.Size == 8 ? "LAVFilters-x64\\" : "LAVFilters-x86\\";
|
||||
|
||||
//ShowViedoControlContainer(null, null);
|
||||
viewerPanel.PreviewMouseMove += ShowViedoControlContainer;
|
||||
|
||||
mediaElement.MediaUriPlayer.PlayerStateChanged += PlayerStateChanged;
|
||||
mediaElement.MediaOpened += MediaOpened;
|
||||
mediaElement.MediaEnded += MediaEnded;
|
||||
mediaElement.MediaFailed += MediaFailed;
|
||||
|
||||
ShouldLoop = SettingHelper.Get("ShouldLoop", false, "QuickLook.Plugin.VideoViewer");
|
||||
|
||||
buttonPlayPause.Click += TogglePlayPause;
|
||||
buttonLoop.Click += ToggleShouldLoop;
|
||||
buttonTime.Click += (sender, e) => buttonTime.Tag = (string)buttonTime.Tag == "Time" ? "Length" : "Time";
|
||||
buttonMute.Click += (sender, e) => volumeSliderLayer.Visibility = Visibility.Visible;
|
||||
volumeSliderLayer.MouseDown += (sender, e) => volumeSliderLayer.Visibility = Visibility.Collapsed;
|
||||
|
||||
sliderProgress.PreviewMouseDown += (sender, e) =>
|
||||
{
|
||||
InitializeComponent();
|
||||
_wasPlaying = mediaElement.IsPlaying;
|
||||
mediaElement.Pause();
|
||||
};
|
||||
sliderProgress.PreviewMouseUp += (sender, e) =>
|
||||
{
|
||||
if (_wasPlaying) mediaElement.Play();
|
||||
};
|
||||
|
||||
// apply global theme
|
||||
Resources.MergedDictionaries[0].MergedDictionaries.Clear();
|
||||
PreviewMouseWheel += (sender, e) => ChangeVolume((double)e.Delta / 120 * 0.04);
|
||||
}
|
||||
|
||||
_context = context;
|
||||
|
||||
mediaElement.MediaUriPlayer.LAVFilterDirectory =
|
||||
IntPtr.Size == 8 ? "LAVFilters-x64\\" : "LAVFilters-x86\\";
|
||||
|
||||
//ShowViedoControlContainer(null, null);
|
||||
viewerPanel.PreviewMouseMove += ShowViedoControlContainer;
|
||||
|
||||
mediaElement.MediaUriPlayer.PlayerStateChanged += PlayerStateChanged;
|
||||
mediaElement.MediaOpened += MediaOpened;
|
||||
mediaElement.MediaEnded += MediaEnded;
|
||||
mediaElement.MediaFailed += MediaFailed;
|
||||
|
||||
ShouldLoop = SettingHelper.Get("ShouldLoop", false, "QuickLook.Plugin.VideoViewer");
|
||||
|
||||
buttonPlayPause.Click += TogglePlayPause;
|
||||
buttonLoop.Click += ToggleShouldLoop;
|
||||
buttonTime.Click += (sender, e) => buttonTime.Tag = (string)buttonTime.Tag == "Time" ? "Length" : "Time";
|
||||
buttonMute.Click += (sender, e) => volumeSliderLayer.Visibility = Visibility.Visible;
|
||||
volumeSliderLayer.MouseDown += (sender, e) => volumeSliderLayer.Visibility = Visibility.Collapsed;
|
||||
|
||||
sliderProgress.PreviewMouseDown += (sender, e) =>
|
||||
{
|
||||
_wasPlaying = mediaElement.IsPlaying;
|
||||
mediaElement.Pause();
|
||||
};
|
||||
sliderProgress.PreviewMouseUp += (sender, e) =>
|
||||
{
|
||||
if (_wasPlaying) mediaElement.Play();
|
||||
};
|
||||
|
||||
PreviewMouseWheel += (sender, e) => ChangeVolume((double)e.Delta / 120 * 0.04);
|
||||
public bool HasVideo
|
||||
{
|
||||
get => _hasVideo;
|
||||
private set
|
||||
{
|
||||
if (value == _hasVideo) return;
|
||||
_hasVideo = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasVideo
|
||||
public bool IsPlaying
|
||||
{
|
||||
get => _isPlaying;
|
||||
private set
|
||||
{
|
||||
get => _hasVideo;
|
||||
private set
|
||||
{
|
||||
if (value == _hasVideo) return;
|
||||
_hasVideo = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
if (value == _isPlaying) return;
|
||||
_isPlaying = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlaying
|
||||
public bool ShouldLoop
|
||||
{
|
||||
get => _shouldLoop;
|
||||
private set
|
||||
{
|
||||
get => _isPlaying;
|
||||
private set
|
||||
{
|
||||
if (value == _isPlaying) return;
|
||||
_isPlaying = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldLoop
|
||||
{
|
||||
get => _shouldLoop;
|
||||
private set
|
||||
{
|
||||
if (value == _shouldLoop) return;
|
||||
_shouldLoop = value;
|
||||
OnPropertyChanged();
|
||||
if (!IsPlaying)
|
||||
{
|
||||
IsPlaying = true;
|
||||
|
||||
mediaElement.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BitmapSource CoverArt
|
||||
{
|
||||
get => _coverArt;
|
||||
private set
|
||||
{
|
||||
if (ReferenceEquals(value, _coverArt)) return;
|
||||
if (value == null) return;
|
||||
_coverArt = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// old plugin use an int-typed "Volume" config key ranged from 0 to 100. Let's use a new one here.
|
||||
SettingHelper.Set("VolumeDouble", LinearVolume, "QuickLook.Plugin.VideoViewer");
|
||||
SettingHelper.Set("ShouldLoop", ShouldLoop, "QuickLook.Plugin.VideoViewer");
|
||||
|
||||
try
|
||||
{
|
||||
mediaElement?.Close();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
mediaElement?.MediaUriPlayer.Dispose();
|
||||
mediaElement = null;
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void MediaOpened(object o, RoutedEventArgs args)
|
||||
{
|
||||
if (mediaElement == null)
|
||||
return;
|
||||
|
||||
HasVideo = mediaElement.HasVideo;
|
||||
|
||||
_context.IsBusy = false;
|
||||
}
|
||||
|
||||
private void MediaFailed(object sender, MediaFailedEventArgs e)
|
||||
{
|
||||
((MediaUriElement)sender).Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
_context.ViewerContent =
|
||||
new Label { Content = e.Exception, VerticalAlignment = VerticalAlignment.Center };
|
||||
_context.IsBusy = false;
|
||||
}));
|
||||
}
|
||||
|
||||
private void MediaEnded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (mediaElement == null)
|
||||
return;
|
||||
|
||||
mediaElement.MediaPosition = 0;
|
||||
if (ShouldLoop)
|
||||
if (value == _shouldLoop) return;
|
||||
_shouldLoop = value;
|
||||
OnPropertyChanged();
|
||||
if (!IsPlaying)
|
||||
{
|
||||
IsPlaying = true;
|
||||
|
||||
mediaElement.Play();
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
|
||||
public BitmapSource CoverArt
|
||||
{
|
||||
get => _coverArt;
|
||||
private set
|
||||
{
|
||||
if (ReferenceEquals(value, _coverArt)) return;
|
||||
if (value == null) return;
|
||||
_coverArt = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// old plugin use an int-typed "Volume" config key ranged from 0 to 100. Let's use a new one here.
|
||||
SettingHelper.Set("VolumeDouble", LinearVolume, "QuickLook.Plugin.VideoViewer");
|
||||
SettingHelper.Set("ShouldLoop", ShouldLoop, "QuickLook.Plugin.VideoViewer");
|
||||
|
||||
try
|
||||
{
|
||||
mediaElement?.Close();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
IsPlaying = false;
|
||||
|
||||
mediaElement.Pause();
|
||||
}
|
||||
mediaElement?.MediaUriPlayer.Dispose();
|
||||
mediaElement = null;
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowViedoControlContainer(object sender, MouseEventArgs e)
|
||||
catch (Exception e)
|
||||
{
|
||||
var show = (Storyboard)videoControlContainer.FindResource("ShowControlStoryboard");
|
||||
if (videoControlContainer.Opacity == 0 || videoControlContainer.Opacity == 1)
|
||||
show.Begin();
|
||||
Debug.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void AutoHideViedoControlContainer(object sender, EventArgs e)
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void MediaOpened(object o, RoutedEventArgs args)
|
||||
{
|
||||
if (mediaElement == null)
|
||||
return;
|
||||
|
||||
HasVideo = mediaElement.HasVideo;
|
||||
|
||||
_context.IsBusy = false;
|
||||
}
|
||||
|
||||
private void MediaFailed(object sender, MediaFailedEventArgs e)
|
||||
{
|
||||
((MediaUriElement)sender).Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
if (!HasVideo)
|
||||
return;
|
||||
_context.ViewerContent =
|
||||
new Label { Content = e.Exception, VerticalAlignment = VerticalAlignment.Center };
|
||||
_context.IsBusy = false;
|
||||
}));
|
||||
}
|
||||
|
||||
if (videoControlContainer.IsMouseOver)
|
||||
return;
|
||||
private void MediaEnded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (mediaElement == null)
|
||||
return;
|
||||
|
||||
var hide = (Storyboard)videoControlContainer.FindResource("HideControlStoryboard");
|
||||
|
||||
hide.Begin();
|
||||
}
|
||||
|
||||
private void PlayerStateChanged(PlayerState oldState, PlayerState newState)
|
||||
mediaElement.MediaPosition = 0;
|
||||
if (ShouldLoop)
|
||||
{
|
||||
switch (newState)
|
||||
{
|
||||
case PlayerState.Playing:
|
||||
IsPlaying = true;
|
||||
break;
|
||||
|
||||
case PlayerState.Paused:
|
||||
case PlayerState.Stopped:
|
||||
case PlayerState.Closed:
|
||||
IsPlaying = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMeta(string path, MediaInfo.MediaInfo info)
|
||||
{
|
||||
if (HasVideo)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (info == null)
|
||||
throw new NullReferenceException();
|
||||
|
||||
var title = info.Get(StreamKind.General, 0, "Title");
|
||||
var artist = info.Get(StreamKind.General, 0, "Performer");
|
||||
var album = info.Get(StreamKind.General, 0, "Album");
|
||||
|
||||
metaTitle.Text = !string.IsNullOrWhiteSpace(title) ? title : Path.GetFileName(path);
|
||||
metaArtists.Text = artist;
|
||||
metaAlbum.Text = album;
|
||||
|
||||
var cs = info.Get(StreamKind.General, 0, "Cover_Data");
|
||||
if (!string.IsNullOrEmpty(cs))
|
||||
using (var ms = new MemoryStream(Convert.FromBase64String(cs)))
|
||||
{
|
||||
CoverArt = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
metaTitle.Text = Path.GetFileName(path);
|
||||
metaArtists.Text = metaAlbum.Text = string.Empty;
|
||||
}
|
||||
|
||||
metaArtists.Visibility = string.IsNullOrEmpty(metaArtists.Text)
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
metaAlbum.Visibility = string.IsNullOrEmpty(metaAlbum.Text)
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
}
|
||||
|
||||
// Newer .net has Math.Clamp
|
||||
private T Clamp<T>(T val, T min, T max) where T : IComparable<T>
|
||||
{
|
||||
if (val.CompareTo(min) < 0) return min;
|
||||
else if (val.CompareTo(max) > 0) return max;
|
||||
else return val;
|
||||
}
|
||||
|
||||
// A change in amplitude by a factor of 10 corresponds to a 20 dB change
|
||||
private const double DecibelAmplitudeMult = 20.0;
|
||||
|
||||
public double LinearVolume
|
||||
{
|
||||
// mediaElement.Volume returns [0,1] where 0 = -100db, 1 = 0db
|
||||
// Decibel is logarithmic. See amplitude table https://en.wikipedia.org/wiki/Decibel
|
||||
get
|
||||
{
|
||||
var dbVol = 100.0 * (mediaElement.Volume - 1.0);
|
||||
var linearVol = Math.Pow(10, dbVol / DecibelAmplitudeMult);
|
||||
return linearVol;
|
||||
}
|
||||
set
|
||||
{
|
||||
var linearVol = Clamp(value, 0.00001, 1.0);
|
||||
var dbVol = DecibelAmplitudeMult * Math.Log10(linearVol);
|
||||
mediaElement.Volume = dbVol / 100.0 + 1.0;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeVolume(double delta)
|
||||
{
|
||||
LinearVolume = LinearVolume + delta; // setter will clamp
|
||||
}
|
||||
|
||||
private void TogglePlayPause(object sender, EventArgs e)
|
||||
{
|
||||
if (mediaElement.IsPlaying)
|
||||
mediaElement.Pause();
|
||||
else
|
||||
mediaElement.Play();
|
||||
}
|
||||
|
||||
private void ToggleShouldLoop(object sender, EventArgs e)
|
||||
{
|
||||
ShouldLoop = !ShouldLoop;
|
||||
}
|
||||
|
||||
public void LoadAndPlay(string path, MediaInfo.MediaInfo info)
|
||||
{
|
||||
UpdateMeta(path, info);
|
||||
|
||||
// detect rotation
|
||||
double.TryParse(info?.Get(StreamKind.Video, 0, "Rotation"), out var rotation);
|
||||
// Correct rotation: on some machine the value "90" becomes "90000" by some reason
|
||||
if (rotation > 360)
|
||||
rotation /= 1e3;
|
||||
if (Math.Abs(rotation) > 0.1)
|
||||
mediaElement.LayoutTransform = new RotateTransform(rotation, 0.5, 0.5);
|
||||
|
||||
mediaElement.Source = new Uri(path);
|
||||
// old plugin use an int-typed "Volume" config key ranged from 0 to 100. Let's use a new one here.
|
||||
LinearVolume = SettingHelper.Get("VolumeDouble", 1d, "QuickLook.Plugin.VideoViewer");
|
||||
IsPlaying = true;
|
||||
|
||||
mediaElement.Play();
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
else
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
IsPlaying = false;
|
||||
|
||||
mediaElement.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowViedoControlContainer(object sender, MouseEventArgs e)
|
||||
{
|
||||
var show = (Storyboard)videoControlContainer.FindResource("ShowControlStoryboard");
|
||||
if (videoControlContainer.Opacity == 0 || videoControlContainer.Opacity == 1)
|
||||
show.Begin();
|
||||
}
|
||||
|
||||
private void AutoHideViedoControlContainer(object sender, EventArgs e)
|
||||
{
|
||||
if (!HasVideo)
|
||||
return;
|
||||
|
||||
if (videoControlContainer.IsMouseOver)
|
||||
return;
|
||||
|
||||
var hide = (Storyboard)videoControlContainer.FindResource("HideControlStoryboard");
|
||||
|
||||
hide.Begin();
|
||||
}
|
||||
|
||||
private void PlayerStateChanged(PlayerState oldState, PlayerState newState)
|
||||
{
|
||||
switch (newState)
|
||||
{
|
||||
case PlayerState.Playing:
|
||||
IsPlaying = true;
|
||||
break;
|
||||
|
||||
case PlayerState.Paused:
|
||||
case PlayerState.Stopped:
|
||||
case PlayerState.Closed:
|
||||
IsPlaying = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMeta(string path, MediaInfo.MediaInfo info)
|
||||
{
|
||||
if (HasVideo)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (info == null)
|
||||
throw new NullReferenceException();
|
||||
|
||||
var title = info.Get(StreamKind.General, 0, "Title");
|
||||
var artist = info.Get(StreamKind.General, 0, "Performer");
|
||||
var album = info.Get(StreamKind.General, 0, "Album");
|
||||
|
||||
metaTitle.Text = !string.IsNullOrWhiteSpace(title) ? title : Path.GetFileName(path);
|
||||
metaArtists.Text = artist;
|
||||
metaAlbum.Text = album;
|
||||
|
||||
var cs = info.Get(StreamKind.General, 0, "Cover_Data");
|
||||
if (!string.IsNullOrEmpty(cs))
|
||||
using (var ms = new MemoryStream(Convert.FromBase64String(cs)))
|
||||
{
|
||||
CoverArt = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
metaTitle.Text = Path.GetFileName(path);
|
||||
metaArtists.Text = metaAlbum.Text = string.Empty;
|
||||
}
|
||||
|
||||
metaArtists.Visibility = string.IsNullOrEmpty(metaArtists.Text)
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
metaAlbum.Visibility = string.IsNullOrEmpty(metaAlbum.Text)
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
}
|
||||
|
||||
// Newer .net has Math.Clamp
|
||||
private T Clamp<T>(T val, T min, T max) where T : IComparable<T>
|
||||
{
|
||||
if (val.CompareTo(min) < 0) return min;
|
||||
else if (val.CompareTo(max) > 0) return max;
|
||||
else return val;
|
||||
}
|
||||
|
||||
// A change in amplitude by a factor of 10 corresponds to a 20 dB change
|
||||
private const double DecibelAmplitudeMult = 20.0;
|
||||
|
||||
public double LinearVolume
|
||||
{
|
||||
// mediaElement.Volume returns [0,1] where 0 = -100db, 1 = 0db
|
||||
// Decibel is logarithmic. See amplitude table https://en.wikipedia.org/wiki/Decibel
|
||||
get
|
||||
{
|
||||
var dbVol = 100.0 * (mediaElement.Volume - 1.0);
|
||||
var linearVol = Math.Pow(10, dbVol / DecibelAmplitudeMult);
|
||||
return linearVol;
|
||||
}
|
||||
set
|
||||
{
|
||||
var linearVol = Clamp(value, 0.00001, 1.0);
|
||||
var dbVol = DecibelAmplitudeMult * Math.Log10(linearVol);
|
||||
mediaElement.Volume = dbVol / 100.0 + 1.0;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeVolume(double delta)
|
||||
{
|
||||
LinearVolume = LinearVolume + delta; // setter will clamp
|
||||
}
|
||||
|
||||
private void TogglePlayPause(object sender, EventArgs e)
|
||||
{
|
||||
if (mediaElement.IsPlaying)
|
||||
mediaElement.Pause();
|
||||
else
|
||||
mediaElement.Play();
|
||||
}
|
||||
|
||||
private void ToggleShouldLoop(object sender, EventArgs e)
|
||||
{
|
||||
ShouldLoop = !ShouldLoop;
|
||||
}
|
||||
|
||||
public void LoadAndPlay(string path, MediaInfo.MediaInfo info)
|
||||
{
|
||||
UpdateMeta(path, info);
|
||||
|
||||
// detect rotation
|
||||
double.TryParse(info?.Get(StreamKind.Video, 0, "Rotation"), out var rotation);
|
||||
// Correct rotation: on some machine the value "90" becomes "90000" by some reason
|
||||
if (rotation > 360)
|
||||
rotation /= 1e3;
|
||||
if (Math.Abs(rotation) > 0.1)
|
||||
mediaElement.LayoutTransform = new RotateTransform(rotation, 0.5, 0.5);
|
||||
|
||||
mediaElement.Source = new Uri(path);
|
||||
// old plugin use an int-typed "Volume" config key ranged from 0 to 100. Let's use a new one here.
|
||||
LinearVolume = SettingHelper.Get("VolumeDouble", 1d, "QuickLook.Plugin.VideoViewer");
|
||||
|
||||
mediaElement.Play();
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user