1、View
cs
<Window x:Class="CommonControls.VideoPlayer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CommonControls"
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
mc:Ignorable="d" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen" Closing="Window_Closing"
Title="VideoPlayer" Width="1200" Height="800" WindowStyle="None" Background="Transparent">
<Grid>
<vlc:VideoView x:Name="vlcPlyer"/>
</Grid>
</Window>
2、制作播放器完整代码:
包含快进、慢放、暂停、开始和截图功能
cs
/// <summary>
/// 监控信息
/// </summary>
public class MonitorInfo
{
/// <summary>
/// 摄像机IP
/// </summary>
public string IP { get; set; }
/// <summary>
/// 摄像机端口
/// </summary>
public string Port { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 通道号
/// </summary>
public string ChannelNumber { get; set; }
/// <summary>
/// 是否是回放
/// </summary>
public string IsBackPlay { get; set; }
/// <summary>
/// 监控名称
/// </summary>
public string deviceName { get; set; }
/// <summary>
/// 报警时间
/// </summary>
public DateTime alarmDateTime { get; set; }
/// <summary>
/// 厂家id(1:宇视 2:海康 3:大华 4:华为)
/// </summary>
public string manufacturerId { get; set; }
/// <summary>
/// 设备编码
/// </summary>
public string cameraCode { get; set; }
public string deviceId { get; set; }
public VideoType VideoType { get; set; }
}
/// <summary>
/// VideoPlayer.xaml 的交互逻辑
/// </summary>
public partial class VideoPlayer : Window, INotifyPropertyChanged
{
#region 变量
IBaseVideoControler _videoController = null;
bool _isPlayingBack = false;
VideoType _videoType;
int _timespan = 0;
string _path = "";
#endregion
#region 属性
private string _playOrPauseSource = "pack://application:,,,/iHCRS.Resources;component/Images/PlayBack/播放@2x.png";
/// <summary>
/// 播放或暂停图片地址
/// </summary>
public string PlayOrPauseSource
{
get { return _playOrPauseSource; }
set { _playOrPauseSource = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PlayOrPauseSource))); }
}
private double _speed = 1;
/// <summary>
/// 速度
/// </summary>
public double Speed
{
get { return _speed; }
set { _speed = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Speed))); }
}
private double _TotalSeconds;
/// <summary>
/// 所有的秒数
/// </summary>
public double TotalSeconds
{
get { return _TotalSeconds; }
set { _TotalSeconds = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TotalSeconds))); }
}
private double _SliderValue;
/// <summary>
/// 进度条值
/// </summary>
public double SliderValue
{
get { return _SliderValue; }
set
{
_SliderValue = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SliderValue)));
}
}
private string _StartDateTime;
public string StartDateTime
{
get { return _StartDateTime; }
set
{
if (_StartDateTime != value)
{
if ((Convert.ToDateTime(value) >= Convert.ToDateTime(EndDateTime)) && EndDateTime != null)
{
CMessageBox.Show("提示", "开始时间不能晚于结束时间!", false, this);
}
else
{
_StartDateTime = value;
TotalSeconds = (Convert.ToDateTime(EndDateTime) - Convert.ToDateTime(_StartDateTime)).TotalSeconds;
SliderValue = 0;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(StartDateTime)));
if (_StartDateTime == null || EndDateTime == null)
return;
try
{
timer?.Stop();
PlayBackByTime(Convert.ToDateTime(_StartDateTime), Convert.ToDateTime(EndDateTime));
}
catch (Exception ex)
{
GlobalData.logger.Error($"根据时间回放出现异常,异常信息:{ex.Message}");
}
}
}
}
}
private string _EndDateTime;
public string EndDateTime
{
get { return _EndDateTime; }
set
{
if (_EndDateTime != value)
{
if ((Convert.ToDateTime(StartDateTime) >= Convert.ToDateTime(value)) && value != null)
{
CMessageBox.Show("提示", "结束时间不能早于开始时间!", false, this);
}
else
{
_EndDateTime = value;
TotalSeconds = (Convert.ToDateTime(_EndDateTime) - Convert.ToDateTime(StartDateTime)).TotalSeconds;
SliderValue = 0;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(EndDateTime)));
if (_EndDateTime == null || StartDateTime == null)
return;
try
{
timer?.Stop();
PlayBackByTime(Convert.ToDateTime(StartDateTime), Convert.ToDateTime(_EndDateTime));
}
catch (Exception ex)
{
GlobalData.logger.Error($"根据时间回放出现异常,异常信息:{ex.Message}");
}
}
}
}
}
private bool _IsStartTimeDropDownOpen;
public bool IsStartTimeDropDownOpen
{
get { return _IsStartTimeDropDownOpen; }
set { _IsStartTimeDropDownOpen = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsStartTimeDropDownOpen))); }
}
private bool _IsEndTimeDropDownOpen;
public bool IsEndTimeDropDownOpen
{
get { return _IsEndTimeDropDownOpen; }
set { _IsEndTimeDropDownOpen = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsEndTimeDropDownOpen))); }
}
public event PropertyChangedEventHandler PropertyChanged;
private bool IsFinishPlay = false;
private LibVLCSharp.Shared.MediaPlayer _mediaPlayer;
#endregion
public VideoPlayer(string videoTitle, string path, VideoType videoType, int timespan)
{
_timespan = timespan;
_videoType = videoType;
_path = path;
InitializeComponent();
this.DataContext = this;
videoNameTB.Text = videoTitle;
this.Loaded += PlayerWindow_Loaded;
}
private void PlayerWindow_Loaded(object sender, RoutedEventArgs e)
{
//StartDateTime = DateTime.Now.ToString("yyyy-MM-dd 00:00:00");
StartDateTime = "2023/03/20 13:56:52";
///设置enddatetime的时候已经执行了回放,所以加载的时候不再执行回放。
EndDateTime = "2023/03/20 13:57:49"; //DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
TotalSeconds = (Convert.ToDateTime(EndDateTime) - Convert.ToDateTime(StartDateTime)).TotalSeconds;
TotalSeconds = _timespan;
IsStartTimeDropDownOpen = false;
IsEndTimeDropDownOpen = false;
}
private Timer timer;
/// <summary>
/// 根据开始和结束时间进行回放
/// </summary>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
private void PlayBackByTime(DateTime startTime, DateTime endTime)
{
try
{
vlcPlyer.MediaPlayer = new LibVLCSharp.Shared.MediaPlayer(VlcLibInit.Instance.VlcLib)
{
Volume = 0,
EnableHardwareDecoding = true
};
var fromType = FromType.FromLocation;
if (_videoType == VideoType.LocalVideo)
{
fromType = FromType.FromPath;
}
var m = new Media(VlcLibInit.Instance.VlcLib, _path, fromType);
//一下是设置相应的参数,播放rtsp流的生活,设置和不设置是有很大差距的,大家可以注释代码体验一下
m.AddOption(":rtsp-tcp");
m.AddOption(":clock-synchro=0");
m.AddOption(":live-caching=0");
m.AddOption(":network-caching=100");
m.AddOption(":file-caching=100");
m.AddOption(":grayscale");
m.AddOption(":avcodec-hw=any");
_mediaPlayer = vlcPlyer.MediaPlayer;
_mediaPlayer.Play(m);
}
catch (Exception ex)
{
GlobalData.logger.Error($"按时间回放出现异常,异常信息:{ex.Message}");
}
SetVideoPlayState();
}
private void SetVideoPlayState()
{
Speed = 1;
_isPlayingBack = true;
PlayOrPauseSource = "pack://application:,,,/iHCRS.Resources;component/Images/PlayBack/暂停@2x.png";
if (timer != null)
{
timer.Stop();
timer.Dispose();
timer = null;
}
timer = new Timer();
timer.Interval = 1000; //时间间隔为一秒
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
if (SliderValue > TotalSeconds)
{
_mediaPlayer.Stop();
PlayOrPauseSource = "pack://application:,,,/iHCRS.Resources;component/Images/PlayBack/播放@2x.png";
_isPlayingBack = false;
backOffBtn.IsEnabled = false;
fastForwardBtn.IsEnabled = false;
snapBtn.IsEnabled = false;
timer?.Stop();
timer?.Dispose();
IsFinishPlay = true;
return;
}
SliderValue++;
}
private void headerGrid_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
this.DragMove();
}
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
this.Close();
}
private void allScreenBtn_Click(object sender, RoutedEventArgs e)
{
this.WindowState = this.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
}
/// <summary>
/// 截图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void snapBtn_Click(object sender, RoutedEventArgs e)
{
if (!_isPlayingBack)
{
return;
}
var folderPath = System.Windows.Forms.Application.StartupPath + "\\SnapshotPictures";
if (!Directory.Exists(folderPath))
{
DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
directoryInfo.Create();
}
var filePath = folderPath + $"\\{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg";
// 创建一个PngBitmapEncoder并添加帧
PngBitmapEncoder encoder = new PngBitmapEncoder();
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(
(int)vlcPlyer.ActualWidth,
(int)vlcPlyer.ActualHeight,
96, 96,
PixelFormats.Pbgra32);
// 渲染vlcPlayer到RenderTargetBitmap
renderTargetBitmap.Render(vlcPlyer);
encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
{
encoder.Save(fileStream);
}
CMessageBox.Show("提示", $"截图成功,保存路径:{filePath}");
}
/// <summary>
/// 慢放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backOffBtn_Click(object sender, RoutedEventArgs e)
{
if (timer == null)
return;
if (Speed > 1)
{
if (_isPlayingBack)
{
Speed = Speed / 2;
timer.Interval = timer.Interval * 2;
_mediaPlayer.SetRate((float)Speed);
}
}
}
/// <summary>
/// 快放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void fastForwardBtn_Click(object sender, RoutedEventArgs e)
{
if (timer == null)
return;
if (Speed < 16)
{
if (_isPlayingBack)
{
Speed = Speed * 2;
timer.Interval = timer.Interval / 2;
_mediaPlayer.SetRate((float)Speed);
}
}
}
/// <summary>
/// 播放或暂停
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void playOrPauseBtn_Click(object sender, RoutedEventArgs e)
{
if (_isPlayingBack)
{
_mediaPlayer.Pause();
PlayOrPauseSource = "pack://application:,,,/iHCRS.Resources;component/Images/PlayBack/播放@2x.png";
_isPlayingBack = false;
backOffBtn.IsEnabled = false;
fastForwardBtn.IsEnabled = false;
snapBtn.IsEnabled = false;
timer?.Stop();
}
else
{
if (IsFinishPlay && SliderValue >= TotalSeconds)//播放完毕的情况下再次点击播放则从头开始播放
{
SliderValue = 0;
}
_isPlayingBack = true;
backOffBtn.IsEnabled = true;
fastForwardBtn.IsEnabled = true;
snapBtn.IsEnabled = true;
_mediaPlayer.Play();
timer.Start();
PlayOrPauseSource = "pack://application:,,,/iHCRS.Resources;component/Images/PlayBack/暂停@2x.png";
}
}
private void Window_Closing(object sender, CancelEventArgs e)
{
timer?.Stop();
timer?.Dispose();
_mediaPlayer?.Stop();
_mediaPlayer?.Dispose();
}
private void Slider_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
_mediaPlayer.Time = (long)SliderValue * 1000;
}
private void slider_MouseDown(object sender, MouseButtonEventArgs e)
{
var value = (e.GetPosition(slider).X / slider.ActualWidth) * (slider.Maximum - slider.Minimum);
SliderValue = value;
_mediaPlayer.Time = (long)SliderValue * 1000;
}
private void Close_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}