Skip to content

Commit

Permalink
Refix again :sad:
Browse files Browse the repository at this point in the history
  • Loading branch information
dedmen committed Oct 1, 2022
1 parent 8f11569 commit dedfcdc
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 6 deletions.
79 changes: 77 additions & 2 deletions obs-websocket-dotnet/Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using System.Collections.Generic;
using System.Diagnostics;
using OBSWebsocketDotNet.Types.Events;
using System.Data.Common;
using System.Net.WebSockets;
using Websocket.Client;

namespace OBSWebsocketDotNet
{
Expand Down Expand Up @@ -265,10 +268,31 @@ public partial class OBSWebsocket
/// </summary>
public event EventHandler<InputAudioMonitorTypeChangedEventArgs> InputAudioMonitorTypeChanged;


private event EventHandler<InputVolumeMetersEventArgs> inputVolumeMeters;
/// <summary>
/// A high-volume event providing volume levels of all active inputs every 50 milliseconds.
/// </summary>
public event EventHandler<InputVolumeMetersEventArgs> InputVolumeMeters;
public event EventHandler<InputVolumeMetersEventArgs> InputVolumeMeters
{
// This event needs special subscription, handle that here
add
{
if (inputVolumeMeters == null || inputVolumeMeters.GetInvocationList().Length == 0)
{
RegisterEvent(EventSubscription.InputVolumeMeters);
}
inputVolumeMeters += value;
}
remove
{
inputVolumeMeters -= value;
if (inputVolumeMeters == null || inputVolumeMeters.GetInvocationList().Length == 0)
{
UnRegisterEvent(EventSubscription.InputVolumeMeters);
}
}
}

/// <summary>
/// The replay buffer has been saved.
Expand All @@ -292,6 +316,57 @@ public partial class OBSWebsocket

#endregion


#region EventSubscription

private EventSubscription registeredEvents = EventSubscription.All;

private void RegisterEvent(EventSubscription newSubscription)
{
registeredEvents |= newSubscription;
SendReidentify();
}

private void UnRegisterEvent(EventSubscription removeSubscription)
{
registeredEvents &= ~removeSubscription;
SendReidentify();
}

/// <summary>
/// Send a Reidentify with new event subscriptions
/// </summary>
/// <returns>true if we sent the reidentify, false if failed</returns>
protected bool SendReidentify()
{
if (wsConnection == null || !wsConnection.IsStarted) return false; // #TODO check if we are in Identified/Connected state, if we didn't send our Identify yet, we shouldn't send Reidentify now

var requestFields = new JObject
{
{ "eventSubscriptions", (uint)registeredEvents }
};

try
{
// Throws ErrorResponseException if auth fails
SendRequest(MessageTypes.ReIdentify, null, requestFields, false);
}
catch (ErrorResponseException ex)
{
Disconnected?.Invoke(this, new ObsDisconnectionInfo(
ObsCloseCodes.UnknownReason,
"Reidentify Failed",
new DisconnectionInfo(DisconnectionType.Error, WebSocketCloseStatus.ProtocolError, "Reidentify Failed", String.Empty, new AuthFailureException())
));
Disconnect();
return false;
}

return true;
}

#endregion

#region EventProcessing

/// <summary>
Expand Down Expand Up @@ -500,7 +575,7 @@ protected void ProcessEventType(string eventType, JObject body)
break;

case nameof(InputVolumeMeters):
InputVolumeMeters?.Invoke(this, new InputVolumeMetersEventArgs(JsonConvert.DeserializeObject<List<JObject>>((string)body["inputs"])));
inputVolumeMeters?.Invoke(this, new InputVolumeMetersEventArgs(body["inputs"].ToObject<List<InputVolumeMeter>>()));
break;

case nameof(ReplayBufferSaved):
Expand Down
5 changes: 3 additions & 2 deletions obs-websocket-dotnet/OBSWebsocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,8 @@ protected void SendIdentify(string password, OBSAuthInfo authInfo = null)
{
var requestFields = new JObject
{
{ "rpcVersion", SUPPORTED_RPC_VERSION }
{ "rpcVersion", SUPPORTED_RPC_VERSION },
{ "eventSubscriptions", (uint)registeredEvents }
};

if (authInfo != null)
Expand All @@ -301,7 +302,7 @@ protected void SendIdentify(string password, OBSAuthInfo authInfo = null)

SendRequest(MessageTypes.Identify, null, requestFields, false);
}

/// <summary>
/// Encode a Base64-encoded SHA-256 hash
/// </summary>
Expand Down
31 changes: 31 additions & 0 deletions obs-websocket-dotnet/Types/EventSubscription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace OBSWebsocketDotNet.Types
{
[Flags]
internal enum EventSubscription
{
None = 0,
General = (1 << 0),
Config = (1 << 1),
Scenes = (1 << 2),
Inputs = (1 << 3),
Transitions = (1 << 4),
Filters = (1 << 5),
Outputs = (1 << 6),
SceneItems = (1 << 7),
MediaInputs = (1 << 8),
Vendors = (1 << 9),
Ui = (1 << 10),
All = (General | Config | Scenes | Inputs | Transitions | Filters | Outputs | SceneItems | MediaInputs | Vendors | Ui),

// High volume event need separate subscription

InputVolumeMeters = (1 << 16),
InputActiveStateChanged = (1 << 17),
InputShowStateChanged = (1 << 18),
SceneItemTransformChanged = (1 << 19)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ public class InputVolumeMetersEventArgs : EventArgs
/// <summary>
/// Array of active inputs with their associated volume levels
/// </summary>
public List<JObject> inputs { get; }
public List<InputVolumeMeter> inputs { get; }

/// <summary>
/// Default Constructor
/// </summary>
/// <param name="inputs">Collection inputs as JObjects</param>
public InputVolumeMetersEventArgs(List<JObject> inputs)
public InputVolumeMetersEventArgs(List<InputVolumeMeter> inputs)
{
this.inputs = inputs;
}
Expand Down
69 changes: 69 additions & 0 deletions obs-websocket-dotnet/Types/InputVolumeMeter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace OBSWebsocketDotNet.Types
{
public class InputVolumeMeter
{
/// <summary>
/// Name of the input
/// </summary>
[JsonProperty(PropertyName = "inputName")]
public string InputName { set; get; }

// Convert json Array of 3 scalars, into a struct
private class ChannelLevelConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ChannelLevel);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.StartArray)
throw new ProtocolViolationException("Expected InputVolumeMeter/inputLevelsMul to be an array");

JToken token = JToken.Load(reader);
var items = token.ToObject<float[]>();

if (items.Length != 3)
throw new ProtocolViolationException($"Expected InputVolumeMeter/inputLevelsMul to be an 3 element array, but instead got {items.Length} element array");

ChannelLevel contentStruct;
contentStruct.PeakRaw = items[0];
contentStruct.PeakWithVolume = items[1];
contentStruct.magnitudeWithVolume = items[2];
return contentStruct;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

[JsonConverter(typeof(ChannelLevelConverter))]
public struct ChannelLevel
{
// https://github.com/obsproject/obs-websocket/blob/f4b72b69ce7f9ec6a5fdb1b06971e00d2b091bec/src/utils/Obs_VolumeMeter.cpp#L87


public float magnitudeWithVolume;
public float PeakWithVolume;
public float PeakRaw;
}

/// <summary>
/// Array of channels on this input
/// </summary>
[JsonProperty(PropertyName = "inputLevelsMul")]
public List<ChannelLevel> InputLevels { set; get; }


}
}

0 comments on commit dedfcdc

Please sign in to comment.