obs_websocket 2.2.3
obs_websocket: ^2.2.3 copied to clipboard

obs_websocket allows dart-based connections to the Open Broadcaster plugin obs-websocket

obs_websocket #

Some background first. I needed a way to automate the start and stop streaming actions for OBS (Open Broadcast Software) with cron on OSX. This package will allow you to do that with dart or can be used with flutter to control OBS with a platform independent mobile app.

This package gives access to all of the methods and events outlined by the obs-websocket 4.9.1 protocol reference through the command method documented below, but also has helper methods for many of the more popular Requests that are made avaialble through the protocol reference.

pub package

Please feel free to submit PRs for any addtional helper methods, or report an issue for a missing helper method and I'll add it if I have time available.

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:

  obs_websocket: ^2.2.3

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.

To open a websocket connection, we need to create new ObsWebSocket using the special protocol ws in the url:

//the method to connect has changed with v2.1.x
ObsWebSocket obsWebSocket =
    await ObsWebSocket.connect(connectUrl: 'ws://[obs-studio host ip]:4444');

obs-studio host ip - is the ip address or host name of the computer running OBS that wou would like to send remote control commands to.

Authenticating to OBS #

OBS has an optional, but highly recommended password security feature, the getAuthRequired method will check if the password security has been enabled. The AuthRequired object that the method call returns is used as part of the authentication process. The protocol documentation provided on the obs-websocket github pages covers this in detail.

final AuthRequired authRequired = await obsWebSocket.getAuthRequired();

if (authRequired.status)
	await obsWebSocket.authenticate(authRequired, '[password]');

Sending Commands to OBS #

The available commands 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 StreamStatusResponse status = await obsWebSocket.getStreamStatus();

