From: Andrew Lorimer
Date: Sat, 1 May 2021 07:11:33 +0000 (+1000)
Subject: bugfixing, obs interface
X-Git-Tag: v0.0.1~3
X-Git-Url: https://git.lorimer.id.au/ppt-control.git/diff_plain/0dafb3fe809570fed80f0e0fb06511a231201748
bugfixing, obs interface
---
diff --git a/icons/ppt.ico b/icons/ppt.ico
new file mode 100755
index 0000000..e3fb47b
Binary files /dev/null and b/icons/ppt.ico differ
diff --git a/icons/ppt.png b/icons/ppt.png
new file mode 100755
index 0000000..841b67b
Binary files /dev/null and b/icons/ppt.png differ
diff --git a/index.html b/index.html
index 5a0cec6..b19415f 100755
--- a/index.html
+++ b/index.html
@@ -3,6 +3,7 @@
+
ppt-control
@@ -28,7 +29,7 @@
- Current: /?
+ Current: /?
@@ -41,6 +42,7 @@
+
diff --git a/obs_ppt.py b/obs_ppt.py
deleted file mode 100755
index a4e0c39..0000000
--- a/obs_ppt.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import obspython as obs
-# pip install pywin32
-import win32com.client
-import pywintypes
-import os
-import shutil
-import http_server_39 as server
-#import http.server as server
-import socketserver
-import threading
-import functools
-
-powerpoint = None
-hotkey_id_frst = None
-hotkey_id_prev = None
-hotkey_id_next = None
-hotkey_id_last = None
-hotkey_id_black = None
-
-HOTKEY_NAME_FRST = 'powerpoint_slides.first'
-HOTKEY_NAME_PREV = 'powerpoint_slides.previous'
-HOTKEY_NAME_NEXT = 'powerpoint_slides.next'
-HOTKEY_NAME_LAST = 'powerpoint_slides.last'
-HOTKEY_NAME_BLACK = 'powerpoint_slides.black'
-HOTKEY_NAME_WHITE = 'powerpoint_slides.white'
-
-HOTKEY_DESC_FRST = 'First PowerPoint slide'
-HOTKEY_DESC_PREV = 'Previous PowerPoint slide'
-HOTKEY_DESC_NEXT = 'Next PowerPoint slide'
-HOTKEY_DESC_LAST = 'Last PowerPoint slide'
-HOTKEY_DESC_BLACK = 'Black PowerPoint slide'
-HOTKEY_DESC_WHITE = 'White PowerPoint slide'
-
-class Handler(server.CGIHTTPRequestHandler):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, directory=os.path.dirname(os.path.realpath(__file__)))
-
-def run_http():
- httpd = server.HTTPServer(("", 8000), Handler)
- httpd.serve_forever()
-
-
-
-
-# ------------------------------------------------------------
-# global functions for script plugins
-
-def script_load(settings):
- global hotkey_id_frst
- global hotkey_id_prev
- global hotkey_id_next
- global hotkey_id_last
- global hotkey_id_black
- global hotkey_id_white
-
- hotkey_id_frst = register_and_load_hotkey(settings, HOTKEY_NAME_FRST, HOTKEY_DESC_FRST, slideshow_view_first)
- hotkey_id_prev = register_and_load_hotkey(settings, HOTKEY_NAME_PREV, HOTKEY_DESC_PREV, slideshow_view_previous)
- hotkey_id_next = register_and_load_hotkey(settings, HOTKEY_NAME_NEXT, HOTKEY_DESC_NEXT, slideshow_view_next)
- hotkey_id_last = register_and_load_hotkey(settings, HOTKEY_NAME_LAST, HOTKEY_DESC_LAST, slideshow_view_last)
- hotkey_id_black = register_and_load_hotkey(settings, HOTKEY_NAME_BLACK, HOTKEY_DESC_BLACK, slideshow_view_black)
- hotkey_id_white = register_and_load_hotkey(settings, HOTKEY_NAME_WHITE, HOTKEY_DESC_WHITE, slideshow_view_white)
-
- daemon = threading.Thread(name="daemon_server", target=run_http)
- daemon.setDaemon(True)
- daemon.start()
-
-def script_unload():
- obs.obs_hotkey_unregister(slideshow_view_first)
- obs.obs_hotkey_unregister(slideshow_view_previous)
- obs.obs_hotkey_unregister(slideshow_view_next)
- obs.obs_hotkey_unregister(slideshow_view_last)
- obs.obs_hotkey_unregister(slideshow_view_black)
- obs.obs_hotkey_unregister(slideshow_view_white)
-
-def script_save(settings):
- save_hotkey(settings, HOTKEY_NAME_FRST, hotkey_id_frst)
- save_hotkey(settings, HOTKEY_NAME_PREV, hotkey_id_prev)
- save_hotkey(settings, HOTKEY_NAME_NEXT, hotkey_id_next)
- save_hotkey(settings, HOTKEY_NAME_LAST, hotkey_id_last)
- save_hotkey(settings, HOTKEY_NAME_BLACK, hotkey_id_black)
- save_hotkey(settings, HOTKEY_NAME_WHITE, hotkey_id_white)
-
-def script_description():
- return 'Navigate Powerpoint Slides.'
-
-def script_defaults(settings):
- obs.obs_data_set_default_string(settings, 'cache', r'''C:\Windows\Temp''')
-
-def script_properties():
- props = obs.obs_properties_create()
-
- obs.obs_properties_add_path(props, "cache", "Slide cache: ", obs.OBS_PATH_DIRECTORY, "*.jpg", r'''C:\Windows\Temp''')
- return props
-
-def script_update(settings):
- global cache
- cache = obs.obs_data_get_string(settings, "cache").replace("/", "\\")
-
-def register_and_load_hotkey(settings, name, description, callback):
- hotkey_id = obs.obs_hotkey_register_frontend(name, description, callback)
- hotkey_save_array = obs.obs_data_get_array(settings, name)
- obs.obs_hotkey_load(hotkey_id, hotkey_save_array)
- obs.obs_data_array_release(hotkey_save_array)
-
- return hotkey_id
-
-def save_hotkey(settings, name, hotkey_id):
- hotkey_save_array = obs.obs_hotkey_save(hotkey_id)
- obs.obs_data_set_array(settings, name, hotkey_save_array)
- obs.obs_data_array_release(hotkey_save_array)
-
-#-------------------------------------
-
-def get_slideshow_view():
- global powerpoint
-
- if powerpoint is None:
- powerpoint = win32com.client.Dispatch('Powerpoint.Application')
-
- if powerpoint is None:
- return
-
- ssw = powerpoint.SlideShowWindows
- if ssw.Count == 0:
- return
-
- # https://docs.microsoft.com/en-us/office/vba/api/powerpoint.slideshowwindow.view
- ssv = ssw[0].View
-
- return ssv
-
-def get_activepresentation():
- global powerpoint
-
- if powerpoint is None:
- powerpoint = win32com.client.Dispatch('Powerpoint.Application')
-
- if powerpoint is None:
- return
-
- activepres = powerpoint.ActivePresentation
- return activepres
-
-def export_next(slide):
- global cache
- ssp = get_activepresentation()
- if ssp:
- if slide < len(ssp.Slides):
- ssp.Slides(slide + 1).Export(cache + r'''\slide0.jpg''', "JPG")
- attempts = 0
- while attempts < 3:
- try:
- os.replace(cache + r'''\slide0.jpg''', cache + r'''\slide.jpg''')
- except:
- pass
- attempts += 1
- else:
- shutil.copyfileobj(open(os.path.dirname(os.path.realpath(__file__)) + r'''\blank.jpg''', 'rb'), open(cache + r'''\slide.jpg''', 'wb'))
-
-def slideshow_view_first(pressed):
- if pressed:
- ssv = get_slideshow_view()
- if ssv:
- ssv.First()
- ssv.State = 1
-
-def slideshow_view_previous(pressed):
- if pressed:
- ssv = get_slideshow_view()
- if ssv:
- ssv.Previous()
- ssv.State = 1
- export_next(ssv.CurrentShowPosition)
-
-def slideshow_view_next(pressed):
- if pressed:
- ssv = get_slideshow_view()
- if ssv:
- ssv.Next()
- ssv.State = 1
- export_next(ssv.CurrentShowPosition)
-
-
-def slideshow_view_last(pressed):
- if pressed:
- ssv = get_slideshow_view()
- if ssv:
- ssv.Last()
- ssv.State = 1
-
-def slideshow_view_black(pressed):
- if pressed:
- ssv = get_slideshow_view()
- if ssv:
- if ssv.State == 3 or ssv.State == 4:
- ssv.State = 1
- else:
- ssv.State = 3
-
-def slideshow_view_white(pressed):
- if pressed:
- ssv = get_slideshow_view()
- if ssv:
- if ssv.State == 4 or ssv.State == 3:
- ssv.State = 1
- else:
- ssv.State = 4
diff --git a/ppt-control.js b/ppt-control.js
index 7e4c312..e1b8841 100644
--- a/ppt-control.js
+++ b/ppt-control.js
@@ -1,4 +1,6 @@
+var DEFAULT_TITLE = "ppt-control"
var preloaded = false;
+var preload = [];
function imageRefresh(id) {
img = document.getElementById(id);
@@ -108,6 +110,11 @@ function sync_next() {
}
show_next.onclick = sync_next;
+function sync_shortcuts() {
+ saveSettings();
+}
+shortcuts.onclick = sync_shortcuts;
+
function set_control_width() {
var width = window.innerWidth
|| document.documentElement.clientWidth
@@ -154,10 +161,27 @@ document.addEventListener('keydown', function (e) {
}
});
+function sleep(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+
+function disconnect() {
+ document.title = DEFAULT_TITLE;
+ current_img.src = "/black.jpg";
+ next_img.src = "/black.jpg";
+ users.textContent = "Connection to PowerPoint failed";
+}
+
websocket.onmessage = function (event) {
+ console.log("Received data");
data = JSON.parse(event.data);
switch (data.type) {
case 'state':
+ if (data.connected == "0" || data.connected == 0) {
+ console.log("Disconnected");
+ disconnect();
+ break;
+ }
var d = new Date;
switch (data.visible) {
case 3:
@@ -194,14 +218,13 @@ websocket.onmessage = function (event) {
console.error(
"unsupported event", data);
}
- if (!preloaded) {
- var i = 0
- var preload = [];
+ if (preloaded == false && ! isNaN(total.textContent)) {
+ image = document.getElementById("preload_img");
for (let i=1; i<=Number(total.textContent); i++) {
- image = new Image();
image.src = "/cache/" + i + ".jpg";
preload.push(image);
- console.log("Preloaded image " + i);
+ console.log("Preloaded " + total.textContent);
+ //sleep(0.5)
}
preloaded = true;
}
@@ -211,6 +234,7 @@ websocket.onmessage = function (event) {
var interval = setInterval(refresh, 5000);
function refresh() {
+ console.log("Refreshing")
websocket.send(JSON.stringify({action: 'refresh'}));
}
diff --git a/ppt_control.py b/ppt_control.py
index 75cf1b0..2e0cc3d 100755
--- a/ppt_control.py
+++ b/ppt_control.py
@@ -15,9 +15,15 @@ import urllib
import posixpath
import time
import pythoncom
+import pystray
+import tkinter as tk
+from tkinter import ttk
+from PIL import Image, ImageDraw
logging.basicConfig()
+global STATE
+global STATE_DEFAULT
global current_slideshow
current_slideshow = None
CACHEDIR = r'''C:\Windows\Temp\ppt-cache'''
@@ -50,6 +56,9 @@ class Handler(server.SimpleHTTPRequestHandler):
if len(words) > 0 and words[0] == "cache":
if current_slideshow:
path = CACHEDIR + "\\" + current_slideshow.name()
+ else:
+ path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "black.jpg") + '/'
+ return path
words.pop(0)
else:
path = self.directory
@@ -67,11 +76,13 @@ def run_http():
http_server = server.HTTPServer(("", 80), Handler)
http_server.serve_forever()
-STATE = {"connected": 0, "current": 0, "total": 0, "visible": 0, "name": ""}
+STATE_DEFAULT = {"connected": 0, "current": 0, "total": 0, "visible": 0, "name": ""}
+STATE = STATE_DEFAULT
USERS = set()
def state_event():
+ print("Running state event")
return json.dumps({"type": "state", **STATE})
@@ -80,12 +91,15 @@ def users_event():
async def notify_state():
- global current_slideshow
- if current_slideshow:
+ print("Notifying state to " + str(len(USERS)) + " users")
+ global STATE
+ if current_slideshow and STATE["connected"] == 1:
STATE["current"] = current_slideshow.current_slide()
STATE["total"] = current_slideshow.total_slides()
STATE["visible"] = current_slideshow.visible()
STATE["name"] = current_slideshow.name()
+ else:
+ STATE = STATE_DEFAULT
if USERS: # asyncio.wait doesn't accept an empty list
message = state_event()
await asyncio.wait([user.send(message) for user in USERS])
@@ -108,6 +122,7 @@ async def unregister(websocket):
async def ws_handle(websocket, path):
+ print("Received command")
global current_slideshow
# register(websocket) sends user_event() to websocket
await register(websocket)
@@ -150,19 +165,22 @@ async def ws_handle(websocket, path):
current_slideshow.goto(int(data["value"]))
await notify_state()
elif data["action"] == "refresh":
+ print("Received refresh command")
+ await notify_state()
if current_slideshow:
current_slideshow.export_current_next()
current_slideshow.refresh()
- await notify_state()
else:
logging.error("unsupported event: {}", data)
finally:
await unregister(websocket)
def run_ws():
+ # https://stackoverflow.com/questions/21141217/how-to-launch-win32-applications-in-separate-threads-in-python/22619084#22619084
+ # https://www.reddit.com/r/learnpython/comments/mwt4qi/pywintypescom_error_2147417842_the_application/
pythoncom.CoInitializeEx(pythoncom.COINIT_MULTITHREADED)
asyncio.set_event_loop(asyncio.new_event_loop())
- start_server = websockets.serve(ws_handle, "0.0.0.0", 5678)
+ start_server = websockets.serve(ws_handle, "0.0.0.0", 5678, ping_interval=None)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
@@ -200,71 +218,120 @@ class Slideshow:
if self.instance.ActivePresentation is None:
raise ValueError("PPT instance has no active presentation")
self.presentation = self.instance.ActivePresentation
-
- self.export_all()
+
+ def unload(self):
+ connect_ppt()
def refresh(self):
- if self.instance is None:
- raise ValueError("PPT instance cannot be None")
+ try:
+ if self.instance is None:
+ raise ValueError("PPT instance cannot be None")
- #if self.instance.SlideShowWindows.Count == 0:
- # raise ValueError("PPT instance has no slideshow windows")
- self.view = self.instance.SlideShowWindows[0].View
+ if self.instance.SlideShowWindows.Count == 0:
+ raise ValueError("PPT instance has no slideshow windows")
+ self.view = self.instance.SlideShowWindows[0].View
- if self.instance.ActivePresentation is None:
- raise ValueError("PPT instance has no active presentation")
+ if self.instance.ActivePresentation is None:
+ raise ValueError("PPT instance has no active presentation")
+ except:
+ self.unload()
def total_slides(self):
- return len(self.presentation.Slides)
+ try:
+ self.refresh()
+ return len(self.presentation.Slides)
+ except ValueError or pywintypes.com_error:
+ self.unload()
def current_slide(self):
- return self.view.CurrentShowPosition
+ try:
+ self.refresh()
+ return self.view.CurrentShowPosition
+ except ValueError or pywintypes.com_error:
+ self.unload()
def visible(self):
- return self.view.State
+ try:
+ self.refresh()
+ return self.view.State
+ except ValueError or pywintypes.com_error:
+ self.unload()
def prev(self):
- self.refresh()
- self.view.Previous()
+ try:
+ self.refresh()
+ self.view.Previous()
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def next(self):
- self.refresh()
- self.view.Next()
- self.export_current_next()
+ try:
+ self.refresh()
+ self.view.Next()
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def first(self):
- self.refresh()
- self.view.First()
- self.export_current_next()
+ try:
+ self.refresh()
+ self.view.First()
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def last(self):
- self.refresh()
- self.view.Last()
- self.export_current_next()
+ try:
+ self.refresh()
+ self.view.Last()
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def goto(self, slide):
- self.refresh()
- if slide <= self.total_slides():
- self.view.GotoSlide(slide)
- else:
- self.last()
- self.next()
- self.export_current_next()
+ try:
+ self.refresh()
+ if slide <= self.total_slides():
+ self.view.GotoSlide(slide)
+ else:
+ self.last()
+ self.next()
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def black(self):
- self.refresh()
- self.view.State = 3
+ try:
+ self.refresh()
+ self.view.State = 3
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def white(self):
- self.refresh()
- self.view.State = 4
+ try:
+ self.refresh()
+ self.view.State = 4
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def normal(self):
- self.refresh()
- self.view.State = 1
+ try:
+ self.refresh()
+ self.view.State = 1
+ self.export_current_next()
+ except ValueError or pywintypes.com_error:
+ self.unload()
def name(self):
- return self.presentation.Name
+ try:
+ self.refresh()
+ return self.presentation.Name
+ except ValueError or pywintypes.com_error:
+ self.unload()
+
def export_current_next(self):
self.export(self.current_slide())
@@ -279,7 +346,6 @@ class Slideshow:
while attempts < 3:
try:
self.presentation.Slides(slide).Export(destination, "JPG")
- time.sleep(0.5)
break
except:
pass
@@ -302,22 +368,74 @@ def get_ppt_instance():
def get_current_slideshow():
return current_slideshow
-
-if __name__ == "__main__":
-
- start_server()
-
+def connect_ppt():
+ global STATE
+ if STATE["connected"] == 1:
+ print("Disconnected from PowerPoint instance")
+ STATE = STATE_DEFAULT
while True:
- # Check if PowerPoint is running
- instance = get_ppt_instance()
try:
+ instance = get_ppt_instance()
+ global current_slideshow
current_slideshow = Slideshow(instance)
STATE["connected"] = 1
STATE["current"] = current_slideshow.current_slide()
STATE["total"] = current_slideshow.total_slides()
print("Connected to PowerPoint instance")
+ current_slideshow.export_all()
break
except ValueError as e:
current_slideshow = None
pass
time.sleep(1)
+
+def start(_=None):
+ #root = tk.Tk()
+ #root.iconphoto(False, tk.PhotoImage(file="icons/ppt.png"))
+ #root.geometry("250x150+300+300")
+ #app = Interface(root)
+ #interface_thread = threading.Thread(target=root.mainloop())
+ #interface_thread.setDaemon(True)
+ #interface_thread.start()
+ start_server()
+ connect_ppt()
+
+
+def null_action():
+ pass
+
+class Interface(ttk.Frame):
+
+ def __init__(self, parent):
+ ttk.Frame.__init__(self, parent)
+
+ self.parent = parent
+
+ self.initUI()
+
+ def initUI(self):
+
+ self.parent.title("ppt-control")
+ self.style = ttk.Style()
+ #self.style.theme_use("default")
+
+ self.pack(fill=tk.BOTH, expand=1)
+
+ quitButton = ttk.Button(self, text="Close",
+ command=self.quit)
+ quitButton.place(x=50, y=50)
+ status_label = ttk.Label(self, text="PowerPoint status: not detected")
+ status_label.place(x=10,y=10)
+
+
+
+def show_icon():
+ menu = (pystray.MenuItem("Status", lambda: null_action(), enabled=False),
+ pystray.MenuItem("Restart", lambda: start()),
+ pystray.MenuItem("Settings", lambda: open_settings()))
+ icon = pystray.Icon("ppt-control", Image.open("icons/ppt.ico"), "ppt-control", menu)
+ icon.visible = True
+ icon.run(setup=start)
+
+if __name__ == "__main__":
+ show_icon()
diff --git a/ppt_control_obs.py b/ppt_control_obs.py
new file mode 100755
index 0000000..d9ab70d
--- /dev/null
+++ b/ppt_control_obs.py
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+
+import obspython as obs
+import asyncio
+import websockets
+import threading
+
+hotkey_id_first = None
+hotkey_id_prev = None
+hotkey_id_next = None
+hotkey_id_last = None
+hotkey_id_black = None
+hotkey_id_white = None
+
+HOTKEY_NAME_FIRST = 'powerpoint_slides.first'
+HOTKEY_NAME_PREV = 'powerpoint_slides.previous'
+HOTKEY_NAME_NEXT = 'powerpoint_slides.next'
+HOTKEY_NAME_LAST = 'powerpoint_slides.last'
+HOTKEY_NAME_BLACK = 'powerpoint_slides.black'
+HOTKEY_NAME_WHITE = 'powerpoint_slides.white'
+
+HOTKEY_DESC_FIRST = 'First PowerPoint slide'
+HOTKEY_DESC_PREV = 'Previous PowerPoint slide'
+HOTKEY_DESC_NEXT = 'Next PowerPoint slide'
+HOTKEY_DESC_LAST = 'Last PowerPoint slide'
+HOTKEY_DESC_BLACK = 'Black PowerPoint slide'
+HOTKEY_DESC_WHITE = 'White PowerPoint slide'
+
+global cmd
+cmd = ""
+
+async def communicate():
+ global cmd
+ async with websockets.connect("ws://10.0.0.93:5678", ping_interval=None) as websocket:
+ while True:
+ if cmd:
+ await websocket.send("{\"action\": \"" + cmd + "\"}")
+ cmd = ""
+ await asyncio.sleep(0.05)
+
+def run_ws():
+ asyncio.set_event_loop(asyncio.new_event_loop())
+ asyncio.get_event_loop().run_until_complete(communicate())
+
+
+
+#------------------------------------------------------------
+# global functions for script plugins
+
+def script_load(settings):
+ global hotkey_id_first
+ global hotkey_id_prev
+ global hotkey_id_next
+ global hotkey_id_last
+ global hotkey_id_black
+ global hotkey_id_white
+
+ hotkey_id_first = register_and_load_hotkey(settings, HOTKEY_NAME_FIRST, HOTKEY_DESC_FIRST, first_slide)
+ hotkey_id_prev = register_and_load_hotkey(settings, HOTKEY_NAME_PREV, HOTKEY_DESC_PREV, prev_slide)
+ hotkey_id_next = register_and_load_hotkey(settings, HOTKEY_NAME_NEXT, HOTKEY_DESC_NEXT, next_slide)
+ hotkey_id_last = register_and_load_hotkey(settings, HOTKEY_NAME_LAST, HOTKEY_DESC_LAST, last_slide)
+ hotkey_id_black = register_and_load_hotkey(settings, HOTKEY_NAME_BLACK, HOTKEY_DESC_BLACK, black)
+ hotkey_id_white = register_and_load_hotkey(settings, HOTKEY_NAME_WHITE, HOTKEY_DESC_WHITE, white)
+ ws_daemon = threading.Thread(name="ws_daemon", target=run_ws)
+ ws_daemon.setDaemon(True)
+ ws_daemon.start()
+ print("Started websocket client")
+
+def script_unload():
+ obs.obs_hotkey_unregister(first_slide)
+ obs.obs_hotkey_unregister(prev_slide)
+ obs.obs_hotkey_unregister(next_slide)
+ obs.obs_hotkey_unregister(last_slide)
+ obs.obs_hotkey_unregister(black)
+ obs.obs_hotkey_unregister(white)
+
+def script_save(settings):
+ save_hotkey(settings, HOTKEY_NAME_FIRST, hotkey_id_first)
+ save_hotkey(settings, HOTKEY_NAME_PREV, hotkey_id_prev)
+ save_hotkey(settings, HOTKEY_NAME_NEXT, hotkey_id_next)
+ save_hotkey(settings, HOTKEY_NAME_LAST, hotkey_id_last)
+ save_hotkey(settings, HOTKEY_NAME_BLACK, hotkey_id_black)
+ save_hotkey(settings, HOTKEY_NAME_WHITE, hotkey_id_white)
+
+def script_description():
+ return "ppt-control client\nHotkeys for controlling PowerPoint slides using websockets"
+
+def script_defaults(settings):
+ obs.obs_data_set_default_int(settings, 'port', 5678)
+
+def script_properties():
+ props = obs.obs_properties_create()
+
+ obs.obs_properties_add_int(props, "port", "Websocket port: ", 0, 9999, 1)
+ return props
+
+def script_update(settings):
+ global port
+ port = obs.obs_data_get_int(settings, "port")
+
+def register_and_load_hotkey(settings, name, description, callback):
+ hotkey_id = obs.obs_hotkey_register_frontend(name, description, callback)
+ hotkey_save_array = obs.obs_data_get_array(settings, name)
+ obs.obs_hotkey_load(hotkey_id, hotkey_save_array)
+ obs.obs_data_array_release(hotkey_save_array)
+
+ return hotkey_id
+
+def save_hotkey(settings, name, hotkey_id):
+ hotkey_save_array = obs.obs_hotkey_save(hotkey_id)
+ obs.obs_data_set_array(settings, name, hotkey_save_array)
+ obs.obs_data_array_release(hotkey_save_array)
+
+#-------------------------------------
+
+def first_slide(pressed):
+ if pressed:
+ global cmd
+ cmd = "first"
+
+def prev_slide(pressed):
+ if pressed:
+ global cmd
+ cmd = "prev"
+
+def next_slide(pressed):
+ if pressed:
+ global cmd
+ cmd = "next"
+
+def last_slide(pressed):
+ if pressed:
+ global cmd
+ cmd = "last"
+
+def black(pressed):
+ if pressed:
+ global cmd
+ cmd = "black"
+
+def white(pressed):
+ if pressed:
+ global cmd
+ cmd = "white"
diff --git a/settings.js b/settings.js
index eb94f8e..901af0b 100644
--- a/settings.js
+++ b/settings.js
@@ -25,16 +25,17 @@ function getCookie(cname) {
}
function saveSettings() {
+ console.log("Saving settings")
settingsString = JSON.stringify({showcurrent: show_current.checked, shownext: show_next.checked, enable_shortcuts: shortcuts.checked});
setCookie(COOKIENAME, settingsString, COOKIEEXP);
}
function initSettings() {
if (getCookie(COOKIENAME) == 0) {
- if (window.obssstudio) {
- shortcuts.checked = False;
- show_current.checked = False;
- }
+ if (window.obssstudio) {
+ shortcuts.checked = False;
+ show_current.checked = False;
+ }
saveSettings()
} else {
cookie = JSON.parse(getCookie(COOKIENAME));