Skip to content

Commit

Permalink
Merge branch 'master' into feature/add-readonly-collections-to-events…
Browse files Browse the repository at this point in the history
…-#99
  • Loading branch information
grofit authored Aug 29, 2024
2 parents 6cefd6b + b8ae595 commit 7d831fc
Show file tree
Hide file tree
Showing 61 changed files with 1,901 additions and 154 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ This library is available on the [NuGet gallery](https://www.nuget.org/packages/
See the `TestClient` project for a working example.

# v5 Updates
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)
NOTE: As OBS Websocket v5.0 is not backward compatible with 4.9.x, neither is the .Net version.
**What's new in v5.0.0.3:**
* Fixed issue with integer overflow for OutputStatus objects
(Older updates):
* Each event now has a dedicated EventArgs class. This will break the previous event signature
* Finished adding all v5 methods
* `Connect()` function is now obsolete, use `ConnectAsync()` instead.
* Additional bugfixes and stability fixes

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)

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

## EOL for v4.x branch
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.
NOTE: We will no longer be updating the v4.x branch as we move towards v5.0 (which is NOT backwards compatible).
2 changes: 1 addition & 1 deletion TestClient/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ private void btnConnect_Click(object sender, EventArgs e)
{
try
{
obs.Connect(txtServerIP.Text, txtServerPassword.Text);
obs.ConnectAsync(txtServerIP.Text, txtServerPassword.Text);
}
catch (Exception ex)
{
Expand Down
1,357 changes: 1,357 additions & 0 deletions obs-websocket-dotnet/IOBSWebsocket.cs

Large diffs are not rendered by default.

64 changes: 37 additions & 27 deletions obs-websocket-dotnet/OBSWebsocket.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net.WebSockets;
using Websocket.Client;
using OBSWebsocketDotNet.Communication;

namespace OBSWebsocketDotNet
{
public partial class OBSWebsocket
public partial class OBSWebsocket : IOBSWebsocket
{
#region Private Members
private const string WEBSOCKET_URL_PREFIX = "ws://";
private const int SUPPORTED_RPC_VERSION = 1;
private TimeSpan wsTimeout = TimeSpan.FromSeconds(10);
private string connectionPassword = null;
private WebsocketClient wsConnection;

private delegate void RequestCallback(OBSWebsocket sender, JObject body);
private readonly ConcurrentDictionary<string, TaskCompletionSource<JObject>> responseHandlers;

// Random should never be created inside a function
private static readonly Random random = new Random();

#endregion

/// <summary>
/// WebSocket request timeout, represented as a TimeSpan object
/// </summary>
Expand All @@ -34,18 +47,7 @@ public TimeSpan WSTimeout
}
}
}

#region Private Members
private const string WEBSOCKET_URL_PREFIX = "ws://";
private const int SUPPORTED_RPC_VERSION = 1;
private TimeSpan wsTimeout = TimeSpan.FromSeconds(10);
private string connectionPassword = null;

// Random should never be created inside a function
private static readonly Random random = new Random();

#endregion


/// <summary>
/// Current connection state
/// </summary>
Expand All @@ -57,14 +59,6 @@ public bool IsConnected
}
}

/// <summary>
/// Underlying WebSocket connection to an obs-websocket server. Value is null when disconnected.
/// </summary>
public WebsocketClient wsConnection { get; private set; }

private delegate void RequestCallback(OBSWebsocket sender, JObject body);
private readonly ConcurrentDictionary<string, TaskCompletionSource<JObject>> responseHandlers;

/// <summary>
/// Constructor
/// </summary>
Expand All @@ -74,11 +68,24 @@ public OBSWebsocket()
}

/// <summary>
/// Connect this instance to the specified URL, and authenticate (if needed) with the specified password
/// Connect this instance to the specified URL, and authenticate (if needed) with the specified password.
/// NOTE: Please subscribe to the Connected/Disconnected events (or atleast check the IsConnected property) to determine when the connection is actually fully established
/// </summary>
/// <param name="url">Server URL in standard URL format.</param>
/// <param name="password">Server password</param>
[Obsolete("Please use ConnectAsync, this function will be removed in the next version")]
public void Connect(string url, string password)
{
ConnectAsync(url, password);
}

