先展示基本效果:

 

实现过程:

首先通过 Nuget 下载 VLC 相关的组件;

 

View 层(XAML)

添加引用 和 控件(里面使用了许多自定义的控件样式,这里就不在赘述)

<UserControl x:Class=”Client.Modules.Video.View.uc_video”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
xmlns:local=”clr-namespace:Client.Modules.Video.View”
xmlns:ctrl=”clr-namespace:Resource.Control;assembly=Resource”
xmlns:Vlc=”clr-namespace:Vlc.DotNet.Wpf;assembly=Vlc.DotNet.Wpf”
xmlns:conver=”clr-namespace:Resource.Convert;assembly=Resource”
xmlns:i=”clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity”
xmlns:gmc=”clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform”
mc:Ignorable=”d”
d:DesignHeight=”450″ d:DesignWidth=”800″
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height=”Auto” />
</Grid.RowDefinitions>
<Vlc:VlcControl Grid.RowSpan=”2″ x:Name=”vc” />
<Grid x:Name=”rt_ctrl_panel” Grid.Row=”1″ Style=”{StaticResource panel_realtime_control}”
Width=”450″
MouseEnter=”rt_ctrl_panel_MouseEnter” MouseLeave=”rt_ctrl_panel_MouseLeave”>
<Grid.Background>
<SolidColorBrush Opacity=”0.9″ Color=”#273555″/>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Row=”0″ CornerRadius=”5 5 0 0″ BorderBrush=”{StaticResource primary}” BorderThickness=”1 1 1 0″>
<StackPanel Orientation=”Horizontal” HorizontalAlignment=”Center” VerticalAlignment=”Center” >
<Button Style=”{StaticResource btn_icon}” Foreground=”{StaticResource btn.fg_inverse}” Width=”35″ Height=”35″ FontSize=”28″ Content=”&#xf191;” Click=”btn_frame_pre” Margin=”20 0 10 0″ />
<ctrl:FCheckBox Style=”{StaticResource ckb_changeicon}” Width=”35″ Height=”35″ Foreground=”Gray” FontSize=”30″ Content=”&#xf04c;” FAIcon=”&#xf04b;” Click=”chk_Pause_Checked” IsChecked=”{Binding IsPaused}” Margin=”10 0 10 0″/>
<Button Style=”{StaticResource btn_icon}” Foreground=”{StaticResource btn.fg_inverse}” Width=”35″ Height=”35″ FontSize=”28″ Content=”&#xf152;” Click=”btn_frame_nxt” Margin=”10 0 10 0″ />
<Button Style=”{StaticResource btn_icon}” Foreground=”{StaticResource btn.fg_inverse}” Width=”35″ Height=”35″ FontSize=”28″ Content=”&#xf030;” Click=”btn_snapshot” Margin=”10 0 10 0″ />
<Button Style=”{StaticResource btn_icon}” Foreground=”{StaticResource btn.fg_inverse}” Width=”35″ Height=”35″ FontSize=”28″ Content=”&#xf381;” Click=”btn_save” Margin=”10 0 10 0″ />
<ComboBox x:Name=”combobox_rate” Style=”{StaticResource DefaultComboBox}” ItemsSource=”{Binding DropDownList_Rate}”
DisplayMemberPath=”Key” SelectedValuePath=”Value” SelectionChanged=”combobox_rate_SelectionChanged” Width=”100″ Margin=”10 0 20 0″/>
</StackPanel>
</Border>
<Border Grid.Row=”1″ CornerRadius=”0 0 5 5″ BorderBrush=”{StaticResource primary}” BorderThickness=”1 0 1 1″ Height=”20″>
<Slider x:Name=”progressbar” Style=”{StaticResource style_slider}” Margin=”10 0″ VerticalAlignment=”Center” MouseUp=”progressbar_MouseUp” />
</Border>
</Grid>
</Grid>
</UserControl>
基本的控件加载和视频控制事件:

#region 初始化
/// <summary>
/// 初始化
/// </summary>
public uc_video()
{
InitializeComponent();
DataContext = my_vm;

if (vc.SourceProvider.MediaPlayer == null)
{
var vlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, “libvlc”, IntPtr.Size == 4 ? “win-x86” : “win-x64”));
Task.Factory.StartNew(() =>
{
App.dispatcher.Invoke(() =>
{
vc.SourceProvider.CreatePlayer(vlcLibDirectory, new string[] { });
});
});
}
Init_Timer();
progressbar.Minimum = 0;
progressbar.Maximum = 100000;

my_vm.DropDownList_Rate.Clear();
my_vm.DropDownList_Rate.Add(new KeyValuePair<string, float>(“慢放”, 0.5f));
my_vm.DropDownList_Rate.Add(new KeyValuePair<string, float>(“正常”, 1));
my_vm.DropDownList_Rate.Add(new KeyValuePair<string, float>(“快放”, 2));

