using AIK.Models.VideoModels; using AIK.ViewModels.CommonViewModel; using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging.Messages; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Shell; using System.Windows.Threading; namespace AIK.Views.MenuPages.CommonPage { /// /// VideoPopupWindow.xaml 的交互逻辑 /// public partial class VideoPopupWindow : Window { private DispatcherTimer _progressTimer; private bool _isDragging = false; public Action CloseAction { get; set; } private VideoPlayerViewModel _viewModel; public VideoPopupWindow() { InitializeComponent(); _viewModel = Ioc.Default.GetService(); DataContext = _viewModel; InitializeMediaPlayer(); RegisterSubMessage(); //this.Closed += OnWindowClosed; } #region 内存释放和清理 #endregion #region 消息注册与接收 private void RegisterSubMessage() { WeakReferenceMessenger.Default.Register(this, OnVideoControlMessage); WeakReferenceMessenger.Default.Register(this, OnShowVideoMessage); WeakReferenceMessenger.Default.Register(this, OnVolumeChangedMessage); } private void OnVideoControlMessage(object recipient, VideoControlMessage message) { Dispatcher.Invoke(() => { switch (message.Action) { case VideoControlMessage.ControlAction.Play: MediaPlayer.Play(); _viewModel.IsPlaying = true; break; case VideoControlMessage.ControlAction.Pause: MediaPlayer.Pause(); _viewModel.IsPlaying = false; break; case VideoControlMessage.ControlAction.Stop: MediaPlayer.Stop(); _viewModel.IsPlaying = false; _viewModel.Progress = 0; break; case VideoControlMessage.ControlAction.Seek when message.Position.HasValue: MediaPlayer.Position = message.Position.Value; break; case VideoControlMessage.ControlAction.ToggleFullScreen: ToggleFullScreen(); break; } }); } private void OnShowVideoMessage(object recipient, ShowVideoMessage message) { var videoUrl = message.VideoPath; if (message.VideoPath != null) { // 加载并显示视频 if (DataContext != null && DataContext is VideoPlayerViewModel vm) { vm.CloseAction = () => this.HideWindow(); // 监听属性变化 vm.PropertyChanged += (s, e) => { switch (e.PropertyName) { case nameof(VideoPlayerViewModel.IsPlaying): if (vm.IsPlaying) { MediaPlayer.Play(); UpdatePlayPauseButton(true); // 确保进度计时器启动 if (!_progressTimer.IsEnabled) { _progressTimer.Start(); } } else { MediaPlayer.Pause(); UpdatePlayPauseButton(false); } break; case nameof(VideoPlayerViewModel.Volume): MediaPlayer.Volume = vm.Volume; break; case nameof(VideoPlayerViewModel.IsMuted): MediaPlayer.IsMuted = vm.IsMuted; UpdateVolumeButton(vm.IsMuted); break; } }; // 监听进度变化 vm.ProgressChanged += (progress) => { if (!_isDragging && MediaPlayer.NaturalDuration.HasTimeSpan) { var newPosition = TimeSpan.FromSeconds((progress / 100) * MediaPlayer.NaturalDuration.TimeSpan.TotalSeconds); MediaPlayer.Position = newPosition; } }; // 设置视频路径并加载 if (!string.IsNullOrEmpty(videoUrl)) { vm.VideoPath = videoUrl; LoadVideo(videoUrl); } } } } private void OnVolumeChangedMessage(object recipient, VolumeChangedMessage message) { Dispatcher.Invoke(() => { try { MediaPlayer.Volume = message.Volume; MediaPlayer.IsMuted = message.IsMuted; // 更新音量按钮显示 UpdateVolumeButton(message.IsMuted, message.Volume); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"音量设置失败: {ex.Message}"); } }); } #endregion private void LoadVideo(string videoUrl) { try { MediaPlayer.Source = new Uri(videoUrl); MediaPlayer.Play(); } catch (Exception ex) { MessageBox.Show($"加载视频失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } private void InitializeMediaPlayer() { // 初始化进度计时器 _progressTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) }; _progressTimer.Tick += ProgressTimer_Tick; // 设置音量 MediaPlayer.Volume = 0.7; } private void HideWindow() { this.Hide(); //_viewModel.IsPlaying = false; } private void ProgressTimer_Tick(object sender, EventArgs e) { if (_viewModel == null || !MediaPlayer.NaturalDuration.HasTimeSpan || _isDragging) return; var totalSeconds = MediaPlayer.NaturalDuration.TimeSpan.TotalSeconds; var currentSeconds = MediaPlayer.Position.TotalSeconds; if (totalSeconds > 0) { var progress = (currentSeconds / totalSeconds) * 100; _viewModel.Progress = progress; _viewModel.CurrentTime = MediaPlayer.Position.ToString(@"mm\:ss"); } } private void MediaPlayer_MediaOpened(object sender, RoutedEventArgs e) { if (_viewModel == null) return; if (MediaPlayer.NaturalDuration.HasTimeSpan) { _viewModel.TotalTime = MediaPlayer.NaturalDuration.TimeSpan.ToString(@"mm\:ss"); } _viewModel.IsPlaying = true; if (!_progressTimer.IsEnabled) { _progressTimer.Start(); } } private void MediaPlayer_MediaEnded(object sender, RoutedEventArgs e) { if (_viewModel == null) return; _viewModel.IsPlaying = false; MediaPlayer.Position = TimeSpan.Zero; _viewModel.Progress = 0; _viewModel.CurrentTime = "00:00"; _progressTimer.Stop(); } private void ProgressSlider_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e) { _isDragging = true; } private void ProgressSlider_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e) { if (_viewModel == null) return; if (MediaPlayer.NaturalDuration.HasTimeSpan) { var newPosition = TimeSpan.FromSeconds((_viewModel.Progress / 100) * MediaPlayer.NaturalDuration.TimeSpan.TotalSeconds); MediaPlayer.Position = newPosition; } _isDragging = false; } // 更新播放/暂停按钮显示 private void UpdatePlayPauseButton(bool isPlaying) { var button = PlayPauseButton; if (button != null) { button.Content = isPlaying ? "❚❚" : "▶"; } } // 更新音量按钮显示 private void UpdateVolumeButton(bool isMuted) { var button = VolumeButton; if (button != null) { button.Content = isMuted ? "🔇" : "🔊"; } } private void UpdateVolumeButton(bool isMuted, double volume) { var button = VolumeButton; if (button != null) { // 根据音量和静音状态显示不同的图标 if (isMuted || volume <= 0) { button.Content = "🔇"; } else if (volume < 0.3) { button.Content = "🔈"; // 小音量 } else if (volume < 0.7) { button.Content = "🔉"; // 中音量 } else { button.Content = "🔊"; // 大音量 } } } private void ToggleFullScreen() { if (WindowState == WindowState.Normal) { WindowState = WindowState.Maximized; WindowStyle = WindowStyle.None; ResizeMode = ResizeMode.NoResize; WindowChrome.SetWindowChrome(this, null); } else { WindowState = WindowState.Normal; WindowStyle = WindowStyle.None; ResizeMode = ResizeMode.CanResize; // 恢复WindowChrome WindowChrome.SetWindowChrome(this, new WindowChrome { GlassFrameThickness = new Thickness(0), ResizeBorderThickness = new Thickness(5), CaptionHeight = 40 }); } } } }