Class ObsModel
- Namespace
- OBSStudioClient.Model
- Assembly
- OBSClient.dll
A model of OBS Studio that keeps itself up to date, and that finds scenes, inputs and scene items by name.
public sealed class ObsModel : INotifyPropertyChanged, IDisposable, IAsyncDisposable
- Inheritance
-
ObsModel
- Implements
- Inherited Members
Examples
await using var obs = new ObsModel();
await obs.ConnectAsync("localhost", 4455, "password");
var gaming = obs.Scenes["Gaming"];
Console.WriteLine($"{gaming.Name} has {gaming.Items.Count} scene items; the webcam is {(gaming.Items["Webcam"].IsEnabled ? "on" : "off")}.");
obs.Changed += (_, e) => Console.WriteLine(e);
Remarks
OBS Studio identifies most things by a UUID, or by an id or an index. An ObsModel reads the scenes, inputs and scene items when it
connects, listens to the events that OBS Studio sends when they change, and keeps a copy in memory. The copy is what you ask for, by name:
obs.Scenes["Gaming"].Items["Webcam"].IsEnabled is answered at once, without a request to OBS Studio.
It is built on the ObsClient, which it owns the connection of, and which stays available as Client: every request and every event of OBS Studio can still be used through it. Do not call ConnectAsync(bool, string, string, int, EventSubscriptions, CancellationToken), Disconnect() or ReidentifyAsync(EventSubscriptions, CancellationToken) on it while it belongs to an ObsModel: use ConnectAsync(string, int, string, CancellationToken) and DisconnectAsync().
The model needs OBS Studio 30.1 or newer (obs-websocket 5.4), the first version that identifies scenes and inputs by UUID. Older versions work with the ObsClient alone. From OBS Studio 31.1 (obs-websocket 5.6) OBS Studio says which inputs have audio. Before that the model asks for the audio state of every input, which OBS Studio refuses for an input without audio, and takes the refusal as the answer: the model is the same, and connecting takes two more requests for each input without audio.
Everything that is a property is answered from the model, and can be read from any thread. The model is updated on a thread of its own; what you see changes between two reads. The notifications (Changed and the PropertyChanged events) are raised one at a time, in order, outside that thread (see NotificationContext).
Changes are methods on the objects, for example SetEnabledAsync(bool, CancellationToken), SetMutedAsync(bool, CancellationToken) and SwitchToAsync(CancellationToken). They are made one at a time, in the order in which you ask for them (OBS Studio can answer requests that arrive together in any order), and each returns when the model shows the change, so that what you read next is what you changed. A change is never made twice: when OBS Studio does not answer, or the connection ends, or the answer can not be read, the call ends with an ObsUnknownOutcomeException, and the model reads again what the change was about. A change is not sent when there is no connection, or when the connection that it was asked for on has ended and another was made (ObsNotConnectedException), while OBS Studio changes its scene collection (ObsNotReadyException), or to something that OBS Studio removed (ObsRemovedException). The model applies what the client reads a moment later, so the checks do not rest on the model alone: they are made again when the change is about to be written (which can be much later than when it was asked for), they look at the connection that it is written on, and a change of the scene collection that the client has read and the model has not applied yet stops the changes until it has. What is left is the time between OBS Studio sending the event and the client reading it (a few milliseconds on a local connection): a change that is sent then is refused by OBS Studio while it changes its scene collection (it answers that it is not ready, and the call ends with the same ObsNotReadyException), and nothing was changed. When OBS Studio made the change and the model can not show it (the events did not come in time, and the model could not be read again in time) the call ends with an ObsNotConfirmedException: the change was made, so do not send it again. A token that ends a call ends the wait at once and keeps a change that was not sent yet from being sent; one that was sent is not undone, and the next change still waits for the answer of OBS Studio to it, so that the order holds.
Scenes, inputs and scene items are made, renamed and removed in the same way: CreateSceneAsync(string, CancellationToken), CreateInputAsync(string, string, object?, bool, CancellationToken),
AddAsync(ObsSource, bool, CancellationToken), RenameAsync(string, CancellationToken), RemoveAsync(CancellationToken), RenameAsync(string, CancellationToken) and
RemoveAsync(CancellationToken). A name that is taken is refused with an ObsNameInUseException that says what holds it. OBS Studio keeps an input or a scene
that was removed alive for as long as scene items show it (it is Detached): the name of the input stays taken, and so does the name of the scene
with OBS Studio 31.0 and older (OBS Studio 31.1 and newer free the name of a scene that was removed at once). RemoveAsync removes those scene items too, so that OBS Studio
destroys the object (Gone) and the name is free.
Constructors
- ObsModel(ObsModelOptions?, ILoggerFactory?)
Creates an ObsModel with a new ObsClient, which it disposes of when it is disposed.
- ObsModel(ObsClient, ObsModelOptions?, ILogger<ObsModel>?)
Creates an ObsModel on an ObsClient that you have made. The client has to be disconnected, and it can have only one ObsModel. You remain the owner of the client: disposing of the ObsModel disconnects it, and does not dispose of it.
Properties
- Canvases
Gets the canvases of OBS Studio: the main canvas, and the ones that plugins made. It is the same object for as long as the ObsModel lives. The model holds the scenes of the main canvas (Scenes).
- Client
Gets the ObsClient that the model is built on. Every request and every event of OBS Studio is available through it.
- Inputs
Gets the inputs that were not removed, ordered by name.
- IsExiting
Gets whether OBS Studio said that it is shutting down (see ExitStarted). It tells a connection that ended because OBS Studio was closed from one that was lost: when the state is Reconnecting and this is true, OBS Studio was closed.
- IsStale
Gets whether the values that the model holds may be out of date: the model was complete once, and is not now (the connection is lost, or the model is being read again, or the ObsModel is disposed of). The values are the last that were known. Before the first connection there are no values, and this is false.
- IsStudioModeEnabled
Gets whether studio mode is on. SetStudioModeEnabledAsync(bool, CancellationToken) switches it.
- ObsVersion
Gets the version of OBS Studio that the model is connected to (for example 33.0.0), or null until a connection has said it, and when it said it in a form that cannot be read.
- Outputs
Gets the outputs: the stream, the recording, the virtual camera and the replay buffer. They are the same objects for as long as the ObsModel lives.
- Platform
Gets the platform that OBS Studio runs on, as it says it ("windows", "macos", "ubuntu"...), or null until a connection has said it.
- PreviewScene
Gets the preview scene: the scene that studio mode shows next to the program scene, and that becomes the program scene when the transition is triggered (TriggerAsync(CancellationToken)). It is null while studio mode is off (IsStudioModeEnabled).
- Profiles
Gets the profiles of OBS Studio: which one is current, their names, and the calls that switch to one, make one and remove one. It is the same object for as long as the ObsModel lives.
- ProgramScene
Gets the program scene: the scene that is on the air. It is null until it is known.
- SceneCollections
Gets the scene collections of OBS Studio: which one is loaded, their names, and the calls that load one and make one. It is the same object for as long as the ObsModel lives.
- Scenes
Gets the scenes, in the order of the list of scenes of OBS Studio. Groups, and scenes that OBS Studio removed but keeps alive, are not in the list.
- State
Gets the state of the model: whether there is a connection, and whether the model is complete. After the ObsModel is disposed of it is Disconnected.
- SupportedImageFormats
Gets the image formats that OBS Studio can make a screenshot in (
png,jpgand so on), as it said when it connected: the formats that GetScreenshotAsync(string, int?, int?, int?, CancellationToken) can ask for. It is empty until a connection has said it.
- Transitions
Gets the scene transitions: the current one, how long it takes, whether one is running, and the calls that change them. It is the same object for as long as the ObsModel lives.
- WebSocketVersion
Gets the version of obs-websocket that the model is connected to (for example 5.7.6), or null until a connection has said it. It decides which requests OBS Studio has: some come with a newer version (splitting a recording needs 5.5.0, and canvases 5.7.0).
Methods
- BroadcastCustomEventAsync(object, CancellationToken)
Sends a custom event to every client of OBS Studio that listens to the general events, this model included, and returns when OBS Studio has accepted it.
- CallVendorRequestAsync(string, string, object?, CancellationToken)
Calls a request that a plugin or a script of OBS Studio registered (a vendor request), and returns what it answered.
- ConnectAsync(string, int, string, CancellationToken)
Connects to OBS Studio, and reads its scenes, inputs and scene items. The task completes when the model is complete.
- CreateSceneAsync(string, CancellationToken)
Makes a scene, and returns it when the model shows it.
- DisconnectAsync()
Closes the connection to OBS Studio. The model keeps the last values that it knew (IsStale). The task completes when the connection is closed.
- Dispose()
Ends the connection and stops the model. Disposes of the ObsClient when this ObsModel made it.
- DisposeAsync()
Ends the connection and stops the model. Disposes of the ObsClient when this ObsModel made it.
- GetDefaultFilterSettingsAsync(string, CancellationToken)
Asks OBS Studio for the settings that a filter of a kind has until they are changed.
- GetDefaultInputSettingsAsync(string, CancellationToken)
Asks OBS Studio for the settings that an input of a kind has until they are changed.
- GetFilterKindsAsync(CancellationToken)
Asks OBS Studio for the kinds of filters that it can make (and that its plugins add):
color_filter_v2,noise_gate_filter,chroma_key_filter_v2, and so on.
- GetHotkeysAsync(CancellationToken)
Asks OBS Studio for the names of its hotkeys.
- GetInputKindsAsync(bool, CancellationToken)
Asks OBS Studio for the kinds of inputs that it can make (and that its plugins add):
color_source_v3,wasapi_input_capture,browser_source, and so on.
- GetMonitorsAsync(CancellationToken)
Asks OBS Studio for the monitors that it sees.
- GetPersistentDataAsync(ObsDataRealm, string, CancellationToken)
Asks OBS Studio for the data that it keeps for an application in a slot.
- GetRecordDirectoryAsync(CancellationToken)
Asks OBS Studio for the folder that it records to.
- GetSpecialInputsAsync(CancellationToken)
Asks OBS Studio which inputs it uses for the audio devices of the computer that every scene has: the desktop audio and the microphones.
- GetStatsAsync(CancellationToken)
Asks OBS Studio for its statistics: the load on the computer, the frame rate, the frames that were skipped, and the traffic of this connection.
- GetStreamServiceAsync(CancellationToken)
Asks OBS Studio for its stream service: where the stream of the profile that is current goes.
- GetVideoSettingsAsync(CancellationToken)
Asks OBS Studio for its video settings: the base (canvas) resolution, the output resolution and the frame rate of the profile that is current.
- OpenVideoMixProjectorAsync(MixType, int?, string?, CancellationToken)
Opens a projector of the preview, the program or the multiview of OBS Studio, and returns when OBS Studio has answered.
- SetPersistentDataAsync(ObsDataRealm, string, object, CancellationToken)
Puts data in a slot that OBS Studio keeps for an application, and returns when OBS Studio has answered.
- SetRecordDirectoryAsync(string, CancellationToken)
Changes the folder that OBS Studio records to (for the profile that is current), and returns when OBS Studio has made the change.
- SetStreamServiceAsync(string, object, CancellationToken)
Changes the stream service of OBS Studio (the profile that is current), and returns when OBS Studio has made the change.
- SetStudioModeEnabledAsync(bool, CancellationToken)
Switches studio mode on or off, and returns when the model shows it.
- SetVideoSettingsAsync((int Width, int Height)?, (int Width, int Height)?, (int Numerator, int Denominator)?, CancellationToken)
Changes the video settings of OBS Studio (the profile that is current), and returns when OBS Studio has made the change.
- TriggerHotkeyAsync(ObsKey, KeyModifier, CancellationToken)
Presses a key in OBS Studio, with the modifier keys that you give, and releases it, so that the hotkeys of OBS Studio that this key sequence is set for react. It returns when OBS Studio has answered.
- TriggerHotkeyAsync(string, string?, CancellationToken)
Triggers a hotkey of OBS Studio by its name, as if the key was pressed and released, and returns when OBS Studio has answered.
- WaitUntilSettledAsync(TimeSpan?, CancellationToken)
Waits until the model has applied everything that has arrived and has nothing left to read.
Events
- AudioLevels
Occurs when OBS Studio sent new levels of the audio of the inputs that are on the air (twenty times a second, as long as they change). It is only raised when the model was asked to follow them (HighVolume with AudioLevels).
- Changed
Occurs when something in the model changes: an object appeared or went, a value changed, or the model corrected itself. The records come in the order in which the changes happened, one at a time.
- CustomEvent
Occurs when somebody sends a custom event: a program that called BroadcastCustomEventAsync(object, CancellationToken) (this one included), or a script of OBS Studio.
- ExitStarted
Occurs when OBS Studio begins to shut down. The connection ends a moment later, and with AutoReconnect the model is then Reconnecting until OBS Studio is back: this event tells that OBS Studio was closed, and not that the connection was lost.
- FilterSettingsChanged
Occurs when OBS Studio says that the settings of a filter changed, with the filter and the settings that it has now.
- PropertyChanged
Occurs when a property value changes.
- Resynchronized
Occurs when the model has been read completely: after the first connection, after a connection that was lost is restored, and after OBS Studio changed its scene collection. Everything that you hold may have changed (scenes and inputs that were added, removed or renamed while the connection was down), so read what you need again. When OBS Studio changes its scene collection every scene, input and scene item that you hold is Gone: they belong to the collection that was left, and what is in the new one is new objects, also when a scene of the same name (or UUID) is in both. The same happens when the connection is lost while OBS Studio is changing its scene collection and is restored afterwards: the model cannot tell whether OBS Studio went to another collection or came back to the same one, so it takes it for a change. It is also raised when notifications were dropped because your handlers were too slow (see MaxPendingNotifications).
- SceneItemSelected
Occurs when a scene item is selected in OBS Studio (somebody clicked it in the list of scene items or in the preview, or OBS Studio selected one that was just made, which it does for every new scene item).
- ScreenshotSaved
Occurs when OBS Studio has saved a screenshot that was asked for in OBS Studio itself (the hotkey for a screenshot, or its menu), with the path of the file.
- VendorEvent
Occurs when a plugin or a script of OBS Studio sends an event of its own (a vendor event). It is only raised when you subscribed to the vendor events, with AdditionalEvents (Vendors): the model does not need them, and a plugin can send a great many.