asyncio.get_event_loop().run_forever()\r
\r
def start_server():\r
- #STATE["current"] = current_slide()\r
http_daemon = threading.Thread(name="http_daemon", target=run_http)\r
http_daemon.setDaemon(True)\r
http_daemon.start()\r
print("Started HTTP server")\r
-\r
- #run_ws()\r
\r
ws_daemon = threading.Thread(name="ws_daemon", target=run_ws)\r
ws_daemon.setDaemon(True)\r
ws_daemon.start()\r
print("Started websocket server")\r
\r
- #try:\r
- # ws_daemon.start()\r
- # http_daemon.start()\r
- #except (KeyboardInterrupt, SystemExit):\r
- # cleanup_stop_thread()\r
- # sys.exit()\r
-\r
class Slideshow:\r
def __init__(self, instance):\r
self.instance = instance\r
import asyncio\r
import websockets\r
import threading\r
+from time import sleep\r
+\r
+PORT_DEFAULT = 5678\r
+HOSTNAME_DEFAULT = "localhost"\r
\r
hotkey_id_first = None\r
hotkey_id_prev = None\r
HOTKEY_DESC_BLACK = 'Black PowerPoint slide'\r
HOTKEY_DESC_WHITE = 'White PowerPoint slide'\r
\r
-global cmd \r
+global cmd\r
+global attempts\r
cmd = ""\r
+hostname = HOSTNAME_DEFAULT\r
+port = PORT_DEFAULT\r
+attempts = 0\r
\r
async def communicate():\r
- global cmd\r
- async with websockets.connect("ws://10.0.0.93:5678", ping_interval=None) as websocket:\r
+ async with websockets.connect("ws://%s:%s" % (hostname, port), ping_interval=None) as websocket:\r
+ global cmd\r
+ global attempts \r
while True:\r
if cmd:\r
- await websocket.send("{\"action\": \"" + cmd + "\"}")\r
- cmd = ""\r
- await asyncio.sleep(0.05)\r
+ try:\r
+ await websocket.send('{"action": "%s"}' % cmd)\r
+ cmd = ""\r
+ except websockets.ConnectionClosed as exc:\r
+ attempts += 1\r
+ if attempts == 4:\r
+ print("Failed to send command after {} attempts - aborting connection".format(attempts))\r
+ attempts = 0\r
+ cmd = ""\r
+ raise websockets.exceptions.ConnectionClosedError(1006, "Sending command failed after {} attempts".format(attempts))\r
+ await asyncio.sleep(0.05 + 0.5*attempts**2)\r
\r
def run_ws():\r
- asyncio.set_event_loop(asyncio.new_event_loop())\r
- asyncio.get_event_loop().run_until_complete(communicate())\r
-\r
-\r
+ while True:\r
+ try:\r
+ asyncio.set_event_loop(asyncio.new_event_loop())\r
+ asyncio.get_event_loop().run_until_complete(communicate())\r
+ except (OSError, websockets.exceptions.ConnectionClosedError):\r
+ # No server available - just keep trying\r
+ pass\r
+ except Exception as e:\r
+ print("Failed to connect to websocket: {} - {}".format(type(e), e))\r
+ finally:\r
+ sleep(1)\r
\r
#------------------------------------------------------------\r
# global functions for script plugins\r
hotkey_id_last = register_and_load_hotkey(settings, HOTKEY_NAME_LAST, HOTKEY_DESC_LAST, last_slide)\r
hotkey_id_black = register_and_load_hotkey(settings, HOTKEY_NAME_BLACK, HOTKEY_DESC_BLACK, black)\r
hotkey_id_white = register_and_load_hotkey(settings, HOTKEY_NAME_WHITE, HOTKEY_DESC_WHITE, white)\r
+\r
ws_daemon = threading.Thread(name="ws_daemon", target=run_ws)\r
ws_daemon.setDaemon(True)\r
ws_daemon.start()\r
save_hotkey(settings, HOTKEY_NAME_WHITE, hotkey_id_white)\r
\r
def script_description():\r
- return "ppt-control client\nHotkeys for controlling PowerPoint slides using websockets"\r
+ return """ppt-control client\r
+\r
+ Provides hotkeys for controlling PowerPoint slides using websockets.\r
+ Go to OBS settings -> Hotkeys to change hotkeys (none set by default)."""\r
\r
def script_defaults(settings):\r
- obs.obs_data_set_default_int(settings, 'port', 5678)\r
+ obs.obs_data_set_default_string(settings, 'hostname', HOSTNAME_DEFAULT)\r
+ obs.obs_data_set_default_int(settings, 'port', PORT_DEFAULT)\r
\r
def script_properties():\r
props = obs.obs_properties_create()\r
\r
- obs.obs_properties_add_int(props, "port", "Websocket port: ", 0, 9999, 1)\r
+ obs.obs_properties_add_text(props, "hostname", "Hostname: ", obs.OBS_TEXT_DEFAULT)\r
+ obs.obs_properties_add_int(props, "port", "Port: ", 0, 9999, 1)\r
return props\r
\r
def script_update(settings):\r
global port\r
port = obs.obs_data_get_int(settings, "port")\r
+ hostname = obs.obs_data_get_string(settings, "hostname")\r
\r
def register_and_load_hotkey(settings, name, description, callback):\r
hotkey_id = obs.obs_hotkey_register_frontend(name, description, callback)\r