Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/cleanup and resolution update #9

Merged
merged 2 commits into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ Bin/
obj/
Obj/

# Visual Studio Code
.vscode/

# Visual Studio 2015 cache/options directory
.vs/
.config/
Expand Down
90 changes: 47 additions & 43 deletions Classes/Recorders/LibObsRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,23 @@ public override void Start() {
};
bool resetAudioCode = obs_reset_audio(ref avi);

// scene rendering resolution
int MainWidth = 1920;
int MainHeight = 1080;
// Should match monitor resolution
int baseWidth = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
int baseHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
// output resolution
int outputWidth = 1920;
int outputHeight = 1080;


obs_video_info ovi = new() {
adapter = 0,
graphics_module = "libobs-d3d11",
fps_num = 60,
fps_den = 1,
base_width = (uint)MainWidth,
base_height = (uint)MainHeight,
output_width = (uint)MainWidth,
output_height = (uint)MainHeight,
base_width = (uint)baseWidth,
base_height = (uint)baseHeight,
output_width = (uint)outputWidth,
output_height = (uint)outputHeight,
output_format = video_format.VIDEO_FORMAT_NV12,
gpu_conversion = true,
colorspace = video_colorspace.VIDEO_CS_DEFAULT,
Expand Down Expand Up @@ -126,9 +130,21 @@ public override void Stop() {
public override async Task<bool> StartRecording() {
signalOutputStop = false;
var session = RecordingService.GetCurrentSession();
IntPtr handle = EnumerateProcessWindowHandles(session.Pid).First();
IntPtr handle;
if (session.Pid == 0) {
// If session is empty, this is a manual record attempt. Lets try to yolo record the foregroundwindow
handle = GetForegroundWindow();
if (handle == IntPtr.Zero)
Logger.WriteLine(string.Format(""));
if (GetWindowThreadProcessId(handle, out int processId) == 0)
Logger.WriteLine(string.Format(""));
// string title = GetWindowTitle(handle);
AutoDetectGame(processId, autoRecord:false);
session = RecordingService.GetCurrentSession();
}

// attempt to retrieve process's window handle to retieve class name and window title
handle = EnumerateProcessWindowHandles(session.Pid).First();
int retryAttempt = 0;
while (handle == IntPtr.Zero && retryAttempt < maxRetryAttempts) {
await Task.Delay(retryInterval);
Expand Down Expand Up @@ -295,31 +311,8 @@ public void ProcessCreation_EventArrived(object sender, EventArrivedEventArgs e)
var executablePath = instanceDescription.GetPropertyValue("ExecutablePath");
var cmdLine = instanceDescription.GetPropertyValue("CommandLine"); // may or may not be useful in the future

if (executablePath != null && !String.IsNullOrEmpty(executablePath.ToString())) {
string exe = Path.GetFileName(executablePath.ToString());

bool isGame = DetectionService.IsMatchedGame(exe);
bool isNonGame = DetectionService.IsMatchedNonGame(exe);

if (isGame && !isNonGame) {
Logger.WriteLine(string.Format("This process [{0}] is a recordable game [{1}], prepared to record", processId, exe));

string gameTitle = DetectionService.GetGameTitle(exe);
RecordingService.SetCurrentSession(processId, gameTitle);
RecordingService.GetCurrentSession().Exe = exe;
AutoDetectGame(processId);

if (SettingsService.Settings.captureSettings.recordingMode == "automatic")
RecordingService.StartRecording();
}
else if (!isGame && !isNonGame) {
Logger.WriteLine(string.Format("This process [{0}] is an unknown application [{1}], lets guess if it is a game", processId, exe));

AutoDetectGame(processId);
}
else {
Logger.WriteLine(string.Format("This process [{0}] is a non-game [{1}]", processId, exe));
}
}
}
}
catch (ManagementException) { }
Expand Down Expand Up @@ -415,7 +408,7 @@ public void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int
/// </summary>
/// <param name="processId"></param>
/// <param name="executablePath">Full path to executable, if possible</param>
public void AutoDetectGame(int processId, string executablePath = null) {
public void AutoDetectGame(int processId, string executablePath = null, bool autoRecord = true) {
bool isGame = false, isNonGame = false;
string exeFile = executablePath;
string modules = "";
Expand All @@ -427,15 +420,25 @@ public void AutoDetectGame(int processId, string executablePath = null) {

if (exeFile == null) {
exeFile = process.ProcessName + ".exe";
isNonGame = DetectionService.IsMatchedNonGame(exeFile);
if (isNonGame) {
return;
}
}

if (!autoRecord){
// This is a manual record event so lets just yolo it and assume user knows best
string gameTitle = DetectionService.GetGameTitle(exeFile);
RecordingService.SetCurrentSession(processId, gameTitle);
RecordingService.GetCurrentSession().Exe = exeFile;
return;
}

isNonGame = DetectionService.IsMatchedNonGame(exeFile);
if (isNonGame) {
return;
}

isGame = DetectionService.IsMatchedGame(exeFile);

if (!isGame) {
Logger.WriteLine(string.Format("Process [{0}] isn't in the game detection list, checking if it might be a game", Path.GetFileName(exeFile)));
try {
foreach (ProcessModule module in process.Modules) {
if (module == null) continue;
Expand All @@ -451,21 +454,22 @@ public void AutoDetectGame(int processId, string executablePath = null) {

if (name.StartsWith("d3d") || name.StartsWith("opengl")) {
isGame = true;
Logger.WriteLine(string.Format("This process [{0}]:[{1}] : [{2}], appears to be a game.", processId, name, Path.GetFileName(exeFile)));
}
module.Dispose();
}
}
catch (Exception) {
if (DetectionService.IsMatchedGame(exeFile)) {
isGame = true;
}
Logger.WriteLine(string.Format("Failed to view all ProcessModules for [{0}{1}] isGame: {2} isNonGame: {3}", Path.GetFileName(exeFile), modules, isGame, isNonGame));
}
}
}
}
catch (Exception) { } // sometimes, the process locks us out from reading and throws exception (anticheat functionality?)
catch (Exception) { // sometimes, the process locks us out from reading and throws exception (anticheat functionality?)
Logger.WriteLine(string.Format("Exception while trying to determine if {0} is a game. isGame: {1} isNonGame: {2}", Path.GetFileName(exeFile), isGame, isNonGame));
}

if (isGame && !DetectionService.IsMatchedNonGame(exeFile)) {
if (isGame) {
if (EnumerateProcessWindowHandles(processId).Count() <= 0) return;

string gameTitle = DetectionService.GetGameTitle(exeFile);
Expand All @@ -474,7 +478,7 @@ public void AutoDetectGame(int processId, string executablePath = null) {

Logger.WriteLine(string.Format("This process [{0}] is a recordable game [{1}{2}], prepared to record", processId, Path.GetFileName(exeFile), modules));

if (SettingsService.Settings.captureSettings.recordingMode == "automatic")
if (autoRecord && SettingsService.Settings.captureSettings.recordingMode == "automatic")
RecordingService.StartRecording();
}
}
Expand Down
4 changes: 4 additions & 0 deletions Classes/Services/RecordingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ public static async void StartRecording() {
}
//DetectionService.DisposeDetections();
}
if (!result) {
// recorder failed to start properly so lets restart the currentSession Pid
currentSession.Pid = 0;
}
IsPreRecording = false;
}

Expand Down