diff --git a/README.md b/README.md index 5ab0ae8..f947450 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,50 @@ # OBS-to-XAir -Sync current OBS scene to channel mute stat of a Behringer XAir Mixer +This is a small script that mutes and unmutes channels on Behringer XAir Mixers depending on the current scene. + +## Requirements + +- The [obs-websocket plugin](https://github.com/Palakis/obs-websocket/releases) (Version >= 4.5.1) +- A fairly recent version of Python 3 +- [websocket-client](https://github.com/websocket-client/websocket-client) +- [python-osc](https://github.com/attwad/python-osc) + +## General Setup + +- Install Python 3.x.x + - On Windows: Make sure you trick "Add Python 3.x to PATH" in the setup +- Make sure you also install pip +- Open up a command line and execute these commands to install the required pip modules: + - pip install python-osc + - pip install websocket-client +- OBS Websocket: + - Download the installer from the link above and run it + - Start OBS, open the "Tools" menu and select "websocket server settings" + - Make sure that "Enable Websocket server" is checked, "Server Port" is 4444 and "Enable authentification" is unchecked + +## Configuration + +You have to configure your scene-to-channel mapping and the IP settings. Open up the .py file with a text editor. + +- The mapping: +This python dict resolves the OBS scene names to the XAir channels. 3 Channels come pre-set as a template. +The format follows the rule "scene name": "mixer channel". +"scene name" is the scene name in OBS which you want to pair to a mixer channel. "mixer channel" is the channel on the XAir mixer. Important: If you use the lower channels 1-9 you have to add zero-padding so "1" becomes "01" and so on. You can find all available channel names besides the normal 01-16 in the "parameters.txt" when you download the latest mixer firmware zip. + +- OBS IP and Port: +In line 9 and 10 you can set the IP and port from the machine that runs OBS. If you are running the script locally you don't need to change anything. + +- XAir Mixer IP: +In line 11 you need to set the IP address of your XAir Mixer. The OSC Port can't be changed so it's hardcoded. + +## Usage + +Just run the script, either from the command line or with a double-click. There will be no further output besides "Websocket open" when it's running. If the connection to OBS is broken, you will get an error. + +## Compatibility + +This script was developed and tested with: +- OBS 23.1.0 +- obs-websocket 4.5.1 +- A Behringer XR18 + +It should theoretically also work with the XR12, XR16 and X32 but i cannot validate this myself. Feel free to let me know if it worked for you. \ No newline at end of file diff --git a/obs-to-xair.py b/obs-to-xair.py new file mode 100644 index 0000000..a952057 --- /dev/null +++ b/obs-to-xair.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +import websocket, json +from time import sleep +from pythonosc import osc_message_builder +from pythonosc import udp_client + +mapping = {"scene1": "01", "scene2": "02", "scene3": "03"} #set the mapping for the scene to channel mapping here. "scenename": "channel" +obsip = "localhost" #set the obs machine ip here. localhost works if you run this script on the same machine. +obsport = "4444" #set the ob websocket port here. 4444 is defult +xairip = "192.168.1.10" #set the xairip here + +def ws1_on_message(ws, message): + jsn = json.loads(message) + if jsn["update-type"] == "SwitchScenes": + for scene in mapping: + if scene == jsn["scene-name"]: + client.send_message("/ch/" + mapping[scene] + "/mix/on", 1) + else: + client.send_message("/ch/" + mapping[scene] + "/mix/on", 0) + elif jsn["update-type"] == "TransitionBegin": + for scene in mapping: + if scene == jsn["to-scene"]: + client.send_message("/ch/" + mapping[scene] + "/mix/on", 1) + elif scene == jsn["from-scene"] and not jsn["name"] == "Cut": + client.send_message("/ch/" + mapping[scene] + "/mix/on", 1) + else: + client.send_message("/ch/" + mapping[scene] + "/mix/on", 0) + +def ws1_on_error(ws, error): + print(error) + +def ws1_on_close(ws): + print("Websocket close") + +def ws1_on_open(ws): + print("Websocket open") + +def ws1_start(): + while True: + ws1.run_forever() + print("Websocket restart") + print("This most likely means that OBS is not open or you lost network connection.") + sleep(1) + +if __name__ == "__main__": + client = udp_client.SimpleUDPClient(xairip, 10024) + ws1 = websocket.WebSocketApp("ws://" + obsip + ":" + obsport, on_message = ws1_on_message, on_error = ws1_on_error, on_close = ws1_on_close) + ws1.on_open = ws1_on_open + ws1_start()