obs_websocket 5.0.0-dev.1 obs_websocket: ^5.0.0-dev.1 copied to clipboard
obs_websocket allows dart-based connections to the OBS (Open Broadcaster Software) plugin obs-websocket
obs_websocket #
This package gives access to all of the methods and events outlined by the obs-websocket 5.0.0 protocol reference through the send
method documented below, but also has helper methods for many of the more popular requests that are made available through the protocol reference.
Please feel free to submit PRs for any additional helper methods, or report an issue for a missing helper method and I'll add it if I have time available.
Breaking changes from v2.4.3 (obs-websocket v4.9.1 protocol) #
The short answer is that everything has changed. The obs-websocket v5.0.0 protocol is very different from the older v4.9.1 protocol. Any code written for the v4.9.1 protocol needs to be re-written for v5.0.0
Getting Started #
Requirements #
- The OBS application needs to be installed on a machine reachable on the local network
- The obs-websocket plugin needs to be installed on the same machine
In your project add the dependency:
dependencies:
...
obs_websocket: ^5.0.0-dev.1
For help getting started with dart, check out these guides.
Usage Example #
Import the websocket connection library and the response library.
import 'package:obs_websocket/obs_websocket.dart';
Opening a websocket Connection #
The WebSocket protocol, described in the specification RFC 6455 provides a way to exchange data between client and server via a persistent connection. The data can be passed in both directions as “packets”.
Before a websocket connection can be made to a running instance of OBS, you will need to have the obs-websocket plugin installed and configured. The instruction and links to downloaded and install are available on the project Release page.
To open a websocket connection, we need to create new ObsWebSocket using the special protocol ws in the url:
final obsWebSocket =
await ObsWebSocket.connect('ws://[obs-studio host ip]:[port]', password: '[password]');
obs-studio host ip
- is the ip address or host name of the OBS device running obs-websocket protocol v5.0.0 that wou would like to send remote control commands to.
port
is the port number used to connect to the OBS device running obs-websocket protocol v5.0.0
password
- is the password configured for obs-websocket.
These settings are available to change and review through the OBS user interface by clicking Tools, obs-websocket Settings
.
Authenticating to OBS #
If a password
is supplied to the connect
method, authentication will occur automatically assuming that it is enabled for OBS.
Sending Commands to OBS #
The available commands/requests are documented on the protocol page of the obs-websocket github page. Note that not all commands listed on the protocol page have been implemented in code at this time. For any command not yet implemented, refer to the low-level
method of sending commands, documented below.
final status = await obs.stream.status();
// or this works too
// final status = await obs.stream.getStreamStatus();
if (!status.outputActive) {
await obsWebSocket.stream.start();
}
Supported high-level commands #
For any of the items that have an [x] from the list below, a high level helper command is available for that operation, i.e. obsWebSocket.general.version
or obsWebSocket.general.getVersion()
. Otherwise a low-level command can be used to perform the operation, i.e. obsWebSocket.send('GetVersion')
.
Requests Table of Contents #
- General Requests -
obsWebSocket.general
- ✅ GetVersion - Gets data about the current plugin and RPC version.
- ✅ GetStats - Gets statistics about OBS, obs-websocket, and the current session.
- ❌ BroadcastCustomEvent
- ❌ CallVendorRequest
- ✅ GetHotkeyList - Gets an array of all hotkey names in OBS
- ✅ TriggerHotkeyByName - Triggers a hotkey using its name. See GetHotkeyList
- ❌ TriggerHotkeyByKeySequence
- ❌ Sleep
- Config Requests -
obsWebSocket.config
- ❌ GetPersistentData
- ❌ SetPersistentData
- ❌ GetSceneCollectionList
- ❌ SetCurrentSceneCollection
- ❌ CreateSceneCollection
- ❌ GetProfileList
- ✅ SetCurrentProfile - Switches to a profile.
- ✅ CreateProfile - Creates a new profile, switching to it in the process
- ✅ RemoveProfile - Removes a profile. If the current profile is chosen, it will change to a different profile first.
- ❌ GetProfileParameter
- ❌ SetProfileParameter
- ✅ GetVideoSettings - Gets the current video settings.
- ✅ SetVideoSettings - Sets the current video settings.
- ✅ GetStreamServiceSettings - Gets the current stream service settings (stream destination).
- ✅ SetStreamServiceSettings - Sets the current stream service settings (stream destination).
- Sources Requests -
obsWebSocket.sources
- ✅ GetSourceActive - Gets the active and show state of a source.
- ✅ GetSourceScreenshot - Gets a Base64-encoded screenshot of a source.
- ✅ SaveSourceScreenshot - Saves a screenshot of a source to the filesystem.
- Scenes Requests -
obsWebSocket.scenes
- ✅ GetSceneList - Gets an array of all scenes in OBS.
- ✅ GetGroupList - Gets an array of all groups in OBS.
- ✅ GetCurrentProgramScene - Gets the current program scene.
- ✅ SetCurrentProgramScene - Sets the current program scene.
- ✅ GetCurrentPreviewScene - Gets the current preview scene (only available when studio mode is enabled).
- ✅ SetCurrentPreviewScene - Sets the current preview scene (only available when studio mode is enabled).
- ✅ CreateScene - Creates a new scene in OBS.
- ✅ RemoveScene - Removes a scene from OBS.
- ✅ SetSceneName - Sets the name of a scene (rename).
- ❌ GetSceneSceneTransitionOverride
- ❌ SetSceneSceneTransitionOverride
- Inputs Requests -
obsWebSocket.inputs
- ❌ GetInputList
- ❌ GetInputKindList
- ❌ GetSpecialInputs
- ❌ CreateInput
- ✅ RemoveInput - Removes an existing input.
- ✅ SetInputName - Sets the name of an input (rename).
- ❌ GetInputDefaultSettings
- ❌ GetInputSettings
- ❌ SetInputSettings
- ❌ GetInputMute
- ❌ SetInputMute
- ❌ ToggleInputMute
- ❌ GetInputVolume
- ❌ SetInputVolume
- ❌ GetInputAudioBalance
- ❌ SetInputAudioBalance
- ❌ GetInputAudioSyncOffset
- ❌ SetInputAudioSyncOffset
- ❌ GetInputAudioMonitorType
- ❌ SetInputAudioMonitorType
- ❌ GetInputAudioTracks
- ❌ SetInputAudioTracks
- ❌ GetInputPropertiesListPropertyItems
- ❌ PressInputPropertiesButton
- Transitions Requests -
obsWebSocket.transitions
- Filters Requests -
obsWebSocket.filters
- Scene Items Requests -
obsWebSocket.sceneItems
- ✅ GetSceneItemList - Gets a list of all scene items in a scene.
- ✅ GetGroupSceneItemList - Basically GetSceneItemList, but for groups.
- ✅ GetSceneItemId - Searches a scene for a source, and returns its id.
- ❌ CreateSceneItem
- ❌ RemoveSceneItem
- ❌ DuplicateSceneItem
- ❌ GetSceneItemTransform
- ❌ SetSceneItemTransform
- ✅ GetSceneItemEnabled - Gets the enable state of a scene item.
- ✅ SetSceneItemEnabled - Sets the enable state of a scene item.
- ❌ GetSceneItemLocked
- ❌ SetSceneItemLocked
- ❌ GetSceneItemIndex
- ❌ SetSceneItemIndex
- ❌ GetSceneItemBlendMode
- ❌ SetSceneItemBlendMode
- Outputs Requests -
obsWebSocket.outputs
- ❌ GetVirtualCamStatus
- ❌ ToggleVirtualCam
- ❌ StartVirtualCam
- ❌ StopVirtualCam
- ❌ GetReplayBufferStatus
- ❌ ToggleReplayBuffer
- ❌ StartReplayBuffer
- ❌ StopReplayBuffer
- ❌ SaveReplayBuffer
- ❌ GetLastReplayBufferReplay
- ❌ GetOutputList
- ❌ GetOutputStatus
- ❌ ToggleOutput
- ✅ StartOutput - Starts an output.
- ✅ StopOutput - Stops an output.
- ❌ GetOutputSettings
- ❌ SetOutputSettings
- Stream Requests -
obsWebSocket.stream
- ✅ GetStreamStatus - Gets the status of the stream output.
- ✅ ToggleStream - Toggles the status of the stream output.
- ✅ StartStream - Starts the stream output.
- ✅ StopStream - Stops the stream output.
- ❌ SendStreamCaption
- Record Requests -
obsWebSocket.record
- ✅ GetRecordStatus - Gets the status of the record output.
- ✅ ToggleRecord - Toggles the status of the record output.
- ✅ StartRecord - Starts the record output.
- ✅ StopRecord - Stops the record output.
- ✅ ToggleRecordPause - Toggles pause on the record output.
- ✅ PauseRecord - Pauses the record output.
- ✅ ResumeRecord - Resumes the record output.
- Media Inputs Requests -
obsWebSocket.mediaInputs
- ❌ GetMediaInputStatus
- ✅ SetMediaInputCursor - Sets the cursor position of a media input.
- ❌ OffsetMediaInputCursor
- ❌ TriggerMediaInputAction
- Ui Requests -
obsWebSocket.ui
- ✅ GetStudioModeEnabled - Gets whether studio is enabled.
- ✅ SetStudioModeEnabled - Enables or disables studio mode.
- ❌ OpenInputPropertiesDialog
- ❌ OpenInputFiltersDialog
- ❌ OpenInputInteractDialog
- ❌ GetMonitorList
- ❌ OpenVideoMixProjector
- ❌ OpenSourceProjector
Sending Commands to OBS - low level #
Alternatively, there is a low-level interface for sending commands. This can be used in place of the above, or in the case that a specific documented Request has not been implemented as a helper method yet. The available commands are documented on the protocol page of the obs-websocket github page
var response = await obsWebSocket.send('GetStreamStatus');
print('request status: ${response?.requestStatus.code}'); // 100 - for success
print('is streaming: ${response?.responseData?['outputActive']}'); // false - if not currently streaming
response?.requestStatus.result
will be true
on success. response?.requestStatus.code
will give a response code that is explained in the RequestStatus portion of the protocol documentation.
response?.requestStatus.comment
will sometimes give additional information about errors that might be generated.
Dealing with a list in the responseData
.
var response = await obs.send('GetSceneList');
var scenes = response?.responseData?['scenes'];
scenes.forEach(
(scene) => print('${scene['sceneName']} - ${scene['sceneIndex']}'));
Additionally you can provide arguments with a command:
response = await obs.send('GetVideoSettings');
var newSettings =
Map<String, dynamic>.from(response?.responseData as Map<String, dynamic>);
newSettings.addAll({
'baseWidth': 1440,
'baseHeight': 1080,
'outputWidth': 1440,
'outputHeight': 1080
});
// send the settings as an additional parameter.
await obs.send('SetVideoSettings', newSettings);
Events #
Events generated by OBS through the websocket can be hooked into by supplying an event listener in the form of addHandler<T>(Function handler)
. In the sample code below a hook is created that waits for a SceneItemEnableStateChanged
event. If the specified SceneItem
is visible the code hides the SceneItem
after 13 seconds. This code from the show_scene_item.dart
example could be used in a cron job to show and then hide an OBS SceneItem
periodically.
final obsWebSocket = await ObsWebSocket.connect(config['host'], password: config['password']);
// sceneItem to show/hide
final sceneItem = 'ytBell';
// tell obsWebSocket to listen to events, since the default is to ignore them
await obsWebSocket.listen(EventSubscription.all.code);
// get the current scene
final currentScene = await obsWebSocket.scenes.getCurrentProgramScene();
// get the id of the required sceneItem
final sceneItemId = await obsWebSocket.sceneItems.getSceneItemId(SceneItemId(
sceneName: currentScene,
sourceName: sceneItem,
));
// this handler will only run when a SceneItemEnableStateChanged event is generated
obsWebSocket.addHandler<SceneItemEnableStateChanged>(
(SceneItemEnableStateChanged sceneItemEnableStateChanged) async {
print(
'event: ${sceneItemEnableStateChanged.sceneName} ${sceneItemEnableStateChanged.sceneItemEnabled}');
// make sure we have the correct sceneItem and that it's currently visible
if (sceneItemEnableStateChanged.sceneName == currentScene &&
sceneItemEnableStateChanged.sceneItemEnabled) {
// wait 13 seconds
await Future.delayed(Duration(seconds: 13));
// hide the sceneItem
await obsWebSocket.sceneItems.setSceneItemEnabled(SceneItemEnableStateChanged(
sceneName: currentScene,
sceneItemId: sceneItemId,
sceneItemEnabled: false));
// close the socket when complete
await obsWebSocket.close();
}
});
// get the current state of the sceneItem
final sceneItemEnabled =
await obsWebSocket.sceneItems.getSceneItemEnabled(SceneItemEnabled(
sceneName: currentScene,
sceneItemId: sceneItemId,
));
// if the sceneItem is hidden, show it
if (!sceneItemEnabled) {
await obsWebSocket.sceneItems.setSceneItemEnabled(SceneItemEnableStateChanged(
sceneName: currentScene,
sceneItemId: sceneItemId,
sceneItemEnabled: true));
}
Supported Events for addHandler<T>
#
- General Events
- ✅ ExitStarted - OBS has begun the shutdown process.
- ✅ VendorEvent - An event has been emitted from a vendor.
- Config Events
- Scenes Events
- Inputs Events
- Transitions Events
- Filters Events
- Scene Items Events
- ❌ SceneItemCreated
- ❌ SceneItemRemoved
- ❌ SceneItemListReindexed
- ✅ SceneItemEnableStateChanged - A scene item's enable state has changed.
- ❌ SceneItemLockStateChanged
- ✅ SceneItemSelected - A scene item has been selected in the Ui.
- ❌ SceneItemTransformChanged
- Outputs Events
- ✅ StreamStateChanged - The state of the stream output has changed.
- ✅ RecordStateChanged - The state of the record output has changed.
- ❌ ReplayBufferStateChanged
- ❌ VirtualcamStateChanged
- ❌ ReplayBufferSaved
- Media Inputs Events
- Ui Events
- ✅ StudioModeStateChanged - Studio mode has been enabled or disabled.
Handling events not yet supported #
You can supply a fallbackEvent
to the ObsWebSocket
constructor to handle events that are not yet supported directly in the code. The following code snippet provides an example of this.
final obs = await ObsWebSocket.connect(
'ws://[obs-studio host ip]:4455',
password: '[password]',
fallbackEventHandler: (Event event) =>
print('type: ${event.eventType} data: ${event.eventData}'),
);
// tell obsWebSocket to listen to events, since the default is to ignore them
await obsWebSocket.listen(EventSubscription.all);
Closing the websocket #
Finally before your code completes, you will should close the websocket connection. Failing to close the connection can lead to unexpected performance related issues for your OBS instance.
obsWebSocket.close();