OBS Websocket and initial blur, still some bugs
This commit is contained in:
parent
f9c1f4e739
commit
7e22fa58e3
227
OBSBlur/OBS/Blur.cs
Normal file
227
OBSBlur/OBS/Blur.cs
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using OBSBlur.Window;
|
||||||
|
using OBSWebsocketDotNet;
|
||||||
|
using OBSWebsocketDotNet.Communication;
|
||||||
|
using OBSWebsocketDotNet.Types;
|
||||||
|
using OBSWebsocketDotNet.Types.Events;
|
||||||
|
|
||||||
|
namespace OBSBlur.OBS;
|
||||||
|
|
||||||
|
public class Blur
|
||||||
|
{
|
||||||
|
WindowManager windowManager = new ();
|
||||||
|
private OBSWebsocket _websocket = new ();
|
||||||
|
private string currentScene;
|
||||||
|
private string[] enabledScenes;
|
||||||
|
private string[] blurPrograms;
|
||||||
|
private Dictionary<IntPtr, uint> windowHandleSceneItems = new();
|
||||||
|
|
||||||
|
public Blur(string obsUrl, string obsPassword, string[] enabledScenes, string[] blurPrograms)
|
||||||
|
{
|
||||||
|
this.enabledScenes = enabledScenes;
|
||||||
|
this.blurPrograms = blurPrograms;
|
||||||
|
windowManager.UpdateInterval = 1;
|
||||||
|
_websocket.CurrentProgramSceneChanged += WebsocketOnCurrentProgramSceneChanged;
|
||||||
|
_websocket.Connected += WebsocketOnConnected;
|
||||||
|
_websocket.Disconnected += WebsocketOnDisconnected;
|
||||||
|
|
||||||
|
_websocket.ConnectAsync(obsUrl, obsPassword);
|
||||||
|
|
||||||
|
windowManager.WindowsChanged += WindowManagerOnWindowsChanged;
|
||||||
|
windowManager.WindowZOrderChanged += WindowManagerOnWindowZOrderChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBlurs(WindowInfo[]? windowInfos = null, IntPtr[]? zOrder = null)
|
||||||
|
{
|
||||||
|
if (!enabledScenes.Contains(currentScene))
|
||||||
|
return;
|
||||||
|
if (!_websocket.IsConnected)
|
||||||
|
return;
|
||||||
|
windowInfos ??= windowManager.WindowInfos;
|
||||||
|
zOrder ??= windowManager.WindowZOrder;
|
||||||
|
|
||||||
|
bool addRemove = true;
|
||||||
|
|
||||||
|
foreach (IntPtr window in zOrder)
|
||||||
|
{
|
||||||
|
WindowInfo windowInfo = windowInfos.FirstOrDefault(w => w.WindowHandle == window);
|
||||||
|
if(windowInfo is {WindowHandle: 0x0})
|
||||||
|
continue;
|
||||||
|
bool blur = false;
|
||||||
|
foreach(string program in blurPrograms)
|
||||||
|
if (windowInfo.ProcessInfo.ProcessName.Contains(program, StringComparison.OrdinalIgnoreCase))
|
||||||
|
blur = true;
|
||||||
|
|
||||||
|
if(blur && addRemove)
|
||||||
|
BlurWindow(windowInfo);
|
||||||
|
else if(blur && addRemove is false)
|
||||||
|
DeleteBlur(windowInfo);
|
||||||
|
|
||||||
|
if (windowInfo.WindowPlacement.ShowCmd is ShowWindowCommands.Maximize)
|
||||||
|
addRemove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(WindowInfo windowInfo in windowInfos)
|
||||||
|
if (windowInfo.WindowPlacement.ShowCmd is ShowWindowCommands.ShowMinimized &&
|
||||||
|
windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle))
|
||||||
|
{
|
||||||
|
DeleteBlur(windowInfo);
|
||||||
|
windowHandleSceneItems.Remove(windowInfo.WindowHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BlurWindow(WindowInfo windowInfo)
|
||||||
|
{
|
||||||
|
if(windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle))
|
||||||
|
MoveBlur(windowInfo);
|
||||||
|
else
|
||||||
|
AddBlur(windowInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddBlur(WindowInfo windowInfo)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> request = new()
|
||||||
|
{
|
||||||
|
{"sceneName", currentScene},
|
||||||
|
{"sceneItemId", GetBlurSource()}
|
||||||
|
};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JObject response = _websocket.SendRequest("DuplicateSceneItem", JObject.FromObject(request));
|
||||||
|
windowHandleSceneItems.Add(windowInfo.WindowHandle, response["sceneItemId"]!.Value<uint>());
|
||||||
|
MoveBlur(windowInfo);
|
||||||
|
}
|
||||||
|
catch (ErrorResponseException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("No Scene Item with name 'Blur' found.");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveBlur(WindowInfo windowInfo)
|
||||||
|
{
|
||||||
|
if (!windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SceneItemTransformInfo info = windowInfo.WindowPlacement.ShowCmd switch
|
||||||
|
{
|
||||||
|
ShowWindowCommands.Maximize => new ()
|
||||||
|
{
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
BoundsHeight = 1080, //TODO desktop res
|
||||||
|
BoundsWidth = 1920,
|
||||||
|
BoundsType = SceneItemBoundsType.OBS_BOUNDS_STRETCH,
|
||||||
|
Alignnment = 5
|
||||||
|
},
|
||||||
|
_ => new()
|
||||||
|
{
|
||||||
|
X = windowInfo.WindowPlacement.NormalPosition.Left,
|
||||||
|
Y = windowInfo.WindowPlacement.NormalPosition.Top,
|
||||||
|
BoundsHeight = windowInfo.WindowPlacement.NormalPosition.Height,
|
||||||
|
BoundsWidth = windowInfo.WindowPlacement.NormalPosition.Width,
|
||||||
|
BoundsType = SceneItemBoundsType.OBS_BOUNDS_STRETCH,
|
||||||
|
Alignnment = 5
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Dictionary<string, object> request = new()
|
||||||
|
{
|
||||||
|
{"sceneName", currentScene},
|
||||||
|
{"sceneItemId", windowHandleSceneItems[windowInfo.WindowHandle]},
|
||||||
|
{"sceneItemTransform", info}
|
||||||
|
};
|
||||||
|
_websocket.SendRequest("SetSceneItemTransform", JObject.FromObject(request));
|
||||||
|
|
||||||
|
|
||||||
|
Dictionary<string, object> request2 = new()
|
||||||
|
{
|
||||||
|
{"sceneName", currentScene},
|
||||||
|
{"sceneItemId", windowHandleSceneItems[windowInfo.WindowHandle]},
|
||||||
|
{"sceneItemEnabled", true}
|
||||||
|
};
|
||||||
|
_websocket.SendRequest("SetSceneItemEnabled", JObject.FromObject(request2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteBlur(WindowInfo windowInfo)
|
||||||
|
{
|
||||||
|
if (!windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle))
|
||||||
|
return;
|
||||||
|
Dictionary<string, object> request = new()
|
||||||
|
{
|
||||||
|
{"sceneName", currentScene},
|
||||||
|
{"sceneItemId", windowHandleSceneItems[windowInfo.WindowHandle]}
|
||||||
|
};
|
||||||
|
_websocket.SendRequest("RemoveSceneItem", JObject.FromObject(request));
|
||||||
|
windowHandleSceneItems.Remove(windowInfo.WindowHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint GetBlurSource()
|
||||||
|
{
|
||||||
|
Dictionary<string, string> request = new()
|
||||||
|
{
|
||||||
|
{"sceneName", currentScene},
|
||||||
|
{"sourceName", "Blur"}
|
||||||
|
};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JObject response = _websocket.SendRequest("GetSceneItemId", JObject.FromObject(request));
|
||||||
|
return response["sceneItemId"]!.Value<uint>();
|
||||||
|
}
|
||||||
|
catch (ErrorResponseException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("No Scene Item with name 'Blur' found.");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowManagerOnWindowZOrderChanged(IntPtr[] neworder)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
uint i = 0;
|
||||||
|
string prnt = "";
|
||||||
|
foreach (IntPtr windowHandle in order)
|
||||||
|
{
|
||||||
|
WindowInfo windowInfo = windowManager.WindowInfos.FirstOrDefault(w => w.WindowHandle == windowHandle);
|
||||||
|
if(windowInfo.WindowHandle is 0x0)
|
||||||
|
continue;
|
||||||
|
prnt += $"{++i,3} {windowInfo}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.Clear();
|
||||||
|
Console.WriteLine(prnt);*/
|
||||||
|
Console.WriteLine($"Z-order changed {DateTime.UtcNow:O}");
|
||||||
|
UpdateBlurs(zOrder: neworder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowManagerOnWindowsChanged(WindowInfo[] before, WindowInfo[] after)
|
||||||
|
{
|
||||||
|
string prnt = "";
|
||||||
|
foreach (WindowInfo windowInfo in after)
|
||||||
|
prnt += $"{windowInfo}\n";
|
||||||
|
Console.WriteLine(prnt);
|
||||||
|
Console.WriteLine($"Windows changed {DateTime.UtcNow:O}");
|
||||||
|
UpdateBlurs(windowInfos: after);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WebsocketOnDisconnected(object? sender, ObsDisconnectionInfo e)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Obs Disconnected {DateTime.UtcNow:O}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WebsocketOnConnected(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
currentScene = _websocket.GetCurrentProgramScene();
|
||||||
|
Console.WriteLine($"Obs Connected. Current Scene {currentScene} {DateTime.UtcNow:O}");
|
||||||
|
UpdateBlurs();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WebsocketOnCurrentProgramSceneChanged(object? sender, ProgramSceneChangedEventArgs e)
|
||||||
|
{
|
||||||
|
currentScene = e.SceneName;
|
||||||
|
Console.WriteLine($"Obs Scene Changed -> {currentScene} {DateTime.UtcNow:O}");
|
||||||
|
UpdateBlurs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -7,4 +7,8 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="obs-websocket-dotnet" Version="5.0.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
using OBSBlur.Window;
|
using OBSBlur.OBS;
|
||||||
|
|
||||||
new WindowManager();
|
|
||||||
|
|
||||||
|
Blur _ = new Blur("ws://localhost:4444", "", new []{"Desktop"}, new []{ "Discord", "VRCX" });
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
Thread.Sleep(100);
|
Loading…
x
Reference in New Issue
Block a user