diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj
index 18e7db34..330bb137 100644
--- a/BetterGenshinImpact/BetterGenshinImpact.csproj
+++ b/BetterGenshinImpact/BetterGenshinImpact.csproj
@@ -10,7 +10,7 @@
true
Assets\Images\logo.ico
BetterGI
- 10.38.6
+ 10.38.7
x64
embedded
diff --git a/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs b/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs
index fa911db3..26e6cf4b 100644
--- a/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs
+++ b/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs
@@ -14,6 +14,7 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Video;
+using BetterGenshinImpact.Core.Video.obs;
using NAudio.Wave;
using SharpAvi;
using Vanara.PInvoke;
@@ -82,6 +83,7 @@ public class GlobalKeyMouseRecord : Singleton
_videoRecorder = VideoRecorderFactory.Create(TaskContext.Instance().Config.CommonConfig.Recorder, fileName);
_directInputMonitor = new DirectInputMonitor();
+ var recorderTmp = new KeyMouseRecorderJsonLine(fileName);
// TaskTriggerDispatcher.Instance().StopTimer();
@@ -98,10 +100,26 @@ public class GlobalKeyMouseRecord : Singleton
}
- var videoEnabled = _videoRecorder.Start();
-
+ var tmpTime = DateTime.Now;
+
+ var sw = new Stopwatch();
+ sw.Start();
+ long current;
+
+
_directInputMonitor.Start();
- _recorder = new KeyMouseRecorderJsonLine(fileName);
+ _logger.LogInformation("从开始到directInput启动累计耗时ms:{Text}", sw.ElapsedMilliseconds);
+
+ var videoEnabled = _videoRecorder.Start();
+ _logger.LogInformation("从开始到视频录制启动累计耗时(OBS是WS通知完成耗时,并非实际录制时间)ms:{Text}", sw.ElapsedMilliseconds);
+
+ _recorder = recorderTmp.Start();
+ _recorder.AppendStartInfo();
+ _logger.LogInformation("从开始到键鼠录制启动累计耗时ms:{Text}", sw.ElapsedMilliseconds);
+
+ sw.Stop();
+
+ ObsLogFileProcessor.FindStartTime(fileName, tmpTime);
Status = KeyMouseRecorderStatus.Recording;
@@ -115,13 +133,18 @@ public class GlobalKeyMouseRecord : Singleton
throw new InvalidOperationException("未处于录制中状态,无法停止");
}
+ var sw = new Stopwatch();
+ sw.Start();
// var macro = _recorder?.ToJsonMacro() ?? string.Empty;
_recorder = null;
_directInputMonitor?.Stop();
_directInputMonitor?.Dispose();
_directInputMonitor = null;
+ _logger.LogInformation("从结束触发到键鼠录制关闭累计耗时ms:{Text}", sw.ElapsedMilliseconds);
_videoRecorder?.Stop();
+ _logger.LogInformation("从结束触发到视频录制关闭累计耗时ms:{Text}", sw.ElapsedMilliseconds);
+
if (_timer.Enabled)
{
@@ -182,7 +205,6 @@ public class GlobalKeyMouseRecord : Singleton
public void GlobalHookKeyUp(KeyEventArgsExt e)
{
-
if (_keyDownState.TryGetValue(e.KeyCode, out bool state) && state)
{
// Debug.WriteLine($"KeyUp: {e.KeyCode}");
diff --git a/BetterGenshinImpact/Core/Recorder/KeyMouseRecorderJsonLine.cs b/BetterGenshinImpact/Core/Recorder/KeyMouseRecorderJsonLine.cs
index f2d5889b..6b81c199 100644
--- a/BetterGenshinImpact/Core/Recorder/KeyMouseRecorderJsonLine.cs
+++ b/BetterGenshinImpact/Core/Recorder/KeyMouseRecorderJsonLine.cs
@@ -42,11 +42,12 @@ public class KeyMouseRecorderJsonLine
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
+ string _path;
+
public KeyMouseRecorderJsonLine(string folderName)
{
- var path = Global.Absolute($@"User\KeyMouseScript\{folderName}\");
+ _path = Global.Absolute($@"User\KeyMouseScript\{folderName}\");
- DateTime startTime = DateTime.Now;
// var bootTime = EnvironmentUtil.LastBootUpTime();
// if (bootTime == null)
// {
@@ -65,14 +66,28 @@ public class KeyMouseRecorderJsonLine
Width = rect.Width,
Height = rect.Height,
RecordDpi = TaskContext.Instance().DpiScale,
- StartTime = $"{startTime:yyyy-MM-dd HH:mm:ss:ffff}",
- StartTimeUnixTimestamp = (startTime.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalNanoseconds.ToString("F0"),
- SysParams = RecordContext.Instance.SysParams
+ SysParams = RecordContext.Instance.SysParams
};
- var infoJson = JsonSerializer.Serialize(Info, JsonOptions);
- File.WriteAllText(Path.Combine(path, $"systemInfo.json"), infoJson);
- _consumerTask = Task.Run(async () => await ConsumeEventsAsync(path));
+ _consumerTask = Task.Run(async () => await ConsumeEventsAsync(_path));
+ }
+
+ public KeyMouseRecorderJsonLine Start()
+ {
+ StartTick = Kernel32.GetTickCount();
+ return this;
+ }
+
+ public void AppendStartInfo()
+ {
+ Task.Run(() =>
+ {
+ DateTime startTime = DateTime.Now;
+ Info.StartTime = $"{startTime:yyyy-MM-dd HH:mm:ss:ffff}";
+ Info.StartTimeUnixTimestamp = (startTime.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalNanoseconds.ToString("F0");
+ var infoJson = JsonSerializer.Serialize(Info, JsonOptions);
+ File.WriteAllText(Path.Combine(_path, $"systemInfo.json"), infoJson);
+ });
}
private async Task ConsumeEventsAsync(string path)
diff --git a/BetterGenshinImpact/Core/Video/ObsRecorder.cs b/BetterGenshinImpact/Core/Video/ObsRecorder.cs
index 433753cb..c1e7dbbb 100644
--- a/BetterGenshinImpact/Core/Video/ObsRecorder.cs
+++ b/BetterGenshinImpact/Core/Video/ObsRecorder.cs
@@ -106,7 +106,7 @@ public class ObsRecorder : IVideoRecorder
{
obs.StartRecord();
_lastRecordTime = DateTime.Now;
- TaskControl.Logger.LogInformation("OBS: 开始录制,时间: {Time}", _lastRecordTime.ToString("yyyy-MM-dd HH:mm:ss:ffff"));
+ TaskControl.Logger.LogInformation("OBS: ws请求开始录制,时间: {Time}", _lastRecordTime.ToString("yyyy-MM-dd HH:mm:ss.ffff"));
return true;
}
catch (ErrorResponseException ex)
@@ -118,7 +118,7 @@ public class ObsRecorder : IVideoRecorder
}
else
{
- TaskControl.Logger.LogError($"OBS: 开始录制失败: {ex.Message}");
+ TaskControl.Logger.LogError($"OBS: ws请求开始录制失败: {ex.Message}");
throw;
}
}
@@ -187,7 +187,7 @@ public class ObsRecorder : IVideoRecorder
TaskControl.Logger.LogError("OBS: 未找到录制结果文件");
}
- File.WriteAllText(Path.Combine(folderPath, "videoStartTime.txt"), (_lastRecordTime.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalNanoseconds.ToString("F0"));
+ // File.WriteAllText(Path.Combine(folderPath, "videoStartTime.txt"), (_lastRecordTime.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalNanoseconds.ToString("F0"));
}
catch (Exception e)
{
diff --git a/BetterGenshinImpact/Core/Video/obs/ObsLogFileProcessor.cs b/BetterGenshinImpact/Core/Video/obs/ObsLogFileProcessor.cs
new file mode 100644
index 00000000..a39baf07
--- /dev/null
+++ b/BetterGenshinImpact/Core/Video/obs/ObsLogFileProcessor.cs
@@ -0,0 +1,133 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using BetterGenshinImpact.Core.Config;
+using BetterGenshinImpact.GameTask.Common;
+using Microsoft.Extensions.Logging;
+
+namespace BetterGenshinImpact.Core.Video.obs;
+
+public class ObsLogFileProcessor
+{
+ private static readonly string ObsLogPath = Global.Absolute(@"video\bin\OBS-Studio-31.0.0-Windows\config\obs-studio\logs");
+
+ public static FileInfo? GetLogFilePath()
+ {
+ // 找到目录中最新的日志文件
+ if (!Directory.Exists(ObsLogPath))
+ {
+ TaskControl.Logger.LogError("OBS日志目录不存在");
+ return null;
+ }
+
+ var files = Directory.GetFiles(ObsLogPath, "*.txt");
+ if (files.Length == 0)
+ {
+ TaskControl.Logger.LogError("OBS日志文件不存在");
+ return null;
+ }
+
+ FileInfo? latestFile = null;
+ foreach (var file in files)
+ {
+ var fileInfo = new FileInfo(file);
+ if (latestFile == null || fileInfo.LastWriteTime > latestFile.LastWriteTime)
+ {
+ latestFile = fileInfo;
+ }
+ }
+
+ TaskControl.Logger.LogDebug("当前最新的OBS日志文件:{Path}", latestFile?.FullName);
+ return latestFile;
+ }
+
+ public static async Task ProcessLog(DateTime? beforeStartTime)
+ {
+ var logFile = GetLogFilePath();
+ if (logFile == null)
+ {
+ return null;
+ }
+
+ // 以共享的方式读取日志文件
+ string content;
+ try
+ {
+ await using var fileStream = new FileStream(logFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ using var reader = new StreamReader(fileStream);
+ content = await reader.ReadToEndAsync();
+ }
+ catch (IOException e)
+ {
+ TaskControl.Logger.LogError("OBS日志文件读取失败:{Msg}", e.Message);
+ return null;
+ }
+
+ // 从下网上找到最近一次 = Recording Start = 关键词的行
+ var lines = content.Split('\n');
+ string? lastLine = null;
+ for (var i = lines.Length - 1; i >= 0; i--)
+ {
+ if (lines[i].Contains("= Recording Start ="))
+ {
+ if (beforeStartTime != null)
+ {
+ var timeStr = lines[i].Substring(0, 12);
+ if (DateTime.TryParse(timeStr, out var time))
+ {
+ if (time >= beforeStartTime)
+ {
+ lastLine = lines[i];
+ return time;
+ }
+ }
+ }
+ else
+ {
+ lastLine = lines[i];
+ break;
+ }
+ }
+ }
+
+ if (lastLine == null)
+ {
+ TaskControl.Logger.LogDebug("未找到OBS日志中录制开始关键词");
+ return null;
+ }
+
+ // 内容应该是 16:19:40.665: ==== Recording Start ===============================================
+ var timeStr2 = lastLine.Substring(0, 12);
+ // 16:19:40.665 转换到datetime
+ if (DateTime.TryParse(timeStr2, out var time2))
+ {
+ return time2;
+ }
+
+ return null;
+ }
+
+ public static void FindStartTime(string fileName, DateTime beforeStartTime)
+ {
+ Task.Run(async () =>
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ await Task.Delay(1000);
+ var time = await ProcessLog(beforeStartTime);
+ if (time != null)
+ {
+ var t = time.Value;
+ TaskControl.Logger.LogInformation("OBS实际录制开始时间(来自log):{Time}", t.ToString("yyyy-MM-dd HH:mm:s.ffff"));
+ var folderPath = Global.Absolute($@"User\KeyMouseScript\{fileName}\");
+ await File.WriteAllTextAsync(Path.Combine(folderPath, "videoStartTime.txt"), (t.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalNanoseconds.ToString("F0"));
+ break;
+ }
+ else
+ {
+ TaskControl.Logger.LogDebug("未找到OBS实际录制开始时间,等待1s后重试");
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs b/BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs
index 858113d5..e154d362 100644
--- a/BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs
+++ b/BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs
@@ -324,7 +324,7 @@ public class GenshinGameSettings
}
var str = Encoding.UTF8.GetString(rawBytes);
- Debug.WriteLine(str);
+ // Debug.WriteLine(str);
return str;
}
diff --git a/BetterGenshinImpact/Service/Singletons/StartEndSingleton.cs b/BetterGenshinImpact/Service/Singletons/StartEndSingleton.cs
index e3e25f7d..01f80717 100644
--- a/BetterGenshinImpact/Service/Singletons/StartEndSingleton.cs
+++ b/BetterGenshinImpact/Service/Singletons/StartEndSingleton.cs
@@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Video;
+using BetterGenshinImpact.Core.Video.obs;
using BetterGenshinImpact.GameTask;
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.Genshin.Settings;
@@ -65,7 +66,7 @@ public class StartEndSingleton : Singleton
// // 退出
// Environment.Exit(0);
// }
- TosClientHelper.Instance.Test(Global.Absolute(@$"User/config.json"));
+ // TosClientHelper.Instance.Test(Global.Absolute(@$"User/config.json"));
}