兼容win7版应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
11 KiB

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
{
/// <summary>
/// VideoPopupWindow.xaml 的交互逻辑
/// </summary>
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<VideoPlayerViewModel>();
DataContext = _viewModel;
InitializeMediaPlayer();
RegisterSubMessage();
//this.Closed += OnWindowClosed;
}
#region 内存释放和清理
#endregion
#region 消息注册与接收
private void RegisterSubMessage()
{
WeakReferenceMessenger.Default.Register<VideoControlMessage>(this, OnVideoControlMessage);
WeakReferenceMessenger.Default.Register<ShowVideoMessage>(this, OnShowVideoMessage);
WeakReferenceMessenger.Default.Register<VolumeChangedMessage>(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
});
}
}
}
}