diff --git a/BetterGenshinImpact/Core/Monitor/MouseKeyMonitor.cs b/BetterGenshinImpact/Core/Monitor/MouseKeyMonitor.cs index 2ec49595..41af890e 100644 --- a/BetterGenshinImpact/Core/Monitor/MouseKeyMonitor.cs +++ b/BetterGenshinImpact/Core/Monitor/MouseKeyMonitor.cs @@ -41,8 +41,8 @@ public class MouseKeyMonitor // Note: for the application hook, use the Hook.AppEvents() instead _globalHook = Hook.GlobalEvents(); - _globalHook.KeyDown += GlobalHookKeyDown; - _globalHook.KeyUp += GlobalHookKeyUp; + _globalHook.KeyDownExt += GlobalHookKeyDown; + _globalHook.KeyUpExt += GlobalHookKeyUp; _globalHook.MouseDownExt += GlobalHookMouseDownExt; _globalHook.MouseUpExt += GlobalHookMouseUpExt; _globalHook.MouseMoveExt += GlobalHookMouseMoveExt; @@ -59,9 +59,11 @@ public class MouseKeyMonitor _fTimer.Elapsed += (sender, args) => { Simulation.PostMessage(_hWnd).KeyPress(User32.VK.VK_F); }; } - private void GlobalHookKeyDown(object? sender, KeyEventArgs e) + private void GlobalHookKeyDown(object? sender, KeyEventArgsExt e) { - // Debug.WriteLine("KeyDown: \t{0}", e.KeyCode); + // Debug.WriteLine(Kernel32.GetTickCount()); + // Debug.WriteLine(System.Environment.TickCount); + // Debug.WriteLine("KeyDown: \t{0} \tIsKeyDown:{1} \tIsKeyUp:{2} \t Time:{3}", e.KeyCode, e.IsKeyDown, e.IsKeyUp, e.Timestamp); GlobalKeyMouseRecord.Instance.GlobalHookKeyDown(e); // 热键按下事件 @@ -97,7 +99,7 @@ public class MouseKeyMonitor } } - private void GlobalHookKeyUp(object? sender, KeyEventArgs e) + private void GlobalHookKeyUp(object? sender, KeyEventArgsExt e) { // Debug.WriteLine("KeyUp: \t{0}", e.KeyCode); GlobalKeyMouseRecord.Instance.GlobalHookKeyUp(e); @@ -178,8 +180,8 @@ public class MouseKeyMonitor { if (_globalHook != null) { - _globalHook.KeyDown -= GlobalHookKeyDown; - _globalHook.KeyUp -= GlobalHookKeyUp; + _globalHook.KeyDownExt -= GlobalHookKeyDown; + _globalHook.KeyUpExt -= GlobalHookKeyUp; _globalHook.MouseDownExt -= GlobalHookMouseDownExt; _globalHook.MouseUpExt -= GlobalHookMouseUpExt; _globalHook.MouseMoveExt -= GlobalHookMouseMoveExt; diff --git a/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs b/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs index 98b594a8..eb2fed89 100644 --- a/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs +++ b/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs @@ -16,6 +16,7 @@ using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Video; using NAudio.Wave; using SharpAvi; +using Vanara.PInvoke; using Wpf.Ui.Violeta.Controls; namespace BetterGenshinImpact.Core.Recorder; @@ -150,7 +151,7 @@ public class GlobalKeyMouseRecord : Singleton ra.Dispose(); } - public void GlobalHookKeyDown(KeyEventArgs e) + public void GlobalHookKeyDown(KeyEventArgsExt e) { // 排除热键 if (e.KeyCode.ToString() == _keyMouseMacroRecordHotkey) @@ -178,7 +179,7 @@ public class GlobalKeyMouseRecord : Singleton _recorder?.KeyDown(e); } - public void GlobalHookKeyUp(KeyEventArgs e) + public void GlobalHookKeyUp(KeyEventArgsExt e) { if (e.KeyCode.ToString() == TaskContext.Instance().Config.HotKeyConfig.Test1Hotkey) { @@ -241,20 +242,22 @@ public class GlobalKeyMouseRecord : Singleton return; } + var tick = Kernel32.GetTickCount(); + if (_paimonSwitchEnabled) { if (!_isInMainUi) { - _recorder?.MouseMoveBy(state, false); + _recorder?.MouseMoveBy(state, tick, false); } else { - _recorder?.MouseMoveBy(state, true); + _recorder?.MouseMoveBy(state, tick, true); } } else { - _recorder?.MouseMoveBy(state, true); + _recorder?.MouseMoveBy(state, tick, true); } } } diff --git a/BetterGenshinImpact/Core/Recorder/KeyMouseRecorder.cs b/BetterGenshinImpact/Core/Recorder/KeyMouseRecorder.cs index c5608529..63c06c1d 100644 --- a/BetterGenshinImpact/Core/Recorder/KeyMouseRecorder.cs +++ b/BetterGenshinImpact/Core/Recorder/KeyMouseRecorder.cs @@ -6,10 +6,12 @@ using Gma.System.MouseKeyHook; using SharpDX.DirectInput; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; using System.Windows.Forms; +using Vanara.PInvoke; namespace BetterGenshinImpact.Core.Recorder; @@ -22,6 +24,8 @@ public class KeyMouseRecorder public DateTime StartTime { get; set; } = DateTime.UtcNow; + public uint StartTick { get; set; } = Kernel32.GetTickCount(); + public DateTime LastOrientationDetection { get; set; } = DateTime.UtcNow; public double MergedEventTimeMax { get; set; } = 20.0; @@ -38,6 +42,9 @@ public class KeyMouseRecorder public string ToJsonMacro() { + // MacroEvents 需要以实际时间进行排序 + MacroEvents.Sort((a, b) => a.Time.CompareTo(b.Time)); + var rect = TaskContext.Instance().SystemInfo.CaptureAreaRect; KeyMouseScript keyMouseScript = new() { @@ -58,58 +65,63 @@ public class KeyMouseRecorder return JsonSerializer.Serialize(keyMouseScript, JsonOptions); } - public void KeyDown(KeyEventArgs e) + public void KeyDown(KeyEventArgsExt e) { + var time = e.Timestamp - StartTick; MacroEvents.Add(new MacroEvent { Type = MacroEventType.KeyDown, KeyCode = e.KeyValue, - Time = (DateTime.UtcNow - StartTime).TotalMilliseconds + Time = time }); } - public void KeyUp(KeyEventArgs e) + public void KeyUp(KeyEventArgsExt e) { + var time = e.Timestamp - StartTick; MacroEvents.Add(new MacroEvent { Type = MacroEventType.KeyUp, KeyCode = e.KeyValue, - Time = (DateTime.UtcNow - StartTime).TotalMilliseconds + Time = time }); } public void MouseDown(MouseEventExtArgs e) { + var time = e.Timestamp - StartTick; MacroEvents.Add(new MacroEvent { Type = MacroEventType.MouseDown, MouseX = e.X, MouseY = e.Y, MouseButton = e.Button.ToString(), - Time = (DateTime.UtcNow - StartTime).TotalMilliseconds + Time = time }); } public void MouseUp(MouseEventExtArgs e) { + var time = e.Timestamp - StartTick; MacroEvents.Add(new MacroEvent { Type = MacroEventType.MouseUp, MouseX = e.X, MouseY = e.Y, MouseButton = e.Button.ToString(), - Time = (DateTime.UtcNow - StartTime).TotalMilliseconds + Time = time }); } public void MouseMoveTo(MouseEventExtArgs e, bool save = false) { + var time = e.Timestamp - StartTick; var mEvent = new MacroEvent { Type = MacroEventType.MouseMoveTo, MouseX = e.X, MouseY = e.Y, - Time = (DateTime.UtcNow - StartTime).TotalMilliseconds + Time = time }; MouseMoveToMacroEvents.Add(mEvent); if (save) @@ -120,24 +132,34 @@ public class KeyMouseRecorder public void MouseWheel(MouseEventExtArgs e) { + var time = e.Timestamp - StartTick; MacroEvents.Add(new MacroEvent { Type = MacroEventType.MouseWheel, MouseY = e.Delta, // 120 的倍率 - Time = (DateTime.UtcNow - StartTime).TotalMilliseconds + Time = time }); } - public void MouseMoveBy(MouseState state, bool save = false) + public void MouseMoveBy(MouseState state, uint tick, bool save = false) { - var now = DateTime.UtcNow; + uint prevTickCount = 0; + if (MouseMoveByMacroEvents.Count > 0) + { + prevTickCount = MouseMoveByMacroEvents[^1].TickCount - StartTick; + } + else + { + prevTickCount = tick - 5; // 减去间隔时间5ms + } var mEvent = new MacroEvent { Type = MacroEventType.MouseMoveBy, MouseX = state.X, MouseY = state.Y, - Time = (now - StartTime).TotalMilliseconds, + Time = prevTickCount, + TickCount = tick }; MouseMoveByMacroEvents.Add(mEvent); if (save) diff --git a/BetterGenshinImpact/Core/Recorder/Model/MacroEvent.cs b/BetterGenshinImpact/Core/Recorder/Model/MacroEvent.cs index 1db722d6..07b605be 100644 --- a/BetterGenshinImpact/Core/Recorder/Model/MacroEvent.cs +++ b/BetterGenshinImpact/Core/Recorder/Model/MacroEvent.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Serialization; namespace BetterGenshinImpact.Core.Recorder.Model; @@ -11,6 +12,9 @@ public class MacroEvent public int MouseY { get; set; } public string? MouseButton { get; set; } public double Time { get; set; } + + [JsonIgnore] + public uint TickCount { get; set; } public int? CameraOrientation { get; set; } } diff --git a/BetterGenshinImpact/Core/Video/FfmpegRecorder.cs b/BetterGenshinImpact/Core/Video/FfmpegRecorder.cs index 3e423ad3..2ed42dde 100644 --- a/BetterGenshinImpact/Core/Video/FfmpegRecorder.cs +++ b/BetterGenshinImpact/Core/Video/FfmpegRecorder.cs @@ -33,11 +33,13 @@ public class FfmpegRecorder throw new Exception("ffmpeg.exe不存在"); } - _filePath = Global.Absolute($@"User\KeyMouseScript\{fileName}.mp4"); + var folderPath = Global.Absolute($@"User\KeyMouseScript\{fileName}\"); + Directory.CreateDirectory(folderPath); + _filePath = Path.Combine(folderPath, "%Y-%m-%d_%H-%M-%S.mp4"); var processInfo = new ProcessStartInfo { FileName = FfmpegPath, - Arguments = $" -f gdigrab -hwaccel cuvid -show_region 1 -framerate 60 -use_wallclock_as_timestamps 1 -i title=原神 -pix_fmt yuv420p -c:v libx264 -preset ultrafast \"{_filePath}\"", + Arguments = $" -f gdigrab -hwaccel cuvid -show_region 1 -framerate 60 -use_wallclock_as_timestamps 1 -i title=原神 -pix_fmt yuv420p -c:v libx264 -preset ultrafast -f segment -segment_time 300 -reset_timestamps 1 -strftime 1 \"{_filePath}\"", StandardInputEncoding = Encoding.UTF8, UseShellExecute = false, CreateNoWindow = true, @@ -62,6 +64,7 @@ public class FfmpegRecorder { _startTime = match.Groups[1].Value.Replace(".", ""); TaskControl.Logger.LogInformation("ffmpeg录制: 视频起始时间戳 {Text}", _startTime); + File.WriteAllText(Path.Combine(folderPath, $"{_startTime}.txt"), _startTime); } } } @@ -109,18 +112,18 @@ public class FfmpegRecorder _process.Dispose(); - Thread.Sleep(3000); - if (File.Exists(_filePath)) - { - // 重命名文件 - var newFilePath = Global.Absolute($@"User\KeyMouseScript\{_fileName}_{_startTime}.mp4"); - File.Move(_filePath, newFilePath); - TaskControl.Logger.LogInformation("ffmpeg录制: {Text}", $"录制完成"); - } - else - { - TaskControl.Logger.LogError("ffmpeg录制: {Text}", "未找到结果文件,录制失败"); - } + // Thread.Sleep(3000); + // if (File.Exists(_filePath)) + // { + // // 重命名文件 + // var newFilePath = Global.Absolute($@"User\KeyMouseScript\{_fileName}_{_startTime}.mp4"); + // File.Move(_filePath, newFilePath); + // TaskControl.Logger.LogInformation("ffmpeg录制: {Text}", $"录制完成"); + // } + // else + // { + // TaskControl.Logger.LogError("ffmpeg录制: {Text}", "未找到结果文件,录制失败"); + // } } catch (Exception e) { diff --git a/Common/MouseKeyHook/Implementation/KeyListener.cs b/Common/MouseKeyHook/Implementation/KeyListener.cs index 417a7d10..2c8ec188 100644 --- a/Common/MouseKeyHook/Implementation/KeyListener.cs +++ b/Common/MouseKeyHook/Implementation/KeyListener.cs @@ -26,16 +26,26 @@ namespace Gma.System.MouseKeyHook.Implementation public event EventHandler KeyUpExt; public void InvokeKeyDown(KeyEventArgsExt e) + { + OnKeyDownExt(e); + OnKeyDown(e); + } + + + private void OnKeyDown(KeyEventArgsExt e) { var handler = KeyDown; if (handler == null || e.Handled || !e.IsKeyDown) return; handler(this, e); - - var handlerExt = KeyDownExt; - if (handlerExt == null || e.Handled || !e.IsKeyDown) + } + + private void OnKeyDownExt(KeyEventArgsExt e) + { + var handler = KeyDownExt; + if (handler == null || e.Handled || !e.IsKeyDown) return; - handlerExt(this, e); + handler(this, e); } public void InvokeKeyPress(KeyPressEventArgsExt e) @@ -55,16 +65,25 @@ namespace Gma.System.MouseKeyHook.Implementation } public void InvokeKeyUp(KeyEventArgsExt e) + { + OnKeyUpExt(e); + OnKeyUp(e); + } + + private void OnKeyUp(KeyEventArgsExt e) { var handler = KeyUp; if (handler == null || e.Handled || !e.IsKeyUp) return; handler(this, e); - - var handlerExt = KeyUpExt; - if (handlerExt == null || e.Handled || !e.IsKeyDown) + } + + private void OnKeyUpExt(KeyEventArgsExt e) + { + var handler = KeyUpExt; + if (handler == null || e.Handled || !e.IsKeyUp) return; - handlerExt(this, e); + handler(this, e); } protected override bool Callback(CallbackData data) @@ -98,13 +117,6 @@ namespace Gma.System.MouseKeyHook.Implementation protected abstract IEnumerable GetPressEventArgs(CallbackData data); protected abstract KeyEventArgsExt GetDownUpEventArgs(CallbackData data); - - private void OnKeyUpExt(KeyEventArgsExt e) - { - var handler = KeyUpExt; - if (handler == null || e.Handled || !e.IsKeyUp) - return; - handler(this, e); - } + } } \ No newline at end of file