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
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
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|