diff --git a/TestClient/AdvancedWindow.cs b/TestClient/AdvancedWindow.cs index eca9e00..e8ca352 100644 --- a/TestClient/AdvancedWindow.cs +++ b/TestClient/AdvancedWindow.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; using OBSWebsocketDotNet; using OBSWebsocketDotNet.Types; using System; @@ -323,7 +323,7 @@ private void btnSourceInfo_Click(object sender, EventArgs e) bool isLocked = obs.GetSceneItemLocked(scene, itemId); LogMessage($"Source Locked: {isLocked}"); - JObject data = obs.GetSceneItemTransformRaw(scene, itemId); + JsonObject data = obs.GetSceneItemTransformRaw(scene, itemId); LogMessage($"Raw Data: {data}"); var transform = obs.GetSceneItemTransform(scene, itemId); @@ -439,7 +439,7 @@ private void btnTransition_Click(object sender, EventArgs e) obs.SetCurrentSceneTransition(transition.Name); var activeTransition = obs.GetCurrentSceneTransition(); var info = activeTransition.Settings; - info ??= new JObject(); + info ??= new JsonObject(); LogMessage($"Transition: {transition.Name} has {info.Count} settings"); } obs.SetCurrentSceneTransition(enteringTransition.Name); diff --git a/obs-websocket-dotnet-tests/UnitTest_Types.cs b/obs-websocket-dotnet-tests/UnitTest_Types.cs index cd82fd4..d229574 100644 --- a/obs-websocket-dotnet-tests/UnitTest_Types.cs +++ b/obs-websocket-dotnet-tests/UnitTest_Types.cs @@ -1,5 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; using OBSWebsocketDotNet.Communication; using OBSWebsocketDotNet.Types; @@ -19,7 +19,7 @@ public void OBSScene_BuildFromJSON() int sceneItemId = 22; - JObject itemData = new JObject + JsonObject itemData = new JsonObject { { "sourceName", itemName }, { "sourceType", (int)sourceType }, @@ -39,7 +39,7 @@ public void OBSScene_BuildFromJSON() itemData }; - var data = new JObject + var data = new JsonObject { { "sceneName", sceneName }, { "sources", items }, @@ -64,7 +64,7 @@ public void OBSAuthInfo_BuildFromJSON() string challenge = "pBWv82hj"; string salt = "B9fL8CF7"; - var data = new JObject + var data = new JsonObject { { "authRequired", true }, { "challenge", challenge }, @@ -90,7 +90,7 @@ public void OBSVersion_BuildFromJSON() var requests = new JArray(availableRequests.Split(',')); var images = new JArray(supportedImageFormats.Split(',')); - var data = new JObject + var data = new JsonObject { { "obsWebSocketVersion", pluginVersion }, { "obsVersion", obsVersion }, @@ -120,7 +120,7 @@ public void OBSStreamStatus_BuildFromJSON() int outputSkippedFrames = 120; int outputTotalFrames = 2000; - var data = new JObject + var data = new JsonObject { { "outputActive", true }, { "outputReconnecting", true }, @@ -147,7 +147,7 @@ public void OBSStreamStatus_BuildFromJSON() [TestMethod] public void OBSOutputStatus_BuildFromJSON() { - var data = new JObject + var data = new JsonObject { { "outputActive", true } }; @@ -168,7 +168,7 @@ public void OBSCurrentTransitionInfo_BuildFromJSON() bool transitionFixed = true; bool transitionConfigurable = true; - var data = new JObject + var data = new JsonObject { { "transitionName", transitionName }, { "transitionDuration", duration }, @@ -192,7 +192,7 @@ public void OBSVolumeInfo_BuildFromJSON() float volumeMul = 0.50f; float volumeDB = 45.4f; - var data = new JObject + var data = new JsonObject { { "inputVolumeMul", volumeMul }, { "inputVolumeDb", volumeDB } diff --git a/obs-websocket-dotnet/AppJsonSerializerContext.cs b/obs-websocket-dotnet/AppJsonSerializerContext.cs new file mode 100644 index 0000000..a0616a6 --- /dev/null +++ b/obs-websocket-dotnet/AppJsonSerializerContext.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Text.Json.Serialization; +using System.Text.Json.Nodes; +using OBSWebsocketDotNet.Types; +using OBSWebsocketDotNet.Communication; + +namespace OBSWebsocketDotNet +{ [JsonSerializable(typeof(ObsVideoSettings))] + [JsonSerializable(typeof(ObsStats))] + [JsonSerializable(typeof(GetSceneListInfo))] + [JsonSerializable(typeof(List))] + [JsonSerializable(typeof(FilterSettings))] + [JsonSerializable(typeof(List))] + [JsonSerializable(typeof(GetProfileListInfo))] + [JsonSerializable(typeof(RecordingStatus))] [JsonSerializable(typeof(GetTransitionListInfo))] + [JsonSerializable(typeof(StreamingService))] + [JsonSerializable(typeof(StreamingServiceSettings))] + [JsonSerializable(typeof(SceneItemTransformInfo))] + [JsonSerializable(typeof(ServerMessage))] + [JsonSerializable(typeof(JsonObject))] + [JsonSerializable(typeof(List))] + // Types used in PopulateObject calls + [JsonSerializable(typeof(List))] + [JsonSerializable(typeof(FilterReorderItem))] + [JsonSerializable(typeof(VolumeInfo))] + [JsonSerializable(typeof(VirtualCamStatus))] + [JsonSerializable(typeof(TransitionSettings))] + [JsonSerializable(typeof(SourceTracks))] + [JsonSerializable(typeof(SourceActiveInfo))] + [JsonSerializable(typeof(SceneItemDetails))] + [JsonSerializable(typeof(RecordStateChanged))] [JsonSerializable(typeof(OutputStatus))] + [JsonSerializable(typeof(OutputStateChanged))] + [JsonSerializable(typeof(ObsVersion))] + [JsonSerializable(typeof(ObsScene))] + [JsonSerializable(typeof(Monitor))] + [JsonSerializable(typeof(MediaInputStatus))] + [JsonSerializable(typeof(InputVolume))] + [JsonSerializable(typeof(InputSettings))] + [JsonSerializable(typeof(InputFFMpegSettings))] [JsonSerializable(typeof(InputBrowserSourceSettings))] + [JsonSerializable(typeof(InputBasicInfo))] + [JsonSerializable(typeof(Input))] + [JsonSerializable(typeof(OBSAuthInfo))] + [JsonSerializable(typeof(TransitionOverrideInfo))] + [JsonSourceGenerationOptions(WriteIndented = true)] + internal partial class AppJsonSerializerContext : JsonSerializerContext + { + } +} diff --git a/obs-websocket-dotnet/Communication/MessageFactory.cs b/obs-websocket-dotnet/Communication/MessageFactory.cs index d002153..b1a8691 100644 --- a/obs-websocket-dotnet/Communication/MessageFactory.cs +++ b/obs-websocket-dotnet/Communication/MessageFactory.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; using System; using System.Collections.Generic; using System.Text; @@ -7,15 +7,15 @@ namespace OBSWebsocketDotNet.Communication { internal static class MessageFactory { - internal static JObject BuildMessage(MessageTypes opCode, string messageType, JObject additionalFields, out string messageId) + internal static JsonObject BuildMessage(MessageTypes opCode, string messageType, JsonObject additionalFields, out string messageId) { messageId = Guid.NewGuid().ToString(); - JObject payload = new JObject() + JsonObject payload = new JsonObject() { { "op", (int)opCode } }; - JObject data = new JObject(); + JsonObject data = new JsonObject(); switch (opCode) { diff --git a/obs-websocket-dotnet/Communication/OBSAuthInfo.cs b/obs-websocket-dotnet/Communication/OBSAuthInfo.cs index 8ce72db..439ec48 100644 --- a/obs-websocket-dotnet/Communication/OBSAuthInfo.cs +++ b/obs-websocket-dotnet/Communication/OBSAuthInfo.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Communication { @@ -11,22 +11,23 @@ public class OBSAuthInfo /// /// Authentication challenge /// - [JsonProperty(PropertyName = "challenge")] + [JsonPropertyName("challenge")] public readonly string Challenge; /// /// Password salt /// - [JsonProperty(PropertyName = "salt")] + [JsonPropertyName("salt")] public readonly string PasswordSalt; /// /// Builds the object from JSON response body /// /// JSON response body as a - public OBSAuthInfo(JObject data) + public OBSAuthInfo(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + Challenge = data["challenge"]?.ToString(); + PasswordSalt = data["salt"]?.ToString(); } /// diff --git a/obs-websocket-dotnet/Communication/ServerMessage.cs b/obs-websocket-dotnet/Communication/ServerMessage.cs index 665f48e..592582b 100644 --- a/obs-websocket-dotnet/Communication/ServerMessage.cs +++ b/obs-websocket-dotnet/Communication/ServerMessage.cs @@ -1,5 +1,6 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Communication { @@ -11,13 +12,13 @@ internal class ServerMessage /// /// Server Message's operation code /// - [JsonProperty(PropertyName = "op")] + [JsonPropertyName("op")] public MessageTypes OperationCode { set; get; } /// /// Server Data /// - [JsonProperty(PropertyName = "d")] - public JObject Data { get; set; } + [JsonPropertyName("d")] + public JsonObject Data { get; set; } } } diff --git a/obs-websocket-dotnet/Events.cs b/obs-websocket-dotnet/Events.cs index d313603..1b5c1ca 100644 --- a/obs-websocket-dotnet/Events.cs +++ b/obs-websocket-dotnet/Events.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using OBSWebsocketDotNet.Communication; using OBSWebsocketDotNet.Types; using System; @@ -305,22 +305,18 @@ public partial class OBSWebsocket /// /// Value of "event-type" in the JSON body /// full JSON message body - protected void ProcessEventType(string eventType, JObject body) + protected void ProcessEventType(string eventType, JsonObject body) { - body = (JObject)body["eventData"]; + body = body["eventData"]?.AsObject(); switch (eventType) { case nameof(CurrentProgramSceneChanged): CurrentProgramSceneChanged?.Invoke(this, new ProgramSceneChangedEventArgs((string)body["sceneName"])); - break; - - case nameof(SceneListChanged): - SceneListChanged?.Invoke(this, new SceneListChangedEventArgs(JsonConvert.DeserializeObject>((string)body["scenes"]))); - break; - - case nameof(SceneItemListReindexed): - SceneItemListReindexed?.Invoke(this, new SceneItemListReindexedEventArgs((string)body["sceneName"], JsonConvert.DeserializeObject>((string)body["sceneItems"]))); + break; case nameof(SceneListChanged): + SceneListChanged?.Invoke(this, new SceneListChangedEventArgs(JsonSerializer.Deserialize>((string)body["scenes"], AppJsonSerializerContext.Default.ListJsonObject))); + break; case nameof(SceneItemListReindexed): + SceneItemListReindexed?.Invoke(this, new SceneItemListReindexedEventArgs((string)body["sceneName"], JsonSerializer.Deserialize>((string)body["sceneItems"], AppJsonSerializerContext.Default.ListJsonObject))); break; case nameof(SceneItemCreated): @@ -341,10 +337,8 @@ protected void ProcessEventType(string eventType, JObject body) case nameof(CurrentSceneCollectionChanged): CurrentSceneCollectionChanged?.Invoke(this, new CurrentSceneCollectionChangedEventArgs((string)body["sceneCollectionName"])); - break; - - case nameof(SceneCollectionListChanged): - SceneCollectionListChanged?.Invoke(this, new SceneCollectionListChangedEventArgs(JsonConvert.DeserializeObject>((string)body["sceneCollections"]))); + break; case nameof(SceneCollectionListChanged): + SceneCollectionListChanged?.Invoke(this, new SceneCollectionListChangedEventArgs(JsonSerializer.Deserialize>((string)body["sceneCollections"], AppJsonSerializerContext.Default.ListString))); break; case nameof(CurrentSceneTransitionChanged): @@ -369,10 +363,8 @@ protected void ProcessEventType(string eventType, JObject body) case nameof(CurrentProfileChanged): CurrentProfileChanged?.Invoke(this, new CurrentProfileChangedEventArgs((string)body["profileName"])); - break; - - case nameof(ProfileListChanged): - ProfileListChanged?.Invoke(this, new ProfileListChangedEventArgs(JsonConvert.DeserializeObject>((string)body["profiles"]))); + break; case nameof(ProfileListChanged): + ProfileListChanged?.Invoke(this, new ProfileListChangedEventArgs(JsonSerializer.Deserialize>((string)body["profiles"], AppJsonSerializerContext.Default.ListString))); break; case nameof(StreamStateChanged): @@ -404,7 +396,7 @@ protected void ProcessEventType(string eventType, JObject body) break; case nameof(SceneItemTransformChanged): - SceneItemTransformChanged?.Invoke(this, new SceneItemTransformEventArgs((string)body["sceneName"], (string)body["sceneItemId"], new SceneItemTransformInfo((JObject)body["sceneItemTransform"]))); + SceneItemTransformChanged?.Invoke(this, new SceneItemTransformEventArgs((string)body["sceneName"], (string)body["sceneItemId"], new SceneItemTransformInfo(body["sceneItemTransform"]?.AsObject()))); break; case nameof(InputAudioSyncOffsetChanged): @@ -420,18 +412,16 @@ protected void ProcessEventType(string eventType, JObject body) break; case nameof(SourceFilterCreated): - SourceFilterCreated?.Invoke(this, new SourceFilterCreatedEventArgs((string)body["sourceName"], (string)body["filterName"], (string)body["filterKind"], (int)body["filterIndex"], (JObject)body["filterSettings"], (JObject)body["defaultFilterSettings"])); + SourceFilterCreated?.Invoke(this, new SourceFilterCreatedEventArgs((string)body["sourceName"], (string)body["filterName"], (string)body["filterKind"], (int)body["filterIndex"], body["filterSettings"]?.AsObject(), body["defaultFilterSettings"]?.AsObject())); break; case nameof(SourceFilterRemoved): SourceFilterRemoved?.Invoke(this, new SourceFilterRemovedEventArgs((string)body["sourceName"], (string)body["filterName"])); - break; - - case nameof(SourceFilterListReindexed): + break; case nameof(SourceFilterListReindexed): if (SourceFilterListReindexed != null) { List filters = new List(); - JsonConvert.PopulateObject(body["filters"].ToString(), filters); + filters = JsonSerializer.Deserialize>((string)body["filters"], AppJsonSerializerContext.Default.ListFilterReorderItem); SourceFilterListReindexed?.Invoke(this, new SourceFilterListReindexedEventArgs((string)body["sourceName"], filters)); } @@ -474,7 +464,7 @@ protected void ProcessEventType(string eventType, JObject body) break; case nameof(InputCreated): - InputCreated?.Invoke(this, new InputCreatedEventArgs((string)body["inputName"], (string)body["inputKind"], (string)body["unversionedInputKind"], (JObject)body["inputSettings"], (JObject)body["defaultInputSettings"])); + InputCreated?.Invoke(this, new InputCreatedEventArgs((string)body["inputName"], (string)body["inputKind"], (string)body["unversionedInputKind"], body["inputSettings"]?.AsObject(), body["defaultInputSettings"]?.AsObject())); break; case nameof(InputRemoved): @@ -498,15 +488,13 @@ protected void ProcessEventType(string eventType, JObject body) break; case nameof(InputAudioTracksChanged): - InputAudioTracksChanged?.Invoke(this, new InputAudioTracksChangedEventArgs((string)body["inputName"], (JObject)body["inputAudioTracks"])); + InputAudioTracksChanged?.Invoke(this, new InputAudioTracksChangedEventArgs((string)body["inputName"], body["inputAudioTracks"]?.AsObject())); break; case nameof(InputAudioMonitorTypeChanged): InputAudioMonitorTypeChanged?.Invoke(this, new InputAudioMonitorTypeChangedEventArgs((string)body["inputName"], (string)body["monitorType"])); - break; - - case nameof(InputVolumeMeters): - InputVolumeMeters?.Invoke(this, new InputVolumeMetersEventArgs(JsonConvert.DeserializeObject>((string)body["inputs"]))); + break; case nameof(InputVolumeMeters): + InputVolumeMeters?.Invoke(this, new InputVolumeMetersEventArgs(JsonSerializer.Deserialize>((string)body["inputs"], AppJsonSerializerContext.Default.ListJsonObject))); break; case nameof(ReplayBufferSaved): diff --git a/obs-websocket-dotnet/IOBSWebsocket.cs b/obs-websocket-dotnet/IOBSWebsocket.cs index 7913cbb..865f63c 100644 --- a/obs-websocket-dotnet/IOBSWebsocket.cs +++ b/obs-websocket-dotnet/IOBSWebsocket.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; using OBSWebsocketDotNet.Communication; using OBSWebsocketDotNet.Types; using OBSWebsocketDotNet.Types.Events; @@ -128,9 +128,9 @@ public interface IOBSWebsocket /// /// Source with filter /// Filter name - /// JObject with filter settings + /// JsonObject with filter settings /// Apply over existing settings? - void SetSourceFilterSettings(string sourceName, string filterName, JObject filterSettings, bool overlay = false); + void SetSourceFilterSettings(string sourceName, string filterName, JsonObject filterSettings, bool overlay = false); /// /// Apply settings to a source filter @@ -175,8 +175,8 @@ public interface IOBSWebsocket /// Name of the source for the filter /// Name of the filter /// Type of filter - /// JObject holding filter settings object - void CreateSourceFilter(string sourceName, string filterName, string filterKind, JObject filterSettings); + /// JsonObject holding filter settings object + void CreateSourceFilter(string sourceName, string filterName, string filterKind, JsonObject filterSettings); /// /// Add a filter to a source @@ -228,7 +228,7 @@ public interface IOBSWebsocket /// Transition settings (they can be partial) /// Whether to overlay over the current settins or replace them /// Updated transition settings - void SetCurrentSceneTransitionSettings(JObject transitionSettings, bool overlay); + void SetCurrentSceneTransitionSettings(JsonObject transitionSettings, bool overlay); /// /// Change the volume of the specified source @@ -271,8 +271,8 @@ public interface IOBSWebsocket /// /// Name of the scene that has the SceneItem /// Id of the Scene Item - /// JObject holding transform settings - void SetSceneItemTransform(string sceneName, int sceneItemId, JObject sceneItemTransform); + /// JsonObject holding transform settings + void SetSceneItemTransform(string sceneName, int sceneItemId, JsonObject sceneItemTransform); /// /// Sets the transform and crop info of a scene item @@ -507,7 +507,7 @@ public interface IOBSWebsocket /// Broadcasts a `CustomEvent` to all WebSocket clients. Receivers are clients which are identified and subscribed. /// /// Data payload to emit to all receivers - void BroadcastCustomEvent(JObject eventData); + void BroadcastCustomEvent(JsonObject eventData); /// /// Sets the cursor position of a media input. @@ -534,14 +534,14 @@ public interface IOBSWebsocket /// Jobject holding the settings object to initialize the input with /// Whether to set the created scene item to enabled or disabled /// ID of the SceneItem in the scene. - int CreateInput(string sceneName, string inputName, string inputKind, JObject inputSettings, bool? sceneItemEnabled); + int CreateInput(string sceneName, string inputName, string inputKind, JsonObject inputSettings, bool? sceneItemEnabled); /// /// Gets the default settings for an input kind. /// /// Input kind to get the default settings for /// Object of default settings for the input kind - JObject GetInputDefaultSettings(string inputKind); + JsonObject GetInputDefaultSettings(string inputKind); /// /// Gets a list of all scene items in a scene. @@ -578,8 +578,8 @@ public interface IOBSWebsocket /// Sets the enable state of audio tracks of an input. /// /// Name of the input - /// JObject holding track settings to apply - void SetInputAudioTracks(string inputName, JObject inputAudioTracks); + /// JsonObject holding track settings to apply + void SetInputAudioTracks(string inputName, JsonObject inputAudioTracks); /// /// Sets the enable state of audio tracks of an input. @@ -624,7 +624,7 @@ public interface IOBSWebsocket /// The data realm to select. `OBS_WEBSOCKET_DATA_REALM_GLOBAL` or `OBS_WEBSOCKET_DATA_REALM_PROFILE` /// The name of the slot to retrieve data from /// Value associated with the slot. `null` if not set - JObject GetPersistentData(string realm, string slotName); + JsonObject GetPersistentData(string realm, string slotName); /// /// Sets the value of a \"slot\" from the selected persistent data realm. @@ -632,7 +632,7 @@ public interface IOBSWebsocket /// The data realm to select. `OBS_WEBSOCKET_DATA_REALM_GLOBAL` or `OBS_WEBSOCKET_DATA_REALM_PROFILE` /// The name of the slot to retrieve data from /// The value to apply to the slot - void SetPersistentData(string realm, string slotName, JObject slotValue); + void SetPersistentData(string realm, string slotName, JsonObject slotValue); /// /// Creates a new scene collection, switching to it in the process.\n\nNote: This will block until the collection has finished changing. @@ -658,7 +658,7 @@ public interface IOBSWebsocket /// Category of the parameter to get /// Name of the parameter to get /// - JObject GetProfileParameter(string parameterCategory, string parameterName); + JsonObject GetProfileParameter(string parameterCategory, string parameterName); /// /// Sets the value of a parameter in the current profile's configuration. @@ -680,7 +680,7 @@ public interface IOBSWebsocket /// /// Filter kind to get the default settings for /// Object of default settings for the filter kind - JObject GetSourceFilterDefaultSettings(string filterKind); + JsonObject GetSourceFilterDefaultSettings(string filterKind); /// /// Sets the name of a source filter (rename). @@ -713,7 +713,7 @@ public interface IOBSWebsocket /// The request type to call /// Object containing appropriate request data /// Object containing appropriate response data. {} if request does not provide any response data - JObject CallVendorRequest(string vendorName, string requestType, JObject requestData = null); + JsonObject CallVendorRequest(string vendorName, string requestType, JsonObject requestData = null); /// /// Gets an array of all hotkey names in OBS @@ -777,7 +777,7 @@ public interface IOBSWebsocket /// Name of the input to set the settings of /// Object of settings to apply /// True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. - void SetInputSettings(string inputName, JObject inputSettings, bool overlay = true); + void SetInputSettings(string inputName, JsonObject inputSettings, bool overlay = true); /// /// Gets the audio balance of an input. @@ -801,7 +801,7 @@ public interface IOBSWebsocket /// Name of the input /// Name of the list property to get the items of /// Array of items in the list property - List GetInputPropertiesListPropertyItems(string inputName, string propertyName); + List GetInputPropertiesListPropertyItems(string inputName, string propertyName); /// /// Presses a button in the properties of an input. @@ -853,7 +853,7 @@ public interface IOBSWebsocket /// /// Name of the group to get the items of /// Array of scene items in the group - List GetGroupSceneItemList(string sceneName); + List GetGroupSceneItemList(string sceneName); /// /// Searches a scene for a source, and returns its id.\n\nScenes and Groups @@ -874,13 +874,13 @@ public interface IOBSWebsocket SceneItemTransformInfo GetSceneItemTransform(string sceneName, int sceneItemId); /// - /// Gets the JObject of transform settings for a scene item. Use this one you don't want it populated with default values. + /// Gets the JsonObject of transform settings for a scene item. Use this one you don't want it populated with default values. /// Scenes and Groups /// /// Name of the scene the item is in /// Numeric ID of the scene item /// Object containing scene item transform info - JObject GetSceneItemTransformRaw(string sceneName, int sceneItemId); + JsonObject GetSceneItemTransformRaw(string sceneName, int sceneItemId); /// /// Gets the enable state of a scene item. @@ -1063,7 +1063,7 @@ public interface IOBSWebsocket /// obs-websocket request type, must be one specified in the protocol specification /// additional JSON fields if required by the request type /// The server's JSON response as a JObject - JObject SendRequest(string requestType, JObject additionalFields = null); + JsonObject SendRequest(string requestType, JsonObject additionalFields = null); /// /// Request authentication data. You don't have to call this manually. diff --git a/obs-websocket-dotnet/JsonExtensions.cs b/obs-websocket-dotnet/JsonExtensions.cs new file mode 100644 index 0000000..7a7f826 --- /dev/null +++ b/obs-websocket-dotnet/JsonExtensions.cs @@ -0,0 +1,158 @@ +#nullable enable +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; +using System.Threading; +using System.Threading.Tasks; + +namespace OBSWebsocketDotNet +{ + /// + /// 提供 JSON 序列化的擴展方法,類似於 Newtonsoft.Json 的 PopulateObject 功能 + /// + public static partial class JsonExtensions + { + /// + /// 使用指定的 JSON 內容和序列化上下文來填充現有物件的屬性 + /// 這是 AOT 編譯友好的版本,不需要反射 + /// + /// 要填充的物件型別 + /// 包含要填充資料的 JSON 字串 + /// 要被填充的現有物件 + /// JSON 序列化上下文,包含型別資訊 + /// 當 context 為 null 時拋出 + public static void PopulateObject(ReadOnlySpan json, T value, JsonSerializerContext context) where T : class + { + ArgumentNullException.ThrowIfNull(context); + PopulateObject(json, value, context, t => context.GetTypeInfo(t)); + } + + /// + /// 使用指定的 JSON 字串和序列化上下文來填充現有物件的屬性 + /// 這是 AOT 編譯友好的版本,不需要反射 + /// + /// 要填充的物件型別 + /// 包含要填充資料的 JSON 字串 + /// 要被填充的現有物件 + /// JSON 序列化上下文,包含型別資訊 + /// 當 context 為 null 時拋出 + public static void PopulateObject(string json, T value, JsonSerializerContext context) where T : class + { + PopulateObject(json.AsSpan(), value, context); + } /// + /// 使用指定的 JSON 內容和序列化選項來填充現有物件的屬性 + /// 注意:此方法需要反射功能,不適用於 AOT 編譯 + /// + /// 要填充的物件型別 + /// 包含要填充資料的 JSON 字串 + /// 要被填充的現有物件 + /// JSON 序列化選項,如果為 null 則使用預設值 + /// 當反射被停用或無法找到型別資訊時拋出 + [RequiresUnreferencedCode("Use the method JsonExtensions.PopulateObject(string json, T value, JsonSerializerContext context) instead")] + [RequiresDynamicCode("Use the method JsonExtensions.PopulateObject(string json, T value, JsonSerializerContext context) instead")] + public static void PopulateObject(ReadOnlySpan json, T value, JsonSerializerOptions? options = default) where T : class + { + options = options ?? JsonSerializerOptions.Default; + var originalResolver = options.TypeInfoResolver + ?? (JsonSerializer.IsReflectionEnabledByDefault + ? new DefaultJsonTypeInfoResolver() : throw new JsonException("Reflection-based serialization is disabled, please use an explicit JsonSerializerContext")); + PopulateObject(json, value, originalResolver, t => originalResolver.GetTypeInfo(t, options)); + } /// + /// 內部核心方法,執行實際的物件填充邏輯 + /// + /// 要填充的物件型別 + /// JSON 內容 + /// 要被填充的物件 + /// 原始的型別資訊解析器 + /// 取得原始型別資訊的函數 + /// 當 value 或 originalResolver 為 null 時拋出 + /// 當物件無法被填充時拋出 + [UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", + Justification = "The required warning was emitted for public static void PopulateObject(string json, T value, JsonSerializerOptions? options = default)")] + [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", + Justification = "The required warning was emitted for public static void PopulateObject(string json, T value, JsonSerializerOptions? options = default)")] + static void PopulateObject(ReadOnlySpan json, T value, IJsonTypeInfoResolver originalResolver, Func getOriginalTypeInfo) where T : class + { + ArgumentNullException.ThrowIfNull(value); + ArgumentNullException.ThrowIfNull(originalResolver); + + if (value is IList list && list.IsFixedSize) + throw new JsonException($"Fixed size lists of type {value.GetType()} cannot be populated with {nameof(JsonExtensions.PopulateObject)}<{typeof(T).Name}>()"); + var declaredType = typeof(T) == typeof(object) ? value.GetType() : typeof(T); + var originalTypeInfo = getOriginalTypeInfo(declaredType); + if (originalTypeInfo == null) + throw new JsonException($"No JsonTypeInfo was generated for type {declaredType}"); + if (originalTypeInfo.Kind is JsonTypeInfoKind.None) + throw new JsonException($"Object of type {value.GetType()} (kind {originalTypeInfo.Kind}) cannot be populated with {nameof(JsonExtensions.PopulateObject)}<{typeof(T).Name}>()"); + var originalOptions = originalTypeInfo.Options; + + JsonSerializerOptions populateOptions = new(originalOptions) + { + PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate, + TypeInfoResolver = originalResolver + .WithAddedModifier(new RootObjectInjector(value).WithRootObjectCreator) + .WithAddedModifier(PopulateProperties), + }; + + try + { + populateOptions.MakeReadOnly(); + if (populateOptions.GetTypeInfo(declaredType) == null) + throw new JsonException($"Object of type {declaredType} cannot be populated with {nameof(JsonExtensions.PopulateObject)}<{typeof(T).Name}>() using {originalResolver}"); + var returnedValue = JsonSerializer.Deserialize(json, declaredType, populateOptions); + if (returnedValue is not null && !object.ReferenceEquals(returnedValue, value)) + throw new JsonException($"A different object was returned for {returnedValue}"); + } + catch (Exception ex) + { + throw new JsonException($"Object of type {declaredType} cannot be populated with {nameof(JsonExtensions.PopulateObject)}<{typeof(T).Name}>() using {originalResolver}", ex); + } + } /// + /// 根物件注入器,用於確保反序列化時使用現有的物件實例而非建立新實例 + /// + /// 根物件的型別 + class RootObjectInjector where T : class + { + readonly Type valueType; + T? value; + + /// + /// 初始化根物件注入器 + /// + /// 要注入的根物件實例 + /// 當 value 為 null 時拋出 + public RootObjectInjector(T value) => (this.value, this.valueType) = (value ?? throw new ArgumentNullException(nameof(value)), value.GetType()); /// + /// 當需要建立根物件時,提供現有的物件實例而非建立新實例 + /// + /// JSON 型別資訊 + internal void WithRootObjectCreator(JsonTypeInfo typeInfo) + { + if (valueType.IsAssignableTo(typeInfo.Type)) + { + var oldCreateObject = typeInfo.CreateObject; + typeInfo.CreateObject = () => + Interlocked.Exchange(ref this.value, null) is { } rootValue + ? rootValue : (oldCreateObject is not null ? oldCreateObject() : throw new JsonException($"No default creator exists for {typeInfo.Type}.")); + } + } + } + + /// + /// 設定屬性物件的建立處理方式為填充模式 + /// + /// 要修改的 JSON 型別資訊 + static void PopulateProperties(JsonTypeInfo typeInfo) + { + // Set PreferredPropertyObjectCreationHandling unless explicitly set by attributes + if (typeInfo.Kind == JsonTypeInfoKind.Object) + typeInfo.PreferredPropertyObjectCreationHandling ??= JsonObjectCreationHandling.Populate; + } } + + +} diff --git a/obs-websocket-dotnet/JsonObjectExtensions.cs b/obs-websocket-dotnet/JsonObjectExtensions.cs new file mode 100644 index 0000000..d268133 --- /dev/null +++ b/obs-websocket-dotnet/JsonObjectExtensions.cs @@ -0,0 +1,186 @@ +#nullable enable +using OBSWebsocketDotNet; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; + +namespace OBSWebsocketDotNet +{ + public static class JsonObjectExtensions + { + /// + /// Merges the properties of the specified source into the target . + /// + /// If a property in the source has the same key as a property + /// in the target , the value from the source will overwrite the value in the target. + /// Properties in the target that do not exist in the source will remain unchanged. + /// The target to which properties will be added or updated. + /// The source containing the properties to merge into the target. + /// Thrown when or is null. + public static void Merge(this JsonObject dist, JsonObject source) + { + ArgumentNullException.ThrowIfNull(dist); + ArgumentNullException.ThrowIfNull(source); + + // 遍歷來源 JsonObject 的所有屬性 + foreach (var kvp in source) + { + string propertyName = kvp.Key; + JsonNode? sourceValue = kvp.Value; + + // 檢查目標 JsonObject 是否已經包含此屬性 + if (dist.ContainsKey(propertyName)) + { + JsonNode? targetValue = dist[propertyName]; + + // 如果來源和目標的值都是 JsonObject,則遞迴合併 + if (sourceValue is JsonObject sourceObj && targetValue is JsonObject targetObj) + { + targetObj.Merge(sourceObj); + } + else + { + // 否則直接覆蓋目標值 + dist[propertyName] = sourceValue?.DeepClone(); + } + } + else + { + // 如果目標中不存在此屬性,則直接添加(深拷貝以避免引用共享) + dist[propertyName] = sourceValue?.DeepClone(); + } + } + } /// + /// 將 JsonObject 轉換為指定類型的新物件實例,使用 JsonSerializerOptions + /// 此方法提供了與 Newtonsoft.Json JObject.ToObject<T>() 類似的功能 + /// + /// 要轉換的目標類型 + /// 要轉換的 JsonObject + /// JSON 序列化選項,如果為 null 則使用預設值 + /// 轉換後的新物件實例 + /// 當 obj 為 null 時拋出 + /// 當轉換失敗時拋出 + [RequiresUnreferencedCode("Use ToObject(this JsonObject obj, JsonSerializerContext context) instead")] + [RequiresDynamicCode("Use ToObject(this JsonObject obj, JsonSerializerContext context) instead")] + public static T ToObject(this JsonObject obj, JsonSerializerOptions? options = null) where T : class + { + return obj.Deserialize(options) ?? throw new JsonException($"Failed to deserialize JsonObject to type {typeof(T).Name}: result is null"); + } /// + /// 將 JsonObject 轉換為指定類型的新物件實例,使用 JsonSerializerContext + /// 這是 AOT 編譯友好的版本,不需要反射 + /// + /// 要轉換的目標類型 + /// 要轉換的 JsonObject + /// JSON 序列化上下文,包含型別資訊 + /// 轉換後的新物件實例 + /// 當 obj 或 context 為 null 時拋出 + /// 當轉換失敗時拋出 + public static T ToObject(this JsonObject obj, JsonSerializerContext context) where T : class + { + ArgumentNullException.ThrowIfNull(obj); + ArgumentNullException.ThrowIfNull(context); + + var typeInfo = context.GetTypeInfo(typeof(T)); + if (typeInfo == null) + throw new JsonException($"No JsonTypeInfo found for type {typeof(T).Name} in the provided context"); + + return obj.Deserialize(typeInfo) as T ?? throw new JsonException($"Failed to deserialize JsonObject to type {typeof(T).Name}: result is null"); + } + + public static bool HasValue(this JsonObject obj, string key) + { + ArgumentNullException.ThrowIfNull(obj); + ArgumentNullException.ThrowIfNull(key); + return obj.ContainsKey(key) && obj[key] is not null; + } + + public static bool HasValues(this JsonObject obj) + { + ArgumentNullException.ThrowIfNull(obj); + return obj.Count > 0; + } + + public static bool ContainsKey(this JsonNode node, string key) + { + try + { + var _node = node.AsObject(); + + return _node.ContainsKey(key); + } + catch (InvalidCastException) + { + // 如果 node 不是 JsonObject,則返回 false + return false; + } + catch (NullReferenceException) + { + // 如果 node 為 null,則返回 false + return false; + } + catch (Exception ex) + { + // 捕獲其他異常,這裡可以根據需要進行處理或記錄 + throw new JsonException($"Error checking key '{key}' in JsonNode: {ex.Message}", ex); + } + + } + + /// + /// 將物件序列化為 JsonNode,使用 JsonSerializerOptions + /// 此方法提供了與 Newtonsoft.Json JToken.FromObject() 類似的功能 + /// + /// 要序列化的物件 + /// JSON 序列化選項,如果為 null 則使用預設值 + /// 序列化後的 JsonNode + /// 當序列化失敗時拋出 + [RequiresUnreferencedCode("Use FromObject(object obj, JsonSerializerContext context) instead")] + [RequiresDynamicCode("Use FromObject(object obj, JsonSerializerContext context) instead")] + public static JsonNode? FromObject(object? obj, JsonSerializerOptions? options = null) + { + if (obj == null) + return null; + + try + { + return JsonSerializer.SerializeToNode(obj, options); + } + catch (Exception ex) + { + throw new JsonException($"Failed to serialize object of type {obj.GetType().Name} to JsonNode", ex); + } + } /// + /// 將物件序列化為 JsonNode,使用 JsonSerializerContext + /// 這是 AOT 編譯友好的版本,不需要反射 + /// + /// 物件的類型 + /// 要序列化的物件 + /// JSON 序列化上下文,包含型別資訊 + /// 序列化後的 JsonNode + /// 當 context 為 null 時拋出 + /// 當序列化失敗時拋出 + public static JsonNode? FromObject(T obj, JsonSerializerContext context) + { + ArgumentNullException.ThrowIfNull(context); + + if (obj == null) + return null; + + try + { + var typeInfo = context.GetTypeInfo(typeof(T)); + if (typeInfo == null) + throw new JsonException($"No JsonTypeInfo found for type {typeof(T).Name} in the provided context"); + + return JsonSerializer.SerializeToNode(obj, typeInfo); + } + catch (Exception ex) + { + throw new JsonException($"Failed to serialize object of type {typeof(T).Name} to JsonNode", ex); + } + } + } +} \ No newline at end of file diff --git a/obs-websocket-dotnet/JsonSerializer2.cs b/obs-websocket-dotnet/JsonSerializer2.cs new file mode 100644 index 0000000..35b7df9 --- /dev/null +++ b/obs-websocket-dotnet/JsonSerializer2.cs @@ -0,0 +1,76 @@ +#nullable enable +using OBSWebsocketDotNet; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace OBSWebsocketDotNet +{ + /// + /// JsonSerializer 的靜態輔助類,提供 PopulateObject 方法 + /// 使用方式:JsonSerializer.PopulateObject(json, obj, options) + /// + public static partial class JsonSerializer2 + { + /// + /// 使用指定的 JSON 字串來填充現有物件的屬性 + /// 此方法提供了與 Newtonsoft.Json JsonConvert.PopulateObject 類似的功能 + /// + /// 要填充的物件型別 + /// 包含要填充資料的 JSON 字串 + /// 要被填充的現有物件 + /// JSON 序列化選項,如果為 null 則使用預設值 + /// 當反射被停用或無法找到型別資訊時拋出 + [RequiresUnreferencedCode("Use PopulateObject(string json, T obj, JsonSerializerContext context) instead")] + [RequiresDynamicCode("Use PopulateObject(string json, T obj, JsonSerializerContext context) instead")] + public static void PopulateObject(string json, T obj, JsonSerializerOptions? options = null) where T : class + { + JsonExtensions.PopulateObject(json.AsSpan(), obj, options); + } + + /// + /// 使用指定的 JSON 內容來填充現有物件的屬性 + /// 此方法提供了與 Newtonsoft.Json JsonConvert.PopulateObject 類似的功能 + /// + /// 要填充的物件型別 + /// 包含要填充資料的 JSON 內容 + /// 要被填充的現有物件 + /// JSON 序列化選項,如果為 null 則使用預設值 + /// 當反射被停用或無法找到型別資訊時拋出 + [RequiresUnreferencedCode("Use PopulateObject(ReadOnlySpan json, T obj, JsonSerializerContext context) instead")] + [RequiresDynamicCode("Use PopulateObject(ReadOnlySpan json, T obj, JsonSerializerContext context) instead")] + public static void PopulateObject(ReadOnlySpan json, T obj, JsonSerializerOptions? options = null) where T : class + { + JsonExtensions.PopulateObject(json, obj, options); + } + + /// + /// 使用指定的 JSON 字串和序列化上下文來填充現有物件的屬性 + /// 這是 AOT 編譯友好的版本,不需要反射 + /// + /// 要填充的物件型別 + /// 包含要填充資料的 JSON 字串 + /// 要被填充的現有物件 + /// JSON 序列化上下文,包含型別資訊 + /// 當 context 為 null 時拋出 + public static void PopulateObject(string json, T obj, JsonSerializerContext context) where T : class + { + JsonExtensions.PopulateObject(json, obj, context); + } + + /// + /// 使用指定的 JSON 內容和序列化上下文來填充現有物件的屬性 + /// 這是 AOT 編譯友好的版本,不需要反射 + /// + /// 要填充的物件型別 + /// 包含要填充資料的 JSON 內容 + /// 要被填充的現有物件 + /// JSON 序列化上下文,包含型別資訊 + /// 當 context 為 null 時拋出 + public static void PopulateObject(ReadOnlySpan json, T obj, JsonSerializerContext context) where T : class + { + JsonExtensions.PopulateObject(json, obj, context); + } + } +} diff --git a/obs-websocket-dotnet/OBSWebsocket.cs b/obs-websocket-dotnet/OBSWebsocket.cs index 4099f7c..5f4b7f4 100644 --- a/obs-websocket-dotnet/OBSWebsocket.cs +++ b/obs-websocket-dotnet/OBSWebsocket.cs @@ -6,8 +6,9 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; using OBSWebsocketDotNet.Communication; using Websocket.Client; @@ -22,8 +23,8 @@ public partial class OBSWebsocket : IOBSWebsocket private string connectionPassword = null; private WebsocketClient wsConnection; - private delegate void RequestCallback(OBSWebsocket sender, JObject body); - private readonly ConcurrentDictionary> responseHandlers; + private delegate void RequestCallback(OBSWebsocket sender, JsonObject body); + private readonly ConcurrentDictionary> responseHandlers; // Random should never be created inside a function private static readonly Random random = new Random(); @@ -71,7 +72,7 @@ public bool IsConnected /// public OBSWebsocket() { - responseHandlers = new ConcurrentDictionary>(); + responseHandlers = new ConcurrentDictionary>(); } /// @@ -164,8 +165,8 @@ private void WebsocketMessageHandler(object sender, ResponseMessage e) return; } - ServerMessage msg = JsonConvert.DeserializeObject(e.Text); - JObject body = msg.Data; + ServerMessage msg = JsonSerializer.Deserialize(e.Text, AppJsonSerializerContext.Default.ServerMessage); + JsonObject body = msg.Data; switch (msg.OperationCode) { @@ -186,7 +187,7 @@ private void WebsocketMessageHandler(object sender, ResponseMessage e) // its associated message ID string msgID = (string)body["requestId"]; - if (responseHandlers.TryRemove(msgID, out TaskCompletionSource handler)) + if (responseHandlers.TryRemove(msgID, out TaskCompletionSource handler)) { // Set the response body as Result and notify the request sender handler.SetResult(body); @@ -213,7 +214,7 @@ private void WebsocketMessageHandler(object sender, ResponseMessage e) /// obs-websocket request type, must be one specified in the protocol specification /// additional JSON fields if required by the request type /// The server's JSON response as a JObject - public JObject SendRequest(string requestType, JObject additionalFields = null) + public JsonObject SendRequest(string requestType, JsonObject additionalFields = null) { return SendRequest(MessageTypes.Request, requestType, additionalFields, true); } @@ -227,7 +228,7 @@ public JObject SendRequest(string requestType, JObject additionalFields = null) /// additional JSON fields if required by the request type /// Should wait for reply vs "fire and forget" /// The server's JSON response as a JObject - internal JObject SendRequest(MessageTypes operationCode, string requestType, JObject additionalFields = null, bool waitForReply = true) + internal JsonObject SendRequest(MessageTypes operationCode, string requestType, JsonObject additionalFields = null, bool waitForReply = true) { if (wsConnection == null) { @@ -235,8 +236,8 @@ internal JObject SendRequest(MessageTypes operationCode, string requestType, JOb } // Prepare the asynchronous response handler - var tcs = new TaskCompletionSource(); - JObject message = null; + var tcs = new TaskCompletionSource(); + JsonObject message = null; do { // Generate a random message id @@ -266,14 +267,14 @@ internal JObject SendRequest(MessageTypes operationCode, string requestType, JOb if (!(bool)result["requestStatus"]["result"]) { - var status = (JObject)result["requestStatus"]; + var status = result["requestStatus"]; throw new ErrorResponseException($"ErrorCode: {status["code"]}{(status.ContainsKey("comment") ? $", Comment: {status["comment"]}" : "")}", (int)status["code"]); } if (result.ContainsKey("responseData")) // ResponseData is optional - return result["responseData"].ToObject(); + return result["responseData"].AsObject(); - return new JObject(); + return new JsonObject(); } /// @@ -282,7 +283,7 @@ internal JObject SendRequest(MessageTypes operationCode, string requestType, JOb /// Authentication data in an object public OBSAuthInfo GetAuthInfo() { - JObject response = SendRequest("GetAuthRequired"); + JsonObject response = SendRequest("GetAuthRequired"); return new OBSAuthInfo(response); } @@ -294,7 +295,7 @@ public OBSAuthInfo GetAuthInfo() /// true if authentication succeeds, false otherwise protected void SendIdentify(string password, OBSAuthInfo authInfo = null) { - var requestFields = new JObject + var requestFields = new JsonObject { { "rpcVersion", SUPPORTED_RPC_VERSION } }; @@ -345,7 +346,7 @@ protected string NewMessageID(int length = 16) return result; } - private void HandleHello(JObject payload) + private void HandleHello(JsonObject payload) { if (!wsConnection.IsStarted) { @@ -356,7 +357,7 @@ private void HandleHello(JObject payload) if (payload.ContainsKey("authentication")) { // Authentication required - authInfo = new OBSAuthInfo((JObject)payload["authentication"]); + authInfo = new OBSAuthInfo(payload["authentication"].AsObject()); } SendIdentify(connectionPassword, authInfo); diff --git a/obs-websocket-dotnet/OBSWebsocket_Requests.cs b/obs-websocket-dotnet/OBSWebsocket_Requests.cs index 9378399..8d02af7 100644 --- a/obs-websocket-dotnet/OBSWebsocket_Requests.cs +++ b/obs-websocket-dotnet/OBSWebsocket_Requests.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using OBSWebsocketDotNet.Types; using System; using System.Collections.Generic; @@ -22,13 +22,12 @@ public partial class OBSWebsocket #endregion - /// - /// Get basic OBS video information + /// /// Get basic OBS video information /// public ObsVideoSettings GetVideoSettings() { - JObject response = SendRequest(nameof(GetVideoSettings)); - return JsonConvert.DeserializeObject(response.ToString()); + JsonObject response = SendRequest(nameof(GetVideoSettings)); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.ObsVideoSettings); } /// @@ -46,7 +45,7 @@ public ObsVideoSettings GetVideoSettings() /// Base64-encoded screenshot string public string SaveSourceScreenshot(string sourceName, string imageFormat, string imageFilePath, int imageWidth = -1, int imageHeight = -1, int imageCompressionQuality = -1) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(imageFormat), imageFormat }, @@ -91,7 +90,7 @@ public string SaveSourceScreenshot(string sourceName, string imageFormat, string /// Unique name of the hotkey, as defined when registering the hotkey (e.g. "ReplayBuffer.Save") public void TriggerHotkeyByName(string hotkeyName) { - var request = new JObject + var request = new JsonObject { { nameof(hotkeyName), hotkeyName } }; @@ -106,10 +105,10 @@ public void TriggerHotkeyByName(string hotkeyName) /// Optional key modifiers object. You can combine multiple key operators. e.g. KeyModifier.Shift | KeyModifier.Control public void TriggerHotkeyByKeySequence(OBSHotkey keyId, KeyModifier keyModifier = KeyModifier.None) { - var request = new JObject + var request = new JsonObject { { nameof(keyId), keyId.ToString() }, - { "keyModifiers", new JObject{ + { "keyModifiers", new JsonObject{ { "shift", (keyModifier & KeyModifier.Shift) == KeyModifier.Shift }, { "alt", (keyModifier & KeyModifier.Alt) == KeyModifier.Alt }, { "control", (keyModifier & KeyModifier.Control) == KeyModifier.Control }, @@ -126,7 +125,7 @@ public void TriggerHotkeyByKeySequence(OBSHotkey keyId, KeyModifier keyModifier /// Name of the current scene public string GetCurrentProgramScene() { - JObject response = SendRequest(nameof(GetCurrentProgramScene)); + JsonObject response = SendRequest(nameof(GetCurrentProgramScene)); return (string)response["currentProgramSceneName"]; } @@ -136,7 +135,7 @@ public string GetCurrentProgramScene() /// The desired scene name public void SetCurrentProgramScene(string sceneName) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName } }; @@ -149,8 +148,8 @@ public void SetCurrentProgramScene(string sceneName) /// public ObsStats GetStats() { - JObject response = SendRequest(nameof(GetStats)); - return JsonConvert.DeserializeObject(response.ToString()); + JsonObject response = SendRequest(nameof(GetStats)); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.ObsStats); } /// @@ -168,8 +167,8 @@ public List ListScenes() /// public GetSceneListInfo GetSceneList() { - JObject response = SendRequest(nameof(GetSceneList)); - return JsonConvert.DeserializeObject(response.ToString()); + JsonObject response = SendRequest(nameof(GetSceneList)); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.GetSceneListInfo); } /// @@ -179,12 +178,12 @@ public GetSceneListInfo GetSceneList() /// TransitionOverrideInfo public TransitionOverrideInfo GetSceneSceneTransitionOverride(string sceneName) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName } }; - JObject response = SendRequest(nameof(GetSceneSceneTransitionOverride), request); + JsonObject response = SendRequest(nameof(GetSceneSceneTransitionOverride), request); return response.ToObject(); } @@ -196,7 +195,7 @@ public TransitionOverrideInfo GetSceneSceneTransitionOverride(string sceneName) /// Duration in milliseconds of the transition if transition is not fixed. Defaults to the current duration specified in the UI if there is no current override and this value is not given public void SetSceneSceneTransitionOverride(string sceneName, string transitionName, int transitionDuration = -1) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(transitionName), transitionName } @@ -222,7 +221,7 @@ public void SetTBarPosition(double position, bool release = true) throw new ArgumentOutOfRangeException(nameof(position)); } - var request = new JObject + var request = new JsonObject { { nameof(position), position }, { nameof(release), release} @@ -236,11 +235,11 @@ public void SetTBarPosition(double position, bool release = true) /// /// Source with filter /// Filter name - /// JObject with filter settings + /// JsonObject with filter settings /// Apply over existing settings? - public void SetSourceFilterSettings(string sourceName, string filterName, JObject filterSettings, bool overlay = false) + public void SetSourceFilterSettings(string sourceName, string filterName, JsonObject filterSettings, bool overlay = false) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(filterName), filterName }, @@ -260,7 +259,7 @@ public void SetSourceFilterSettings(string sourceName, string filterName, JObjec /// Apply over existing settings? public void SetSourceFilterSettings(string sourceName, string filterName, FilterSettings filterSettings, bool overlay = false) { - SetSourceFilterSettings(sourceName, filterName, JObject.FromObject(filterSettings), overlay); + SetSourceFilterSettings(sourceName, filterName, JsonObjectExtensions.FromObject(filterSettings, AppJsonSerializerContext.Default.JsonObject.Options).AsObject(), overlay); } @@ -273,7 +272,7 @@ public void SetSourceFilterSettings(string sourceName, string filterName, Filter /// New filter state public void SetSourceFilterEnabled(string sourceName, string filterName, bool filterEnabled) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(filterName), filterName }, @@ -289,18 +288,18 @@ public void SetSourceFilterEnabled(string sourceName, string filterName, bool fi /// Source name public List GetSourceFilterList(string sourceName) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName } }; - JObject response = SendRequest(nameof(GetSourceFilterList), request); - if (!response.HasValues) + JsonObject response = SendRequest(nameof(GetSourceFilterList), request); + if (!response.HasValues()) { return new List(); } - return JsonConvert.DeserializeObject>(response["filters"].ToString()); + return JsonSerializer.Deserialize>(response["filters"]?.ToString() ?? "[]", AppJsonSerializerContext.Default.ListFilterSettings); } /// @@ -310,14 +309,14 @@ public List GetSourceFilterList(string sourceName) /// Filter name public FilterSettings GetSourceFilter(string sourceName, string filterName) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(filterName), filterName } }; - JObject response = SendRequest(nameof(GetSourceFilter), request); - return JsonConvert.DeserializeObject(response.ToString()); + JsonObject response = SendRequest(nameof(GetSourceFilter), request); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.FilterSettings); } /// @@ -327,7 +326,7 @@ public FilterSettings GetSourceFilter(string sourceName, string filterName) /// Name of the filter to remove public bool RemoveSourceFilter(string sourceName, string filterName) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(filterName), filterName } @@ -351,10 +350,10 @@ public bool RemoveSourceFilter(string sourceName, string filterName) /// Name of the source for the filter /// Name of the filter /// Type of filter - /// JObject holding filter settings object - public void CreateSourceFilter(string sourceName, string filterName, string filterKind, JObject filterSettings) + /// JsonObject holding filter settings object + public void CreateSourceFilter(string sourceName, string filterName, string filterKind, JsonObject filterSettings) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(filterName), filterName }, @@ -374,7 +373,7 @@ public void CreateSourceFilter(string sourceName, string filterName, string filt /// Filter settings object public void CreateSourceFilter(string sourceName, string filterName, string filterKind, FilterSettings filterSettings) { - CreateSourceFilter(sourceName, filterName, filterKind, JObject.FromObject(filterSettings)); + CreateSourceFilter(sourceName, filterName, filterKind, JsonObjectExtensions.FromObject(filterSettings, AppJsonSerializerContext.Default.JsonObject.Options).AsObject()); } /// @@ -422,7 +421,7 @@ public TransitionSettings GetCurrentSceneTransition() /// Desired transition name public void SetCurrentSceneTransition(string transitionName) { - var request = new JObject + var request = new JsonObject { { nameof(transitionName), transitionName } }; @@ -436,7 +435,7 @@ public void SetCurrentSceneTransition(string transitionName) /// Desired transition duration (in milliseconds) public void SetCurrentSceneTransitionDuration(int transitionDuration) { - var request = new JObject + var request = new JsonObject { { nameof(transitionDuration), transitionDuration } }; @@ -450,11 +449,10 @@ public void SetCurrentSceneTransitionDuration(int transitionDuration) /// Transition settings (they can be partial) /// Whether to overlay over the current settins or replace them /// Updated transition settings - public void SetCurrentSceneTransitionSettings(JObject transitionSettings, bool overlay) - { - var requestFields = new JObject + public void SetCurrentSceneTransitionSettings(JsonObject transitionSettings, bool overlay) + { var requestFields = new JsonObject { - { nameof(transitionSettings), JToken.FromObject(transitionSettings)}, + { nameof(transitionSettings), JsonNode.Parse(JsonSerializer.Serialize(transitionSettings, AppJsonSerializerContext.Default.JsonObject)) }, { nameof(overlay), overlay } }; @@ -469,7 +467,7 @@ public void SetCurrentSceneTransitionSettings(JObject transitionSettings, bool o /// Interperet `volume` data as decibels instead of amplitude/mul. public void SetInputVolume(string inputName, float inputVolume, bool inputVolumeDb = false) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(inputName), inputName } }; @@ -494,7 +492,7 @@ public void SetInputVolume(string inputName, float inputVolume, bool inputVolume /// An Object containing the volume and mute state of the specified source. public VolumeInfo GetInputVolume(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -510,7 +508,7 @@ public VolumeInfo GetInputVolume(string inputName) /// Whether the input is muted public bool GetInputMute(string inputName) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(inputName), inputName } }; @@ -526,7 +524,7 @@ public bool GetInputMute(string inputName) /// Desired mute state public void SetInputMute(string inputName, bool inputMuted) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(inputName), inputName }, { nameof(inputMuted), inputMuted } @@ -541,7 +539,7 @@ public void SetInputMute(string inputName, bool inputMuted) /// Name of the source which mute state will be toggled public void ToggleInputMute(string inputName) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(inputName), inputName } }; @@ -554,10 +552,10 @@ public void ToggleInputMute(string inputName) /// /// Name of the scene that has the SceneItem /// Id of the Scene Item - /// JObject holding transform settings - public void SetSceneItemTransform(string sceneName, int sceneItemId, JObject sceneItemTransform) + /// JsonObject holding transform settings + public void SetSceneItemTransform(string sceneName, int sceneItemId, JsonObject sceneItemTransform) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId }, @@ -575,7 +573,7 @@ public void SetSceneItemTransform(string sceneName, int sceneItemId, JObject sce /// Transform settings public void SetSceneItemTransform(string sceneName, int sceneItemId, SceneItemTransformInfo sceneItemTransform) { - SetSceneItemTransform(sceneName, sceneItemId, JObject.FromObject(sceneItemTransform)); + SetSceneItemTransform(sceneName, sceneItemId, JsonObjectExtensions.FromObject(sceneItemTransform, AppJsonSerializerContext.Default.JsonObject.Options).AsObject()); } /// @@ -584,7 +582,7 @@ public void SetSceneItemTransform(string sceneName, int sceneItemId, SceneItemTr /// Desired scene collection name public void SetCurrentSceneCollection(string sceneCollectionName) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(sceneCollectionName), sceneCollectionName } }; @@ -610,7 +608,7 @@ public string GetCurrentSceneCollection() public List GetSceneCollectionList() { var response = SendRequest(nameof(GetSceneCollectionList)); - return JsonConvert.DeserializeObject>(response["sceneCollections"].ToString()); + return JsonSerializer.Deserialize>(response["sceneCollections"]?.ToString() ?? "[]", AppJsonSerializerContext.Default.ListString); } /// @@ -619,7 +617,7 @@ public List GetSceneCollectionList() /// Name of the desired profile public void SetCurrentProfile(string profileName) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(profileName), profileName } }; @@ -634,7 +632,7 @@ public void SetCurrentProfile(string profileName) public GetProfileListInfo GetProfileList() { var response = SendRequest(nameof(GetProfileList)); - return JsonConvert.DeserializeObject(response.ToString()); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.GetProfileListInfo); } /// @@ -704,7 +702,7 @@ public string GetRecordDirectory() public RecordingStatus GetRecordStatus() { var response = SendRequest(nameof(GetRecordStatus)); - return JsonConvert.DeserializeObject(response.ToString()); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.RecordingStatus); } /// @@ -725,7 +723,7 @@ public GetTransitionListInfo GetSceneTransitionList() { var response = SendRequest(nameof(GetSceneTransitionList)); - return JsonConvert.DeserializeObject(response.ToString()); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.GetTransitionListInfo); } /// @@ -744,7 +742,7 @@ public bool GetStudioModeEnabled() /// public void SetStudioModeEnabled(bool studioModeEnabled) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(studioModeEnabled), studioModeEnabled } }; @@ -770,7 +768,7 @@ public string GetCurrentPreviewScene() /// Preview scene name public void SetCurrentPreviewScene(string sceneName) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(sceneName), sceneName } }; @@ -840,7 +838,7 @@ public void SaveReplayBuffer() /// Audio offset (in nanoseconds) for the specified source public void SetInputAudioSyncOffset(string inputName, int inputAudioSyncOffset) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(inputName), inputName }, { nameof(inputAudioSyncOffset), inputAudioSyncOffset } @@ -856,7 +854,7 @@ public void SetInputAudioSyncOffset(string inputName, int inputAudioSyncOffset) /// Audio offset (in nanoseconds) of the specified source public int GetInputAudioSyncOffset(string inputName) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(inputName), inputName } }; @@ -872,7 +870,7 @@ public int GetInputAudioSyncOffset(string inputName) /// Scene name from which to delete item public void RemoveSceneItem(string sceneName, int sceneItemId) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId } @@ -887,7 +885,7 @@ public void RemoveSceneItem(string sceneName, int sceneItemId) /// Captions text public void SendStreamCaption(string captionText) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(captionText), captionText } }; @@ -903,7 +901,7 @@ public void SendStreamCaption(string captionText) /// Name of scene to add the new duplicated Scene Item. If not specified will assume sceneName public void DuplicateSceneItem(string sceneName, int sceneItemId, string destinationSceneName = null) { - var requestFields = new JObject + var requestFields = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId } @@ -925,7 +923,7 @@ public Dictionary GetSpecialInputs() { var response = SendRequest(nameof(GetSpecialInputs)); var sources = new Dictionary(); - foreach (KeyValuePair kvp in response) + foreach (var kvp in response) { string key = kvp.Key; string value = (string)kvp.Value; @@ -935,19 +933,17 @@ public Dictionary GetSpecialInputs() } } return sources; - } - - /// + } /// /// Sets the current stream service settings (stream destination). /// Note: Simple RTMP settings can be set with type `rtmp_custom` and the settings fields `server` and `key`. /// /// Stream Service Type Name and Settings objects public void SetStreamServiceSettings(StreamingService service) { - var requestFields = new JObject + var requestFields = new JsonObject { { "streamServiceType", service.Type }, - { "streamServiceSettings", JToken.FromObject(service.Settings) } + { "streamServiceSettings", JsonObjectExtensions.FromObject(service.Settings, AppJsonSerializerContext.Default) } }; SendRequest(nameof(SetStreamServiceSettings), requestFields); @@ -961,7 +957,7 @@ public StreamingService GetStreamServiceSettings() { var response = SendRequest(nameof(GetStreamServiceSettings)); - return JsonConvert.DeserializeObject(response.ToString()); + return JsonSerializer.Deserialize(response.ToString(), AppJsonSerializerContext.Default.StreamingService); } /// @@ -975,7 +971,7 @@ public StreamingService GetStreamServiceSettings() /// The monitor type in use public string GetInputAudioMonitorType(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -991,7 +987,7 @@ public string GetInputAudioMonitorType(string inputName) /// Audio monitor type. See `GetInputAudioMonitorType for possible types. public void SetInputAudioMonitorType(string inputName, string monitorType) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(monitorType), monitorType } @@ -1004,9 +1000,9 @@ public void SetInputAudioMonitorType(string inputName, string monitorType) /// Broadcasts a `CustomEvent` to all WebSocket clients. Receivers are clients which are identified and subscribed. /// /// Data payload to emit to all receivers - public void BroadcastCustomEvent(JObject eventData) + public void BroadcastCustomEvent(JsonObject eventData) { - var request = new JObject + var request = new JsonObject { { nameof(eventData), eventData } }; @@ -1022,7 +1018,7 @@ public void BroadcastCustomEvent(JObject eventData) /// New cursor position to set (milliseconds). public void SetMediaInputCursor(string inputName, int mediaCursor) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(mediaCursor), mediaCursor } @@ -1039,7 +1035,7 @@ public void SetMediaInputCursor(string inputName, int mediaCursor) /// Value to offset the current cursor position by (milliseconds +/-) public void OffsetMediaInputCursor(string inputName, int mediaCursorOffset) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(mediaCursorOffset), mediaCursorOffset } @@ -1057,9 +1053,9 @@ public void OffsetMediaInputCursor(string inputName, int mediaCursorOffset) /// Jobject holding the settings object to initialize the input with /// Whether to set the created scene item to enabled or disabled /// ID of the SceneItem in the scene. - public int CreateInput(string sceneName, string inputName, string inputKind, JObject inputSettings, bool? sceneItemEnabled) + public int CreateInput(string sceneName, string inputName, string inputKind, JsonObject inputSettings, bool? sceneItemEnabled) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(inputName), inputName }, @@ -1085,15 +1081,15 @@ public int CreateInput(string sceneName, string inputName, string inputKind, JOb /// /// Input kind to get the default settings for /// Object of default settings for the input kind - public JObject GetInputDefaultSettings(string inputKind) + public JsonObject GetInputDefaultSettings(string inputKind) { - var request = new JObject + var request = new JsonObject { { nameof(inputKind), inputKind } }; var response = SendRequest(nameof(GetInputDefaultSettings), request); - return (JObject)response["defaultInputSettings"]; + return response["defaultInputSettings"].AsObject(); } /// @@ -1104,17 +1100,17 @@ public JObject GetInputDefaultSettings(string inputKind) /// Array of scene items in the scene public List GetSceneItemList(string sceneName) { - JObject request = null; + JsonObject request = null; if (!string.IsNullOrEmpty(sceneName)) { - request = new JObject + request = new JsonObject { { nameof(sceneName), sceneName } }; } var response = SendRequest(nameof(GetSceneItemList), request); - return response["sceneItems"].Select(m => new SceneItemDetails((JObject)m)).ToList(); + return response["sceneItems"].AsArray().Select(m => new SceneItemDetails(m.AsObject())).ToList(); } /// @@ -1127,7 +1123,7 @@ public List GetSceneItemList(string sceneName) /// Numeric ID of the scene item public int CreateSceneItem(string sceneName, string sourceName, bool sceneItemEnabled = true) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sourceName), sourceName }, @@ -1144,7 +1140,7 @@ public int CreateSceneItem(string sceneName, string sourceName, bool sceneItemEn /// Name for the new scene public void CreateScene(string sceneName) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName } }; @@ -1159,7 +1155,7 @@ public void CreateScene(string sceneName) /// Object of audio tracks and associated enable states public SourceTracks GetInputAudioTracks(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -1172,10 +1168,10 @@ public SourceTracks GetInputAudioTracks(string inputName) /// Sets the enable state of audio tracks of an input. /// /// Name of the input - /// JObject holding track settings to apply - public void SetInputAudioTracks(string inputName, JObject inputAudioTracks) + /// JsonObject holding track settings to apply + public void SetInputAudioTracks(string inputName, JsonObject inputAudioTracks) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(inputAudioTracks), inputAudioTracks } @@ -1191,7 +1187,7 @@ public void SetInputAudioTracks(string inputName, JObject inputAudioTracks) /// Track settings to apply public void SetInputAudioTracks(string inputName, SourceTracks inputAudioTracks) { - SetInputAudioTracks(inputName, JObject.FromObject(inputAudioTracks)); + SetInputAudioTracks(inputName, JsonObjectExtensions.FromObject(inputAudioTracks, AppJsonSerializerContext.Default.JsonObject.Options).AsObject()); } /// @@ -1202,7 +1198,7 @@ public void SetInputAudioTracks(string inputName, SourceTracks inputAudioTracks) /// Whether the source is showing in Program public SourceActiveInfo GetSourceActive(string sourceName) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName } }; @@ -1217,7 +1213,7 @@ public SourceActiveInfo GetSourceActive(string sourceName) /// An object describing the current virtual camera state public VirtualCamStatus GetVirtualCamStatus() { - JObject response = SendRequest(nameof(GetVirtualCamStatus)); + JsonObject response = SendRequest(nameof(GetVirtualCamStatus)); var outputStatus = new VirtualCamStatus(response); return outputStatus; } @@ -1244,7 +1240,7 @@ public void StopVirtualCam() /// Whether the output is active public VirtualCamStatus ToggleVirtualCam() { - JObject response = SendRequest(nameof(ToggleVirtualCam)); + JsonObject response = SendRequest(nameof(ToggleVirtualCam)); var outputStatus = new VirtualCamStatus(response); return outputStatus; } @@ -1255,9 +1251,9 @@ public VirtualCamStatus ToggleVirtualCam() /// The data realm to select. `OBS_WEBSOCKET_DATA_REALM_GLOBAL` or `OBS_WEBSOCKET_DATA_REALM_PROFILE` /// The name of the slot to retrieve data from /// Value associated with the slot. `null` if not set - public JObject GetPersistentData(string realm, string slotName) + public JsonObject GetPersistentData(string realm, string slotName) { - var request = new JObject + var request = new JsonObject { { nameof(realm), realm }, { nameof(slotName), slotName } @@ -1272,9 +1268,9 @@ public JObject GetPersistentData(string realm, string slotName) /// The data realm to select. `OBS_WEBSOCKET_DATA_REALM_GLOBAL` or `OBS_WEBSOCKET_DATA_REALM_PROFILE` /// The name of the slot to retrieve data from /// The value to apply to the slot - public void SetPersistentData(string realm, string slotName, JObject slotValue) + public void SetPersistentData(string realm, string slotName, JsonObject slotValue) { - var request = new JObject + var request = new JsonObject { { nameof(realm), realm }, { nameof(slotName), slotName }, @@ -1290,7 +1286,7 @@ public void SetPersistentData(string realm, string slotName, JObject slotValue) /// Name for the new scene collection public void CreateSceneCollection(string sceneCollectionName) { - var request = new JObject + var request = new JsonObject { { nameof(sceneCollectionName), sceneCollectionName } }; @@ -1304,7 +1300,7 @@ public void CreateSceneCollection(string sceneCollectionName) /// Name for the new profile public void CreateProfile(string profileName) { - var request = new JObject + var request = new JsonObject { { nameof(profileName), profileName } }; @@ -1318,7 +1314,7 @@ public void CreateProfile(string profileName) /// Name of the profile to remove public void RemoveProfile(string profileName) { - var request = new JObject + var request = new JsonObject { { nameof(profileName), profileName } }; @@ -1332,9 +1328,9 @@ public void RemoveProfile(string profileName) /// Category of the parameter to get /// Name of the parameter to get /// - public JObject GetProfileParameter(string parameterCategory, string parameterName) + public JsonObject GetProfileParameter(string parameterCategory, string parameterName) { - var request = new JObject + var request = new JsonObject { { nameof(parameterCategory), parameterCategory }, { nameof(parameterName), parameterName } @@ -1351,7 +1347,7 @@ public JObject GetProfileParameter(string parameterCategory, string parameterNam /// Value of the parameter to set. Use `null` to delete public void SetProfileParameter(string parameterCategory, string parameterName, string parameterValue) { - var request = new JObject + var request = new JsonObject { { nameof(parameterCategory), parameterCategory }, { nameof(parameterName), parameterName }, @@ -1368,7 +1364,7 @@ public void SetProfileParameter(string parameterCategory, string parameterName, /// Object containing video settings public void SetVideoSettings(ObsVideoSettings obsVideoSettings) { - SendRequest(nameof(SetVideoSettings), JObject.FromObject(obsVideoSettings)); + SendRequest(nameof(SetVideoSettings), JsonObjectExtensions.FromObject(obsVideoSettings, AppJsonSerializerContext.Default.JsonObject.Options).AsObject()); } /// @@ -1376,9 +1372,9 @@ public void SetVideoSettings(ObsVideoSettings obsVideoSettings) /// /// Filter kind to get the default settings for /// Object of default settings for the filter kind - public JObject GetSourceFilterDefaultSettings(string filterKind) + public JsonObject GetSourceFilterDefaultSettings(string filterKind) { - var request = new JObject + var request = new JsonObject { { nameof(filterKind), filterKind } }; @@ -1394,7 +1390,7 @@ public JObject GetSourceFilterDefaultSettings(string filterKind) /// New name for the filter public void SetSourceFilterName(string sourceName, string filterName, string newFilterName) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(filterName), filterName }, @@ -1412,7 +1408,7 @@ public void SetSourceFilterName(string sourceName, string filterName, string new /// New index position of the filter public void SetSourceFilterIndex(string sourceName, string filterName, int filterIndex) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(filterName), filterName }, @@ -1428,7 +1424,7 @@ public void SetSourceFilterIndex(string sourceName, string filterName, int filte /// Version info in an object public ObsVersion GetVersion() { - JObject response = SendRequest(nameof(GetVersion)); + JsonObject response = SendRequest(nameof(GetVersion)); return new ObsVersion(response); } @@ -1441,9 +1437,9 @@ public ObsVersion GetVersion() /// The request type to call /// Object containing appropriate request data /// Object containing appropriate response data. {} if request does not provide any response data - public JObject CallVendorRequest(string vendorName, string requestType, JObject requestData = null) + public JsonObject CallVendorRequest(string vendorName, string requestType, JsonObject requestData = null) { - var request = new JObject + var request = new JsonObject { { nameof(vendorName), vendorName }, { nameof(requestType), requestType }, @@ -1460,7 +1456,7 @@ public JObject CallVendorRequest(string vendorName, string requestType, JObject public List GetHotkeyList() { var response = SendRequest(nameof(GetHotkeyList)); - return JsonConvert.DeserializeObject>(response["hotkeys"].ToString()); + return JsonSerializer.Deserialize>(response["hotkeys"]?.ToString() ?? "[]", AppJsonSerializerContext.Default.ListString); } /// @@ -1470,7 +1466,7 @@ public List GetHotkeyList() /// Number of frames to sleep for (if `SERIAL_FRAME` mode) public void Sleep(int sleepMillis, int sleepFrames) { - var request = new JObject + var request = new JsonObject { { nameof(sleepMillis), sleepMillis }, { nameof(sleepFrames), sleepFrames } @@ -1486,7 +1482,7 @@ public void Sleep(int sleepMillis, int sleepFrames) /// List of Inputs in OBS public List GetInputList(string inputKind = null) { - var request = new JObject + var request = new JsonObject { { nameof(inputKind), inputKind } }; @@ -1496,9 +1492,9 @@ public List GetInputList(string inputKind = null) : SendRequest(nameof(GetInputList), request); var returnList = new List(); - foreach (var input in response["inputs"]) + foreach (var input in response["inputs"].AsObject()) { - returnList.Add(new InputBasicInfo(input as JObject)); + returnList.Add(new InputBasicInfo(input.Value.AsObject())); } return returnList; @@ -1511,7 +1507,7 @@ public List GetInputList(string inputKind = null) /// Array of input kinds public List GetInputKindList(bool unversioned = false) { - var request = new JObject + var request = new JsonObject { { nameof(unversioned), unversioned } }; @@ -1520,7 +1516,7 @@ public List GetInputKindList(bool unversioned = false) ? SendRequest(nameof(GetInputKindList)) : SendRequest(nameof(GetInputKindList), request); - return JsonConvert.DeserializeObject>(response["inputKinds"].ToString()); + return JsonSerializer.Deserialize>(response["inputKinds"]?.ToString() ?? "[]", AppJsonSerializerContext.Default.ListString); } /// @@ -1530,7 +1526,7 @@ public List GetInputKindList(bool unversioned = false) /// Name of the input to remove public void RemoveInput(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -1545,7 +1541,7 @@ public void RemoveInput(string inputName) /// New name for the input public void SetInputName(string inputName, string newInputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(newInputName), newInputName } @@ -1562,7 +1558,7 @@ public void SetInputName(string inputName, string newInputName) /// New populated InputSettings object public InputSettings GetInputSettings(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -1588,9 +1584,9 @@ public void SetInputSettings(InputSettings inputSettings, bool overlay = true) /// Name of the input to set the settings of /// Object of settings to apply /// True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. - public void SetInputSettings(string inputName, JObject inputSettings, bool overlay = true) + public void SetInputSettings(string inputName, JsonObject inputSettings, bool overlay = true) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(inputSettings), inputSettings }, @@ -1607,7 +1603,7 @@ public void SetInputSettings(string inputName, JObject inputSettings, bool overl /// Audio balance value from 0.0-1.0 public double GetInputAudioBalance(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -1623,7 +1619,7 @@ public double GetInputAudioBalance(string inputName) /// New audio balance value public void SetInputAudioBalance(string inputName, double inputAudioBalance) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(inputAudioBalance), inputAudioBalance } @@ -1640,16 +1636,16 @@ public void SetInputAudioBalance(string inputName, double inputAudioBalance) /// Name of the input /// Name of the list property to get the items of /// Array of items in the list property - public List GetInputPropertiesListPropertyItems(string inputName, string propertyName) + public List GetInputPropertiesListPropertyItems(string inputName, string propertyName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(propertyName), propertyName } }; var response = SendRequest(nameof(GetInputPropertiesListPropertyItems), request); - return response["propertyItems"].Value>(); + return response["propertyItems"].AsArray().Select(x => x.AsObject()).ToList(); } /// @@ -1661,7 +1657,7 @@ public List GetInputPropertiesListPropertyItems(string inputName, strin /// Name of the button property to press public void PressInputPropertiesButton(string inputName, string propertyName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(propertyName), propertyName } @@ -1685,7 +1681,7 @@ public void PressInputPropertiesButton(string inputName, string propertyName) /// Object containing string mediaState, int mediaDuration, int mediaCursor properties public MediaInputStatus GetMediaInputStatus(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -1700,7 +1696,7 @@ public MediaInputStatus GetMediaInputStatus(string inputName) /// Identifier of the `ObsMediaInputAction` enum public void TriggerMediaInputAction(string inputName, string mediaAction) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName }, { nameof(mediaAction), mediaAction } @@ -1735,15 +1731,15 @@ public void ToggleRecordPause() /// /// Name of the group to get the items of /// Array of scene items in the group - public List GetGroupSceneItemList(string sceneName) + public List GetGroupSceneItemList(string sceneName) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName } }; var response = SendRequest(nameof(GetGroupSceneItemList), request); - return JsonConvert.DeserializeObject>((string)response["sceneItems"]); + return JsonSerializer.Deserialize>((string)response["sceneItems"], AppJsonSerializerContext.Default.ListJsonObject); } /// @@ -1755,7 +1751,7 @@ public List GetGroupSceneItemList(string sceneName) /// Numeric ID of the scene item public int GetSceneItemId(string sceneName, string sourceName, int searchOffset) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sourceName), sourceName }, @@ -1776,19 +1772,19 @@ public int GetSceneItemId(string sceneName, string sourceName, int searchOffset) public SceneItemTransformInfo GetSceneItemTransform(string sceneName, int sceneItemId) { var response = GetSceneItemTransformRaw(sceneName, sceneItemId); - return JsonConvert.DeserializeObject(response["sceneItemTransform"].ToString()); + return JsonSerializer.Deserialize(response["sceneItemTransform"]?.ToString() ?? "{}", AppJsonSerializerContext.Default.SceneItemTransformInfo); } /// - /// Gets the JObject of transform settings for a scene item. Use this one you don't want it populated with default values. + /// Gets the JsonObject of transform settings for a scene item. Use this one you don't want it populated with default values. /// Scenes and Groups /// /// Name of the scene the item is in /// Numeric ID of the scene item /// Object containing scene item transform info - public JObject GetSceneItemTransformRaw(string sceneName, int sceneItemId) + public JsonObject GetSceneItemTransformRaw(string sceneName, int sceneItemId) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId } @@ -1806,7 +1802,7 @@ public JObject GetSceneItemTransformRaw(string sceneName, int sceneItemId) /// Whether the scene item is enabled. `true` for enabled, `false` for disabled public bool GetSceneItemEnabled(string sceneName, int sceneItemId) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId } @@ -1825,7 +1821,7 @@ public bool GetSceneItemEnabled(string sceneName, int sceneItemId) /// New enable state of the scene item public void SetSceneItemEnabled(string sceneName, int sceneItemId, bool sceneItemEnabled) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId }, @@ -1844,7 +1840,7 @@ public void SetSceneItemEnabled(string sceneName, int sceneItemId, bool sceneIte /// Whether the scene item is locked. `true` for locked, `false` for unlocked public bool GetSceneItemLocked(string sceneName, int sceneItemId) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId } @@ -1863,7 +1859,7 @@ public bool GetSceneItemLocked(string sceneName, int sceneItemId) /// New lock state of the scene item public void SetSceneItemLocked(string sceneName, int sceneItemId, bool sceneItemLocked) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId }, @@ -1883,7 +1879,7 @@ public void SetSceneItemLocked(string sceneName, int sceneItemId, bool sceneItem /// Index position of the scene item public int GetSceneItemIndex(string sceneName, int sceneItemId) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId } @@ -1902,7 +1898,7 @@ public int GetSceneItemIndex(string sceneName, int sceneItemId) /// New index position of the scene item public void SetSceneItemIndex(string sceneName, int sceneItemId, int sceneItemIndex) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId }, @@ -1929,7 +1925,7 @@ public void SetSceneItemIndex(string sceneName, int sceneItemId, int sceneItemIn /// Current blend mode public string GetSceneItemBlendMode(string sceneName, int sceneItemId) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId } @@ -1948,7 +1944,7 @@ public string GetSceneItemBlendMode(string sceneName, int sceneItemId) /// public void SetSceneItemBlendMode(string sceneName, int sceneItemId, string sceneItemBlendMode) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(sceneItemId), sceneItemId }, @@ -1966,7 +1962,7 @@ public void SetSceneItemBlendMode(string sceneName, int sceneItemId, string scen public List GetGroupList() { var response = SendRequest(nameof(GetGroupList)); - return JsonConvert.DeserializeObject>(response["groups"].ToString()); + return JsonSerializer.Deserialize>(response["groups"]?.ToString() ?? "[]", AppJsonSerializerContext.Default.ListString); } /// @@ -1975,7 +1971,7 @@ public List GetGroupList() /// Name of the scene to remove public void RemoveScene(string sceneName) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName } }; @@ -1990,7 +1986,7 @@ public void RemoveScene(string sceneName) /// New name for the scene public void SetSceneName(string sceneName, string newSceneName) { - var request = new JObject + var request = new JsonObject { { nameof(sceneName), sceneName }, { nameof(newSceneName), newSceneName } @@ -2013,7 +2009,7 @@ public void SetSceneName(string sceneName, string newSceneName) /// Base64-encoded screenshot public string GetSourceScreenshot(string sourceName, string imageFormat, int imageWidth = -1, int imageHeight = -1, int imageCompressionQuality = -1) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(imageFormat), imageFormat } @@ -2044,7 +2040,7 @@ public string GetSourceScreenshot(string sourceName, string imageFormat, int ima public List GetTransitionKindList() { var response = SendRequest(nameof(GetTransitionKindList)); - return JsonConvert.DeserializeObject>(response["transitionKinds"].ToString()); + return JsonSerializer.Deserialize>(response["transitionKinds"]?.ToString() ?? "[]", AppJsonSerializerContext.Default.ListString); } /// @@ -2064,7 +2060,7 @@ public double GetCurrentSceneTransitionCursor() /// Name of the input to open the dialog of public void OpenInputPropertiesDialog(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -2078,7 +2074,7 @@ public void OpenInputPropertiesDialog(string inputName) /// Name of the input to open the dialog of public void OpenInputFiltersDialog(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -2092,7 +2088,7 @@ public void OpenInputFiltersDialog(string inputName) /// Name of the input to open the dialog of public void OpenInputInteractDialog(string inputName) { - var request = new JObject + var request = new JsonObject { { nameof(inputName), inputName } }; @@ -2109,9 +2105,9 @@ public List GetMonitorList() var response = SendRequest(nameof(GetMonitorList)); var monitors = new List(); - foreach(var monitor in response["monitors"]) + foreach(var monitor in response["monitors"].AsObject()) { - monitors.Add(new Monitor((JObject)monitor)); + monitors.Add(new Monitor(monitor.Value.AsObject())); } return monitors; } @@ -2125,7 +2121,7 @@ public List GetMonitorList() /// Monitor index, use GetMonitorList to obtain index. -1 to open in windowed mode public void OpenSourceProjector(string sourceName, string projectorGeometry, int monitorIndex = -1) { - var request = new JObject + var request = new JsonObject { { nameof(sourceName), sourceName }, { nameof(projectorGeometry), projectorGeometry }, @@ -2144,7 +2140,7 @@ public void OpenSourceProjector(string sourceName, string projectorGeometry, int /// Monitor index, use GetMonitorList to obtain index. -1 to open in windowed mode public void OpenVideoMixProjector(string videoMixType, string projectorGeometry, int monitorIndex = -1) { - var request = new JObject + var request = new JsonObject { { nameof(videoMixType), videoMixType }, { nameof(projectorGeometry), projectorGeometry }, diff --git a/obs-websocket-dotnet/Types/Events/InputAudioTracksChangedEventArgs.cs b/obs-websocket-dotnet/Types/Events/InputAudioTracksChangedEventArgs.cs index edc19ad..9f859f5 100644 --- a/obs-websocket-dotnet/Types/Events/InputAudioTracksChangedEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/InputAudioTracksChangedEventArgs.cs @@ -1,5 +1,5 @@ using System; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types.Events { @@ -16,14 +16,14 @@ public class InputAudioTracksChangedEventArgs : EventArgs /// /// Object of audio tracks along with their associated enable states /// - public JObject InputAudioTracks {get;} + public JsonObject InputAudioTracks {get;} /// /// Default Constructor /// /// The input name /// The audio track data as a JObject - public InputAudioTracksChangedEventArgs(string inputName, JObject inputAudioTracks) + public InputAudioTracksChangedEventArgs(string inputName, JsonObject inputAudioTracks) { InputName = inputName; InputAudioTracks = inputAudioTracks; diff --git a/obs-websocket-dotnet/Types/Events/InputCreatedEventArgs.cs b/obs-websocket-dotnet/Types/Events/InputCreatedEventArgs.cs index 810957a..fc38cb9 100644 --- a/obs-websocket-dotnet/Types/Events/InputCreatedEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/InputCreatedEventArgs.cs @@ -1,5 +1,5 @@ using System; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; using OBSWebsocketDotNet; namespace OBSWebsocketDotNet.Types.Events @@ -27,12 +27,12 @@ public class InputCreatedEventArgs : EventArgs /// /// The settings configured to the input when it was created /// - public JObject InputSettings { get; } + public JsonObject InputSettings { get; } /// /// The default settings for the input /// - public JObject DefaultInputSettings { get; } + public JsonObject DefaultInputSettings { get; } /// /// Default Constructor @@ -42,7 +42,7 @@ public class InputCreatedEventArgs : EventArgs /// The unversioned kind of input /// The input settings as a JObject /// The default input settings as a JObject - public InputCreatedEventArgs(string inputName, string inputKind, string unversionedInputKind, JObject inputSettings, JObject defaultInputSettings) + public InputCreatedEventArgs(string inputName, string inputKind, string unversionedInputKind, JsonObject inputSettings, JsonObject defaultInputSettings) { InputName = inputName; InputKind = inputKind; diff --git a/obs-websocket-dotnet/Types/Events/InputVolumeMetersEventArgs.cs b/obs-websocket-dotnet/Types/Events/InputVolumeMetersEventArgs.cs index 647929c..30e45e9 100644 --- a/obs-websocket-dotnet/Types/Events/InputVolumeMetersEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/InputVolumeMetersEventArgs.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types.Events { @@ -12,13 +12,13 @@ public class InputVolumeMetersEventArgs : EventArgs /// /// Array of active inputs with their associated volume levels /// - public List inputs { get; } + public List inputs { get; } /// /// Default Constructor /// /// Collection inputs as JObjects - public InputVolumeMetersEventArgs(List inputs) + public InputVolumeMetersEventArgs(List inputs) { this.inputs = inputs; } diff --git a/obs-websocket-dotnet/Types/Events/SceneItemListReindexedEventArgs.cs b/obs-websocket-dotnet/Types/Events/SceneItemListReindexedEventArgs.cs index 82ee04e..5379a59 100644 --- a/obs-websocket-dotnet/Types/Events/SceneItemListReindexedEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/SceneItemListReindexedEventArgs.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types.Events { @@ -17,14 +17,14 @@ public class SceneItemListReindexedEventArgs : EventArgs /// /// List of all scene items as JObject /// - public List SceneItems { get; } + public List SceneItems { get; } /// /// Default Constructor /// /// The scene name /// The scene item data as a colleciton of JObjects - public SceneItemListReindexedEventArgs(string sceneName, List sceneItems) + public SceneItemListReindexedEventArgs(string sceneName, List sceneItems) { SceneName = sceneName; SceneItems = sceneItems; diff --git a/obs-websocket-dotnet/Types/Events/SceneListChangedEventArgs.cs b/obs-websocket-dotnet/Types/Events/SceneListChangedEventArgs.cs index 3d0ccd0..0aa5ffb 100644 --- a/obs-websocket-dotnet/Types/Events/SceneListChangedEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/SceneListChangedEventArgs.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types.Events { @@ -12,13 +12,13 @@ public class SceneListChangedEventArgs : EventArgs /// /// Updated array of scenes /// - public List Scenes { get; } + public List Scenes { get; } /// /// Default Constructor /// /// Collection of scene data as JObjects - public SceneListChangedEventArgs(List scenes) + public SceneListChangedEventArgs(List scenes) { Scenes = scenes; } diff --git a/obs-websocket-dotnet/Types/Events/SourceFilterCreatedEventArgs.cs b/obs-websocket-dotnet/Types/Events/SourceFilterCreatedEventArgs.cs index 59104d1..bde3033 100644 --- a/obs-websocket-dotnet/Types/Events/SourceFilterCreatedEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/SourceFilterCreatedEventArgs.cs @@ -1,5 +1,5 @@ using System; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; using OBSWebsocketDotNet; namespace OBSWebsocketDotNet.Types.Events @@ -32,12 +32,12 @@ public class SourceFilterCreatedEventArgs : EventArgs /// /// The settings configured to the filter when it was created /// - public JObject FilterSettings{ get; } + public JsonObject FilterSettings{ get; } /// /// The default settings for the filter /// - public JObject DefaultFilterSettings { get; } + public JsonObject DefaultFilterSettings { get; } /// /// Default Constructor @@ -48,7 +48,7 @@ public class SourceFilterCreatedEventArgs : EventArgs /// The index of the filter /// The filters settings as a JObject /// The default filter settings as a JObject - public SourceFilterCreatedEventArgs(string sourceName, string filterName, string filterKind, int filterIndex, JObject filterSettings, JObject defaultFilterSettings) + public SourceFilterCreatedEventArgs(string sourceName, string filterName, string filterKind, int filterIndex, JsonObject filterSettings, JsonObject defaultFilterSettings) { SourceName = sourceName; FilterName = filterName; diff --git a/obs-websocket-dotnet/Types/Events/UnsupportedEventArgs.cs b/obs-websocket-dotnet/Types/Events/UnsupportedEventArgs.cs index e79bc6e..48b1040 100644 --- a/obs-websocket-dotnet/Types/Events/UnsupportedEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/UnsupportedEventArgs.cs @@ -1,5 +1,5 @@ using System; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types.Events { @@ -15,12 +15,12 @@ public class UnsupportedEventArgs : EventArgs /// /// The body of the event /// - public JObject Body { get; } + public JsonObject Body { get; } /// /// Event args for unsupported events /// - public UnsupportedEventArgs(string eventType, JObject body) + public UnsupportedEventArgs(string eventType, JsonObject body) { EventType = eventType; Body = body; diff --git a/obs-websocket-dotnet/Types/Events/VendorEventArgs.cs b/obs-websocket-dotnet/Types/Events/VendorEventArgs.cs index bf4690c..4ac1b07 100644 --- a/obs-websocket-dotnet/Types/Events/VendorEventArgs.cs +++ b/obs-websocket-dotnet/Types/Events/VendorEventArgs.cs @@ -1,5 +1,5 @@ using System; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types.Events { @@ -21,7 +21,7 @@ public class VendorEventArgs : EventArgs /// /// Vendor-provided event data. {} if event does not provide any data /// - public JObject eventData { get; } + public JsonObject eventData { get; } /// /// Default Constructor @@ -29,7 +29,7 @@ public class VendorEventArgs : EventArgs /// The vendor name /// The event type /// The event data as a Json Object - public VendorEventArgs(string vendorName, string eventType, JObject eventData) + public VendorEventArgs(string vendorName, string eventType, JsonObject eventData) { VendorName = vendorName; EventType = eventType; diff --git a/obs-websocket-dotnet/Types/FilterReorderItem.cs b/obs-websocket-dotnet/Types/FilterReorderItem.cs index 951dd09..fb746c8 100644 --- a/obs-websocket-dotnet/Types/FilterReorderItem.cs +++ b/obs-websocket-dotnet/Types/FilterReorderItem.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; namespace OBSWebsocketDotNet.Types { @@ -10,13 +10,13 @@ public class FilterReorderItem /// /// Name of filter /// - [JsonProperty(PropertyName = "name")] + [JsonPropertyName("name")] public string Name { set; get; } /// /// Type of filter /// - [JsonProperty(PropertyName = "type")] + [JsonPropertyName("type")] public string Type { set; get; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/FilterSettings.cs b/obs-websocket-dotnet/Types/FilterSettings.cs index 01718e1..ff35a6b 100644 --- a/obs-websocket-dotnet/Types/FilterSettings.cs +++ b/obs-websocket-dotnet/Types/FilterSettings.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,31 +11,31 @@ public class FilterSettings /// /// Name of the filter /// - [JsonProperty(PropertyName = "filterName")] + [JsonPropertyName("filterName")] public string Name { set; get; } /// /// Type of the specified filter /// - [JsonProperty(PropertyName = "filterKind")] + [JsonPropertyName("filterKind")] public string Kind { set; get; } /// /// Index of the filter in the list, beginning at 0 /// - [JsonProperty(PropertyName = "filterIndex")] + [JsonPropertyName("filterIndex")] public int Index { get; set; } /// /// Status of the specified filter /// - [JsonProperty(PropertyName = "filterEnabled")] + [JsonPropertyName("filterEnabled")] public bool IsEnabled { set; get; } /// /// Settings for the filter /// - [JsonProperty(PropertyName = "filterSettings")] - public JObject Settings { set; get; } + [JsonPropertyName("filterSettings")] + public JsonObject Settings { set; get; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/GetProfileListInfo.cs b/obs-websocket-dotnet/Types/GetProfileListInfo.cs index 541812e..3255f21 100644 --- a/obs-websocket-dotnet/Types/GetProfileListInfo.cs +++ b/obs-websocket-dotnet/Types/GetProfileListInfo.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; using System.Collections.Generic; namespace OBSWebsocketDotNet.Types @@ -11,13 +11,13 @@ public class GetProfileListInfo /// /// Name of the currently active profile /// - [JsonProperty(PropertyName = "currentProfileName")] + [JsonPropertyName("currentProfileName")] public string CurrentProfileName { set; get; } /// /// List of all profiles /// - [JsonProperty(PropertyName = "profiles")] + [JsonPropertyName("profiles")] public List Profiles { set; get; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/GetSceneListInfo.cs b/obs-websocket-dotnet/Types/GetSceneListInfo.cs index 45b5e68..5d6d799 100644 --- a/obs-websocket-dotnet/Types/GetSceneListInfo.cs +++ b/obs-websocket-dotnet/Types/GetSceneListInfo.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; using System.Collections.Generic; namespace OBSWebsocketDotNet.Types @@ -11,20 +11,20 @@ public class GetSceneListInfo /// /// Name of the currently active program scene /// - [JsonProperty(PropertyName = "currentProgramSceneName")] + [JsonPropertyName("currentProgramSceneName")] public string CurrentProgramSceneName { set; get; } /// /// Name of the currently active preview/studio scene /// Note: Will return null if not in studio mode /// - [JsonProperty(PropertyName = "currentPreviewSceneName")] + [JsonPropertyName("currentPreviewSceneName")] public string CurrentPreviewSceneName { set; get; } /// /// Ordered list of the current profile's scenes /// - [JsonProperty(PropertyName = "scenes")] + [JsonPropertyName("scenes")] public List Scenes { set; get; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/GetTransitionListInfo.cs b/obs-websocket-dotnet/Types/GetTransitionListInfo.cs index aeb5669..72682bb 100644 --- a/obs-websocket-dotnet/Types/GetTransitionListInfo.cs +++ b/obs-websocket-dotnet/Types/GetTransitionListInfo.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; using System.Collections.Generic; namespace OBSWebsocketDotNet.Types @@ -11,19 +11,19 @@ public class GetTransitionListInfo /// /// Name of the currently active transition /// - [JsonProperty(PropertyName = "currentSceneTransitionName")] + [JsonPropertyName("currentSceneTransitionName")] public string CurrentTransition { set; get; } /// /// Kind of the currently active transition /// - [JsonProperty(PropertyName = "currentSceneTransitionKind")] + [JsonPropertyName("currentSceneTransitionKind")] public string CurrentTransitionKing { set; get; } /// /// List of transitions. /// - [JsonProperty(PropertyName = "transitions")] + [JsonPropertyName("transitions")] public List Transitions { set; get; } } } diff --git a/obs-websocket-dotnet/Types/Input.cs b/obs-websocket-dotnet/Types/Input.cs index b342e85..c4936d8 100644 --- a/obs-websocket-dotnet/Types/Input.cs +++ b/obs-websocket-dotnet/Types/Input.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,22 +11,23 @@ public abstract class Input /// /// Name of the Input /// - [JsonProperty(PropertyName = "inputName")] + [JsonPropertyName("inputName")] public string InputName { get; set; } /// /// Kind of the Input /// - [JsonProperty(PropertyName = "inputKind")] + [JsonPropertyName("inputKind")] public string InputKind { get; set; } /// /// Instantiate object from response data /// /// - public Input(JObject body) + public Input(JsonObject body) { - JsonConvert.PopulateObject(body.ToString(), this); + InputName = body["inputName"]?.GetValue() ?? InputName; + InputKind = body["inputKind"]?.GetValue() ?? InputKind; } /// diff --git a/obs-websocket-dotnet/Types/InputBasicInfo.cs b/obs-websocket-dotnet/Types/InputBasicInfo.cs index 3306024..65aca59 100644 --- a/obs-websocket-dotnet/Types/InputBasicInfo.cs +++ b/obs-websocket-dotnet/Types/InputBasicInfo.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using System; using System.Collections.Generic; using System.Text; @@ -14,16 +14,16 @@ public class InputBasicInfo : Input /// /// Unversioned Kind of the Input /// - [JsonProperty(PropertyName = "unversionedInputKind")] + [JsonPropertyName("unversionedInputKind")] public string UnversionedKind { get; set; } /// /// Instantiate object from response data /// /// - public InputBasicInfo(JObject body) : base(body) + public InputBasicInfo(JsonObject body) : base(body) { - JsonConvert.PopulateObject(body.ToString(), this); + UnversionedKind = body["unversionedInputKind"]?.GetValue() ?? UnversionedKind; } /// diff --git a/obs-websocket-dotnet/Types/InputBrowserSourceSettings.cs b/obs-websocket-dotnet/Types/InputBrowserSourceSettings.cs index 73b750c..5b59e45 100644 --- a/obs-websocket-dotnet/Types/InputBrowserSourceSettings.cs +++ b/obs-websocket-dotnet/Types/InputBrowserSourceSettings.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using System; using System.Collections.Generic; using System.Text; @@ -18,73 +18,73 @@ public class InputBrowserSourceSettings : Input /// /// Set a custom FPS (using the FPS property) /// - [JsonProperty(PropertyName = "fps_custom")] + [JsonPropertyName("fps_custom")] public bool CustomFPS { get; set; } = false; /// /// Frames Per Second /// - [JsonProperty(PropertyName = "fps")] + [JsonPropertyName("fps")] public int FPS { get; set; } = 30; /// /// Control audio via OBS /// - [JsonProperty(PropertyName = "reroute_audio")] + [JsonPropertyName("reroute_audio")] public bool RerouteAudio { get; set; } = false; /// /// Height /// - [JsonProperty(PropertyName = "height")] + [JsonPropertyName("height")] public int Height { get; set; } = 600; /// /// Width /// - [JsonProperty(PropertyName = "width")] + [JsonPropertyName("width")] public int Width { get; set; } = 800; /// /// Custom CSS /// - [JsonProperty(PropertyName = "css")] + [JsonPropertyName("css")] public string CSS { get; set; } = CSS_DEFAULT_VALUE; /// /// Is Local file /// - [JsonProperty(PropertyName = "is_local_file")] + [JsonPropertyName("is_local_file")] public bool IsLocalFile { get; set; } = false; /// /// Local filename (when IsLocalFile is true) /// - [JsonProperty(PropertyName = "local_file")] + [JsonPropertyName("local_file")] public string LocalFile { get; set; } /// /// URL (when IsLocalFile is false) /// - [JsonProperty(PropertyName = "url")] + [JsonPropertyName("url")] public string URL { get; set; } /// /// Refresh browser when scene becomes active /// - [JsonProperty(PropertyName = "restart_when_active")] + [JsonPropertyName("restart_when_active")] public bool RestartWhenActive { get; set; } = false; /// /// Shutdown source when not visible /// - [JsonProperty(PropertyName = "shutdown")] + [JsonPropertyName("shutdown")] public bool ShutdownWhenNotVisible { get; set; } = false; /// /// Page Permissions /// - [JsonProperty(PropertyName = "webpage_control_level")] + [JsonPropertyName("webpage_control_level")] public int ControlLevel { get; set; } = 1; /// @@ -98,13 +98,25 @@ public static InputBrowserSourceSettings FromInputSettings(InputSettings setting return new InputBrowserSourceSettings(settings); } // Private Constrctor - private InputBrowserSourceSettings(InputSettings settings) : base(JObject.FromObject(settings)) + private InputBrowserSourceSettings(InputSettings settings) : base(JsonSerializer.SerializeToNode(settings, AppJsonSerializerContext.Default.InputSettings)?.AsObject()) { if (settings.InputKind != SUPPORTED_INPUT_KIND) { throw new InvalidCastException(); } - JsonConvert.PopulateObject(settings.Settings.ToString(), this); + CustomFPS = settings.Settings["fps_custom"]?.GetValue() ?? CustomFPS; + FPS = settings.Settings["fps"]?.GetValue() ?? FPS; + RerouteAudio = settings.Settings["reroute_audio"]?.GetValue() ?? RerouteAudio; + Height = settings.Settings["height"]?.GetValue() ?? Height; + Width = settings.Settings["width"]?.GetValue() ?? Width; + CSS = settings.Settings["css"]?.GetValue() ?? CSS; + IsLocalFile = settings.Settings["is_local_file"]?.GetValue() ?? IsLocalFile; + LocalFile = settings.Settings["local_file"]?.GetValue() ?? LocalFile; + URL = settings.Settings["url"]?.GetValue() ?? URL; + RestartWhenActive = settings.Settings["restart_when_active"]?.GetValue() ?? RestartWhenActive; + ShutdownWhenNotVisible = settings.Settings["shutdown"]?.GetValue() ?? ShutdownWhenNotVisible; + ControlLevel = settings.Settings["webpage_control_level"]?.GetValue() ?? ControlLevel; + } } } diff --git a/obs-websocket-dotnet/Types/InputFFMpegSettings.cs b/obs-websocket-dotnet/Types/InputFFMpegSettings.cs index 43eb8cc..c6b30e2 100644 --- a/obs-websocket-dotnet/Types/InputFFMpegSettings.cs +++ b/obs-websocket-dotnet/Types/InputFFMpegSettings.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using System; using System.Collections.Generic; using System.Text; @@ -17,73 +17,73 @@ public class InputFFMpegSettings : Input /// /// Buffering MB /// - [JsonProperty(PropertyName = "buffering_mb")] + [JsonPropertyName("buffering_mb")] public int BufferingMB { get; set; } = 2; /// /// Clear window when media ends /// - [JsonProperty(PropertyName = "clear_on_media_end")] + [JsonPropertyName("clear_on_media_end")] public bool ClearOnMediaEnd { get; set; } = true; /// /// Close when inactive /// - [JsonProperty(PropertyName = "close_when_inactive")] + [JsonPropertyName("close_when_inactive")] public bool CloseWhenInactive { get; set; } = false; /// /// Color Range /// - [JsonProperty(PropertyName = "color_range")] + [JsonPropertyName("color_range")] public int ColorRange { get; set; } = 0; /// /// HW Decoder /// - [JsonProperty(PropertyName = "hw_decode")] + [JsonPropertyName("hw_decode")] public bool HWDecode { get; set; } = false; /// /// Is Local file /// - [JsonProperty(PropertyName = "is_local_file")] + [JsonPropertyName("is_local_file")] public bool IsLocalFile { get; set; } = true; /// /// Local filename /// - [JsonProperty(PropertyName = "local_file")] + [JsonPropertyName("local_file")] public string LocalFile { get; set; } /// /// Looping /// - [JsonProperty(PropertyName = "looping")] + [JsonPropertyName("looping")] public bool Looping { get; set; } = false; /// /// Apply alpha in linear space /// - [JsonProperty(PropertyName = "linear_alpha")] + [JsonPropertyName("linear_alpha")] public bool LinearAlpha { get; set; } = false; /// /// Restart when activated /// - [JsonProperty(PropertyName = "restart_on_activate")] + [JsonPropertyName("restart_on_activate")] public bool RestartOnActivate { get; set; } = true; /// /// ffmpeg options /// - [JsonProperty(PropertyName = "ffmpeg_options")] + [JsonPropertyName("ffmpeg_options")] public string Options { get; set; } /// /// Speed percentage /// - [JsonProperty(PropertyName = "speed_percent")] + [JsonPropertyName("speed_percent")] public int SpeedPercent { get; set; } = 100; /// @@ -95,15 +95,27 @@ public class InputFFMpegSettings : Input public static InputFFMpegSettings FromInputSettings(InputSettings settings) { return new InputFFMpegSettings(settings); - } - // Private Constrctor - private InputFFMpegSettings(InputSettings settings) : base(JObject.FromObject(settings)) + } // Private Constrctor + private InputFFMpegSettings(InputSettings settings) : base(JsonSerializer.SerializeToNode(settings, AppJsonSerializerContext.Default.InputSettings)?.AsObject()) { if (settings.InputKind != SUPPORTED_INPUT_KIND) { throw new InvalidCastException(); } - JsonConvert.PopulateObject(settings.Settings.ToString(), this); + + BufferingMB = settings.Settings["buffering_mb"]?.GetValue() ?? BufferingMB; + ClearOnMediaEnd = settings.Settings["clear_on_media_end"]?.GetValue() ?? ClearOnMediaEnd; + CloseWhenInactive = settings.Settings["close_when_inactive"]?.GetValue() ?? CloseWhenInactive; + ColorRange = settings.Settings["color_range"]?.GetValue() ?? ColorRange; + HWDecode = settings.Settings["hw_decode"]?.GetValue() ?? HWDecode; + IsLocalFile = settings.Settings["is_local_file"]?.GetValue() ?? IsLocalFile; + LocalFile = settings.Settings["local_file"]?.GetValue() ?? string.Empty; + Looping = settings.Settings["looping"]?.GetValue() ?? Looping; + LinearAlpha = settings.Settings["linear_alpha"]?.GetValue() ?? LinearAlpha; + RestartOnActivate = settings.Settings["restart_on_activate"]?.GetValue() ?? RestartOnActivate; + Options = settings.Settings["ffmpeg_options"]?.GetValue() ?? string.Empty; + SpeedPercent = settings.Settings["speed_percent"]?.GetValue() ?? SpeedPercent; + } } } diff --git a/obs-websocket-dotnet/Types/InputSettings.cs b/obs-websocket-dotnet/Types/InputSettings.cs index 06ed098..93604a8 100644 --- a/obs-websocket-dotnet/Types/InputSettings.cs +++ b/obs-websocket-dotnet/Types/InputSettings.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,16 +11,14 @@ public class InputSettings : Input /// /// Settings for the source /// - [JsonProperty(PropertyName = "inputSettings")] - public JObject Settings { set; get; } - - /// + [JsonPropertyName("inputSettings")] + public JsonObject Settings { set; get; } /// /// Builds the object from the JSON data /// - /// JSON item description as a - public InputSettings(JObject data) : base(data) + /// JSON item description as a + public InputSettings(JsonObject data) : base(data) { - JsonConvert.PopulateObject(data.ToString(), this); + Settings = data["inputSettings"]?.AsObject(); } /// diff --git a/obs-websocket-dotnet/Types/InputVolume.cs b/obs-websocket-dotnet/Types/InputVolume.cs index 0cf0ed7..5125b6e 100644 --- a/obs-websocket-dotnet/Types/InputVolume.cs +++ b/obs-websocket-dotnet/Types/InputVolume.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,26 +11,26 @@ public class InputVolume /// /// Name of the source /// - [JsonProperty(PropertyName = "inputName")] + [JsonPropertyName("inputName")] public string InputName { set; get; } /// /// The source volume in percent /// - [JsonProperty(PropertyName = "inputVolumeMul")] + [JsonPropertyName("inputVolumeMul")] public float InputVolumeMul { get; set; } /// /// The source volume in decibels /// - [JsonProperty(PropertyName = "inputVolumeDb")] - public float InputVolumeDb { get; set; } - - /// + [JsonPropertyName("inputVolumeDb")] + public float InputVolumeDb { get; set; } /// /// Builds the object from the JSON response body /// - /// JSON response body as a - public InputVolume(JObject data) + /// JSON response body as a + public InputVolume(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + InputName = data["inputName"]?.GetValue() ?? string.Empty; + InputVolumeMul = data["inputVolumeMul"]?.GetValue() ?? 0.0f; + InputVolumeDb = data["inputVolumeDb"]?.GetValue() ?? 0.0f; } /// diff --git a/obs-websocket-dotnet/Types/MediaInputStatus.cs b/obs-websocket-dotnet/Types/MediaInputStatus.cs index 762f96f..7f4f8ae 100644 --- a/obs-websocket-dotnet/Types/MediaInputStatus.cs +++ b/obs-websocket-dotnet/Types/MediaInputStatus.cs @@ -1,6 +1,6 @@ using System; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -12,7 +12,7 @@ public class MediaInputStatus /// /// State of the media input /// - [JsonProperty(PropertyName = "mediaState")] + [JsonPropertyName("mediaState")] public string StateString { get; set; } /// @@ -34,22 +34,22 @@ public MediaState? State /// /// Total duration of the playing media in milliseconds. `null` if not playing /// - [JsonProperty(PropertyName = "mediaDuration")] + [JsonPropertyName("mediaDuration")] public long? Duration { get; set; } /// /// Position of the cursor in milliseconds. `null` if not playing /// - [JsonProperty(PropertyName = "mediaCursor")] - public long? Cursor { get; set; } - - /// + [JsonPropertyName("mediaCursor")] + public long? Cursor { get; set; } /// /// Instantiate from JObject /// /// - public MediaInputStatus(JObject body) + public MediaInputStatus(JsonObject body) { - JsonConvert.PopulateObject(body.ToString(), this); + StateString = body["mediaState"]?.GetValue() ?? string.Empty; + Duration = body["mediaDuration"]?.GetValue(); + Cursor = body["mediaCursor"]?.GetValue(); } /// diff --git a/obs-websocket-dotnet/Types/Monitor.cs b/obs-websocket-dotnet/Types/Monitor.cs index fee13b9..036456b 100644 --- a/obs-websocket-dotnet/Types/Monitor.cs +++ b/obs-websocket-dotnet/Types/Monitor.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,46 +11,49 @@ public class Monitor /// /// Monitor height (px) /// - [JsonProperty(PropertyName = "monitorHeight")] + [JsonPropertyName("monitorHeight")] public int Height { get; set; } /// /// Monitor width (px) /// - [JsonProperty(PropertyName = "monitorWidth")] + [JsonPropertyName("monitorWidth")] public int Width { get; set; } /// /// Monitor Name /// - [JsonProperty(PropertyName = "monitorName")] + [JsonPropertyName("monitorName")] public string Name { get; set; } /// /// Monitor Index /// - [JsonProperty(PropertyName = "monitorIndex")] + [JsonPropertyName("monitorIndex")] public int Index { get; set; } /// /// Monitor Position X /// - [JsonProperty(PropertyName = "monitorPositionX")] + [JsonPropertyName("monitorPositionX")] public int PositionX { get; set; } /// /// Monitor Position Y /// - [JsonProperty(PropertyName = "monitorPositionY")] - public int PositionY { get; set; } - - /// + [JsonPropertyName("monitorPositionY")] + public int PositionY { get; set; } /// /// Constructor to auto populate /// /// - public Monitor (JObject data) + public Monitor (JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + Height = data["monitorHeight"]?.GetValue() ?? 0; + Width = data["monitorWidth"]?.GetValue() ?? 0; + Name = data["monitorName"]?.GetValue() ?? string.Empty; + Index = data["monitorIndex"]?.GetValue() ?? 0; + PositionX = data["monitorPositionX"]?.GetValue() ?? 0; + PositionY = data["monitorPositionY"]?.GetValue() ?? 0; } /// diff --git a/obs-websocket-dotnet/Types/OBSScene.cs b/obs-websocket-dotnet/Types/OBSScene.cs index 9c39b61..71874f0 100644 --- a/obs-websocket-dotnet/Types/OBSScene.cs +++ b/obs-websocket-dotnet/Types/OBSScene.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using System.Collections.Generic; namespace OBSWebsocketDotNet.Types @@ -12,38 +12,49 @@ public class ObsScene /// /// OBS Scene name /// - [JsonProperty(PropertyName = "sceneName")] + [JsonPropertyName("sceneName")] public string Name; /// /// Is group /// - [JsonProperty(PropertyName = "isGroup")] + [JsonPropertyName("isGroup")] public bool IsGroup; /// /// Scene item list /// - [JsonProperty(PropertyName = "sources")] - public List Items; - - /// + [JsonPropertyName("sources")] + public List Items; /// /// Builds the object from the JSON description /// - /// JSON scene description as a - public ObsScene(JObject data) + /// JSON scene description as a + public ObsScene(JsonObject data) { - JsonSerializerSettings settings = new JsonSerializerSettings - { - ObjectCreationHandling = ObjectCreationHandling.Auto, - NullValueHandling = NullValueHandling.Include - }; if (data.ContainsKey("currentProgramSceneName")) { - var newToken = JToken.FromObject(data["currentProgramSceneName"]); - data.Add("sceneName", newToken); + Name = data["currentProgramSceneName"]?.GetValue() ?? string.Empty; + } + else + { + Name = data["sceneName"]?.GetValue() ?? string.Empty; + } + + IsGroup = data["isGroup"]?.GetValue() ?? false; + + // Handle sources list + var sourcesArray = data["sources"]?.AsArray(); + Items = new List(); + if (sourcesArray != null) + { + foreach (var item in sourcesArray) + { + if (item?.AsObject() != null) + { + Items.Add(new SceneItemDetails(item.AsObject())); + } + } } - JsonConvert.PopulateObject(data.ToString(), this, settings); } /// diff --git a/obs-websocket-dotnet/Types/OBSStats.cs b/obs-websocket-dotnet/Types/OBSStats.cs index e196734..73f42ba 100644 --- a/obs-websocket-dotnet/Types/OBSStats.cs +++ b/obs-websocket-dotnet/Types/OBSStats.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; namespace OBSWebsocketDotNet.Types { @@ -10,67 +10,67 @@ public class ObsStats /// /// Current framerate. /// - [JsonProperty(PropertyName = "activeFps")] + [JsonPropertyName("activeFps")] public double FPS { set; get; } /// /// Number of frames rendered /// - [JsonProperty(PropertyName = "renderTotalFrames")] + [JsonPropertyName("renderTotalFrames")] public long RenderTotalFrames { set; get; } /// /// Number of frames missed due to rendering lag /// - [JsonProperty(PropertyName = "renderSkippedFrames")] + [JsonPropertyName("renderSkippedFrames")] public long RenderMissedFrames { set; get; } /// /// Number of frames outputted /// - [JsonProperty(PropertyName = "outputTotalFrames")] + [JsonPropertyName("outputTotalFrames")] public long OutputTotalFrames { set; get; } /// /// Number of frames skipped due to encoding lag /// - [JsonProperty(PropertyName = "outputSkippedFrames")] + [JsonPropertyName("outputSkippedFrames")] public long OutputSkippedFrames { set; get; } /// /// Average frame render time (in milliseconds) /// - [JsonProperty(PropertyName = "averageFrameRenderTime")] + [JsonPropertyName("averageFrameRenderTime")] public double AverageFrameTime { set; get; } /// /// Current CPU usage (percentage) /// - [JsonProperty(PropertyName = "cpuUsage")] + [JsonPropertyName("cpuUsage")] public double CpuUsage { set; get; } /// /// Current RAM usage (in megabytes) /// - [JsonProperty(PropertyName = "memoryUsage")] + [JsonPropertyName("memoryUsage")] public double MemoryUsage { set; get; } /// /// Free recording disk space (in megabytes) /// - [JsonProperty(PropertyName = "availableDiskSpace")] + [JsonPropertyName("availableDiskSpace")] public double FreeDiskSpace { set; get; } /// /// Total number of messages received by obs-websocket from the client /// - [JsonProperty(PropertyName = "webSocketSessionIncomingMessages")] + [JsonPropertyName("webSocketSessionIncomingMessages")] public long SessionIncomingMessages { get; set; } /// /// Total number of messages sent by obs-websocket to the client /// - [JsonProperty(PropertyName = "webSocketSessionOutgoingMessages")] + [JsonPropertyName("webSocketSessionOutgoingMessages")] public long SessionOutgoingMessages { get; set; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/OBSVersion.cs b/obs-websocket-dotnet/Types/OBSVersion.cs index 8a07f4b..78faffc 100644 --- a/obs-websocket-dotnet/Types/OBSVersion.cs +++ b/obs-websocket-dotnet/Types/OBSVersion.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using System.Collections.Generic; namespace OBSWebsocketDotNet.Types @@ -12,52 +12,80 @@ public class ObsVersion /// /// obs-websocket plugin version /// - [JsonProperty(PropertyName = "obsWebSocketVersion")] + [JsonPropertyName("obsWebSocketVersion")] public string PluginVersion { get; internal set; } /// /// OBS Studio version /// - [JsonProperty(PropertyName = "obsVersion")] + [JsonPropertyName("obsVersion")] public string OBSStudioVersion { get; internal set; } /// /// OBSRemote compatible API version.Fixed to 1.1 for retrocompatibility. /// - [JsonProperty(PropertyName = "rpcVersion")] + [JsonPropertyName("rpcVersion")] public double Version { internal set; get; } /// /// List of available request types, formatted as a comma-separated list string (e.g. : "Method1,Method2,Method3"). /// - [JsonProperty(PropertyName = "availableRequests")] + [JsonPropertyName("availableRequests")] public List AvailableRequests { get; internal set; } /// /// Image formats available in `GetSourceScreenshot` and `SaveSourceScreenshot` requests. /// - [JsonProperty(PropertyName = "supportedImageFormats")] + [JsonPropertyName("supportedImageFormats")] public List SupportedImageFormats { get; internal set; } /// /// Name of the platform. Usually `windows`, `macos`, or `ubuntu` (linux flavor). Not guaranteed to be any of those /// - [JsonProperty(PropertyName = "platform")] + [JsonPropertyName("platform")] public string Platform { get; internal set; } /// /// Description of the platform, like `Windows 10 (10.0)` /// - [JsonProperty(PropertyName = "platformDescription")] - public string PlatformDescription { get; internal set; } - - /// + [JsonPropertyName("platformDescription")] + public string PlatformDescription { get; internal set; } /// /// Builds the object from the JSON response body /// - /// JSON response body as a - public ObsVersion(JObject data) + /// JSON response body as a + public ObsVersion(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + PluginVersion = data["obsWebSocketVersion"]?.GetValue() ?? string.Empty; + OBSStudioVersion = data["obsVersion"]?.GetValue() ?? string.Empty; + Version = data["rpcVersion"]?.GetValue() ?? 0.0; + + // Handle list properties + var availableRequestsArray = data["availableRequests"]?.AsArray(); + AvailableRequests = new List(); + if (availableRequestsArray != null) + { + foreach (var item in availableRequestsArray) + { + var value = item?.GetValue(); + if (!string.IsNullOrEmpty(value)) + AvailableRequests.Add(value); + } + } + + var supportedFormatsArray = data["supportedImageFormats"]?.AsArray(); + SupportedImageFormats = new List(); + if (supportedFormatsArray != null) + { + foreach (var item in supportedFormatsArray) + { + var value = item?.GetValue(); + if (!string.IsNullOrEmpty(value)) + SupportedImageFormats.Add(value); + } + } + + Platform = data["platform"]?.GetValue() ?? string.Empty; + PlatformDescription = data["platformDescription"]?.GetValue() ?? string.Empty; } /// diff --git a/obs-websocket-dotnet/Types/OBSVideoSettings.cs b/obs-websocket-dotnet/Types/OBSVideoSettings.cs index 77bbf25..ce50be2 100644 --- a/obs-websocket-dotnet/Types/OBSVideoSettings.cs +++ b/obs-websocket-dotnet/Types/OBSVideoSettings.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; namespace OBSWebsocketDotNet.Types { @@ -10,37 +10,37 @@ public class ObsVideoSettings /// /// Numerator of the fractional FPS value /// - [JsonProperty(PropertyName = "fpsNumerator")] + [JsonPropertyName("fpsNumerator")] public double FpsNumerator { set; get; } /// /// Denominator of the fractional FPS value /// - [JsonProperty(PropertyName = "fpsDenominator")] + [JsonPropertyName("fpsDenominator")] public double FpsDenominator { set; get; } /// /// Base (canvas) width /// - [JsonProperty(PropertyName = "baseWidth")] + [JsonPropertyName("baseWidth")] public int BaseWidth { set; get; } /// /// Base (canvas) height /// - [JsonProperty(PropertyName = "baseHeight")] + [JsonPropertyName("baseHeight")] public int BaseHeight { set; get; } /// /// Width of the output resolution in pixels /// - [JsonProperty(PropertyName = "outputWidth")] + [JsonPropertyName("outputWidth")] public int OutputWidth { set; get; } /// /// Height of the output resolution in pixels /// - [JsonProperty(PropertyName = "outputHeight")] + [JsonPropertyName("outputHeight")] public int OutputHeight { set; get; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/OutputStateChanged.cs b/obs-websocket-dotnet/Types/OutputStateChanged.cs index 0d16d98..60cad8c 100644 --- a/obs-websocket-dotnet/Types/OutputStateChanged.cs +++ b/obs-websocket-dotnet/Types/OutputStateChanged.cs @@ -1,6 +1,6 @@ using System; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -13,13 +13,13 @@ public class OutputStateChanged /// /// Is output currently active (streaming/recording) /// - [JsonProperty(PropertyName = "outputActive")] + [JsonPropertyName("outputActive")] public bool IsActive { set; get; } /// /// Output state as string /// - [JsonProperty(PropertyName = "outputState")] + [JsonPropertyName("outputState")] public string StateStr { set; get; } /// @@ -41,15 +41,14 @@ public OutputState State { return state.Value; } - } - - /// + } /// /// Constructor /// /// - public OutputStateChanged(JObject body) + public OutputStateChanged(JsonObject body) { - JsonConvert.PopulateObject(body.ToString(), this); + IsActive = body["outputActive"]?.GetValue() ?? false; + StateStr = body["outputState"]?.GetValue() ?? string.Empty; } /// diff --git a/obs-websocket-dotnet/Types/OutputStatus.cs b/obs-websocket-dotnet/Types/OutputStatus.cs index 82a1c0c..a8c1eec 100644 --- a/obs-websocket-dotnet/Types/OutputStatus.cs +++ b/obs-websocket-dotnet/Types/OutputStatus.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -7,62 +7,66 @@ namespace OBSWebsocketDotNet.Types /// Status of streaming output /// public class OutputStatus - { - /// + { /// /// True if streaming is started and running, false otherwise /// - [JsonProperty(PropertyName = "outputActive")] - public readonly bool IsActive; + [JsonPropertyName("outputActive")] + public bool IsActive { get; private set; } /// /// Whether the output is currently reconnectins /// - [JsonProperty(PropertyName = "outputReconnecting")] + [JsonPropertyName("outputReconnecting")] public bool IsReconnecting { get; set; } /// /// Current formatted timecode string for the output /// - [JsonProperty(PropertyName = "outputTimecode")] + [JsonPropertyName("outputTimecode")] public string TimeCode { get; set; } /// /// Current duration in milliseconds for the output /// - [JsonProperty(PropertyName = "outputDuration")] + [JsonPropertyName("outputDuration")] public long Duration { get; set; } /// /// Congestion of the output /// - [JsonProperty(PropertyName = "outputCongestion")] + [JsonPropertyName("outputCongestion")] public double Congestion { get; set; } /// /// Nubmer of bytes sent by the output /// - [JsonProperty(PropertyName = "outputBytes")] + [JsonPropertyName("outputBytes")] public long BytesSent { get; set; } /// /// Number of frames skipped by the output's process /// - [JsonProperty(PropertyName = "outputSkippedFrames")] + [JsonPropertyName("outputSkippedFrames")] public long SkippedFrames { get; set; } /// /// Total number of frames delivered by the output's process /// - [JsonProperty(PropertyName = "outputTotalFrames")] - public long TotalFrames { get; set; } - - /// + [JsonPropertyName("outputTotalFrames")] + public long TotalFrames { get; set; } /// /// Builds the object from the JSON response body /// - /// JSON response body as a - public OutputStatus(JObject data) + /// JSON response body as a + public OutputStatus(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + IsActive = data["outputActive"]?.GetValue() ?? false; + IsReconnecting = data["outputReconnecting"]?.GetValue() ?? false; + TimeCode = data["outputTimecode"]?.GetValue() ?? string.Empty; + Duration = data["outputDuration"]?.GetValue() ?? 0L; + Congestion = data["outputCongestion"]?.GetValue() ?? 0.0; + BytesSent = data["outputBytes"]?.GetValue() ?? 0L; + SkippedFrames = data["outputSkippedFrames"]?.GetValue() ?? 0L; + TotalFrames = data["outputTotalFrames"]?.GetValue() ?? 0L; } /// diff --git a/obs-websocket-dotnet/Types/RecordStateChanged.cs b/obs-websocket-dotnet/Types/RecordStateChanged.cs index 3033f44..76e4e41 100644 --- a/obs-websocket-dotnet/Types/RecordStateChanged.cs +++ b/obs-websocket-dotnet/Types/RecordStateChanged.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json.Linq; -using Newtonsoft.Json; +using System.Text.Json.Nodes; +using System.Text.Json;using System.Text.Json.Serialization; using System; using System.Collections.Generic; using System.Text; @@ -14,16 +14,14 @@ public class RecordStateChanged : OutputStateChanged /// /// File name for the saved recording, if record stopped. null otherwise /// - [JsonProperty(PropertyName = "outputPath")] - public string OutputPath { set; get; } - - /// + [JsonPropertyName("outputPath")] + public string OutputPath { set; get; } /// /// Constructor /// /// - public RecordStateChanged(JObject body) :base(body) + public RecordStateChanged(JsonObject body) :base(body) { - JsonConvert.PopulateObject(body.ToString(), this); + OutputPath = body["outputPath"]?.GetValue() ?? string.Empty; } /// diff --git a/obs-websocket-dotnet/Types/RecordingStatus.cs b/obs-websocket-dotnet/Types/RecordingStatus.cs index 4a89625..1ff1d63 100644 --- a/obs-websocket-dotnet/Types/RecordingStatus.cs +++ b/obs-websocket-dotnet/Types/RecordingStatus.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,40 +11,42 @@ public class RecordingStatus /// /// Current recording status /// - [JsonProperty(PropertyName = "outputActive")] + [JsonPropertyName("outputActive")] public bool IsRecording { set; get; } /// /// Whether the recording is paused or not /// - [JsonProperty(PropertyName = "outputPaused")] + [JsonPropertyName("outputPaused")] public bool IsRecordingPaused { set; get; } /// /// Current formatted timecode string for the output /// - [JsonProperty(PropertyName = "outputTimecode")] + [JsonPropertyName("outputTimecode")] public string RecordTimecode { set; get; } /// /// Current duration in milliseconds for the output /// - [JsonProperty(PropertyName = "outputDuration")] + [JsonPropertyName("outputDuration")] public long RecordingDuration { set; get; } /// /// Number of bytes sent by the output /// - [JsonProperty(PropertyName = "outputBytes")] - public long RecordingBytes { set; get; } - - /// + [JsonPropertyName("outputBytes")] + public long RecordingBytes { set; get; } /// /// Builds the object from the JSON response body /// - /// JSON response body as a - public RecordingStatus(JObject data) + /// JSON response body as a + public RecordingStatus(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + IsRecording = data["outputActive"]?.GetValue() ?? false; + IsRecordingPaused = data["outputPaused"]?.GetValue() ?? false; + RecordTimecode = data["outputTimecode"]?.GetValue() ?? string.Empty; + RecordingDuration = data["outputDuration"]?.GetValue() ?? 0L; + RecordingBytes = data["outputBytes"]?.GetValue() ?? 0L; } /// diff --git a/obs-websocket-dotnet/Types/SceneBasicInfo.cs b/obs-websocket-dotnet/Types/SceneBasicInfo.cs index 60d75d3..b74a045 100644 --- a/obs-websocket-dotnet/Types/SceneBasicInfo.cs +++ b/obs-websocket-dotnet/Types/SceneBasicInfo.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; using System; using System.Collections.Generic; using System.Text; @@ -13,13 +13,13 @@ public class SceneBasicInfo /// /// Name of scene /// - [JsonProperty(PropertyName = "sceneName")] + [JsonPropertyName("sceneName")] public string Name { set; get; } /// /// Index of scene /// - [JsonProperty(PropertyName = "sceneIndex")] - public string Index { set; get; } + [JsonPropertyName("sceneIndex")] + public int Index { set; get; } } } diff --git a/obs-websocket-dotnet/Types/SceneItemDetails.cs b/obs-websocket-dotnet/Types/SceneItemDetails.cs index 27b5f08..a480131 100644 --- a/obs-websocket-dotnet/Types/SceneItemDetails.cs +++ b/obs-websocket-dotnet/Types/SceneItemDetails.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; using System; using System.Collections.Generic; using System.Text; @@ -14,37 +14,47 @@ public class SceneItemDetails /// /// Unique item id of the source item /// - [JsonProperty(PropertyName = "sceneItemId")] + [JsonPropertyName("sceneItemId")] public int ItemId { set; get; } /// /// Kind of source (Example: vlc_source or image_source) /// - [JsonProperty(PropertyName = "inputKind")] + [JsonPropertyName("inputKind")] public string SourceKind { set; get; } /// /// Name of the scene item's source /// - [JsonProperty(PropertyName = "sourceName")] + [JsonPropertyName("sourceName")] public string SourceName { set; get; } /// /// Type of the scene item's source. /// - [JsonProperty(PropertyName = "sourceType")] - public SceneItemSourceType SourceType { set; get; } - - - /// + [JsonPropertyName("sourceType")] + public SceneItemSourceType SourceType { set; get; } /// /// Builds the object from the JSON data /// - /// JSON item description as a - public SceneItemDetails(JObject data) + /// JSON item description as a + public SceneItemDetails(JsonObject data) { if (data != null) { - JsonConvert.PopulateObject(data.ToString(), this); + ItemId = data["sceneItemId"]?.GetValue() ?? 0; + SourceKind = data["inputKind"]?.GetValue() ?? string.Empty; + SourceName = data["sourceName"]?.GetValue() ?? string.Empty; + + // Handle enum conversion safely + var sourceTypeValue = data["sourceType"]?.GetValue(); + if (Enum.TryParse(sourceTypeValue, true, out var sourceType)) + { + SourceType = sourceType; + } + else + { + SourceType = SceneItemSourceType.OBS_SOURCE_TYPE_INPUT; // Default value + } } } diff --git a/obs-websocket-dotnet/Types/SceneItemTransformInfo.cs b/obs-websocket-dotnet/Types/SceneItemTransformInfo.cs index e973e81..62a4d4c 100644 --- a/obs-websocket-dotnet/Types/SceneItemTransformInfo.cs +++ b/obs-websocket-dotnet/Types/SceneItemTransformInfo.cs @@ -1,6 +1,6 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -12,119 +12,138 @@ public class SceneItemTransformInfo /// /// Alignment of the item /// - [JsonProperty(PropertyName = "alignment")] + [JsonPropertyName("alignment")] public int Alignnment { set; get; } /// /// The point on the scene item that the item is manipulated from /// - [JsonProperty(PropertyName = "boundsAlignment")] + [JsonPropertyName("boundsAlignment")] public int BoundsAlignnment { set; get; } /// /// Height of the bounding box /// - [JsonProperty(PropertyName = "boundsHeight")] + [JsonPropertyName("boundsHeight")] public double BoundsHeight { set; get; } /// /// Width of the bounding box /// - [JsonProperty(PropertyName = "boundsWidth")] - public double BoundsWidth { set; get; } - - /// + [JsonPropertyName("boundsWidth")] + public double BoundsWidth { set; get; } /// /// Type of bounding box /// - [JsonProperty(PropertyName = "boundsType")] - [JsonConverter(typeof(StringEnumConverter))] + [JsonPropertyName("boundsType")] + [JsonConverter(typeof(JsonStringEnumConverter))] public SceneItemBoundsType BoundsType { set; get; } /// /// Bottom crop (in pixels) /// - [JsonProperty(PropertyName = "cropBottom")] + [JsonPropertyName("cropBottom")] public int CropBottom; /// /// Left crop (in pixels) /// - [JsonProperty(PropertyName = "cropLeft")] + [JsonPropertyName("cropLeft")] public int CropLeft; /// /// Right crop (in pixels) /// - [JsonProperty(PropertyName = "cropRight")] + [JsonPropertyName("cropRight")] public int CropRight; /// /// Top crop (in pixels) /// - [JsonProperty(PropertyName = "cropTop")] + [JsonPropertyName("cropTop")] public int CropTop; /// /// The clockwise rotation of the scene item in degrees around the point of alignment. /// - [JsonProperty(PropertyName = "rotation")] + [JsonPropertyName("rotation")] public double Rotation { set; get; } /// /// The x-scale factor of the scene item /// - [JsonProperty(PropertyName = "scaleX")] + [JsonPropertyName("scaleX")] public double ScaleX { get; set; } /// /// The y-scale factor of the scene item /// - [JsonProperty(PropertyName = "scaleY")] + [JsonPropertyName("scaleY")] public double ScaleY { get; set; } /// /// Base height (without scaling) of the source /// - [JsonProperty(PropertyName = "sourceHeight")] + [JsonPropertyName("sourceHeight")] public double SourceHeight { set; get; } /// /// Base width (without scaling) of the source /// - [JsonProperty(PropertyName = "sourceWidth")] + [JsonPropertyName("sourceWidth")] public double SourceWidth { set; get; } /// /// Scene item height (base source height multiplied by the vertical scaling factor) /// - [JsonProperty(PropertyName = "height")] + [JsonPropertyName("height")] public double Height { set; get; } /// /// Scene item width (base source width multiplied by the horizontal scaling factor) /// - [JsonProperty(PropertyName = "width")] + [JsonPropertyName("width")] public double Width { set; get; } /// /// The x position of the scene item from the left /// - [JsonProperty(PropertyName = "positionX")] + [JsonPropertyName("positionX")] public double X { set; get; } /// /// The y position of the scene item from the top /// - [JsonProperty(PropertyName = "positionY")] + [JsonPropertyName("positionY")] public double Y { set; get; } /// /// Initialize the scene item transform - /// - /// - public SceneItemTransformInfo(JObject body) + /// /// + public SceneItemTransformInfo(JsonObject body) { - JsonConvert.PopulateObject(body.ToString(), this); + var transformInfo = JsonSerializer.Deserialize(body.ToString(), AppJsonSerializerContext.Default.SceneItemTransformInfo); + if (transformInfo != null) + { + // Copy properties from the deserialized object + this.Alignnment = transformInfo.Alignnment; + this.BoundsAlignnment = transformInfo.BoundsAlignnment; + this.BoundsHeight = transformInfo.BoundsHeight; + this.BoundsWidth = transformInfo.BoundsWidth; + this.BoundsType = transformInfo.BoundsType; + this.CropBottom = transformInfo.CropBottom; + this.CropLeft = transformInfo.CropLeft; + this.CropRight = transformInfo.CropRight; + this.CropTop = transformInfo.CropTop; + this.Height = transformInfo.Height; + this.X = transformInfo.X; + this.Y = transformInfo.Y; + this.Rotation = transformInfo.Rotation; + this.ScaleX = transformInfo.ScaleX; + this.ScaleY = transformInfo.ScaleY; + this.SourceHeight = transformInfo.SourceHeight; + this.SourceWidth = transformInfo.SourceWidth; + this.Width = transformInfo.Width; + } } /// diff --git a/obs-websocket-dotnet/Types/SourceActiveInfo.cs b/obs-websocket-dotnet/Types/SourceActiveInfo.cs index c6bde23..b6eb932 100644 --- a/obs-websocket-dotnet/Types/SourceActiveInfo.cs +++ b/obs-websocket-dotnet/Types/SourceActiveInfo.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,22 +11,21 @@ public class SourceActiveInfo /// /// Whether the source is showing in Program /// - [JsonProperty(PropertyName = "videaActive")] + [JsonPropertyName("videaActive")] public bool VideoActive { get; set; } /// /// Whether the source is showing in the UI (Preview, Projector, Properties) /// - [JsonProperty(PropertyName = "videoShowing")] - public bool VideoShowing { get; set; } - - /// + [JsonPropertyName("videoShowing")] + public bool VideoShowing { get; set; } /// /// Auto populate constructor /// /// - public SourceActiveInfo(JObject data) + public SourceActiveInfo(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + VideoActive = data["videaActive"]?.GetValue() ?? false; + VideoShowing = data["videoShowing"]?.GetValue() ?? false; } /// diff --git a/obs-websocket-dotnet/Types/SourceTracks.cs b/obs-websocket-dotnet/Types/SourceTracks.cs index c8c21b5..ed87177 100644 --- a/obs-websocket-dotnet/Types/SourceTracks.cs +++ b/obs-websocket-dotnet/Types/SourceTracks.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,46 +11,49 @@ public class SourceTracks /// /// Is the track active /// - [JsonProperty(PropertyName = "1")] + [JsonPropertyName("1")] public bool IsTrack1Active { set; get; } /// /// Is the track active /// - [JsonProperty(PropertyName = "2")] + [JsonPropertyName("2")] public bool IsTrack2Active { set; get; } /// /// Is the track active /// - [JsonProperty(PropertyName = "3")] + [JsonPropertyName("3")] public bool IsTrack3Active { set; get; } /// /// Is the track active /// - [JsonProperty(PropertyName = "4")] + [JsonPropertyName("4")] public bool IsTrack4Active { set; get; } /// /// Is the track active /// - [JsonProperty(PropertyName = "5")] + [JsonPropertyName("5")] public bool IsTrack5Active { set; get; } /// /// Is the track active /// - [JsonProperty(PropertyName = "6")] - public bool IsTrack6Active { set; get; } - - /// + [JsonPropertyName("6")] + public bool IsTrack6Active { set; get; } /// /// Builds the object from the JSON data /// - /// JSON item description as a - public SourceTracks(JObject data) + /// JSON item description as a + public SourceTracks(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + IsTrack1Active = data["1"]?.GetValue() ?? false; + IsTrack2Active = data["2"]?.GetValue() ?? false; + IsTrack3Active = data["3"]?.GetValue() ?? false; + IsTrack4Active = data["4"]?.GetValue() ?? false; + IsTrack5Active = data["5"]?.GetValue() ?? false; + IsTrack6Active = data["6"]?.GetValue() ?? false; } /// diff --git a/obs-websocket-dotnet/Types/StreamingService.cs b/obs-websocket-dotnet/Types/StreamingService.cs index c149588..a3125b8 100644 --- a/obs-websocket-dotnet/Types/StreamingService.cs +++ b/obs-websocket-dotnet/Types/StreamingService.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; namespace OBSWebsocketDotNet.Types { @@ -10,13 +10,13 @@ public class StreamingService /// /// Type of streaming service /// - [JsonProperty(PropertyName = "streamServiceType")] + [JsonPropertyName("streamServiceType")] public string Type { set; get; } /// /// Streaming service settings (JSON data) /// - [JsonProperty(PropertyName = "streamServiceSettings")] + [JsonPropertyName("streamServiceSettings")] public StreamingServiceSettings Settings { set; get; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/StreamingServiceSettings.cs b/obs-websocket-dotnet/Types/StreamingServiceSettings.cs index 58aa1f1..cc4e478 100644 --- a/obs-websocket-dotnet/Types/StreamingServiceSettings.cs +++ b/obs-websocket-dotnet/Types/StreamingServiceSettings.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -12,49 +12,47 @@ public class StreamingServiceSettings /// /// The publish URL /// - [JsonProperty(PropertyName = "server")] + [JsonPropertyName("server")] public string Server { set; get; } /// /// The publish key of the stream /// - [JsonProperty(PropertyName = "key")] + [JsonPropertyName("key")] public string Key { set; get; } /// /// Indicates whether authentication should be used when connecting to the streaming server /// - [JsonProperty(PropertyName = "use_auth")] + [JsonPropertyName("use_auth")] public bool UseAuth { set; get; } /// /// The username to use when accessing the streaming server. Only present if use-auth is true /// - [JsonProperty(PropertyName = "username")] + [JsonPropertyName("username")] public string Username { set; get; } /// /// The password to use when accessing the streaming server. Only present if use-auth is true /// - [JsonProperty(PropertyName = "password")] + [JsonPropertyName("password")] public string Password { set; get; } /// /// The service being used to stream /// - [JsonProperty(PropertyName = "service")] + [JsonPropertyName("service")] public string Service { get; set; } /// /// The protocol to use for the stream /// - [JsonProperty(PropertyName = "protocol")] - public string Protocol { get; set; } - - /// + [JsonPropertyName("protocol")] + public string Protocol { get; set; } /// /// Other values not covered by the class /// [JsonExtensionData] - public Dictionary OtherValues { get; set; } + public Dictionary OtherValues { get; set; } } } \ No newline at end of file diff --git a/obs-websocket-dotnet/Types/TransitionOverrideInfo.cs b/obs-websocket-dotnet/Types/TransitionOverrideInfo.cs index 4287109..1c3f324 100644 --- a/obs-websocket-dotnet/Types/TransitionOverrideInfo.cs +++ b/obs-websocket-dotnet/Types/TransitionOverrideInfo.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using System.Text.Json;using System.Text.Json.Serialization; namespace OBSWebsocketDotNet.Types { @@ -10,13 +10,13 @@ public class TransitionOverrideInfo /// /// Name of the current overriding transition. Empty string if no override is set. /// - [JsonProperty(PropertyName = "transitionName")] + [JsonPropertyName("transitionName")] public string Name { internal set; get; } /// /// Transition duration in milliseconds. -1 if no override is set. /// - [JsonProperty(PropertyName = "transitionDuration")] + [JsonPropertyName("transitionDuration")] public int Duration { internal set; get; } } } diff --git a/obs-websocket-dotnet/Types/TransitionSettings.cs b/obs-websocket-dotnet/Types/TransitionSettings.cs index 27ac89d..6e12795 100644 --- a/obs-websocket-dotnet/Types/TransitionSettings.cs +++ b/obs-websocket-dotnet/Types/TransitionSettings.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,46 +11,49 @@ public class TransitionSettings /// /// Transition name /// - [JsonProperty(PropertyName = "transitionName")] + [JsonPropertyName("transitionName")] public string Name { internal set; get; } /// /// Transition duration in milliseconds /// - [JsonProperty(PropertyName = "transitionDuration")] + [JsonPropertyName("transitionDuration")] public int? Duration { internal set; get; } /// /// Kind of the transition /// - [JsonProperty(PropertyName = "transitionKind")] + [JsonPropertyName("transitionKind")] public string Kind { internal set; get; } /// /// Whether the transition uses a fixed (unconfigurable) duration /// - [JsonProperty(PropertyName = "transitionFixed")] + [JsonPropertyName("transitionFixed")] public bool IsFixed { internal set; get; } /// /// Whether the transition supports being configured /// - [JsonProperty(PropertyName = "transitionConfigurable")] + [JsonPropertyName("transitionConfigurable")] public bool IsConfigurable { internal set; get; } /// /// Object of settings for the transition. 'null' if transition is not configurable /// - [JsonProperty(PropertyName = "transitionSettings")] - public JObject Settings { get; set; } - - /// + [JsonPropertyName("transitionSettings")] + public JsonObject Settings { get; set; } /// /// Builds the object from the JSON response body /// - /// JSON response body as a - public TransitionSettings(JObject data) + /// JSON response body as a + public TransitionSettings(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + Name = data["transitionName"]?.GetValue() ?? string.Empty; + Duration = data["transitionDuration"]?.GetValue(); + Kind = data["transitionKind"]?.GetValue() ?? string.Empty; + IsFixed = data["transitionFixed"]?.GetValue() ?? false; + IsConfigurable = data["transitionConfigurable"]?.GetValue() ?? false; + Settings = data["transitionSettings"]?.AsObject(); } /// diff --git a/obs-websocket-dotnet/Types/VirtualCamStatus.cs b/obs-websocket-dotnet/Types/VirtualCamStatus.cs index 55509fd..ad4190c 100644 --- a/obs-websocket-dotnet/Types/VirtualCamStatus.cs +++ b/obs-websocket-dotnet/Types/VirtualCamStatus.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,16 +11,14 @@ public class VirtualCamStatus /// /// Whether the output is active /// - [JsonProperty(PropertyName = "outputActive")] - public bool IsActive { get; set; } - - /// + [JsonPropertyName("outputActive")] + public bool IsActive { get; set; } /// /// Builds the object from the JSON response body /// - /// JSON response body as a - public VirtualCamStatus(JObject data) + /// JSON response body as a + public VirtualCamStatus(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + IsActive = data["outputActive"]?.GetValue() ?? false; } /// diff --git a/obs-websocket-dotnet/Types/VolumeInfo.cs b/obs-websocket-dotnet/Types/VolumeInfo.cs index 13eac79..d6368af 100644 --- a/obs-websocket-dotnet/Types/VolumeInfo.cs +++ b/obs-websocket-dotnet/Types/VolumeInfo.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json;using System.Text.Json.Serialization; +using System.Text.Json.Nodes; namespace OBSWebsocketDotNet.Types { @@ -11,22 +11,21 @@ public class VolumeInfo /// /// Source volume in linear scale (0.0 to 1.0) /// - [JsonProperty(PropertyName = "inputVolumeMul")] + [JsonPropertyName("inputVolumeMul")] public float VolumeMul { internal set; get; } /// /// Volume setting in dB /// - [JsonProperty(PropertyName = "inputVolumeDb")] - public float VolumeDb { internal set; get; } - - /// + [JsonPropertyName("inputVolumeDb")] + public float VolumeDb { internal set; get; } /// /// Builds the object from the JSON response body /// - /// JSON response body as a - public VolumeInfo(JObject data) + /// JSON response body as a + public VolumeInfo(JsonObject data) { - JsonConvert.PopulateObject(data.ToString(), this); + VolumeMul = data["inputVolumeMul"]?.GetValue() ?? 0.0f; + VolumeDb = data["inputVolumeDb"]?.GetValue() ?? 0.0f; } /// diff --git a/obs-websocket-dotnet/obs-websocket-dotnet.csproj b/obs-websocket-dotnet/obs-websocket-dotnet.csproj index 1c360bf..297071d 100644 --- a/obs-websocket-dotnet/obs-websocket-dotnet.csproj +++ b/obs-websocket-dotnet/obs-websocket-dotnet.csproj @@ -1,11 +1,9 @@ - - - - netstandard2.1 + + net8.0 obs-websocket-dotnet OBSWebsocketDotNet Copyright © BarRaider 2025 - 8 + 12 5.0.1 BarRaider LICENSE @@ -14,6 +12,7 @@ Official obs-websocket .NET library. Written in C#. Supports .NET Standard OBS obs-websocket websocket official obs-websocket-dotnet obs.websocket.net obs-websocket-net true + true What's new in v5.0.1 * Fixes for deserialization issues in MediaInputStatus * Allow OBSVideoSettings to be updated via the API @@ -25,11 +24,12 @@ obs-websocket-dotnet.xml + none - + diff --git a/obs-websocket-dotnet/obs-websocket-dotnet.sln b/obs-websocket-dotnet/obs-websocket-dotnet.sln new file mode 100644 index 0000000..277f823 --- /dev/null +++ b/obs-websocket-dotnet/obs-websocket-dotnet.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "obs-websocket-dotnet", "obs-websocket-dotnet.csproj", "{5AC0B170-AAA9-B8F0-EEFB-70DD0783DAB9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5AC0B170-AAA9-B8F0-EEFB-70DD0783DAB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5AC0B170-AAA9-B8F0-EEFB-70DD0783DAB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5AC0B170-AAA9-B8F0-EEFB-70DD0783DAB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5AC0B170-AAA9-B8F0-EEFB-70DD0783DAB9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6924170C-0398-46BF-80E8-94E6D34473DC} + EndGlobalSection +EndGlobal diff --git a/obs-websocket-dotnet/obs-websocket-dotnet.xml b/obs-websocket-dotnet/obs-websocket-dotnet.xml index 29e92b0..132fed1 100644 --- a/obs-websocket-dotnet/obs-websocket-dotnet.xml +++ b/obs-websocket-dotnet/obs-websocket-dotnet.xml @@ -4,6 +4,305 @@ obs-websocket-dotnet + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + Defines the source generated JSON serialization contract metadata for a given type. + + + + + The default associated with a default instance. + + + + + The source-generated options associated with this context. + + + + + + + + + + + Data required by authentication @@ -19,11 +318,11 @@ Password salt - + Builds the object from JSON response body - JSON response body as a + JSON response body as a @@ -430,7 +729,7 @@ An unsupported event has been received. - + Update message handler @@ -478,7 +777,7 @@ Disconnect this instance from the server - + Sends a message to the websocket API with the specified request type and optional parameters @@ -486,7 +785,7 @@ additional JSON fields if required by the request type The server's JSON response as a JObject - + Internal version which allows to set the opcode Sends a message to the websocket API with the specified request type and optional parameters @@ -526,8 +825,7 @@ A random string of alphanumerical characters - - Get basic OBS video information + /// Get basic OBS video information @@ -620,13 +918,13 @@ T-Bar position. This value must be between 0.0 and 1.0. Whether or not the T-Bar gets released automatically after setting its new position (like a user releasing their mouse button after moving the T-Bar). Call ReleaseTBar manually if you set release to false. Defaults to true. - + Apply settings to a source filter Source with filter Filter name - JObject with filter settings + JsonObject with filter settings Apply over existing settings? @@ -666,14 +964,14 @@ Name of the source the filter is on Name of the filter to remove - + Add a filter to a source Name of the source for the filter Name of the filter Type of filter - JObject holding filter settings object + JsonObject holding filter settings object @@ -719,7 +1017,7 @@ Desired transition duration (in milliseconds) - + Change the current settings of a transition @@ -763,13 +1061,13 @@ Name of the source which mute state will be toggled - + Sets the transform and crop info of a scene item Name of the scene that has the SceneItem Id of the Scene Item - JObject holding transform settings + JsonObject holding transform settings @@ -1000,7 +1298,7 @@ Name of the input to set the audio monitor type of Audio monitor type. See `GetInputAudioMonitorType for possible types. - + Broadcasts a `CustomEvent` to all WebSocket clients. Receivers are clients which are identified and subscribed. @@ -1022,7 +1320,7 @@ Name of the media input Value to offset the current cursor position by (milliseconds +/-) - + Creates a new input, adding it as a scene item to the specified scene. @@ -1071,12 +1369,12 @@ Name of the input Object of audio tracks and associated enable states - + Sets the enable state of audio tracks of an input. Name of the input - JObject holding track settings to apply + JsonObject holding track settings to apply @@ -1123,7 +1421,7 @@ The name of the slot to retrieve data from Value associated with the slot. `null` if not set - + Sets the value of a \"slot\" from the selected persistent data realm. @@ -1201,7 +1499,7 @@ Version info in an object - + Call a request registered to a vendor. A vendor is a unique name registered by a third-party plugin or script, which allows for custom requests and events to be added to obs-websocket. @@ -1268,7 +1566,7 @@ Object of settings to apply True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. - + Sets the settings of an input. @@ -1372,7 +1670,7 @@ - Gets the JObject of transform settings for a scene item. Use this one you don't want it populated with default values. + Gets the JsonObject of transform settings for a scene item. Use this one you don't want it populated with default values. Scenes and Groups Name of the scene the item is in @@ -1682,13 +1980,13 @@ T-Bar position. This value must be between 0.0 and 1.0. Whether or not the T-Bar gets released automatically after setting its new position (like a user releasing their mouse button after moving the T-Bar). Call ReleaseTBar manually if you set release to false. Defaults to true. - + Apply settings to a source filter Source with filter Filter name - JObject with filter settings + JsonObject with filter settings Apply over existing settings? @@ -1728,14 +2026,14 @@ Name of the source the filter is on Name of the filter to remove - + Add a filter to a source Name of the source for the filter Name of the filter Type of filter - JObject holding filter settings object + JsonObject holding filter settings object @@ -1781,7 +2079,7 @@ Desired transition duration (in milliseconds) - + Change the current settings of a transition @@ -1825,13 +2123,13 @@ Name of the source which mute state will be toggled - + Sets the transform and crop info of a scene item Name of the scene that has the SceneItem Id of the Scene Item - JObject holding transform settings + JsonObject holding transform settings @@ -2062,7 +2360,7 @@ Name of the input to set the audio monitor type of Audio monitor type. See `GetInputAudioMonitorType for possible types. - + Broadcasts a `CustomEvent` to all WebSocket clients. Receivers are clients which are identified and subscribed. @@ -2084,7 +2382,7 @@ Name of the media input Value to offset the current cursor position by (milliseconds +/-) - + Creates a new input, adding it as a scene item to the specified scene. @@ -2133,12 +2431,12 @@ Name of the input Object of audio tracks and associated enable states - + Sets the enable state of audio tracks of an input. Name of the input - JObject holding track settings to apply + JsonObject holding track settings to apply @@ -2185,7 +2483,7 @@ The name of the slot to retrieve data from Value associated with the slot. `null` if not set - + Sets the value of a \"slot\" from the selected persistent data realm. @@ -2263,7 +2561,7 @@ Version info in an object - + Call a request registered to a vendor. A vendor is a unique name registered by a third-party plugin or script, which allows for custom requests and events to be added to obs-websocket. @@ -2330,7 +2628,7 @@ Object of settings to apply True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. - + Sets the settings of an input. @@ -2434,7 +2732,7 @@ - Gets the JObject of transform settings for a scene item. Use this one you don't want it populated with default values. + Gets the JsonObject of transform settings for a scene item. Use this one you don't want it populated with default values. Scenes and Groups Name of the scene the item is in @@ -2615,7 +2913,7 @@ Disconnect this instance from the server - + Sends a message to the websocket API with the specified request type and optional parameters @@ -2906,6 +3204,189 @@ The name of a scene has changed. + + + 提供 JSON 序列化的擴展方法,類似於 Newtonsoft.Json 的 PopulateObject 功能 + + + + + 使用指定的 JSON 內容和序列化上下文來填充現有物件的屬性 + 這是 AOT 編譯友好的版本,不需要反射 + + 要填充的物件型別 + 包含要填充資料的 JSON 字串 + 要被填充的現有物件 + JSON 序列化上下文,包含型別資訊 + 當 context 為 null 時拋出 + + + + 使用指定的 JSON 字串和序列化上下文來填充現有物件的屬性 + 這是 AOT 編譯友好的版本,不需要反射 + + 要填充的物件型別 + 包含要填充資料的 JSON 字串 + 要被填充的現有物件 + JSON 序列化上下文,包含型別資訊 + 當 context 為 null 時拋出 + + + + 使用指定的 JSON 內容和序列化選項來填充現有物件的屬性 + 注意:此方法需要反射功能,不適用於 AOT 編譯 + + 要填充的物件型別 + 包含要填充資料的 JSON 字串 + 要被填充的現有物件 + JSON 序列化選項,如果為 null 則使用預設值 + 當反射被停用或無法找到型別資訊時拋出 + + + + 內部核心方法,執行實際的物件填充邏輯 + + 要填充的物件型別 + JSON 內容 + 要被填充的物件 + 原始的型別資訊解析器 + 取得原始型別資訊的函數 + 當 value 或 originalResolver 為 null 時拋出 + 當物件無法被填充時拋出 + + + + 根物件注入器,用於確保反序列化時使用現有的物件實例而非建立新實例 + + 根物件的型別 + + + + 初始化根物件注入器 + + 要注入的根物件實例 + 當 value 為 null 時拋出 + + + + 當需要建立根物件時,提供現有的物件實例而非建立新實例 + + JSON 型別資訊 + + + + 設定屬性物件的建立處理方式為填充模式 + + 要修改的 JSON 型別資訊 + + + + Merges the properties of the specified source into the target . + + If a property in the source has the same key as a property + in the target , the value from the source will overwrite the value in the target. + Properties in the target that do not exist in the source will remain unchanged. + The target to which properties will be added or updated. + The source containing the properties to merge into the target. + Thrown when or is null. + + + + 將 JsonObject 轉換為指定類型的新物件實例,使用 JsonSerializerOptions + 此方法提供了與 Newtonsoft.Json JObject.ToObject<T>() 類似的功能 + + 要轉換的目標類型 + 要轉換的 JsonObject + JSON 序列化選項,如果為 null 則使用預設值 + 轉換後的新物件實例 + 當 obj 為 null 時拋出 + 當轉換失敗時拋出 + + + + 將 JsonObject 轉換為指定類型的新物件實例,使用 JsonSerializerContext + 這是 AOT 編譯友好的版本,不需要反射 + + 要轉換的目標類型 + 要轉換的 JsonObject + JSON 序列化上下文,包含型別資訊 + 轉換後的新物件實例 + 當 obj 或 context 為 null 時拋出 + 當轉換失敗時拋出 + + + + 將物件序列化為 JsonNode,使用 JsonSerializerOptions + 此方法提供了與 Newtonsoft.Json JToken.FromObject() 類似的功能 + + 要序列化的物件 + JSON 序列化選項,如果為 null 則使用預設值 + 序列化後的 JsonNode + 當序列化失敗時拋出 + + + + 將物件序列化為 JsonNode,使用 JsonSerializerContext + 這是 AOT 編譯友好的版本,不需要反射 + + 物件的類型 + 要序列化的物件 + JSON 序列化上下文,包含型別資訊 + 序列化後的 JsonNode + 當 context 為 null 時拋出 + 當序列化失敗時拋出 + + + + JsonSerializer 的靜態輔助類,提供 PopulateObject 方法 + 使用方式:JsonSerializer.PopulateObject(json, obj, options) + + + + + 使用指定的 JSON 字串來填充現有物件的屬性 + 此方法提供了與 Newtonsoft.Json JsonConvert.PopulateObject 類似的功能 + + 要填充的物件型別 + 包含要填充資料的 JSON 字串 + 要被填充的現有物件 + JSON 序列化選項,如果為 null 則使用預設值 + 當反射被停用或無法找到型別資訊時拋出 + + + + 使用指定的 JSON 內容來填充現有物件的屬性 + 此方法提供了與 Newtonsoft.Json JsonConvert.PopulateObject 類似的功能 + + 要填充的物件型別 + 包含要填充資料的 JSON 內容 + 要被填充的現有物件 + JSON 序列化選項,如果為 null 則使用預設值 + 當反射被停用或無法找到型別資訊時拋出 + + + + 使用指定的 JSON 字串和序列化上下文來填充現有物件的屬性 + 這是 AOT 編譯友好的版本,不需要反射 + + 要填充的物件型別 + 包含要填充資料的 JSON 字串 + 要被填充的現有物件 + JSON 序列化上下文,包含型別資訊 + 當 context 為 null 時拋出 + + + + 使用指定的 JSON 內容和序列化上下文來填充現有物件的屬性 + 這是 AOT 編譯友好的版本,不需要反射 + + 要填充的物件型別 + 包含要填充資料的 JSON 內容 + 要被填充的現有物件 + JSON 序列化上下文,包含型別資訊 + 當 context 為 null 時拋出 + Event args for @@ -3125,7 +3606,7 @@ Object of audio tracks along with their associated enable states - + Default Constructor @@ -3162,7 +3643,7 @@ The default settings for the input - + Default Constructor @@ -3280,7 +3761,7 @@ Array of active inputs with their associated volume levels - + Default Constructor @@ -3535,7 +4016,7 @@ List of all scene items as JObject - + Default Constructor @@ -3658,7 +4139,7 @@ Updated array of scenes - + Default Constructor @@ -3791,7 +4272,7 @@ The default settings for the filter - + Default Constructor @@ -3949,7 +4430,7 @@ The body of the event - + Event args for unsupported events @@ -3974,7 +4455,7 @@ Vendor-provided event data. {} if event does not provide any data - + Default Constructor @@ -4114,7 +4595,7 @@ Kind of the Input - + Instantiate object from response data @@ -4135,7 +4616,7 @@ Unversioned Kind of the Input - + Instantiate object from response data @@ -4304,11 +4785,11 @@ Settings for the source - + Builds the object from the JSON data - JSON item description as a + JSON item description as a @@ -4335,11 +4816,11 @@ The source volume in decibels - + Builds the object from the JSON response body - JSON response body as a + JSON response body as a @@ -4401,7 +4882,7 @@ Position of the cursor in milliseconds. `null` if not playing - + Instantiate from JObject @@ -4492,7 +4973,7 @@ Monitor Position Y - + Constructor to auto populate @@ -4528,11 +5009,11 @@ Scene item list - + Builds the object from the JSON description - JSON scene description as a + JSON scene description as a @@ -4639,11 +5120,11 @@ Description of the platform, like `Windows 10 (10.0)` - + Builds the object from the JSON response body - JSON response body as a + JSON response body as a @@ -4740,7 +5221,7 @@ OutputState enum of current state - + Constructor @@ -4756,7 +5237,7 @@ Status of streaming output - + True if streaming is started and running, false otherwise @@ -4796,11 +5277,11 @@ Total number of frames delivered by the output's process - + Builds the object from the JSON response body - JSON response body as a + JSON response body as a @@ -4837,11 +5318,11 @@ Number of bytes sent by the output - + Builds the object from the JSON response body - JSON response body as a + JSON response body as a @@ -4858,7 +5339,7 @@ File name for the saved recording, if record stopped. null otherwise - + Constructor @@ -4949,11 +5430,11 @@ Type of the scene item's source. - + Builds the object from the JSON data - JSON item description as a + JSON item description as a @@ -5080,11 +5561,10 @@ The y position of the scene item from the top - + Initialize the scene item transform - - + /// @@ -5106,7 +5586,7 @@ Whether the source is showing in the UI (Preview, Projector, Properties) - + Auto populate constructor @@ -5152,11 +5632,11 @@ Is the track active - + Builds the object from the JSON data - JSON item description as a + JSON item description as a @@ -5273,11 +5753,11 @@ Object of settings for the transition. 'null' if transition is not configurable - + Builds the object from the JSON response body - JSON response body as a + JSON response body as a @@ -5294,11 +5774,11 @@ Whether the output is active - + Builds the object from the JSON response body - JSON response body as a + JSON response body as a @@ -5320,11 +5800,11 @@ Volume setting in dB - + Builds the object from the JSON response body - JSON response body as a + JSON response body as a