Skip to content

Commit a5bda70

Browse files
committed
Fixed for OBS 29 and added more detail to hat selection
1 parent 2c670f8 commit a5bda70

File tree

8 files changed

+142
-128
lines changed

8 files changed

+142
-128
lines changed

Fritz.Chatbot/Commands/PredictHatCommand.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,22 @@ public async Task Execute(IChatService chatService, string userName, ReadOnlyMem
8282
}
8383

8484
var bestMatch = result.Predictions.OrderByDescending(p => p.Probability).FirstOrDefault();
85-
if (bestMatch == null || bestMatch.Probability < 0.7D) {
85+
if (bestMatch.Probability < 0.7D && bestMatch.Probability > 0.5d) {
86+
87+
if (result.Predictions.Count(b => b.Probability > 0.4d) > 1) {
88+
89+
var guess1Data = (await _Repository.GetHatData(bestMatch.TagName));
90+
var guess2Data = (await _Repository.GetHatData(result.Predictions.OrderByDescending(p => p.Probability).Skip(1).First().TagName));
91+
await chatService.SendMessageAsync($"csharpGuess I'm not quite sure if this is {guess1Data.Name} or {guess2Data.Name}");
92+
return;
93+
94+
} else {
95+
var guessData = (await _Repository.GetHatData(bestMatch.TagName));
96+
await chatService.SendMessageAsync($"csharpGuess I'm not quite sure if this is {guessData.Name}");
97+
return;
98+
}
99+
100+
} else if ((bestMatch?.Probability ?? 0) <= 0.4d) {
86101
await chatService.SendMessageAsync("csharpAngry 404 Hat Not Found! Let's ask a moderator to !addhat so we can identify it next time");
87102
// do we store the image?
88103
return;

Fritz.ObsProxy/BotClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public async ValueTask DisposeAsync()
7474

7575
if (_Client != null)
7676
{
77-
await _Client?.DisposeAsync();
77+
await _Client.DisposeAsync();
7878
}
7979

8080
}

Fritz.ObsProxy/Fritz.ObsProxy.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
<ItemGroup>
99
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.2" />
1010
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
11-
<PackageReference Include="OBS.WebSocket.NET" Version="4.7.2" />
12-
<PackageReference Include="SixLabors.ImageSharp" Version="2.0.0" />
11+
<PackageReference Include="obs-websocket-dotnet" Version="5.0.0.3" />
12+
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.0" />
1313
</ItemGroup>
1414

1515
<ItemGroup>

Fritz.ObsProxy/ObsClient.cs

Lines changed: 98 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,149 +1,149 @@
11
using Microsoft.Extensions.Configuration;
22
using Microsoft.Extensions.Logging;
33
using Microsoft.VisualBasic.CompilerServices;
4-
using OBS.WebSocket.NET;
5-
using OBS.WebSocket.NET.Types;
4+
using OBSWebsocketDotNet;
5+
using OBSWebsocketDotNet.Types;
66
using SixLabors.ImageSharp;
77
using SixLabors.ImageSharp.Processing;
88
using System;
99
using System.Collections.Generic;
10+
using System.Diagnostics;
1011
using System.IO;
1112
using System.Linq;
1213
using System.Runtime.InteropServices;
1314
using System.Text;
15+
using System.Threading;
1416
using System.Threading.Tasks;
1517

16-
namespace Fritz.ObsProxy
17-
{
18+
namespace Fritz.ObsProxy;
1819

19-
public class ObsClient : IDisposable
20-
{
21-
private bool _DisposedValue;
22-
private ObsWebSocket _OBS;
2320

24-
private readonly ILogger _Logger;
25-
private readonly IConfiguration _Configuration;
26-
private readonly string _IpAddress;
21+
public class ObsClient : IDisposable {
22+
private bool _DisposedValue;
23+
private static OBSWebsocket _OBS;
2724

28-
public ObsClient(ILoggerFactory loggerFactory, IConfiguration configuration)
29-
{
30-
_Logger = loggerFactory.CreateLogger("ObsClient");
31-
_Configuration = configuration;
32-
_IpAddress = string.IsNullOrEmpty(configuration["ObsIpAddress"]) ? "127.0.0.1:4444" : configuration["ObsIpAddress"];
33-
}
34-
35-
/// <summary>
36-
/// Establish a connection to OBS
37-
/// </summary>
38-
/// <param name="port"></param>
39-
/// <returns></returns>
40-
public Task Connect()
41-
{
25+
private readonly ILogger _Logger;
26+
private readonly IConfiguration _Configuration;
27+
private readonly string _IpAddress;
28+
private readonly string _Password;
4229

43-
_OBS = new ObsWebSocket();
44-
_OBS.Connect($"ws://{_IpAddress}", "");
30+
public bool IsReady { get; set; } = false;
4531

46-
return Task.CompletedTask;
32+
public ObsClient(ILoggerFactory loggerFactory, IConfiguration configuration) {
33+
_Logger = loggerFactory.CreateLogger("ObsClient");
34+
_Configuration = configuration;
35+
_IpAddress = string.IsNullOrEmpty(configuration["ObsIpAddress"]) ? "127.0.0.1:4455" : configuration["ObsIpAddress"];
36+
_Password = configuration["ObsPassword"];
4737

38+
if (_OBS == null) {
39+
_OBS = new OBSWebsocket();
40+
_OBS.Connected += _OBS_Connected;
41+
_OBS.Disconnected += (s, e) => {
42+
OnDisconnect();
43+
};
4844
}
4945

50-
public string ImageFolderLocation => _Configuration["ImageFolder"];
46+
}
5147

52-
public string CameraSource => _Configuration["CameraSource"];
48+
/// <summary>
49+
/// Establish a connection to OBS
50+
/// </summary>
51+
/// <param name="port"></param>
52+
/// <returns></returns>
53+
public void Connect() {
5354

55+
Task.Run(() => _OBS.ConnectAsync($"ws://{_IpAddress}", _Password));
5456

55-
public string TakeScreenshot()
56-
{
57+
}
5758

58-
SourceScreenshotResponse response = null;
59-
if (string.IsNullOrEmpty(ImageFolderLocation))
60-
{
61-
response = _OBS.Api.TakeSourceScreenshot(CameraSource, embedPictureFormat: "png");
62-
var cleanString = response.ImageData.Replace("data:image/png;base64,", "");
63-
var bytes = Convert.FromBase64String(cleanString);
64-
_Logger.LogWarning($"Took screenshot from scene '{CameraSource}'");
65-
return ProcessImage(CameraSource, bytes);
66-
}
67-
else
68-
{
69-
70-
try
71-
{
72-
var imageFileName = ImageFolderLocation + "\\test.png";
73-
response = _OBS.Api.TakeSourceScreenshot(CameraSource, embedPictureFormat: "png");
74-
var cleanString = response.ImageData.Replace("data:image/png;base64,", "");
75-
var bytes = Convert.FromBase64String(cleanString);
76-
var outString = ProcessImage(CameraSource, bytes);
77-
_Logger.LogWarning($"${DateTime.Now} Took screenshot from scene '{CameraSource}'");
78-
return outString;
79-
80-
}
81-
catch (Exception e)
82-
{
83-
_Logger.LogError(e, "Error while taking screenshot");
84-
return null;
85-
}
59+
public static Action OnDisconnect { get; set; } = () => { };
8660

87-
}
61+
private void _OBS_Connected(object sender, EventArgs e) {
8862

89-
return response.ImageData;
63+
IsReady = true;
64+
var versionInfo = _OBS.GetVersion();
65+
Console.WriteLine($"Plugin Version: {versionInfo.PluginVersion}");
66+
}
9067

91-
}
68+
public string ImageFolderLocation => _Configuration["ImageFolder"];
9269

93-
private string ProcessImage(string cameraSource, byte[] imageBytes)
94-
{
70+
public string CameraSource => _Configuration["CameraSource"];
9571

96-
var outString = string.Empty;
9772

98-
using (var img = Image.Load(imageBytes)) {
73+
public string TakeScreenshot() {
9974

100-
// TODO: Crop appropriately for the camerasource
101-
var memStream = new MemoryStream();
102-
img.Clone(ctx => ctx.Crop(new Rectangle(450, 0, 900, 450))).SaveAsPng(memStream);
103-
memStream.Position = 0;
75+
Console.WriteLine($"IsConnected: {_OBS.IsConnected}");
10476

105-
outString = Convert.ToBase64String(memStream.ToArray());
106-
memStream.Dispose();
77+
try {
78+
var imageFileName = System.IO.Path.GetTempFileName();
79+
_OBS.SaveSourceScreenshot(CameraSource, "png", imageFileName);
10780

108-
}
81+
var outString = string.Empty;
82+
using (var tempFile = File.OpenRead(imageFileName)) {
83+
84+
outString = ProcessImage(CameraSource, tempFile);
10985

86+
}
87+
File.Delete(imageFileName);
88+
_Logger.LogWarning($"${DateTime.Now} Took screenshot from scene '{CameraSource}'");
11089
return outString;
11190

11291
}
92+
catch (Exception e) {
93+
_Logger.LogError(e, "Error while taking screenshot");
94+
return null;
95+
}
11396

97+
}
11498

115-
#region Dispose OBS Connection
99+
private string ProcessImage(string cameraSource, Stream image) {
116100

117-
protected virtual void Dispose(bool disposing)
118-
{
119-
if (!_DisposedValue)
120-
{
121-
if (disposing)
122-
{
123-
// TODO: dispose managed state (managed objects)
124-
}
101+
var outString = string.Empty;
125102

126-
_OBS.Disconnect();
127-
_OBS = null;
128-
_DisposedValue = true;
129-
}
130-
}
103+
using (var img = Image.Load(image)) {
104+
105+
// TODO: Crop appropriately for the camerasource
106+
var memStream = new MemoryStream();
107+
img.Clone(ctx => ctx.Crop(new Rectangle(450, 0, 900, 450))).SaveAsPng(memStream);
108+
memStream.Position = 0;
109+
110+
outString = Convert.ToBase64String(memStream.ToArray());
111+
memStream.Dispose();
131112

132-
~ObsClient()
133-
{
134-
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
135-
Dispose(disposing: false);
136113
}
137114

138-
public void Dispose()
139-
{
140-
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
141-
Dispose(disposing: true);
142-
GC.SuppressFinalize(this);
115+
return outString;
116+
117+
}
118+
119+
120+
#region Dispose OBS Connection
121+
122+
protected virtual void Dispose(bool disposing) {
123+
if (!_DisposedValue) {
124+
if (disposing) {
125+
// TODO: dispose managed state (managed objects)
126+
}
127+
128+
_OBS.Disconnect();
129+
_OBS = null;
130+
_DisposedValue = true;
143131
}
132+
}
144133

145-
#endregion
134+
~ObsClient() {
135+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
136+
Dispose(disposing: false);
137+
}
146138

139+
public void Dispose() {
140+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
141+
Dispose(disposing: true);
142+
GC.SuppressFinalize(this);
147143
}
148144

145+
#endregion
146+
147+
148+
149149
}

Fritz.ObsProxy/Program.cs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Threading.Tasks;
1+
using Fritz.ObsProxy;
52
using Microsoft.Extensions.DependencyInjection;
63
using Microsoft.Extensions.Hosting;
74

8-
namespace Fritz.ObsProxy
9-
{
10-
public class Program
11-
{
12-
public static void Main(string[] args)
13-
{
14-
CreateHostBuilder(args).Build().Run();
15-
}
16-
17-
public static IHostBuilder CreateHostBuilder(string[] args) =>
18-
Host.CreateDefaultBuilder(args)
19-
.ConfigureServices((hostContext, services) =>
20-
{
5+
var host = Host.CreateDefaultBuilder(args)
6+
.ConfigureServices((hostContext, services) => {
217
services.AddHostedService<Worker>();
228
services.AddSingleton<ObsClient>();
239
services.AddTransient<BotClient>();
2410
});
25-
}
26-
}
11+
12+
var runningHost = host.Build();
13+
14+
ObsClient.OnDisconnect = () => {
15+
runningHost.StopAsync();
16+
};
17+
18+
runningHost.Run();

Fritz.ObsProxy/Worker.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,17 @@ public Worker(ILogger<Worker> logger, ObsClient obsClient, BotClient botClient,
2828
public async Task StartAsync(CancellationToken cancellationToken)
2929
{
3030

31-
await _ObsClient.Connect();
31+
_ObsClient.Connect();
32+
33+
while (!_ObsClient.IsReady) {
34+
await Task.Delay(100);
35+
Console.WriteLine("Waiting to connect");
36+
}
3237

3338
if (string.IsNullOrEmpty(_Configuration["ObsTest"]) || !bool.Parse(_Configuration["ObsTest"]))
3439
{
3540
await _BotClient.Connect();
41+
3642
} else {
3743
var imgString = _ObsClient.TakeScreenshot();
3844
var bytes = Convert.FromBase64String(imgString);

Fritz.ObsProxy/appsettings.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
},
99
"ImageFolder": "C:\\dev\\stream\\Screenshots",
1010
"ImageFolderOrg": "C:\\dev\\stream\\Screenshots",
11-
"BotUrl": "http://localhost:62574/obshub",
12-
"ObsIpAddress": "127.0.0.1:4444",
13-
"CameraSource": "Razer Kiyo",
11+
"BotUrl": "http://localhost:8000/obshub",
12+
"ObsIpAddress": "127.0.0.1:4455",
13+
"ObsPassword": "Bthu4hq3Ki0NBflq",
14+
"CameraSource": "Local Sony",
1415
"ObsTest": "false"
1516
}

Fritz.StreamTools.sln

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.28527.54
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.6.33417.168
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{520B1405-AC30-493A-8F04-6AA9B8FE2CDD}"
77
EndProject
@@ -32,7 +32,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fritz.Twitch", "Fritz.Twitc
3232
EndProject
3333
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleChatbot", "ConsoleChatbot\ConsoleChatbot.csproj", "{A9F1860F-163B-44AC-A935-C1B584D3CB8A}"
3434
EndProject
35-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fritz.ObsProxy", "Fritz.ObsProxy\Fritz.ObsProxy.csproj", "{4BD07D64-570D-4E12-BA8F-F908B2482E6A}"
35+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fritz.ObsProxy", "Fritz.ObsProxy\Fritz.ObsProxy.csproj", "{4BD07D64-570D-4E12-BA8F-F908B2482E6A}"
3636
EndProject
3737
Global
3838
GlobalSection(SolutionConfigurationPlatforms) = preSolution

0 commit comments

Comments
 (0)