Я пишу простое приложение, которое использует VLC для воспроизведения видео.Обычно это было бы простым решением, но есть побочные эффекты практически для всех библиотек VLC в настоящее время;Vlc.DotNet.WPF великолепен, но имеет побочный эффект: интенсивность использования процессора, но решает проблемы с многоуровневым видео, а LibVLCSharp.WPF намного лучше с загрузкой процессора, но имеет проблемы с многоуровневым видео (проблемы воздушного пространства).Итак, я хочу иметь возможность разрабатывать свое приложение, чтобы позволить мне выбирать, какую библиотеку видео я использую для воспроизведения видео, чтобы я мог управлять компромиссами двух средств визуализации в зависимости от аппаратных и ситуационных требований, которые у меня есть.
Каждая библиотека предоставляет пользовательский элемент управления UserControl для отображения видео в представлении.LibVLCSharp предоставляет LibVLCSharp.WPF.VideoView
, а Vlc.DotNet.WPF - Vlc.DotNet.Wpf.VlcControl
.
. Я структурировал свой код для независимого отображения каждого из них следующим образом:
Класс управления для использования VlcDotNetWpf:
public class vlcPlayerDotNet : Vlc.DotNet.Wpf.VlcControl
{
public vlcPlayerDotNet() {}
~vlcPlayerDotNet()
{
// class-specific cleanup routines
}
public void PlayVideo()
{
// class-specific video playback code to play Source video
}
// Dependency Properties
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(
"Source", typeof(string),
typeof(vlcPlayerDotNet)
);
public string Source
{
get { return (string)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
/*
... and so on, for multiple dependency properties
*/
}
И класс Control для использования LibVlcSharp.Wpf:
public class vlcPlayerLibVLCSharp : LibVLCSharp.WPF.VideoView
{
public vlcPlayerLibVLCSharp() {}
~vlcPlayerLibVLCSharp()
{
// class-specific cleanup routines
}
public void PlayVideo()
{
// class-specific video playback code to play Source video
}
// Dependency Properties
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(
"Source", typeof(string),
typeof(vlcPlayerLibVLCSharp)
);
public string Source
{
get { return (string)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
/*
... and so on, for multiple dependency properties
*/
}
В моей ViewModel у меня есть несколько необходимых входов, а именно:
private string animationFile;
public string AnimationFile
{
get { return animationFile; }
set { SetProperty(ref animationFile, value); }
}
Тогдав моем представлении я определяю, какой элемент управления видео я хочу использовать - например, если я использую проигрыватель LibVLCSharp, я использую следующее:
<Grid>
<local:vlcPlayerLibVLCSharp
Grid.Column="0" Grid.Row="0"
HorizontalAlignment="Center" VerticalAlignment="Center"
Height="720" Width="1280"
Source="{Binding AnimationFile}" LoadedBehavior="Play"
MediaEnded="animationPlayer_MediaEnded"
MediaFailed="animationPlayer_MediaFailed"
x:Name="vlcPlayer"/>
</Grid>
и т. д. для другого проигрывателя.
Чего я НЕ ХОЧУ, так это чтобы два View UserControls были сложены и свернуты;Я хочу иметь возможность иметь ОДИН View UserControl в представлении и иметь возможность динамически выбирать, какой UserControl фактически используется в представлении.Моя цель - иметь простой вид, и было бы замечательно, если бы я мог позже добавить еще один элемент управления без изменения вида (но это не нарушитель правил).
Я исследовал использование ContentControl
в представлении для хранения видео UserControl (ов), но я не мог понять, как обращаться со свойствами зависимости, которые необходимо передать в элемент управления.Я также посмотрел на DataTemplate
и DataTemplateSelector
, но все примеры, которые я нашел, имеют дело со списками, и мне трудно сделать концептуальный переход от списка к этим производным элементам управления.
Любой совет о том, как спроектировать мой код, чтобы разрешить этот обмен под капотом, приветствуется!