Skip to content

Commit 7d831fc

Browse files
authored
Merge branch 'master' into feature/add-readonly-collections-to-events-#99
2 parents 6cefd6b + b8ae595 commit 7d831fc

File tree

61 files changed

+1901
-154
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1901
-154
lines changed

README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,19 @@ This library is available on the [NuGet gallery](https://www.nuget.org/packages/
77
See the `TestClient` project for a working example.
88

99
# v5 Updates
10-
Initial version supporting OBS Websocket v5 is now in master branch and an nuget version is in Beta (must select "Include Prerelease" in nuget). Please report issues/bugs via the [Issues Tracker](https://github.com/BarRaider/obs-websocket-dotnet/issues) or discuss in our [Discord](http://discord.barraider.com)
10+
NOTE: As OBS Websocket v5.0 is not backward compatible with 4.9.x, neither is the .Net version.
11+
**What's new in v5.0.0.3:**
12+
* Fixed issue with integer overflow for OutputStatus objects
13+
(Older updates):
14+
* Each event now has a dedicated EventArgs class. This will break the previous event signature
15+
* Finished adding all v5 methods
16+
* `Connect()` function is now obsolete, use `ConnectAsync()` instead.
17+
* Additional bugfixes and stability fixes
18+
19+
Please report issues/bugs via the [Issues Tracker](https://github.com/BarRaider/obs-websocket-dotnet/issues) or discuss in our [Discord](http://discord.barraider.com)
1120

1221
## Dev Discussions
1322
**Discord:** Discuss in #developers-chat in [Bar Raiders](http://discord.barraider.com)
1423

1524
## EOL for v4.x branch
16-
NOTE: We will no longer be updating the v4.x branch as we move towards v5.0 (which is NOT backwards compatible). Any PRs should be done on the `v5-dev` branch.
25+
NOTE: We will no longer be updating the v4.x branch as we move towards v5.0 (which is NOT backwards compatible).

TestClient/MainWindow.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ private void btnConnect_Click(object sender, EventArgs e)
309309
{
310310
try
311311
{
312-
obs.Connect(txtServerIP.Text, txtServerPassword.Text);
312+
obs.ConnectAsync(txtServerIP.Text, txtServerPassword.Text);
313313
}
314314
catch (Exception ex)
315315
{

obs-websocket-dotnet/IOBSWebsocket.cs

+1,357
Large diffs are not rendered by default.

obs-websocket-dotnet/OBSWebsocket.cs

+37-27
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Security.Cryptography;
43
using System.Text;
54
using Newtonsoft.Json.Linq;
65
using System.Threading.Tasks;
76
using Newtonsoft.Json;
87
using System.Collections.Concurrent;
9-
using System.Diagnostics;
108
using System.Net.WebSockets;
119
using Websocket.Client;
1210
using OBSWebsocketDotNet.Communication;
1311

1412
namespace OBSWebsocketDotNet
1513
{
16-
public partial class OBSWebsocket
14+
public partial class OBSWebsocket : IOBSWebsocket
1715
{
16+
#region Private Members
17+
private const string WEBSOCKET_URL_PREFIX = "ws://";
18+
private const int SUPPORTED_RPC_VERSION = 1;
19+
private TimeSpan wsTimeout = TimeSpan.FromSeconds(10);
20+
private string connectionPassword = null;
21+
private WebsocketClient wsConnection;
22+
23+
private delegate void RequestCallback(OBSWebsocket sender, JObject body);
24+
private readonly ConcurrentDictionary<string, TaskCompletionSource<JObject>> responseHandlers;
25+
26+
// Random should never be created inside a function
27+
private static readonly Random random = new Random();
28+
29+
#endregion
30+
1831
/// <summary>
1932
/// WebSocket request timeout, represented as a TimeSpan object
2033
/// </summary>
@@ -34,18 +47,7 @@ public TimeSpan WSTimeout
3447
}
3548
}
3649
}
37-
38-
#region Private Members
39-
private const string WEBSOCKET_URL_PREFIX = "ws://";
40-
private const int SUPPORTED_RPC_VERSION = 1;
41-
private TimeSpan wsTimeout = TimeSpan.FromSeconds(10);
42-
private string connectionPassword = null;
43-
44-
// Random should never be created inside a function
45-
private static readonly Random random = new Random();
46-
47-
#endregion
48-
50+
4951
/// <summary>
5052
/// Current connection state
5153
/// </summary>
@@ -57,14 +59,6 @@ public bool IsConnected
5759
}
5860
}
5961

60-
/// <summary>
61-
/// Underlying WebSocket connection to an obs-websocket server. Value is null when disconnected.
62-
/// </summary>
63-
public WebsocketClient wsConnection { get; private set; }
64-
65-
private delegate void RequestCallback(OBSWebsocket sender, JObject body);
66-
private readonly ConcurrentDictionary<string, TaskCompletionSource<JObject>> responseHandlers;
67-
6862
/// <summary>
6963
/// Constructor
7064
/// </summary>
@@ -74,11 +68,24 @@ public OBSWebsocket()
7468
}
7569

7670
/// <summary>
77-
/// Connect this instance to the specified URL, and authenticate (if needed) with the specified password
71+
/// Connect this instance to the specified URL, and authenticate (if needed) with the specified password.
72+
/// NOTE: Please subscribe to the Connected/Disconnected events (or atleast check the IsConnected property) to determine when the connection is actually fully established
7873
/// </summary>
7974
/// <param name="url">Server URL in standard URL format.</param>
8075
/// <param name="password">Server password</param>
76+
[Obsolete("Please use ConnectAsync, this function will be removed in the next version")]
8177
public void Connect(string url, string password)
78+
{
79+
ConnectAsync(url, password);
80+
}
81+
82+
/// <summary>
83+
/// Connect this instance to the specified URL, and authenticate (if needed) with the specified password.
84+
/// NOTE: Please subscribe to the Connected/Disconnected events (or atleast check the IsConnected property) to determine when the connection is actually fully established
85+
/// </summary>
86+
/// <param name="url">Server URL in standard URL format.</param>
87+
/// <param name="password">Server password</param>
88+
public void ConnectAsync(string url, string password)
8289
{
8390
if (!url.ToLower().StartsWith(WEBSOCKET_URL_PREFIX))
8491
{
@@ -91,8 +98,11 @@ public void Connect(string url, string password)
9198
}
9299

93100
wsConnection = new WebsocketClient(new Uri(url));
94-
wsConnection.MessageReceived.Subscribe(m => WebsocketMessageHandler(this, m));
95-
wsConnection.DisconnectionHappened.Subscribe(d => OnWebsocketDisconnect(this, d));
101+
wsConnection.IsReconnectionEnabled = false;
102+
wsConnection.ReconnectTimeout = null;
103+
wsConnection.ErrorReconnectTimeout = null;
104+
wsConnection.MessageReceived.Subscribe(m => Task.Run(() => WebsocketMessageHandler(this, m)));
105+
wsConnection.DisconnectionHappened.Subscribe(d => Task.Run(() => OnWebsocketDisconnect(this, d)));
96106

97107
connectionPassword = password;
98108
wsConnection.StartOrFail();
@@ -157,7 +167,7 @@ private void WebsocketMessageHandler(object sender, ResponseMessage e)
157167
HandleHello(body);
158168
break;
159169
case MessageTypes.Identified:
160-
Connected?.Invoke(this, EventArgs.Empty);
170+
Task.Run(() => Connected?.Invoke(this, EventArgs.Empty));
161171
break;
162172
case MessageTypes.RequestResponse:
163173
case MessageTypes.RequestBatchResponse:

obs-websocket-dotnet/OBSWebsocket_Requests.cs

+39-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
using OBSWebsocketDotNet.Types;
44
using System;
55
using System.Collections.Generic;
6-
using System.ComponentModel;
76
using System.Linq;
7+
using System.Net.NetworkInformation;
88

99
namespace OBSWebsocketDotNet
1010
{
@@ -17,10 +17,8 @@ public partial class OBSWebsocket
1717

1818
private const string REQUEST_FIELD_VOLUME_DB = "inputVolumeDb";
1919
private const string REQUEST_FIELD_VOLUME_MUL = "inputVolumeMul";
20-
2120
private const string RESPONSE_FIELD_IMAGE_DATA = "imageData";
2221

23-
2422
#endregion
2523

2624
/// <summary>
@@ -2114,8 +2112,45 @@ public List<Monitor> GetMonitorList()
21142112
{
21152113
monitors.Add(new Monitor((JObject)monitor));
21162114
}
2117-
21182115
return monitors;
21192116
}
2117+
2118+
/// <summary>
2119+
/// Opens a projector for a source.
2120+
/// Note: This request serves to provide feature parity with 4.x. It is very likely to be changed/deprecated in a future release.
2121+
/// </summary>
2122+
/// <param name="sourceName">Name of the source to open a projector for</param>
2123+
/// <param name="projectorGeometry">Size/Position data for a windowed projector, in Qt Base64 encoded format. Mutually exclusive with monitorIndex</param>
2124+
/// <param name="monitorIndex">Monitor index, use GetMonitorList to obtain index. -1 to open in windowed mode</param>
2125+
public void OpenSourceProjector(string sourceName, string projectorGeometry, int monitorIndex = -1)
2126+
{
2127+
var request = new JObject
2128+
{
2129+
{ nameof(sourceName), sourceName },
2130+
{ nameof(projectorGeometry), projectorGeometry },
2131+
{ nameof(monitorIndex), monitorIndex },
2132+
};
2133+
2134+
SendRequest(nameof(OpenSourceProjector), request);
2135+
}
2136+
2137+
/// <summary>
2138+
/// Opens a projector for a specific output video mix.
2139+
/// Note: This request serves to provide feature parity with 4.x. It is very likely to be changed/deprecated in a future release.
2140+
/// </summary>
2141+
/// <param name="videoMixType">Mix types: OBS_WEBSOCKET_VIDEO_MIX_TYPE_PREVIEW, OBS_WEBSOCKET_VIDEO_MIX_TYPE_PROGRAM, OBS_WEBSOCKET_VIDEO_MIX_TYPE_MULTIVIEW</param>
2142+
/// <param name="projectorGeometry">Size/Position data for a windowed projector, in Qt Base64 encoded format. Mutually exclusive with monitorIndex</param>
2143+
/// <param name="monitorIndex">Monitor index, use GetMonitorList to obtain index. -1 to open in windowed mode</param>
2144+
public void OpenVideoMixProjector(string videoMixType, string projectorGeometry, int monitorIndex = -1)
2145+
{
2146+
var request = new JObject
2147+
{
2148+
{ nameof(videoMixType), videoMixType },
2149+
{ nameof(projectorGeometry), projectorGeometry },
2150+
{ nameof(monitorIndex), monitorIndex },
2151+
};
2152+
2153+
SendRequest(nameof(OpenVideoMixProjector), request);
2154+
}
21202155
}
21212156
}

