# -*- 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