pub package

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 available through the protocol reference.

Build Status github last commit github build github issues

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.

New for version 2.4.0

As of the 2.4.0 release of this package, there is a cli utility included that can be used to return data for many API calls currently supported by the package. If you want to get started quickly with the cli utility run these commands in a terminal session:

pub global activate obs_websocket

obs --help

Please see the cli documentation README.md for more detailed usage information.

Getting Started


  • 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.4.4

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 introduced 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 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.

//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

For v2.4.0 of this package the cli model has been completely revamped. Please see the cli documentation README.md for more detailed usage information.

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 exception that can be caught, 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));
// or
// The new connect method also gives the option for a timeout and will throw an exception that can be 
// caught 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.


Messages are exchanged between the client and the server as JSON objects. The protocol is based on the original OBS Remote protocol created by Bill Hamilton, with new commands specific to OBS Studio.