CodeSnippet.Cn
代码片段
Csharp
架构设计
.NetCore
西班牙语
kubernetes
MySql
Redis
Algorithm
Ubuntu
Linux
Other
.NetMvc
VisualStudio
Git
pm
Python
WPF
java
Plug-In
分布式
CSS
微服务架构
JavaScript
DataStructure
Shared
wpf视频播放
0
WPF
Csharp
Kelly
发布于:2024年05月16日
更新于:2024年05月16日
65
#custom-toc-container
这里用的VLC库,需要nuget引入Vlc.DotNet.Wpf,另外VideoLAN.LibVLC.Windows貌似不用引入也可以。 需要注意的: 1 是需要把vlc播放器(libvlc文件夹,在百度网盘里找)拷贝到执行文件夹 2 清空视频需要用 ThreadPool.QueueUserWorkItem(() => Player.SourceProvider.MediaPlayer.Stop()); 前端代码: ```xml
``` 后端代码: ```xml using Microsoft.Win32; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; using Vlc.DotNet.Core.Interops.Signatures; using Vlc.DotNet.Wpf; namespace MediaPlayer { public enum PlayerUserEnum { None, Staining, OcularSurface, Trial } public class CustomRoutedEventArgs : RoutedEventArgs { public CustomRoutedEventArgs(RoutedEvent _event, object _para) : base(_event) { Parameter = _para; } public object Parameter { get; set; } } public sealed class PlayerFactory { private static List
available = new List
(); private static List
used = new List
(); static VlcControl osPlayer; static VlcControl stainingPlayer; static VlcControl trialPlayer; static PlayerFactory() { osPlayer = new VlcControl(); var vlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64")); osPlayer.SourceProvider.CreatePlayer(vlcLibDirectory, new string[] { }); stainingPlayer = new VlcControl(); var vlcLibDirectory2 = new DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64")); stainingPlayer.SourceProvider.CreatePlayer(vlcLibDirectory2, new string[] { }); trialPlayer = new VlcControl(); var vlcLibDirectory3 = new DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64")); trialPlayer.SourceProvider.CreatePlayer(vlcLibDirectory3, new string[] { }); } public static VlcControl GetStaining() { return stainingPlayer; } public static VlcControl GetOS() { return osPlayer; } public static VlcControl GetTrial() { return trialPlayer; } public static VlcControl Get() { if (available.Count == 0) { VlcControl vlcControl = new VlcControl(); var vlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64")); vlcControl.SourceProvider.CreatePlayer(vlcLibDirectory, new string[] { }); available.Add(vlcControl); } VlcControl vlc = available.First(); available.RemoveAt(0); used.Add(vlc); return vlc; } public static void Release(VlcControl playerVlc) { ThreadPool.QueueUserWorkItem(_ => { playerVlc.SourceProvider.MediaPlayer.Stop(); }); } } ///
/// Interaction logic for MainWindow.xaml ///
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); SetPlayer(); } string currentVideoFileName = ""; public PlayerUserEnum PlayerUserType { get { return (PlayerUserEnum)GetValue(PlayerUserTypeProperty); } set { SetValue(PlayerUserTypeProperty, value); } } // Using a DependencyProperty as the backing store for PlayerUserType. This enables animation, styling, binding, etc... public static readonly DependencyProperty PlayerUserTypeProperty = DependencyProperty.Register("PlayerUserType", typeof(PlayerUserEnum), typeof(MainWindow), new PropertyMetadata(PlayerUserEnum.None, OnPlayerUserTypeChanged)); private static void OnPlayerUserTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is MainWindow vlc) { if (vlc.PlayerUserType == PlayerUserEnum.Staining) { vlc.Player = PlayerFactory.GetStaining(); } else if (vlc.PlayerUserType == PlayerUserEnum.OcularSurface) { vlc.Player = PlayerFactory.GetOS(); } else if (vlc.PlayerUserType == PlayerUserEnum.Trial) { vlc.Player = PlayerFactory.GetTrial(); } if (vlc.Player.Parent != null) { StackPanel parent = vlc.Player.Parent as StackPanel; parent.Children.Remove(vlc.Player); } vlc.VlcPlayerContainer.Children.Add(vlc.Player); } } internal VlcControl Player; public void SetPlayer() { Player = PlayerFactory.GetOS(); // 随便选的一个播放器 if (Player.Parent != null) { StackPanel parent = Player.Parent as StackPanel; parent.Children.Remove(Player); } VlcPlayerContainer.Children.Add(Player); } public void ReleasePlayer() { PlayerFactory.Release(Player); tbVideoFilePath.Text = string.Empty; btnPlay.Visibility = Visibility.Visible; btnPause.Visibility = Visibility.Collapsed; btnPlay.IsEnabled = false; btnBackwardRewind.IsEnabled = false; btnForwardRewind.IsEnabled = false; btnSkipToEnd.IsEnabled = false; btnSkipToStart.IsEnabled = false; } public override void BeginInit() { base.BeginInit(); } protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); } private void Window_Loaded(object sender, RoutedEventArgs e) { if (Player != null) { Player.SourceProvider.MediaPlayer.EndReached += MediaPlayer_EndReached; Player.SourceProvider.MediaPlayer.PositionChanged += MediaPlayer_PositionChanged; Player.SourceProvider.MediaPlayer.EncounteredError += MediaPlayer_EncounteredError; } } private void MediaPlayer_EncounteredError(object? sender, Vlc.DotNet.Core.VlcMediaPlayerEncounteredErrorEventArgs e) { //LpSeriLog.Error("播放器报错"); //LpSeriLog.Error(sender); } private DispatcherTimer dispatcherTimer = new DispatcherTimer(); ///
/// 获取进度 ///
public void Init_Timer() { if (!dispatcherTimer.IsEnabled) { dispatcherTimer.Interval = TimeSpan.FromMilliseconds(100); dispatcherTimer.Tick += new EventHandler((sender, e) => { timeSlider.Value = Convert.ToInt32(Player.SourceProvider.MediaPlayer?.Position * 100); //PayTime.Text = TimeSpan.FromMilliseconds(VlcPlayer.SourceProvider.MediaPlayer.Time).ToString().Substring(0,8);//获取播放当前时间 }); dispatcherTimer.IsEnabled = true; } } private void MediaPlayer_PositionChanged(object? sender, Vlc.DotNet.Core.VlcMediaPlayerPositionChangedEventArgs e) { SetPlayStatus(); } private void SetPlayStatus() { App.Current.Dispatcher.Invoke(() => { MediaStates status; if (Player.SourceProvider.MediaPlayer is null) status = MediaStates.Stopped; else status = Player.SourceProvider.MediaPlayer.State; switch (status) { case MediaStates.Playing: btnPlay.Visibility = Visibility.Collapsed; btnPause.Visibility = Visibility.Visible; break; case MediaStates.Paused: case MediaStates.Stopped: case MediaStates.Ended: btnPlay.Visibility = Visibility.Visible; btnPause.Visibility = Visibility.Collapsed; break; case MediaStates.Error: btnPlay.Visibility = Visibility.Visible; btnPause.Visibility = Visibility.Collapsed; //Lepu.OkLens.Common.LpSeriLog.Error("播放器状态错误 MediaStates.Error"); break; } }); } private void MediaPlayer_EndReached(object? sender, Vlc.DotNet.Core.VlcMediaPlayerEndReachedEventArgs e) { SetPlayStatus(); btnPlay.Dispatcher.Invoke(() => { btnPlay.IsEnabled = false; btnBackwardRewind.IsEnabled = false; btnForwardRewind.IsEnabled = false; btnSkipToEnd.IsEnabled = false; btnSkipToStart.IsEnabled = false; tbVideoFilePath.Text = ""; }); //VlcPlayer.SourceProvider.MediaPlayer.Position = 0; //VlcPlayer.SourceProvider.MediaPlayer.Play(); //VlcPlayer.SourceProvider.MediaPlayer.Stop(); //VlcPlayer.SourceProvider.MediaPlayer.ResetMedia(); //VlcPlayer.SourceProvider.MediaPlayer.Play(videoFile); //VlcPlayer.SourceProvider.MediaPlayer.Stop(); 不动了 } #region prodpd public bool ResetVideo { get { return (bool)GetValue(ResetVideoProperty); } set { SetValue(ResetVideoProperty, value); } } // Using a DependencyProperty as the backing store for ResetVideo. This enables animation, styling, binding, etc... public static readonly DependencyProperty ResetVideoProperty = DependencyProperty.Register("ResetVideo", typeof(bool), typeof(MainWindow), new PropertyMetadata(false, OnResetVideoCallback)); private static void OnResetVideoCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is MainWindow playerVlc && e.NewValue is bool resetVideo && resetVideo) { ThreadPool.QueueUserWorkItem((WaitCallback)((a) => { if (playerVlc.Player.SourceProvider.MediaPlayer.CouldPlay) { playerVlc.Player.SourceProvider.MediaPlayer.Position = 1; if (playerVlc.Player.SourceProvider.MediaPlayer.IsPlaying()) playerVlc.Player.SourceProvider.MediaPlayer.Pause(); } })); } } ///
/// 超出设置的图片 ///
public bool ExceedPictureNumFixed { get { return (bool)GetValue(ExceedPictureNumFixedProperty); } set { SetValue(ExceedPictureNumFixedProperty, value); } } // Using a DependencyProperty as the backing store for HasError. This enables animation, styling, binding, etc... public static readonly DependencyProperty ExceedPictureNumFixedProperty = DependencyProperty.Register("ExceedPictureNumFixed", typeof(bool), typeof(MainWindow), new PropertyMetadata(false)); public bool ClearMediaPath { get { return (bool)GetValue(ClearMediaPathProperty); } set { SetValue(ClearMediaPathProperty, value); } } // Using a DependencyProperty as the backing store for MediaPath. This enables animation, styling, binding, etc... public static readonly DependencyProperty ClearMediaPathProperty = DependencyProperty.Register("ClearMediaPath", typeof(bool), typeof(MainWindow), new PropertyMetadata(false, OnClearMediaPathChanged)); private static void OnClearMediaPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is MainWindow playerWrapper) { if (e.NewValue is false) return; try { playerWrapper.ClearMediaPath = !playerWrapper.ClearMediaPath; } catch (Exception ex) { //LpSeriLog.Error(ex); MessageBox.Show(ex.Message); } playerWrapper.SetPlayStatus(); } } #endregion #region events public static readonly RoutedEvent SelectFrameEvent = EventManager.RegisterRoutedEvent("SelectFrame", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(MainWindow)); public event RoutedEventHandler SelectFrame { add { AddHandler(SelectFrameEvent, value, false); } remove { RemoveHandler(SelectFrameEvent, value); } } protected virtual void OnSelectFrame(string selectedFramePath) { RaiseEvent(new CustomRoutedEventArgs(SelectFrameEvent, selectedFramePath)); } #endregion string videoFile = ""; private void selectVideo(object sender, System.Windows.RoutedEventArgs e) { try { ThreadPool.QueueUserWorkItem((WaitCallback)(_ => { this.Player.SourceProvider.MediaPlayer.Stop(); })); OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "视频文件(*.avi,*.mp4)|*.avi;*.mp4"; ofd.ValidateNames = true; ofd.CheckFileExists = true; ofd.CheckPathExists = true; if (ofd.ShowDialog()!.Value) { tbVideoFilePath.Text = ofd.FileName; //if (VlcPlayer.SourceProvider.MediaPlayer.IsPlaying()) //{ // VlcPlayer.SourceProvider.MediaPlayer.Pause(); //} //VlcPlayer.SourceProvider.MediaPlayer.ResetMedia(); Player.SourceProvider.MediaPlayer.Play(new FileInfo(ofd.FileName), new string[] { "input-repeat=65535" }); videoFile = ofd.FileName; btnPlay.Visibility = Visibility.Collapsed; btnPause.Visibility = Visibility.Visible; btnPlay.IsEnabled = true; btnBackwardRewind.IsEnabled = true; btnForwardRewind.IsEnabled = true; btnSkipToEnd.IsEnabled = true; btnSkipToStart.IsEnabled = true; currentVideoFileName = ofd.SafeFileName.Split('.').First(); SetPlayStatus(); } else { } } catch (Exception ex) { //LpSeriLog.Error(ex); MessageBox.Show(ex.Message); } } private void timeSlider_MouseUp(object sender, MouseButtonEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) { return; } double mousePositionX = e.GetPosition(timeSlider).X; double width = timeSlider.ActualWidth; timeSlider.Value = (int)(mousePositionX / width * timeSlider.Maximum); Player.SourceProvider.MediaPlayer.Position = float.Parse(timeSlider.Value.ToString()) / 100; } private void timeSlider_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) { return; } Player.SourceProvider.MediaPlayer.Position = (float)timeSlider.Value / 100; dispatcherTimer.Stop(); } MediaStates playerStatusWhileDrag; private void timeSlider_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e) { playerStatusWhileDrag = Player.SourceProvider.MediaPlayer.State; Player.SourceProvider.MediaPlayer.Pause(); if (playerStatusWhileDrag == MediaStates.Playing) { dispatcherTimer.Start(); } } bool isPlaying; private void btnSkipToStart_Click(object sender, RoutedEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) { return; } if (Player.SourceProvider.MediaPlayer.IsPlaying()) { Player.SourceProvider.MediaPlayer.Pause(); } Player.SourceProvider.MediaPlayer.Position = 0f; } private void btnForwardRewind_Click(object sender, RoutedEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) { return; } float cur_time = Player.SourceProvider.MediaPlayer.Position; cur_time += 0.01f; if (cur_time >= 1) { return; } Player.SourceProvider.MediaPlayer.Position = cur_time; } private void btnPlay_Click(object sender, RoutedEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) { return; } btnPlay.Visibility = Visibility.Collapsed; btnPause.Visibility = Visibility.Visible; if (Player.SourceProvider.MediaPlayer.IsPlaying()) return; Player.SourceProvider.MediaPlayer.Play(); } private void btnBackwardRewind_Click(object sender, RoutedEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) { return; } float cur_time = Player.SourceProvider.MediaPlayer.Position; cur_time -= 0.01f; if (cur_time <= 0) { return; } Player.SourceProvider.MediaPlayer.Position = cur_time; } private void btnSkipToEnd_Click(object sender, RoutedEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) { return; } Player.SourceProvider.MediaPlayer.Position = 1 - 1 / (Player.SourceProvider.MediaPlayer.FramesPerSecond * Player.SourceProvider.MediaPlayer.Length / 1000) - 0.001f; } private void btnPause_Click(object sender, RoutedEventArgs e) { if (Player.SourceProvider.MediaPlayer == null) return; if (!Player.SourceProvider.MediaPlayer.IsPlaying()) { return; } Player.SourceProvider.MediaPlayer.Pause(); btnPlay.Visibility = Visibility.Visible; btnPause.Visibility = Visibility.Collapsed; } } } ```
这里⇓感觉得写点什么,要不显得有点空,但还没想好写什么...
返回顶部
About
京ICP备13038605号
© 代码片段 2024