obs-websocket-dotnet/Types/Events/CurrentPreviewSceneChangedEventArgs.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
namespace OBSWebsocketDotNet.Types.Events
1+
using System;
2+
3+
namespace OBSWebsocketDotNet.Types.Events
24
{
35
/// <summary>
46
/// Event args for <see cref="OBSWebsocket.CurrentPreviewSceneChanged"/>
57
/// </summary>
6-
public class CurrentPreviewSceneChangedEventArgs
8+
public class CurrentPreviewSceneChangedEventArgs : EventArgs
79
{
810
/// <summary>
911
/// Name of the scene that was switched to
1012
/// </summary>
1113
public string SceneName { get; }
1214

15+
/// <summary>
16+
/// Default Constructor
17+
/// </summary>
18+
/// <param name="sceneName">The scene name</param>
1319
public CurrentPreviewSceneChangedEventArgs(string sceneName)
1420
{
1521
SceneName = sceneName;

obs-websocket-dotnet/Types/Events/CurrentProfileChangedEventArgs.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
namespace OBSWebsocketDotNet.Types.Events
1+
using System;
2+
3+
namespace OBSWebsocketDotNet.Types.Events
24
{
35
/// <summary>
46
/// Event args for <see cref="OBSWebsocket.CurrentProfileChanged"/>
57
/// </summary>
6-
public class CurrentProfileChangedEventArgs
8+
public class CurrentProfileChangedEventArgs : EventArgs
79
{
810
/// <summary>
911
/// Name of the new profile
1012
/// </summary>
1113
public string ProfileName { get; }
1214

15+
/// <summary>
16+
/// Default Constructor
17+
/// </summary>
18+
/// <param name="profileName">The profile name</param>
1319
public CurrentProfileChangedEventArgs(string profileName)
1420
{
1521
ProfileName = profileName;

obs-websocket-dotnet/Types/Events/CurrentProfileChangingEventArgs.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
namespace OBSWebsocketDotNet.Types.Events
1+
using System;
2+
3+
namespace OBSWebsocketDotNet.Types.Events
24
{
35
/// <summary>
46
/// Event args for <see cref="OBSWebsocket.CurrentProfileChanging"/>
57
/// </summary>
6-
public class CurrentProfileChangingEventArgs
8+
public class CurrentProfileChangingEventArgs : EventArgs
79
{
810
/// <summary>
911
/// Name of the current profile
1012
/// </summary>
1113
public string ProfileName { get; }
1214

15+
/// <summary>
16+
/// Default Constructor
17+
/// </summary>
18+
/// <param name="profileName">The profile name</param>
1319
public CurrentProfileChangingEventArgs(string profileName)
1420
{
1521
ProfileName = profileName;

obs-websocket-dotnet/Types/Events/CurrentSceneCollectionChangedEventArgs.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
namespace OBSWebsocketDotNet.Types.Events
1+
using System;
2+
3+
namespace OBSWebsocketDotNet.Types.Events
24
{
35
/// <summary>
46
/// Event args for <see cref="OBSWebsocket.CurrentSceneCollectionChanged"/>
57
/// </summary>
6-
public class CurrentSceneCollectionChangedEventArgs
8+
public class CurrentSceneCollectionChangedEventArgs : EventArgs
79
{
810
/// <summary>
911
/// Name of the new scene collection
1012
/// </summary>
1113
public string SceneCollectionName { get; }
1214

15+
/// <summary>
16+
/// Default Constructor
17+
/// </summary>
18+
/// <param name="sceneCollectionName">The scene collection name</param>
1319
public CurrentSceneCollectionChangedEventArgs(string sceneCollectionName)
1420
{
1521
SceneCollectionName = sceneCollectionName;

obs-websocket-dotnet/Types/Events/CurrentSceneCollectionChangingEventArgs.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
namespace OBSWebsocketDotNet.Types.Events
1+
using System;
2+
3+
namespace OBSWebsocketDotNet.Types.Events
24
{
35
/// <summary>
46
/// Event args for <see cref="OBSWebsocket.CurrentSceneCollectionChanging"/>
57
/// </summary>
6-
public class CurrentSceneCollectionChangingEventArgs
8+
public class CurrentSceneCollectionChangingEventArgs : EventArgs
79
{
810
/// <summary>
911
/// Name of the current scene collection
1012
/// </summary>
1113
public string SceneCollectionName { get; }
1214

15+
/// <summary>
16+
/// Default Constructor
17+
/// </summary>
18+
/// <param name="sceneCollectionName">The scene collection name</param>
1319
public CurrentSceneCollectionChangingEventArgs(string sceneCollectionName)
1420
{
1521
SceneCollectionName = sceneCollectionName;

obs-websocket-dotnet/Types/Events/CurrentSceneTransitionChangedEventArgs.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
namespace OBSWebsocketDotNet.Types.Events
1+
using System;
2+
3+
namespace OBSWebsocketDotNet.Types.Events
24
{
35
/// <summary>
46
/// Event args for <see cref="OBSWebsocket.CurrentSceneTransitionChanged"/>
57
/// </summary>
6-
public class CurrentSceneTransitionChangedEventArgs
8+
public class CurrentSceneTransitionChangedEventArgs : EventArgs
79
{
810
/// <summary>
911
/// Name of the new transition
1012
/// </summary>
1113
public string TransitionName { get; }
1214

15+
/// <summary>
16+
/// Default Constructor
17+
/// </summary>
18+
/// <param name="transitionName">The transition name</param>
1319
public CurrentSceneTransitionChangedEventArgs(string transitionName)
1420
{
1521
TransitionName = transitionName;

obs-websocket-dotnet/Types/Events/CurrentSceneTransitionDurationChangedEventArgs.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
namespace OBSWebsocketDotNet.Types.Events
1+
using System;
2+
3+
namespace OBSWebsocketDotNet.Types.Events
24
{
35
/// <summary>
46
/// Event args for <see cref="OBSWebsocket.CurrentSceneTransitionDurationChanged"/>
57
/// </summary>
6-
public class CurrentSceneTransitionDurationChangedEventArgs
8+
public class CurrentSceneTransitionDurationChangedEventArgs : EventArgs
79
{
810
/// <summary>
911
/// Transition duration in milliseconds
1012
/// </summary>
1113
public int TransitionDuration { get; }
1214

15+
/// <summary>
16+
/// Default Constructor
17+
/// </summary>
18+
/// <param name="transitionDuration">The transition duration</param>
1319
public CurrentSceneTransitionDurationChangedEventArgs(int transitionDuration)
1420
{
1521
TransitionDuration = transitionDuration;

0 commit comments

Comments
 (0)