Multi-Instance: How to make a Slave instance of OBS follow a Master instance?

AaronD

Active Member
I need to produce two separate streams with different but related content. One feeds an online meeting platform using the virtual camera, and the other feeds a local display and is recorded. The local display and recording instance has two scenes - screen capture of the meeting, or direct from the master instance - while the master instance has all of the material and producer-interaction as usual. The idea is to produce the feed to the meeting, like any other live broadcast, and simultaneously produce a recording that includes both the featured content and the participants' reactions.

My original version of that system was developed on Windows, using the Advanced Scene Switcher plugin to write the Master's current scene to a file, and then to run the contents of that file through a set of regex's in the Slave so that it can switch automatically when one of them finds a match:
Untitled.png

Use the scene names in the Master to trigger these regex's in the Slave, and thus their pre-determined creative decisions in the local display and recording.

That works perfectly in Windows, which is where I needed it first, but not so much in Ubuntu, using the snap version of OBS. It seems like the snap version is farther along in development than the `apt install` version, so I'd really like to use it if I can. But it seems to have some difficulty with this file-connection between multiple instances.

When it "didn't work" (no tracking whatsoever between instances), I opened that file in the text editor, expecting to see the name of the Master's current scene, and for it to stay current as I reloaded the text editor. Instead, I got what looks like two non-ASCII characters and nothing else. And those characters would change constantly as I reloaded the text editor, without changing scenes in the Master.

What's going on here?

And is there a better way to make this connection?
 

Domassimo

New Member
Can you use obs-websocket on both instances? And then have a simple script that listens for scene change events on the 'lead' OBS instance and request the 'following' instance to also go that scene. Just make sure the websocket on each instance is on a different port to avoid issues. Benefit of this method is that you could run the instances on different machines without much issue, as it's more flexible.
 

AaronD

Active Member
Can you use obs-websocket on both instances? And then have a simple script that listens for scene change events on the 'lead' OBS instance and request the 'following' instance to also go that scene. Just make sure the websocket on each instance is on a different port to avoid issues. Benefit of this method is that you could run the instances on different machines without much issue, as it's more flexible.

That was one of my original considerations, before I came up with the file-based solution. But nothing that I saw about it made sense to me. Is there an absolute-noob-level tutorial that I missed the first time around?
 

AaronD

Active Member
Okay, I think what was tripping me up was a disconcerting lack of how the websocket itself works. This time around, I found a wrapper with documentation and (actually!) minimal examples that I could test, see that they do indeed work, and then modify from there.


(Many a project has been killed for me by having all of the examples try to do everything at the same time, so that a noob can't separate the essentials from the fluff; or by not working as-is out of the box, so I then have to debug something that I don't understand. But that project is good!)

Anyway, here's what I came up with and works (I'm also a noob with python: my native language is C, with a little bit of bash thrown in, which also tripped me up a few times here):

Python:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
import subprocess

from obswebsocket import obsws, events, requests


wsSlv = obsws("localhost", 4445, "********")
wsSlv.connect()


def on_switch(message):
    name = message.getSceneName()
    if re.match("Camera.*", name):
        wsSlv.call(requests.SetCurrentScene("Meeting"))
    if re.match("Media.*", name):
        wsSlv.call(requests.SetCurrentScene("OBS Master"))


wsMst = obsws("localhost", 4444, "********")
wsMst.register(on_switch, events.SwitchScenes)
wsMst.connect()


try:
    subprocess.run(["zenity", "--info", "--width=350", "--title=DO NOT CLOSE THIS!!!", "--text=When the meeting is done:\n1. Hang it up\n2. Exit button in both OBS\n3. Close everything else\n4. Click OK here\n\nEverything else will then clean up automatically."])

except KeyboardInterrupt:
    pass


wsMst.disconnect()
wsSlv.disconnect()

This is called in the middle of the overall bash script, when all of the other setup is done. When zenity exits, this script follows soon after, and then the bash script does its own cleanup.
 
Top