forked from shanselman/PowerPointToOBSSceneSwitcher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OBS.cs
107 lines (88 loc) · 3.73 KB
/
OBS.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
namespace SceneSwitcher {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using OBSWebsocketDotNet;
/// <summary>
/// Main program class.
/// </summary>
public partial class OBS(Config config) : IDisposable {
private readonly Config config = config;
private OBSWebsocket websocket;
private List<string> scenes;
private Dictionary<string, HashSet<string>> sceneSources;
private bool disposedValue;
~OBS() {
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: false);
}
public event EventHandler<string> SceneChanged;
public void Connect() {
websocket = new OBSWebsocket();
websocket.Connected += OnConnect;
websocket.CurrentProgramSceneChanged += (_, args) => SceneChanged?.Invoke(this, args.SceneName);
WebSocketConfig wsc = config.WebSocketConfig;
string url = $"ws://{wsc.Host}:{wsc.Port}";
try {
websocket.ConnectAsync(url, wsc.Password);
} catch (Exception) {
ExitOnConnectError();
}
// No exception appears to be thrown on failed connections. Workaround by
// timing out if not connected after some amount of time.
Task.Run(async () => {
await Task.Delay(10000);
if (!websocket.IsConnected) {
ExitOnConnectError();
}
});
}
public bool HasScene(string scene) {
return scenes.Contains(scene);
}
public void ChangeScene(string scene) {
websocket.SetCurrentProgramScene(scene);
}
public void SetAudioSources(List<string> sources) {
config.VariableAudioSources.ForEach(source => websocket.SetInputMute(source, !sources.Contains(PrefixedNumberRegex().Replace(source, string.Empty))));
}
public ISet<string> GetSceneSources(string scene) {
return sceneSources[scene];
}
public void Dispose() {
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
websocket.Disconnect();
websocket = null;
disposedValue = true;
}
}
[GeneratedRegex(@"^\d+\.\s*")]
private static partial Regex PrefixedNumberRegex();
private static void ExitOnConnectError() {
Console.Error.WriteLine($"\nFailed to connect to OBS Studio. Check it has been started, it can be reached via the network, and the WebSocketConfig has been correctly configured.\nPress any key to exit.");
Console.ReadKey();
Environment.Exit(1);
}
private void OnConnect(object sender, EventArgs args) {
LoadScenes();
Console.WriteLine("\nValid scenes:");
scenes.ForEach(scene => Console.WriteLine($" {scene}"));
Console.WriteLine();
Console.WriteLine($"Current OBS scene is \"{websocket.GetCurrentProgramScene()}\"");
}
private void LoadScenes() {
var scenes = websocket.GetSceneList().Scenes;
this.scenes = new List<string>(scenes.Select(s => s.Name).ToList());
sceneSources = scenes.ToDictionary(
s => s.Name,
s => websocket.GetSceneItemList(s.Name).Select(s => s.SourceName).ToHashSet());
}
}
}