combobox_rate.SelectedIndex = 1;
}
#endregion

#region 控制
/// <summary>
/// 加载视频
/// </summary>
private void Load_Video()
{
if (!string.IsNullOrWhiteSpace(url_video))
{
if (vc.SourceProvider.MediaPlayer.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Ended)
{
vc.SourceProvider.MediaPlayer.ResetMedia();
}

WebRequest req = WebRequest.CreateHttp(url_video);
try
{
WebResponse res = req.GetResponse();
if (res.ContentLength > 0)
{
vc.SourceProvider.MediaPlayer.Play(“您的视频网址或者路径”, new string[] { });
}
}
catch (Exception ex)
{
win_msg.Info(“提示”, $”该列车视频尚未准备就绪…{ex.Message}”); return;
}
}
}
/// <summary>
/// 播放/暂停
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
private void chk_Pause_Checked(object sender, RoutedEventArgs e)
{
if (vc.SourceProvider.MediaPlayer == null) return;
if (string.IsNullOrWhiteSpace(url_video)) { win_msg.Info(“提示”, “该列车视频尚未准备就绪…”); return; }

if (vc.SourceProvider.MediaPlayer.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.NothingSpecial ||
vc.SourceProvider.MediaPlayer.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Stopped ||
vc.SourceProvider.MediaPlayer.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Ended)
{
Load_Video();
}

if (vc.SourceProvider.MediaPlayer.IsPlaying())
{
vc.SourceProvider.MediaPlayer.Pause();
my_vm.IsPaused = true;
}
else
{
vc.SourceProvider.MediaPlayer.Play();
}
}
/// <summary>
/// 上一帧
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
private void btn_frame_pre(object sender, RoutedEventArgs e)
{
if (vc.SourceProvider.MediaPlayer == null) return;
if (vc.SourceProvider.MediaPlayer.IsPlaying()) vc.SourceProvider.MediaPlayer.Pause();
float cur_time = vc.SourceProvider.MediaPlayer.Position;
cur_time -= 0.001f;
if (cur_time <= 0) { return; }
vc.SourceProvider.MediaPlayer.Position = cur_time;
}
/// <summary>
/// 下一帧
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
private void btn_frame_nxt(object sender, RoutedEventArgs e)
{
if (vc.SourceProvider.MediaPlayer == null) return;
if (vc.SourceProvider.MediaPlayer.IsPlaying()) vc.SourceProvider.MediaPlayer.Pause();
float cur_time = vc.SourceProvider.MediaPlayer.Position;
cur_time += 0.001f;
if (cur_time >= 1) { return; }
vc.SourceProvider.MediaPlayer.Position = cur_time;
}
/// <summary>
/// 保存截图
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
private void btn_snapshot(object sender, RoutedEventArgs e)
{
if (vc.SourceProvider.MediaPlayer == null) return;
System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
fbd.Description = “选择截图保存位置”;
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
FileInfo fi = new FileInfo(fbd.SelectedPath + “\\123.jpg”);
vc.SourceProvider.MediaPlayer.TakeSnapshot(fi);
}
}
/// <summary>
/// 保存视频
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
private void btn_save(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
fbd.Description = “选择视频保存位置”;
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
WebClient web = new WebClient();
web.DownloadFile(url_video, fbd.SelectedPath + “\\test.mp4”);
}
}

private TimeSpan ts;
private DispatcherTimer tt = new DispatcherTimer();
/// <summary>
/// 调整进度
/// </summary>
public void Init_Timer()
{
if (!tt.IsEnabled)
{
tt.Interval = TimeSpan.FromMilliseconds(1000);
tt.Tick += new EventHandler((sender, e) =>
{
progressbar.Value = Convert.ToInt32(vc.SourceProvider.MediaPlayer.Position * 100000);
});
tt.IsEnabled = true;
}
}
/// <summary>
/// 进度条调整
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
private void progressbar_MouseUp(object sender, MouseButtonEventArgs e)
{
if (vc.SourceProvider.MediaPlayer == null) return;
vc.SourceProvider.MediaPlayer.Position = float.Parse(progressbar.Value.ToString()) / 100000;
}
/// <summary>
/// 播放速率
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
private void combobox_rate_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (vc.SourceProvider.MediaPlayer == null) return;
KeyValuePair<string, float> kv = (KeyValuePair<string, float>)combobox_rate.SelectedItem;
vc.SourceProvider.MediaPlayer.Rate = kv.Value;
}
#endregion

————————————————
版权声明:本文为CSDN博主「快乐的肉球」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/iceagezh/article/details/105711478