From 052aa060ccb5d179ccd82c02dbcce79d547cf912 Mon Sep 17 00:00:00 2001 From: Solin Date: Sat, 17 Jan 2026 13:53:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD=E4=BB=A5?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B7=A5=E4=BD=9C=E7=8A=B6=E6=80=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ActivityMonitor.cs | 17 ++++++++++++++--- NativeMethods.cs | 32 +++++++++++++++++++++++++++++++- TimerApp.csproj | 2 +- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/ActivityMonitor.cs b/ActivityMonitor.cs index d544b62..52b0527 100644 --- a/ActivityMonitor.cs +++ b/ActivityMonitor.cs @@ -93,10 +93,13 @@ namespace TimerApp } else { + // 检测是否有视频/媒体正在播放 + bool isMediaPlaying = NativeMethods.IsMediaPlaying(); + // 工作/空闲模式逻辑 - if (idleTime > IdleThreshold) + if (idleTime > IdleThreshold || isMediaPlaying) { - // 用户离开了 + // 用户离开了或正在播放视频 if (CurrentState == MonitorState.Working) { // 如果正在工作,但离开了,暂停工作计时? @@ -112,10 +115,18 @@ namespace TimerApp { _accumulatedWorkTime = TimeSpan.Zero; } + + // 如果正在播放视频,不累加工作时间,但保持当前状态 + if (isMediaPlaying && CurrentState == MonitorState.Working) + { + // 保持当前剩余时间不变(不累加,也不减少) + TimeSpan remainingWork = WorkDuration - _accumulatedWorkTime; + WorkProgressChanged?.Invoke(this, remainingWork); + } } else { - // 用户在活动 + // 用户在活动且没有播放视频 if (CurrentState == MonitorState.Idle) { // 从空闲变为工作 diff --git a/NativeMethods.cs b/NativeMethods.cs index a295cbc..b668bde 100644 --- a/NativeMethods.cs +++ b/NativeMethods.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using Windows.Media.Control; namespace TimerApp { @@ -36,7 +37,7 @@ namespace TimerApp // 或者直接使用 unchecked 减法处理溢出 // 更稳健的做法是使用 GetTickCount64 (Vista+),但 Environment.TickCount 在 .NET Core 3.1+ 已经是 64位了(Environment.TickCount64) // 这里为了兼容性,我们简单处理。注意 GetLastInputInfo 返回的是 uint 毫秒数。 - + long envTicks = Environment.TickCount; // 处理 TickCount 翻转问题 (Environment.TickCount 是 int,GetLastInputInfo 是 uint) // 简单的做法: @@ -48,5 +49,34 @@ namespace TimerApp [DllImport("kernel32.dll")] static extern uint GetTickCount(); + + /// + /// 检测是否有媒体正在播放(视频或音频) + /// + /// 如果有媒体正在播放返回 true,否则返回 false + public static bool IsMediaPlaying() + { + try + { + var sessionManager = GlobalSystemMediaTransportControlsSessionManager.RequestAsync().GetAwaiter().GetResult(); + var sessions = sessionManager.GetSessions(); + + foreach (var session in sessions) + { + var playbackInfo = session.GetPlaybackInfo(); + if (playbackInfo.PlaybackStatus == GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing) + { + return true; + } + } + } + catch + { + // 如果 API 调用失败,返回 false(保守处理) + return false; + } + + return false; + } } } diff --git a/TimerApp.csproj b/TimerApp.csproj index c27cd77..8790a06 100644 --- a/TimerApp.csproj +++ b/TimerApp.csproj @@ -2,7 +2,7 @@ WinExe - net9.0-windows + net9.0-windows10.0.17763.0 enable true enable