/// <summary>
/// Connect this instance to the specified URL, and authenticate (if needed) with the specified password.
/// NOTE: Please subscribe to the Connected/Disconnected events (or atleast check the IsConnected property) to determine when the connection is actually fully established
/// </summary>
/// <param name="url">Server URL in standard URL format.</param>
/// <param name="password">Server password</param>
public void ConnectAsync(string url, string password)
{
if (!url.ToLower().StartsWith(WEBSOCKET_URL_PREFIX))
{
Expand All @@ -91,8 +98,11 @@ public void Connect(string url, string password)
}

wsConnection = new WebsocketClient(new Uri(url));
wsConnection.MessageReceived.Subscribe(m => WebsocketMessageHandler(this, m));
wsConnection.DisconnectionHappened.Subscribe(d => OnWebsocketDisconnect(this, d));
wsConnection.IsReconnectionEnabled = false;
wsConnection.ReconnectTimeout = null;
wsConnection.ErrorReconnectTimeout = null;
wsConnection.MessageReceived.Subscribe(m => Task.Run(() => WebsocketMessageHandler(this, m)));
wsConnection.DisconnectionHappened.Subscribe(d => Task.Run(() => OnWebsocketDisconnect(this, d)));

connectionPassword = password;
wsConnection.StartOrFail();
Expand Down Expand Up @@ -157,7 +167,7 @@ private void WebsocketMessageHandler(object sender, ResponseMessage e)
HandleHello(body);
break;
case MessageTypes.Identified:
Connected?.Invoke(this, EventArgs.Empty);
Task.Run(() => Connected?.Invoke(this, EventArgs.Empty));
break;
case MessageTypes.RequestResponse:
case MessageTypes.RequestBatchResponse:
Expand Down
43 changes: 39 additions & 4 deletions obs-websocket-dotnet/OBSWebsocket_Requests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
using OBSWebsocketDotNet.Types;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.NetworkInformation;

namespace OBSWebsocketDotNet
{
Expand All @@ -17,10 +17,8 @@ public partial class OBSWebsocket

private const string REQUEST_FIELD_VOLUME_DB = "inputVolumeDb";
private const string REQUEST_FIELD_VOLUME_MUL = "inputVolumeMul";

private const string RESPONSE_FIELD_IMAGE_DATA = "imageData";


#endregion

/// <summary>
Expand Down Expand Up @@ -2114,8 +2112,45 @@ public List<Monitor> GetMonitorList()
{
monitors.Add(new Monitor((JObject)monitor));
}

return monitors;
}

/// <summary>
/// Opens a projector for a source.
/// Note: This request serves to provide feature parity with 4.x. It is very likely to be changed/deprecated in a future release.
/// </summary>
/// <param name="sourceName">Name of the source to open a projector for</param>
/// <param name="projectorGeometry">Size/Position data for a windowed projector, in Qt Base64 encoded format. Mutually exclusive with monitorIndex</param>
/// <param name="monitorIndex">Monitor index, use GetMonitorList to obtain index. -1 to open in windowed mode</param>
public void OpenSourceProjector(string sourceName, string projectorGeometry, int monitorIndex = -1)
{
var request = new JObject
{
{ nameof(sourceName), sourceName },
{ nameof(projectorGeometry), projectorGeometry },
{ nameof(monitorIndex), monitorIndex },
};

SendRequest(nameof(OpenSourceProjector), request);
}

/// <summary>
/// Opens a projector for a specific output video mix.
/// Note: This request serves to provide feature parity with 4.x. It is very likely to be changed/deprecated in a future release.
/// </summary>
/// <param name="videoMixType">Mix types: OBS_WEBSOCKET_VIDEO_MIX_TYPE_PREVIEW, OBS_WEBSOCKET_VIDEO_MIX_TYPE_PROGRAM, OBS_WEBSOCKET_VIDEO_MIX_TYPE_MULTIVIEW</param>
/// <param name="projectorGeometry">Size/Position data for a windowed projector, in Qt Base64 encoded format. Mutually exclusive with monitorIndex</param>
/// <param name="monitorIndex">Monitor index, use GetMonitorList to obtain index. -1 to open in windowed mode</param>
public void OpenVideoMixProjector(string videoMixType, string projectorGeometry, int monitorIndex = -1)
{
var request = new JObject
{
{ nameof(videoMixType), videoMixType },
{ nameof(projectorGeometry), projectorGeometry },
{ nameof(monitorIndex), monitorIndex },
};

SendRequest(nameof(OpenVideoMixProjector), request);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
namespace OBSWebsocketDotNet.Types.Events
using System;

namespace OBSWebsocketDotNet.Types.Events
{
/// <summary>
/// Event args for <see cref="OBSWebsocket.CurrentPreviewSceneChanged"/>
/// </summary>
public class CurrentPreviewSceneChangedEventArgs
public class CurrentPreviewSceneChangedEventArgs : EventArgs
{
/// <summary>
/// Name of the scene that was switched to
/// </summary>
public string SceneName { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="sceneName">The scene name</param>
public CurrentPreviewSceneChangedEventArgs(string sceneName)
{
SceneName = sceneName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
namespace OBSWebsocketDotNet.Types.Events
using System;

namespace OBSWebsocketDotNet.Types.Events
{
/// <summary>
/// Event args for <see cref="OBSWebsocket.CurrentProfileChanged"/>
/// </summary>
public class CurrentProfileChangedEventArgs
public class CurrentProfileChangedEventArgs : EventArgs
{
/// <summary>
/// Name of the new profile
/// </summary>
public string ProfileName { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="profileName">The profile name</param>
public CurrentProfileChangedEventArgs(string profileName)
{
ProfileName = profileName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
namespace OBSWebsocketDotNet.Types.Events
using System;

namespace OBSWebsocketDotNet.Types.Events
{
/// <summary>
/// Event args for <see cref="OBSWebsocket.CurrentProfileChanging"/>
/// </summary>
public class CurrentProfileChangingEventArgs
public class CurrentProfileChangingEventArgs : EventArgs
{
/// <summary>
/// Name of the current profile
/// </summary>
public string ProfileName { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="profileName">The profile name</param>
public CurrentProfileChangingEventArgs(string profileName)
{
ProfileName = profileName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
namespace OBSWebsocketDotNet.Types.Events
using System;

namespace OBSWebsocketDotNet.Types.Events
{
/// <summary>
/// Event args for <see cref="OBSWebsocket.CurrentSceneCollectionChanged"/>
/// </summary>
public class CurrentSceneCollectionChangedEventArgs
public class CurrentSceneCollectionChangedEventArgs : EventArgs
{
/// <summary>
/// Name of the new scene collection
/// </summary>
public string SceneCollectionName { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="sceneCollectionName">The scene collection name</param>
public CurrentSceneCollectionChangedEventArgs(string sceneCollectionName)
{
SceneCollectionName = sceneCollectionName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
namespace OBSWebsocketDotNet.Types.Events
using System;

namespace OBSWebsocketDotNet.Types.Events
{
/// <summary>
/// Event args for <see cref="OBSWebsocket.CurrentSceneCollectionChanging"/>
/// </summary>
public class CurrentSceneCollectionChangingEventArgs
public class CurrentSceneCollectionChangingEventArgs : EventArgs
{
/// <summary>
/// Name of the current scene collection
/// </summary>
public string SceneCollectionName { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="sceneCollectionName">The scene collection name</param>
public CurrentSceneCollectionChangingEventArgs(string sceneCollectionName)
{
SceneCollectionName = sceneCollectionName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
namespace OBSWebsocketDotNet.Types.Events
using System;

namespace OBSWebsocketDotNet.Types.Events
{
/// <summary>
/// Event args for <see cref="OBSWebsocket.CurrentSceneTransitionChanged"/>
/// </summary>
public class CurrentSceneTransitionChangedEventArgs
public class CurrentSceneTransitionChangedEventArgs : EventArgs
{
/// <summary>
/// Name of the new transition
/// </summary>
public string TransitionName { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="transitionName">The transition name</param>
public CurrentSceneTransitionChangedEventArgs(string transitionName)
{
TransitionName = transitionName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
namespace OBSWebsocketDotNet.Types.Events
using System;

namespace OBSWebsocketDotNet.Types.Events
{
/// <summary>
/// Event args for <see cref="OBSWebsocket.CurrentSceneTransitionDurationChanged"/>
/// </summary>
public class CurrentSceneTransitionDurationChangedEventArgs
public class CurrentSceneTransitionDurationChangedEventArgs : EventArgs
{
/// <summary>
/// Transition duration in milliseconds
/// </summary>
public int TransitionDuration { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="transitionDuration">The transition duration</param>
public CurrentSceneTransitionDurationChangedEventArgs(int transitionDuration)
{
TransitionDuration = transitionDuration;
Expand Down
Loading

0 comments on commit 7d831fc

Please sign in to comment.