if (!status.streaming) {
  await obsWebSocket.startStreaming();

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 method yet. The available commands are documented on the protocol page of the obs-websocket github page

SimpleResponse response await obsWebSocket.command('StartStreaming');

response.status will be true on success. response.error will give an error description if one is available.

Commands can also return a result as a Map:

SimpleResponse response = await obsWebSocket.command('GetSourcesList');

List sources = response.map['sources'];

sources.forEach((source) => print(source['name'] + ' - ' + source['type']));

Additionally you can provide arguments with a command:

response = await obsWebSocket.command('GetSourceSettings', { 'sourceName': 'foreground' });

Map newSettings = Map<String,dynamic>.from(response.map);

newSettings['sourceSettings']['height'] = 1080;
newSettings['sourceSettings']['width'] = 1920;

response = await obsWebSocket.command('SetSourceSettings', newSettings);


Events - v2.1.0 intruduced a new model for event handling #

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 SceneItemStateEvent event. If the type of event is SceneItemState.SceneItemVisibilityChanged, and if the SceneItem is visbile the code hides the SceneItem after 13 seconds. This code from the showSceneitem.dart example could be used in a cron job to show and then hide an OBS SceneItem periodically.

//sceneItem for this event
final sceneItem = 'ytBell';

ObsWebSocket obsWebSocket = ObsWebSocket(
    connectUrl: 'ws://[obs-studio host ip]:4444');

//this handler will only run when a SceneItemState event is generated
    .addHandler<SceneItemStateEvent>((SceneItemStateEvent sceneItemStateEvent) async {
    //make sure we have the correct sceneItem and that it's currently visible
    if (sceneItemStateEvent.type == 'SceneItemVisibilityChanged' &&
        sceneItemStateEvent.itemName == sceneItem &&
        sceneItemStateEvent.state) {
      //wait 13 seconds
      await Future.delayed(Duration(seconds: 13));

      //hide the sceneItem
      await obsWebSocket

      //close the socket when complete
      await obsWebSocket.close();

Supported Events for addHandler<T> #

RecordingStateEventRecordingStarting, RecordingStarted, RecordingStopping, RecordingStopped, RecordingPausedEvent, RecordingResumed
SceneItemEventSceneItemAdded, SceneItemRemoved, SceneItemSelected, SceneItemDeselected
SceneItemStateEventSceneItemVisibilityChanged, SceneItemLockChanged
StreamStateEventStreamStarting, StreamStarted, StreamStopping, StreamStoppedEvent
BaseEventany not listed above, the Map<String, dynamic> rawEvent property gives access to the underlying event response data

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.


Sample OBS cli #

This code base includes sample code for a OBS cli application that can be used to send obs-websocket protocol based commands to OBS. An example of a command is as follows:

dart bin/ws-obs.dart --command GetStreamingStatus --url=ws:///[obs-studio host ip]:4444  --passwd [password]
-h, --help                        Display this helpful message
-p, --passwd                      The OBS websocket password, only required if enabled in OBS
-u, --url=<ws://[host]:[port]>    The url and port for OBS websocket
-c, --command                     Required. The OBS command to send
                                  [StartStopStreaming, StartStreaming, StopStreaming, GetStreamingStatus, GetStreamSettings, SetStreamSettings, SaveStreamSettings, GetSourcesList, GetVolume, SetVolume]
-a, --args                        Optional. The json encoded arguments for the supplied command if required

You can use dart compile to create the cli executable.

Supported high-level commands #

For any of the items that have an [x] from the list below, a high level command is available for that operation, i.e. obsWebSocket.getStudioModeStatus() otherwise a low-level command can be used to perform the operation, obsWebSocket.command('GetVersion').

Breaking changes moving from v2.1.x to v2.2.x #

The dart pub publish analyzer wanted a file name change, so here it is.

//This no longer works
//import 'package:obs_websocket/obsWebsocket.dart';

//instead use
import 'package:obs_websocket/obs_websocket.dart';

Breaking changes moving from v2.0.x to v2.1.x #

The underlying web_socket_channel library defaults to a very long timeout and attempting to connect to OBS when it is not actually running will not throw an catchable exception, there is more info about this available in the project github issue tracker. To resolve this issue in obs_websocket there has been a modification to the code used to connect to OBS.

//This will no longer work
//ObsWebSocket obsWebSocket = ObsWebSocket(connectUrl: 'ws://[obs-studio host ip]:4444');
//alternatively you could use:
//final websocket = await WebSocket.connect(connectUrl).timeout(timeout);
//final obsWebSocket = ObsWebSocket(channel: IOWebSocketChannel(websocket));
//The new connect method also gives the option for a timeout and will throw a catchable exception in 
//the case that OBS is not running.  The default timeout is 30 seconds.
final obsWebSocket =
    await ObsWebSocket.connect(
      connectUrl: 'ws://[obs-studio host ip]:4444', 
      timeout: const Duration(seconds: 5)

Breaking changes moving from v1.x to v2.x #

I'm sorry to say that there are several, but it should be very easy to migrate over v1.0.0 code.

//This no longer works
//import 'package:obs_websocket/obs_websocket.dart';

//instead use
import 'package:obs_websocket/obsWebsocket.dart';

//This additional import is no longer necessary
//import 'package:obs_websocket/response.dart';

//SimpleResponse has gone away
//SimpleResponse response = await obsWebSocket.command('StartStreaming');

//It's been replaces with BaseResponse?
BaseResponse? response = await obsWebSocket.command('StartStreaming');

Known bugs #

I've submitted a bug to the obs-websocket team for a bug that I am seeing when executing a websocket connecting program multiple times in sequence to start and stop steaming causes OBS to crash. For my use case I am able to work around this by stopping and restarting OBS itself before restarting streaming.

pub points



obs_websocket allows dart-based connections to the Open Broadcaster plugin obs-websocket

Repository (GitHub)
View/report issues


API reference




args, crypto, json_annotation, universal_io, web_socket_channel, yaml


Packages that depend on obs_websocket