mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-12 10:19:07 +00:00
refine UI and stability
This commit is contained in:
@@ -67,7 +67,7 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
|
|
||||||
var v = (bool) value;
|
var v = (bool) value;
|
||||||
|
|
||||||
return v ? Visibility.Visible : Visibility.Hidden;
|
return v ? Visibility.Visible : Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
@@ -81,11 +81,11 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return Visibility.Hidden;
|
return Visibility.Collapsed;
|
||||||
|
|
||||||
var v = (bool) value;
|
var v = (bool) value;
|
||||||
|
|
||||||
return v ? Visibility.Hidden : Visibility.Visible;
|
return v ? Visibility.Collapsed : Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
@@ -28,7 +28,7 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
{
|
{
|
||||||
public class Plugin : IViewer
|
public class Plugin : IViewer
|
||||||
{
|
{
|
||||||
private Size _mediaSize;
|
private FFprobe _probe;
|
||||||
private ViewerPanel _vp;
|
private ViewerPanel _vp;
|
||||||
|
|
||||||
public int Priority => int.MaxValue;
|
public int Priority => int.MaxValue;
|
||||||
@@ -46,24 +46,28 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
if (Directory.Exists(path))
|
if (Directory.Exists(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var blacklist = new[]
|
var blacklist = new[] {".txt", ".jpg", ".bmp", ".tiff"};
|
||||||
{
|
|
||||||
".txt", ".jpg", ".bmp"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (blacklist.Contains(Path.GetExtension(path).ToLower()))
|
if (blacklist.Contains(Path.GetExtension(path).ToLower()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return new FFprobe(path).CanDecode();
|
var probe = new FFprobe(path);
|
||||||
|
|
||||||
|
// check if it is a APNG image
|
||||||
|
if (Path.GetExtension(path).ToLower() == ".png" && probe.GetFormatName().ToLower() != "apng")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return probe.CanDecode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Prepare(string path, ContextObject context)
|
public void Prepare(string path, ContextObject context)
|
||||||
{
|
{
|
||||||
var def = new Size(450, 450);
|
var def = new Size(450, 450);
|
||||||
|
|
||||||
_mediaSize = new FFprobe(path).GetViewSize();
|
_probe = new FFprobe(path);
|
||||||
|
var mediaSize = _probe.GetViewSize();
|
||||||
|
|
||||||
var windowSize = _mediaSize == Size.Empty ? def : _mediaSize;
|
var windowSize = mediaSize == Size.Empty ? def : mediaSize;
|
||||||
windowSize.Width = Math.Max(def.Width, windowSize.Width);
|
windowSize.Width = Math.Max(def.Width, windowSize.Width);
|
||||||
windowSize.Height = Math.Max(def.Height, windowSize.Height);
|
windowSize.Height = Math.Max(def.Height, windowSize.Height);
|
||||||
|
|
||||||
@@ -76,13 +80,12 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
|
|
||||||
context.ViewerContent = _vp;
|
context.ViewerContent = _vp;
|
||||||
|
|
||||||
Debug.WriteLine("ViewerContent done");
|
|
||||||
_vp.LoadAndPlay(path);
|
_vp.LoadAndPlay(path);
|
||||||
Debug.WriteLine("LoadAndPlay done");
|
|
||||||
|
|
||||||
_vp.mediaElement.MediaOpened += (sender, e) => context.IsBusy = false;
|
_vp.mediaElement.MediaOpened += (sender, e) => context.IsBusy = false;
|
||||||
|
|
||||||
var info = _mediaSize == Size.Empty ? "Audio" : $"{_mediaSize.Width}×{_mediaSize.Height}";
|
var mediaSize = _probe.GetViewSize();
|
||||||
|
var info = mediaSize == Size.Empty ? "Audio" : $"{mediaSize.Width}×{mediaSize.Height}";
|
||||||
|
|
||||||
context.Title =
|
context.Title =
|
||||||
$"{Path.GetFileName(path)} ({info})";
|
$"{Path.GetFileName(path)} ({info})";
|
||||||
@@ -90,6 +93,8 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
|
|
||||||
public void Cleanup()
|
public void Cleanup()
|
||||||
{
|
{
|
||||||
|
_probe = null;
|
||||||
|
|
||||||
_vp?.Dispose();
|
_vp?.Dispose();
|
||||||
_vp = null;
|
_vp = null;
|
||||||
}
|
}
|
||||||
|
@@ -44,8 +44,8 @@
|
|||||||
</Image.Style>
|
</Image.Style>
|
||||||
</Image>
|
</Image>
|
||||||
|
|
||||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="100"
|
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="100">
|
||||||
Visibility="{Binding NaturalDuration.HasTimeSpan, ElementName=mediaElement, Converter={StaticResource BooleanToVisibilityVisibleConverter}}">
|
<!--Visibility="{Binding NaturalDuration.HasTimeSpan, ElementName=mediaElement, Converter={StaticResource BooleanToVisibilityVisibleConverter}}"-->
|
||||||
<Grid.Background>
|
<Grid.Background>
|
||||||
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
|
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
|
||||||
<GradientStop Offset="0.0" Color="#00000000" />
|
<GradientStop Offset="0.0" Color="#00000000" />
|
||||||
@@ -90,10 +90,10 @@
|
|||||||
</Grid.Style>
|
</Grid.Style>
|
||||||
|
|
||||||
<Slider Grid.Row="1" x:Name="sliderProgress" Style="{StaticResource PositionSliderStyle}"
|
<Slider Grid.Row="1" x:Name="sliderProgress" Style="{StaticResource PositionSliderStyle}"
|
||||||
IsEnabled="{Binding IsOpen, ElementName=mediaElement}"
|
|
||||||
SmallChange="{Binding FrameStepDuration, ElementName=mediaElement,Converter={StaticResource TimeSpanToSecondsConverter}}"
|
SmallChange="{Binding FrameStepDuration, ElementName=mediaElement,Converter={StaticResource TimeSpanToSecondsConverter}}"
|
||||||
LargeChange="{Binding FrameStepDuration, ElementName=mediaElement, Converter={StaticResource TimeSpanToSecondsConverter}}"
|
LargeChange="{Binding FrameStepDuration, ElementName=mediaElement, Converter={StaticResource TimeSpanToSecondsConverter}}"
|
||||||
Maximum="{Binding NaturalDuration, ElementName=mediaElement,Converter={StaticResource TimeSpanToSecondsConverter}}"
|
Maximum="{Binding NaturalDuration, ElementName=mediaElement,Converter={StaticResource TimeSpanToSecondsConverter}}"
|
||||||
|
Visibility="{Binding NaturalDuration.HasTimeSpan, ElementName=mediaElement, Converter={StaticResource BooleanToVisibilityVisibleConverter}}"
|
||||||
Value="{Binding Position, ElementName=mediaElement, Converter={StaticResource TimeSpanToSecondsConverter}}" />
|
Value="{Binding Position, ElementName=mediaElement, Converter={StaticResource TimeSpanToSecondsConverter}}" />
|
||||||
|
|
||||||
<Grid Grid.Row="2">
|
<Grid Grid.Row="2">
|
||||||
@@ -103,6 +103,7 @@
|
|||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<StackPanel Grid.Column="0" VerticalAlignment="Center"
|
<StackPanel Grid.Column="0" VerticalAlignment="Center"
|
||||||
|
Visibility="{Binding HasAudio, ElementName=mediaElement,Converter={StaticResource BooleanToVisibilityVisibleConverter}}"
|
||||||
Orientation="Horizontal" Margin="10,0,0,0">
|
Orientation="Horizontal" Margin="10,0,0,0">
|
||||||
<Grid x:Name="buttonMute" Style="{StaticResource ControlButtonStyle}">
|
<Grid x:Name="buttonMute" Style="{StaticResource ControlButtonStyle}">
|
||||||
<fa:ImageAwesome Height="23" Width="23" Foreground="#FFEFEFEF">
|
<fa:ImageAwesome Height="23" Width="23" Foreground="#FFEFEFEF">
|
||||||
@@ -119,7 +120,7 @@
|
|||||||
</fa:ImageAwesome.Style>
|
</fa:ImageAwesome.Style>
|
||||||
</fa:ImageAwesome>
|
</fa:ImageAwesome>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Slider Style="{StaticResource CustomSliderStyle}" MaxWidth="75" Maximum="1"
|
<Slider Style="{StaticResource CustomSliderStyle}" Width="75" Maximum="1"
|
||||||
Value="{Binding Volume, ElementName=mediaElement}"
|
Value="{Binding Volume, ElementName=mediaElement}"
|
||||||
Visibility="{Binding IsMuted, ElementName=mediaElement, Converter={StaticResource BooleanToVisibilityHiddenConverter}}"
|
Visibility="{Binding IsMuted, ElementName=mediaElement, Converter={StaticResource BooleanToVisibilityHiddenConverter}}"
|
||||||
BorderThickness="0,0,5,0" />
|
BorderThickness="0,0,5,0" />
|
||||||
@@ -157,9 +158,11 @@
|
|||||||
Orientation="Horizontal" Margin="0,0,10,0">
|
Orientation="Horizontal" Margin="0,0,10,0">
|
||||||
<TextBlock FontSize="14" Foreground="#FFEFEFEF"
|
<TextBlock FontSize="14" Foreground="#FFEFEFEF"
|
||||||
Text="{Binding Position, StringFormat=hh\\:mm\\:ss, ElementName=mediaElement}" />
|
Text="{Binding Position, StringFormat=hh\\:mm\\:ss, ElementName=mediaElement}" />
|
||||||
<TextBlock FontSize="14" Text=" / " Foreground="#FFEFEFEF" />
|
<TextBlock FontSize="14" Text=" / " Foreground="#FFEFEFEF"
|
||||||
|
Visibility="{Binding NaturalDuration.HasTimeSpan, ElementName=mediaElement, Converter={StaticResource BooleanToVisibilityVisibleConverter}}" />
|
||||||
<TextBlock FontSize="14" Foreground="#FFEFEFEF"
|
<TextBlock FontSize="14" Foreground="#FFEFEFEF"
|
||||||
Text="{Binding NaturalDuration, StringFormat=hh\\:mm\\:ss, ElementName=mediaElement, Converter={StaticResource DurationToTimeSpanConverter}}" />
|
Text="{Binding NaturalDuration, StringFormat=hh\\:mm\\:ss, ElementName=mediaElement, Converter={StaticResource DurationToTimeSpanConverter}}"
|
||||||
|
Visibility="{Binding NaturalDuration.HasTimeSpan, ElementName=mediaElement, Converter={StaticResource BooleanToVisibilityVisibleConverter}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@@ -46,8 +46,8 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
//};
|
//};
|
||||||
buttonMute.MouseLeftButtonUp += (sender, e) => mediaElement.IsMuted = !mediaElement.IsMuted;
|
buttonMute.MouseLeftButtonUp += (sender, e) => mediaElement.IsMuted = !mediaElement.IsMuted;
|
||||||
buttonStop.MouseLeftButtonUp += (sender, e) => mediaElement.Stop();
|
buttonStop.MouseLeftButtonUp += (sender, e) => mediaElement.Stop();
|
||||||
buttonBackward.MouseLeftButtonUp += (sender, e) => SeekBackward();
|
buttonBackward.MouseLeftButtonUp += (sender, e) => Seek(TimeSpan.FromSeconds(-10));
|
||||||
buttonForward.MouseLeftButtonUp += (sender, e) => SeekForward();
|
buttonForward.MouseLeftButtonUp += (sender, e) => Seek(TimeSpan.FromSeconds(10));
|
||||||
|
|
||||||
sliderProgress.PreviewMouseDown += (sender, e) =>
|
sliderProgress.PreviewMouseDown += (sender, e) =>
|
||||||
{
|
{
|
||||||
@@ -60,52 +60,44 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
};
|
};
|
||||||
|
|
||||||
mediaElement.MediaFailed += ShowErrorNotification;
|
mediaElement.MediaFailed += ShowErrorNotification;
|
||||||
mediaElement.MediaEnded += (s, e) =>
|
/*mediaElement.MediaEnded += (s, e) =>
|
||||||
{
|
{
|
||||||
|
if (mediaElement.IsOpen)
|
||||||
if (!mediaElement.NaturalDuration.HasTimeSpan)
|
if (!mediaElement.NaturalDuration.HasTimeSpan)
|
||||||
{
|
{
|
||||||
mediaElement.Stop();
|
mediaElement.Stop();
|
||||||
mediaElement.Play();
|
mediaElement.Play();
|
||||||
}
|
}
|
||||||
};
|
};*/
|
||||||
|
|
||||||
|
PreviewMouseWheel += (sender, e) => ChangeVolume((double) e.Delta / 120 / 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
mediaElement?.Stop();
|
mediaElement?.Stop();
|
||||||
mediaElement?.Dispose();
|
mediaElement?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.WriteLine(e);
|
||||||
|
}
|
||||||
mediaElement = null;
|
mediaElement = null;
|
||||||
Debug.WriteLine("dispose done");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResumePlaying()
|
private void ChangeVolume(double delta)
|
||||||
{
|
{
|
||||||
_wasPlaying = mediaElement.IsPlaying;
|
mediaElement.Volume += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SeekBackward()
|
private void Seek(TimeSpan delta)
|
||||||
{
|
{
|
||||||
_wasPlaying = mediaElement.IsPlaying;
|
_wasPlaying = mediaElement.IsPlaying;
|
||||||
mediaElement.Pause();
|
mediaElement.Pause();
|
||||||
|
|
||||||
var pos = mediaElement.Position;
|
mediaElement.Position = mediaElement.Position + delta;
|
||||||
var delta = TimeSpan.FromSeconds(15);
|
|
||||||
|
|
||||||
mediaElement.Position = pos < pos - delta ? TimeSpan.Zero : pos - delta;
|
|
||||||
|
|
||||||
if (_wasPlaying) mediaElement.Play();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SeekForward()
|
|
||||||
{
|
|
||||||
_wasPlaying = mediaElement.IsPlaying;
|
|
||||||
mediaElement.Pause();
|
|
||||||
|
|
||||||
var pos = mediaElement.Position;
|
|
||||||
var len = mediaElement.NaturalDuration.TimeSpan;
|
|
||||||
var delta = TimeSpan.FromSeconds(15);
|
|
||||||
|
|
||||||
mediaElement.Position = pos + delta > len ? len : pos + delta;
|
|
||||||
|
|
||||||
if (_wasPlaying) mediaElement.Play();
|
if (_wasPlaying) mediaElement.Play();
|
||||||
}
|
}
|
||||||
@@ -113,10 +105,16 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
private void TogglePlayPause(object sender, MouseButtonEventArgs e)
|
private void TogglePlayPause(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
if (mediaElement.IsPlaying)
|
if (mediaElement.IsPlaying)
|
||||||
|
{
|
||||||
mediaElement.Pause();
|
mediaElement.Pause();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (mediaElement.HasMediaEnded)
|
||||||
|
mediaElement.Stop();
|
||||||
mediaElement.Play();
|
mediaElement.Play();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[DebuggerNonUserCode]
|
[DebuggerNonUserCode]
|
||||||
private void ShowErrorNotification(object sender, ExceptionRoutedEventArgs exceptionRoutedEventArgs)
|
private void ShowErrorNotification(object sender, ExceptionRoutedEventArgs exceptionRoutedEventArgs)
|
||||||
@@ -133,7 +131,7 @@ namespace QuickLook.Plugin.VideoViewer
|
|||||||
public void LoadAndPlay(string path)
|
public void LoadAndPlay(string path)
|
||||||
{
|
{
|
||||||
mediaElement.Source = new Uri(path);
|
mediaElement.Source = new Uri(path);
|
||||||
mediaElement.MediaOpened += (sender, e) => mediaElement.IsMuted = true;
|
mediaElement.MediaOpened += (sender, e) => mediaElement.Volume = 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ViewerPanel()
|
~ViewerPanel()
|
||||||
|
Binary file not shown.
BIN
QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ffme/ffme.pdb
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ffme/ffme.pdb
Normal file
Binary file not shown.
Binary file not shown.
BIN
QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ffme/ffmpeg.pdb
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ffme/ffmpeg.pdb
Normal file
Binary file not shown.
Reference in New Issue
Block a user