vlc 视频局部放大【WPF版】
最近做了一个项目,其中功能有二维、三维地图展示,视频、音频播放,视频解码同步音频等,项目过程中也遇到一些技术难题,但最终还是解决,我个人感觉最应该记录下来的就是视频局放大的功能。先上两张效果图:
根据项目需求,需要对视频进行局部放大,便于对细节地方进行查看,视频播放控件采用的是xZune.Vlc.Wpf - .Net 4.5 的VlcMediaPlayer网上有开源的代码,因为需要对视频的音频输出端口进行设置,而不是通过默认的扬声器输出,设置音频设置端口为:
this.videoPlayer.Initialize(libVlcPath, options);
libVlcPath为libvlc库文件夹路径;options为参数,包括音频输出设备(如:"-I", "dummy", "--avi-index=1", "--ignore-config", "--no-video-title", "--aout=directsound")
视频局部放大主要参考网上有位朋友发的wpf图片局部放大的原理来实现,主要实现步骤如下:
一、布局
<!--右侧大图--> <Canvas x:Name="BigBox" Width="643" Height="643" Canvas.Left="360" Canvas.Top="20" Visibility="Visible"> <!--右侧原图片 注意尺寸--> <Image x:Name="bigImg" Width="2592" Height="1922" Canvas.Left="0" Canvas.Top="-780" /> <Canvas.Clip> <RectangleGeometry Rect="0,0,643,643" /> </Canvas.Clip> </Canvas> <!--左侧小图--> <Canvas x:Name="SmallBox" HorizontalAlignment="Left" VerticalAlignment="Top" MouseMove="MoveRect_MouseMove" Width="121" Height="90" Canvas.Left="20" Canvas.Top="20"> <Canvas.Background> <ImageBrush Stretch="UniformToFill" /> </Canvas.Background> <!--半透明矩形框--> <Rectangle x:Name="MoveRect" Fill="White" Opacity="0.3" Stroke="Red" Width="30" Height="30" Canvas.Top="0" Canvas.Left="0"/> </Canvas>
二、截图框的移动
private void MoveRect_MouseMove(object sender, MouseEventArgs e) { // 鼠标按下时才移动 if (e.LeftButton == MouseButtonState.Released) return; FrameworkElement element = sender as FrameworkElement; //计算鼠标在X轴的移动距离 double deltaV = e.GetPosition(MoveRect).Y - MoveRect.Height / 2; //计算鼠标在Y轴的移动距离 double deltaH = e.GetPosition(MoveRect).X - MoveRect.Width / 2; ; //得到图片Top新位置 double newTop = deltaV + (double)MoveRect.GetValue(Canvas.TopProperty); //得到图片Left新位置 double newLeft = deltaH + (double)MoveRect.GetValue(Canvas.LeftProperty); //边界的判断 if (newLeft <= 0) { newLeft = 0; } //左侧图片框宽度 - 半透明矩形框宽度 if (newLeft >= (this.SmallBox.Width - this.MoveRect.Width)) { newLeft = this.SmallBox.Width - this.MoveRect.Width; } if (newTop <= 0) { newTop = 0; } //左侧图片框高度度 - 半透明矩形框高度度 if (newTop >= this.SmallBox.Height - this.MoveRect.Height) { newTop = this.SmallBox.Height - this.MoveRect.Height; } MoveRect.SetValue(Canvas.TopProperty, newTop); MoveRect.SetValue(Canvas.LeftProperty, newLeft); }
三、图片放大
Timer事件刷新图片,30次/秒,肉眼看上去就是视频的效果啦
private void ImageTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { this.Dispatcher.Invoke(new Action(delegate { if (videoPlayer.VideoSource != null) { bigImg.Source = videoPlayer.VideoSource; imageBrush.ImageSource = videoPlayer.VideoSource; #region //获取右侧大图框与透明矩形框的尺寸比率 double n = this.BigBox.Width / this.MoveRect.Width; //获取半透明矩形框在左侧小图中的位置 double left = (double)this.MoveRect.GetValue(Canvas.LeftProperty); double top = (double)this.MoveRect.GetValue(Canvas.TopProperty); //计算和设置原图在右侧大图框中的Canvas.Left 和 Canvas.Top bigImg.SetValue(Canvas.LeftProperty, -left * n); bigImg.SetValue(Canvas.TopProperty, -top * n); #endregion } })); }
完整的代码:
(布局)
<UserControl x:Class="QACDR.UI.VlcWpf" 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:QACDR.UI" xmlns:vlc="clr-namespace:xZune.Vlc.Wpf;assembly=xZune.Vlc.Wpf" mc:Ignorable="d" Height="349.212" Width="620.7"> <UserControl.Resources> <!--笔刷--> <LinearGradientBrush x:Key="SliderBackground" StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="#59ccfc"/> <GradientStop Offset="0.5" Color="#00b3fe"/> <GradientStop Offset="1" Color="#FFFB1005"/> </LinearGradientBrush> <LinearGradientBrush x:Key="SliderThumb" StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="#FFD9D3E8"/> <!--<GradientStop Offset="1" Color="#dfdfdf"/>--> </LinearGradientBrush> <LinearGradientBrush x:Key="SliderText" StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="#7cce45"/> <GradientStop Offset="1" Color="#4ea017"/> </LinearGradientBrush> <!--Slider模板--> <Style x:Key="Slider_RepeatButton" TargetType="RepeatButton"> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RepeatButton"> <Border Background="{StaticResource SliderBackground}" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Slider_RepeatButton1" TargetType="RepeatButton"> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RepeatButton"> <Border Background="Transparent" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Slider_Thumb" TargetType="Thumb"> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Thumb"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border Background="{StaticResource SliderBackground}"/> <Border Grid.ColumnSpan="2" CornerRadius="4" Background="{StaticResource SliderThumb}" Width="15"> <!--<TextBlock Text="||" HorizontalAlignment="Center" VerticalAlignment="Center"/>--> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Slider_CustomStyle" TargetType="Slider"> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Slider"> <Grid> <!--<Grid.ColumnDefinitions> <ColumnDefinition Width="80"/> <ColumnDefinition/> <ColumnDefinition Width="40"/> </Grid.ColumnDefinitions>--> <Grid.Effect> <DropShadowEffect BlurRadius="10" ShadowDepth="1" /> </Grid.Effect> <!--<Border HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="1,1,0,1" Background="{StaticResource SliderText}" Width="80" CornerRadius="8,0,0,8"/>--> <!--<Border Grid.Column="2" HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="0,1,1,1" Background="{StaticResource SliderText}" Width="40" CornerRadius="0,8,8,0"/>--> <!--<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"/>--> <!--<TextBlock Grid.Column="2" Text="{Binding ElementName=PART_Track,Path=Value,StringFormat=\{0:N0\}}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" DataContext="{Binding}" />--> <Border Grid.Column="1" BorderBrush="Gray" BorderThickness="1" CornerRadius="8,0,0,8"> <Track Grid.Column="1" Name="PART_Track"> <Track.DecreaseRepeatButton> <RepeatButton Style="{StaticResource Slider_RepeatButton}" Command="Slider.DecreaseLarge"/> </Track.DecreaseRepeatButton> <Track.IncreaseRepeatButton> <RepeatButton Style="{StaticResource Slider_RepeatButton1}" Command="Slider.IncreaseLarge"/> </Track.IncreaseRepeatButton> <Track.Thumb> <Thumb Style="{StaticResource Slider_Thumb}"/> </Track.Thumb> </Track> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </UserControl.Resources> <Grid Name="girdParent" Background="#FF0A0909"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="20"/> <RowDefinition Height="32"/> </Grid.RowDefinitions> <vlc:VlcPlayer x:Name="videoPlayer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Visibility="Hidden"/> <DockPanel x:Name="AudioCmdPanel" DockPanel.Dock="Top" VerticalAlignment="Top" Height="20" Background="AliceBlue" Grid.Row="1"> <!--<Label Content="进度" VerticalAlignment="Center" DockPanel.Dock="Left"/>--> <Slider Margin="5,0,0,0" x:Name="videoSlider" Height="15" DockPanel.Dock="Top" Value ="{Binding Position, ElementName=videoPlayer}" Maximum="1" SmallChange="0.001" TickFrequency="100" LargeChange="0.1" Style="{DynamicResource Slider_CustomStyle}" /> </DockPanel> <DockPanel x:Name="AudioBtnPanel" DockPanel.Dock="Bottom" HorizontalAlignment="Center" Grid.Row="2"> <!--<ComboBox Name="cbvChanel" DockPanel.Dock="Right" SelectionChanged="ComboBox_SelectionChanged" Margin="5,0,0,0" Visibility="Visible"> <ComboBoxItem IsSelected="True">立体声</ComboBoxItem> <ComboBoxItem>左声道</ComboBoxItem> <ComboBoxItem>右声道</ComboBoxItem> </ComboBox>--> <!--<Label x:Name="lpSpeed" Content="播放速度:正常" HorizontalAlignment="Left" Margin="10,5,10,0" Grid.Row="2" VerticalAlignment="Top" Height="30" Width="110" Background="#FF0D0E0D" Foreground="#FF45EC14"/> <Label x:Name="lbTitle" Content="" HorizontalAlignment="Left" Margin="10,5,0,0" Grid.Row="2" VerticalAlignment="Top" Height="30" Width="120" Background="#FF0D0E0D" Foreground="#FF45EC14"/>--> <Button x:Name="btnStop" HorizontalAlignment="Center" Command="{Binding VideoBackCommand}" Height="25" Width="25" Click="btnStop_Click" > <Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <Border> <Image x:Name="img" Source="pack://application:,,,/Image/stop.png"/> </Border> </ControlTemplate> </Button.Template> </Button> <Button x:Name="VideoBack" HorizontalAlignment="Center" Command="{Binding VideoBackCommand}" Height="25" Width="25" Click="VideoBack_Click"> <Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <Border> <Image x:Name="img" Source="pack://application:,,,/Image/BackOff.png"/> </Border> </ControlTemplate> </Button.Template> </Button> <Button x:Name="VideoPlay" Margin="5,0,5,0" Command="{Binding VideoPlayCommand}" Height="30" Width="30" Click="VideoPlay_Click"> <Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <Border x:Name="btnBoder"> <Image x:Name="img" Source="pack://application:,,,/Image/Pause.png"/> </Border> </ControlTemplate> </Button.Template> </Button> <Button Command="{Binding VideoForwardCommand}" Height="25" Width="25" Click="Button_Click"> <Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <Border> <Image x:Name="img" Source="pack://application:,,,/Image/Forward.png"/> </Border> </ControlTemplate> </Button.Template> </Button> <!--<Label x:Name="lbTitle" Content="" DockPanel.Dock="Right" Margin="1,7,0,0" Height="30" Width="120" Background="#FF0D0E0D" Foreground="#FF45EC14"/> <Label x:Name="lpSpeed" Content="播放速度:正常" DockPanel.Dock="Right" Margin="10,7,0,0" Height="30" Width="110" Background="#FF0D0E0D" Foreground="#FF45EC14"/>--> <CheckBox x:Name="cbSync" Content="同步音频" Foreground="#FF45EC14" HorizontalAlignment="Right" Margin="10,10,0,0" DockPanel.Dock="Right" Height="20" Width="66" Checked="cbSync_Checked" Unchecked="cbSync_Unchecked"/> <Slider x:Name="voiceSlider" HorizontalAlignment="Right" Margin="0,0,0,0" Height="10" Value="{Binding Volume, ElementName=videoPlayer}" DockPanel.Dock="Right" Width="80" Maximum="100" Style="{DynamicResource Slider_CustomStyle}"/> <Label x:Name="lbVoice" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,0,0,0" DockPanel.Dock="Right" Height="30" Width="30" MouseDown="Label_MouseDown"> <Image Source="pack://application:,,,/Image/voice.png"/> </Label> </DockPanel> <!--右侧大图--> <Canvas x:Name="BigBox" Width="643" Height="643" Canvas.Left="360" Canvas.Top="20" Visibility="Visible"> <!--右侧原图片 注意尺寸--> <Image x:Name="bigImg" Width="2592" Height="1922" Canvas.Left="0" Canvas.Top="-780" /> <Canvas.Clip> <RectangleGeometry Rect="0,0,643,643" /> </Canvas.Clip> </Canvas> <!--左侧小图--> <Canvas x:Name="SmallBox" HorizontalAlignment="Left" VerticalAlignment="Top" MouseMove="MoveRect_MouseMove" Width="121" Height="90" Canvas.Left="20" Canvas.Top="20"> <Canvas.Background> <ImageBrush Stretch="UniformToFill" /> </Canvas.Background> <!--半透明矩形框--> <Rectangle x:Name="MoveRect" Fill="White" Opacity="0.3" Stroke="Red" Width="30" Height="30" Canvas.Top="0" Canvas.Left="0"/> </Canvas> </Grid> </UserControl>
(功能代码)
using DevExpress.XtraEditors; using NAudio.CoreAudioApi; using QACDR.Common; using QACDR.Common.Model; using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.IO; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using xZune.Vlc.Wpf; namespace QACDR.UI { /// <summary> /// VlcWpf.xaml 的交互逻辑 /// </summary> public partial class VlcWpf : UserControl { /// <summary> /// VLC参数 /// </summary> private List<string> baseVlcSettings; /// <summary> /// vlclib路径 /// </summary> private string libVlcPath = "libvlc"; ///音频设备 private MMDevice audioDevice; /// <summary> /// 快进等级 1/2/3 /// </summary> private int rateLevel = 1; /// <summary> /// 当前音量 /// </summary> private int currVolume = 0; /// <summary> /// 是否静音 /// </summary> private bool bNoVoice = false; /// <summary> /// 视频文件列表 /// </summary> private List<VideoFileInfo> videoList = new List<VideoFileInfo>(); /// <summary> /// 当前播放序号 /// </summary> private int currIndex = 0; /// <summary> /// 图片质量 /// </summary> private int quality = 10; private System.Timers.Timer imageTimer = null; private ImageBrush imageBrush = new ImageBrush(); public VlcWpf() { InitializeComponent(); InitVlc(); // 初始化VLC EventPublisher.ChangeVolChEvent += EventPublisher_ChangeVolChEvent; EventPublisher.SearchDataEvent += EventPublisher_SearchDataEvent; videoPlayer.StateChanged += VideoPlayer_StateChanged; EventPublisher.ZoomVideoEvent += EventPublisher_ZoomVideoEvent; int interValue = 100; string str = ConfigurationManager.AppSettings["FreamCount"]; if (!string.IsNullOrEmpty(str)) { interValue = Convert.ToInt32(str); } string strQuality = ConfigurationManager.AppSettings["FreamCount"]; if (!string.IsNullOrEmpty(strQuality)) quality = Convert.ToInt32(strQuality); imageTimer = new System.Timers.Timer(); imageTimer.Enabled = true; imageTimer.Interval = 30; imageTimer.Elapsed += ImageTimer_Elapsed; // 初始化时复制,避免内存增加 SmallBox.Background = imageBrush; SmallBox.Visibility = Visibility.Hidden; MoveRect.Visibility = Visibility.Hidden; videoPlayer.Visibility = Visibility.Visible; bigImg.Visibility = Visibility.Hidden; } private void EventPublisher_ZoomVideoEvent(object sender, ZoomVideoEventArgs e) { if (e.IsZoom) { imageTimer.Start(); SmallBox.Visibility = Visibility.Visible; MoveRect.Visibility = Visibility.Visible; BigBox.Visibility = Visibility.Visible; videoPlayer.Visibility = Visibility.Hidden; bigImg.Visibility = Visibility.Visible; } else { imageTimer.Stop(); SmallBox.Visibility = Visibility.Hidden; MoveRect.Visibility = Visibility.Hidden; BigBox.Visibility = Visibility.Hidden; videoPlayer.Visibility = Visibility.Visible; bigImg.Visibility = Visibility.Hidden; } } private void ImageTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { this.Dispatcher.Invoke(new Action(delegate { if (videoPlayer.VideoSource != null) { bigImg.Source = videoPlayer.VideoSource; imageBrush.ImageSource = videoPlayer.VideoSource; #region //获取右侧大图框与透明矩形框的尺寸比率 double n = this.BigBox.Width / this.MoveRect.Width; //获取半透明矩形框在左侧小图中的位置 double left = (double)this.MoveRect.GetValue(Canvas.LeftProperty); double top = (double)this.MoveRect.GetValue(Canvas.TopProperty); //计算和设置原图在右侧大图框中的Canvas.Left 和 Canvas.Top bigImg.SetValue(Canvas.LeftProperty, -left * n); bigImg.SetValue(Canvas.TopProperty, -top * n); #endregion } })); } /// <summary> /// 初始化VLC /// </summary> private void InitVlc() { try { baseVlcSettings = new List<string> { "-I", "dummy", "--avi-index=1", "--ignore-config", "--no-video-title", "--aout=directsound" }; // 初始化:设置音频输出的默认通道 bool bIsVlcInit = false; MMDeviceEnumerator dve = new MMDeviceEnumerator(); MMDeviceCollection devices = dve.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active); foreach (var device in devices) { if (device.ID == Properties.Settings.Default.AudioDeviceID) { audioDevice = device; List<string> vlcSettings = new List<string>(baseVlcSettings); string[] temp_params = audioDevice.ID.Split('.'); vlcSettings.Add(string.Format("--directx-audio-device={0}", temp_params[temp_params.Length - 1])); this.videoPlayer.Initialize(libVlcPath, vlcSettings.ToArray()); bIsVlcInit = true; break; } } if (bIsVlcInit == false) { this.videoPlayer.Initialize(libVlcPath, baseVlcSettings.ToArray()); } currVolume = 100; videoPlayer.Volume = 100; voiceSlider.Value = 100; } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } /// <summary> /// 播放视频 /// </summary> /// <param name="filePath"></param> public void PlayVideo(VideoFileInfo videoInfo) { try { if (!File.Exists(videoInfo.path)) { MessageBox.Show("视频文件不存在!"); return; } videoPlayer.BeginStop(new Action(delegate { while (videoPlayer.VlcMediaPlayer.Media != null) { videoPlayer.VlcMediaPlayer.Media = null; Thread.Sleep(200); } // 添加此段代码,修复连续播放视频时会死掉的现象 if (videoPlayer.State == xZune.Vlc.Interop.Media.MediaState.Stopped || videoPlayer.State == xZune.Vlc.Interop.Media.MediaState.NothingSpecial) { videoPlayer.LoadMedia(videoInfo.path); videoPlayer.Play(); } })); // 获取当前播放的序号 for (int i = 0; i < videoList.Count; i++) { if (videoList[i].path == videoInfo.path && videoList[i].id == videoInfo.id) { currIndex = i; break; } } FileInfo fi = new FileInfo(videoInfo.path); this.Dispatcher.Invoke(new Action(delegate { //lbTitle.Content = fi.Name; })); } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } /// <summary> /// 设置VLC音频输出端口 /// </summary> /// <param name="options"></param> public void SelectAudioDevice(string[] options) { try { videoPlayer.BeginStop(new Action(delegate { this.videoPlayer.Initialize(libVlcPath, options); })); } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } /// <summary> /// 视频截图 /// </summary> public void Snapshot() { try { string path = AppDomain.CurrentDomain.BaseDirectory + "snapshot"; if (!Directory.Exists(path)) Directory.CreateDirectory(path); string name = path + "\\" + DateTime.Now.ToFileTime() + ".png"; videoPlayer.TakeSnapshot(name, SnapshotFormat.JPG, 30); } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } #region 控件事件 private void VideoPlayer_StateChanged(object sender, xZune.Vlc.ObjectEventArgs<xZune.Vlc.Interop.Media.MediaState> e) { if (e.Value == xZune.Vlc.Interop.Media.MediaState.Ended) { if (currIndex + 1 < videoList.Count) { // 播放下一视频 currIndex++; PlayVideo(videoList[currIndex]); } else { this.Dispatcher.Invoke(new Action(delegate { //lbTitle.Content = "播放完成。"; })); } //EventPublisher.PictureShowEvent(this, new PictureShowEventArgs() { StateShow = ShowEnum.Stop }); } else if (e.Value == xZune.Vlc.Interop.Media.MediaState.Paused) { } } // 声道切换事件 private void EventPublisher_ChangeVolChEvent(object sender, ChangeVolChEventArgs e) { if (e.CType != 2) return; // 如果不是音频所发起的,则不执行 //cbvChanel.Text = e.VolChStr; } // 查询数据 private void EventPublisher_SearchDataEvent(object sender, SearchDataEventArgs e) { string cmdText = "select * from QACDR_VIDEO where operation_id > 0 " + e.Condition + " order by start_time asc"; DataSet ds = SQLiteHelper.ExecuteDataSet(cmdText); if (ds == null || ds.Tables.Count <= 0 || ds.Tables[0].Rows.Count <= 0) return; videoList.Clear(); foreach (DataRow row in ds.Tables[0].Rows) { VideoFileInfo video = new VideoFileInfo(); video.id = Convert.ToInt32(row["id"]); video.operation_id = Convert.ToInt32(row["operation_id"]); video.machine_id = Convert.ToInt32(row["machine_id"]); video.path = row["path"].ToString(); video.start_time = Convert.ToDateTime(row["start_time"]); video.import_time = Convert.ToDateTime(row["import_time"]); videoList.Add(video); } } // 声道 private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { try { //string str = cbvChanel.Text; //EventPublisher.PublishChangeVolChEvent(this, str, 1); } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } // 静音/取消静音 private void Label_MouseDown(object sender, MouseButtonEventArgs e) { try { if (bNoVoice == true) { currVolume = videoPlayer.Volume; videoPlayer.Volume = 0; System.Windows.Controls.Image img = new Image(); img.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + @"Image\NoVoice.png")); lbVoice.Content = img; voiceSlider.IsEnabled = false; bNoVoice = false; } else { videoPlayer.Volume = currVolume; System.Windows.Controls.Image img = new Image(); img.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + @"Image\Voice.png")); lbVoice.Content = img; voiceSlider.IsEnabled = true; bNoVoice = true; } } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } // 停止 private void btnStop_Click(object sender, RoutedEventArgs e) { try { videoPlayer.BeginStop(new Action(delegate { this.Dispatcher.Invoke(new Action(delegate { //lbTitle.Content = "播放完成。"; })); })); } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } // 快退 private void VideoBack_Click(object sender, RoutedEventArgs e) { try { float tp = videoPlayer.Position - (float)0.05; if (tp > 0) { videoPlayer.Position = tp; } else { videoPlayer.Position = 0; } } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } // 播放/暂停 private void VideoPlay_Click(object sender, RoutedEventArgs e) { try { if (videoPlayer.State == xZune.Vlc.Interop.Media.MediaState.Playing) { System.Windows.Controls.Border boder = (System.Windows.Controls.Border)VideoPlay.Template.FindName("btnBoder", VideoPlay); System.Windows.Controls.Image img = (System.Windows.Controls.Image)boder.FindName("img"); img.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + @"Image\Play.png")); } else if (videoPlayer.State == xZune.Vlc.Interop.Media.MediaState.Paused) { System.Windows.Controls.Border boder = (System.Windows.Controls.Border)VideoPlay.Template.FindName("btnBoder", VideoPlay); System.Windows.Controls.Image img = (System.Windows.Controls.Image)boder.FindName("img"); img.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + @"Image\Pause.png")); } videoPlayer.PauseOrResume(); } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } // 快进 private void Button_Click(object sender, RoutedEventArgs e) { try { if (rateLevel == 1) { rateLevel = 2; videoPlayer.Rate = 3.0f; //lpSpeed.Content = "播放速度:快进x1"; } else if (rateLevel == 2) { rateLevel = 3; videoPlayer.Rate = 5.0f; //lpSpeed.Content = "播放速度:快进x2"; } else if (rateLevel == 3) { rateLevel = 4; videoPlayer.Rate = 7.0f; //lpSpeed.Content = "播放速度:快进x3"; } else if (rateLevel == 4) { rateLevel = 1; videoPlayer.Rate = 1; //lpSpeed.Content = "播放速度:正常"; } } catch (Exception ex) { Log4Allen.WriteLog(typeof(VlcWpf), ex); } } // 同步音频 private void cbSync_Checked(object sender, RoutedEventArgs e) { if (Utils.Mode == SyncModeEnum.DDS) { XtraMessageBox.Show("正在进行DDS同步,视频同步音频。"); return; } EventPublisher.PublishSetAudioSyncEvent(this, new SetAudioSyncEventArgs() { IsSync = true }); Utils.Mode = SyncModeEnum.VIDEO; } private void cbSync_Unchecked(object sender, RoutedEventArgs e) { EventPublisher.PublishSetAudioSyncEvent(this, new SetAudioSyncEventArgs() { IsSync = false }); Utils.Mode = SyncModeEnum.NONE; } #endregion private void MoveRect_MouseMove(object sender, MouseEventArgs e) { // 鼠标按下时才移动 if (e.LeftButton == MouseButtonState.Released) return; FrameworkElement element = sender as FrameworkElement; //计算鼠标在X轴的移动距离 double deltaV = e.GetPosition(MoveRect).Y - MoveRect.Height / 2; //计算鼠标在Y轴的移动距离 double deltaH = e.GetPosition(MoveRect).X - MoveRect.Width / 2; ; //得到图片Top新位置 double newTop = deltaV + (double)MoveRect.GetValue(Canvas.TopProperty); //得到图片Left新位置 double newLeft = deltaH + (double)MoveRect.GetValue(Canvas.LeftProperty); //边界的判断 if (newLeft <= 0) { newLeft = 0; } //左侧图片框宽度 - 半透明矩形框宽度 if (newLeft >= (this.SmallBox.Width - this.MoveRect.Width)) { newLeft = this.SmallBox.Width - this.MoveRect.Width; } if (newTop <= 0) { newTop = 0; } //左侧图片框高度度 - 半透明矩形框高度度 if (newTop >= this.SmallBox.Height - this.MoveRect.Height) { newTop = this.SmallBox.Height - this.MoveRect.Height; } MoveRect.SetValue(Canvas.TopProperty, newTop); MoveRect.SetValue(Canvas.LeftProperty, newLeft); } public void ResizeCtrl() { } } }