def playsound(filename, volume, speed): obs.script_log(obs.LOG_DEBUG, "Trying to play " + filename + " to source " + sourcename) scenesource = obs.obs_frontend_get_current_scene() scene = obs.obs_scene_from_source(scenesource) #obs.script_log(obs.LOG_DEBUG,"Scene "+str(scene)) sceneitem = obs.obs_scene_find_source(scene, sourcename) #obs.script_log(obs.LOG_DEBUG,"Scene item "+str(sceneitem)) source = obs.obs_sceneitem_get_source(sceneitem) obs.obs_source_set_volume(source, volume) set_source_speed(source, speed) obs.obs_sceneitem_set_visible(sceneitem, False) settings = obs.obs_source_get_settings(source) #obs.script_log(obs.LOG_DEBUG,str(obs.obs_data_get_json(settings))) obs.obs_data_set_string(settings, "local_file", audiofolder + filename) #obs.script_log(obs.LOG_DEBUG,str(obs.obs_data_get_json(settings))) obs.obs_source_update(source, settings) obs.obs_sceneitem_set_visible(sceneitem, True) obs.obs_data_release(settings) obs.obs_source_release(scenesource)
def load_url(url): try: urllib.request.urlopen(url) except urllib.error.URLError as err: obs.script_log(obs.LOG_WARNING, "Error opening URL '" + url + "': " + err.reason)
def script_load(settings): obs.script_log(obs.LOG_DEBUG, "Loading script") hidesource() unsetfilename() #obs.timer_add(server_handle,100) start_server() obs.timer_add(play_task, 100)
def load_start_url(): global starturl obs.script_log(obs.LOG_DEBUG, "Trying to start...") if starturl != "": obs.script_log(obs.LOG_DEBUG, "Accessing Start URL") load_url(starturl)
def load_stop_url(): global stopurl obs.script_log(obs.LOG_DEBUG, "Trying to stop...") if stopurl != "": obs.script_log(obs.LOG_DEBUG, "Accessing Stop URL") load_url(stopurl)
def script_load(settings): global new_state if DEBUG: obs.script_log( obs.LOG_WARNING, "I'm joined to the party") new_state["api_endpoint"] = obs.obs_data_get_string( settings, "api_endpoint") new_state["jsonpath"] = obs.obs_data_get_string(settings, "jsonpath").replace(" ", "").strip() if "," in new_state["jsonpath"]: new_state["jsonpath"] = new_state["jsonpath"].split(",") new_state["text_source"] = obs.obs_data_get_string(settings, "text_source") new_state["format_rule"] = obs.obs_data_get_string(settings, "format_rule") if type(new_state["jsonpath"]) == str: new_state["format_args"] = [""] elif type(new_state["jsonpath"]) in [list, tuple]: new_state["format_args"] = [] for _ in new_state["jsonpath"]: new_state["format_args"].append("") if DEBUG: obs.script_log( obs.LOG_WARNING, f"{new_state}") save_pressed(None, None)
def script_properties(): props = obs.obs_properties_create() obs.obs_properties_add_color(props, "tally^IdleColor", "Idle Color") obs.obs_properties_add_int_slider(props, "tally^IdleBrightness", "Idle Brightness", 0, 10, 1) obs.obs_properties_add_color(props, "tally^PreviewColor", "Queued Color") obs.obs_properties_add_int_slider(props, "tally^PreviewBrightness", "Queued Brightness", 0, 10, 1) obs.obs_properties_add_color(props, "tally^ProgramColor", "Live Color") obs.obs_properties_add_int_slider(props, "tally^ProgramBrightness", "Live Brightness", 0, 10, 1) sources = obs.obs_enum_sources() if sources is not None: for source in sources: source_id = obs.obs_source_get_id(source) if source_id == 'av_capture_input': source_name = obs.obs_source_get_name(source) obs.script_log(obs.LOG_INFO, "Found source: " + source_name) obs.obs_properties_add_text(props, source_name, source_name + " light addr:", obs.OBS_TEXT_DEFAULT) obs.source_list_release(sources) return props
def run_import(props, prop): global template_scene_name global video_directory template_source = obs.obs_get_source_by_name(template_scene_name) template_scene = obs.obs_scene_from_source(template_source) files = glob.glob(video_directory + "/*") files.sort() transition_number = 0 for filename in files: transition_number += 1 bare_name = "Transition " + str(transition_number) new_scene = obs.obs_scene_duplicate(template_scene, bare_name, obs.OBS_SCENE_DUP_REFS) source_data = obs.obs_data_create() obs.obs_data_set_string(source_data, 'local_file', filename) source = obs.obs_source_create('ffmpeg_source', 'Video - ' + bare_name, source_data, None) scene_item = obs.obs_scene_add(new_scene, source) obs.obs_sceneitem_set_order(scene_item, obs.OBS_ORDER_MOVE_BOTTOM) import_utils.fit_to_screen(scene_item) obs.obs_source_release(source) obs.obs_scene_release(new_scene) obs.script_log(obs.LOG_INFO, "created scene '" + bare_name + "' from " + filename) obs.obs_source_release(template_source)
def update_text(): """Updates text sources for the scoreboard""" global scoreboard_source_names, rate_vs, rate_nc, rate_tr scoreboard_source_names['RATE_VS'] = rate_vs scoreboard_source_names['RATE_NC'] = rate_nc scoreboard_source_names['RATE_TR'] = rate_tr for name in scoreboard_source_names: # Iterate through list and update sources in OBS source = obs.obs_get_source_by_name(name) if source is not None: try: settings = obs.obs_data_create() obs.obs_data_set_string(settings, "text", scoreboard_source_names[name]) obs.obs_source_update(source, settings) obs.obs_data_release(settings) except: obs.script_log( obs.LOG_WARNING, f'[{datetime.datetime.now()}][TRACKER] Encountered error updating ' f'scoreboard source') obs.remove_current_callback() obs.obs_source_release( source) # Releases source and prevents memory leak
def run_import(props, prop): global template_scene_name global image_directory template_source = obs.obs_get_source_by_name(template_scene_name) template_scene = obs.obs_scene_from_source(template_source) # expecting filenames like '01 - test.jpg' files = glob.glob(image_directory + "/*") files.sort() for filename in files: # try to remove the initial ordinal, but don't error if it isn't present. # '01 - test.jpg' -> 'test' # 'test.jpg' -> 'test' parts = Path(filename).stem.split('-') bare_name = parts[len(parts) - 1].strip() new_scene = obs.obs_scene_duplicate(template_scene, bare_name, obs.OBS_SCENE_DUP_REFS) source_data = obs.obs_data_create() obs.obs_data_set_string(source_data, 'file', filename) source = obs.obs_source_create('image_source', 'Image - ' + bare_name, source_data, None) scene_item = obs.obs_scene_add(new_scene, source) obs.obs_sceneitem_set_order(scene_item, obs.OBS_ORDER_MOVE_BOTTOM) import_utils.fit_to_screen(scene_item) obs.obs_source_release(source) obs.obs_scene_release(new_scene) obs.script_log(obs.LOG_INFO, "created scene '" + bare_name + "' from " + filename) obs.obs_source_release(template_source)
def script_load(settings): global curRec global curStream obs.script_log(obs.LOG_DEBUG, "Loading script") curStream = obs.obs_frontend_streaming_active() curRec = obs.obs_frontend_recording_active() obs.timer_add(check_stream_state, 1000)
def run_ws(): global api_endpoint if DEBUG: obs.script_log( obs.LOG_WARNING, f"This is endpoint: {api_endpoint}") websocket = websockets.WebSocketApp(api_endpoint, on_message=on_message, on_error=on_any_trouble, on_close=on_any_trouble) websocket.run_forever()
def wikimedia_query(url): try: with urllib.request.urlopen(url) as response: data = response.read() decoded_data = data.decode('utf-8') return WikiMediaQuery(json.loads(decoded_data)) except Exception as err: obs.script_log(obs.LOG_WARNING, "Error opening URL '" + url + "': " + repr(err)) obs.remove_current_callback()
def script_load(settings): global status_file global idle_scene global playing_scene status_file = obs.obs_data_get_string(settings, 'status_file') idle_scene = obs.obs_data_get_string(settings, 'idle_scene') playing_scene = obs.obs_data_get_string(settings, 'playing_scene') # Delay check valid source until OBS is fully loaded obs.script_log(obs.LOG_INFO, 'Starting in 10 seconds...') obs.timer_add(validate_and_start, 10000)
def start_server(): global httpd global serverthread obs.script_log(obs.LOG_DEBUG, "Server started") server_address = ("", PORT) httpd = ThreadingHTTPServer(server_address, Handler) if serverthread == None: serverthread = Thread(target=server_task) serverthread.start()
def server_task(): global httpd global stopserver obs.script_log(obs.LOG_DEBUG, "Server task started") while not stopserver: httpd.timeout = 0.001 httpd.handle_request() sleep(0.1) obs.script_log(obs.LOG_DEBUG, "Server task stopped") stopserver = False
def start_tracker(props, prop): """Starts necessary threads for tracking matches.""" global start_pressed, current_match, target_zone if not start_pressed: start_pressed = True obs.script_log( obs.LOG_INFO, f'[{datetime.datetime.now()}][TRACKER] \'Start Tracker\' button pressed, ' f'initializing websocket and tracker.') current_match = OWMatch(int(target_zone)) obs.script_log( obs.LOG_INFO, f'[{datetime.datetime.now()}][TRACKER] Starting rate data update thread.' ) start_rate_update(current_match) obs.script_log( obs.LOG_INFO, f'[{datetime.datetime.now()}][TRACKER] Starting API data update thread.' ) start_api_update(current_match) else: obs.script_log( obs.LOG_WARNING, f'[{datetime.datetime.now()}][TRACKER] \'Start Tracker\' button was pressed ' f'after tracker already started. No action was performed.')
def stop_server(): global httpd global serverthread global stopserver obs.script_log(obs.LOG_DEBUG, "Server stopped") if serverthread != None: stopserver = True serverthread = None if httpd: httpd.server_close() httpd = None
def ui_logic(articles_queue: queue.Queue): global obs_manager global current_state global queued_path while current_state == 'reading': obs.script_log(obs.LOG_DEBUG, repr(current_state)) wiki_super_container: WikiSuperContainer = articles_queue.get() wiki_article = wiki_super_container.wiki_article obs.script_log(obs.LOG_DEBUG, wiki_article.get_title()) obs.script_log(obs.LOG_DEBUG, repr(articles_queue.qsize())) obs.script_log(obs.LOG_DEBUG, repr(wiki_super_container.audio.file)) obs_manager.update_title(wiki_article.get_title()) with open(wiki_super_container.audio.file) as f: m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) sound_length_seconds = pygame.mixer.Sound( wiki_super_container.audio.file).get_length() pygame.mixer.music.load(m) pygame.mixer.music.play() article_images = wiki_super_container.downloaded_images for article_image in article_images: if not pygame.mixer.music.get_busy(): break obs_manager.update_image(article_image) time.sleep(sound_length_seconds / len(article_images)) while pygame.mixer.music.get_busy(): time.sleep(0.5) m.close() final_folder = os.path.join(queued_path, str(wiki_article.get_page_id())) shutil.rmtree(final_folder) obs_manager.clear_image()
def validate_and_start(): global initial_load global idle_scene global playing_scene initial_load = True obs.timer_remove(validate_and_start) obs.timer_remove(check_status_and_toggle) # check if file exists if not os.path.isfile(status_file): raise FileNotFoundError(f"Could not find file '{status_file}'") obs.script_log(obs.LOG_INFO, f'{status_file} found!') # check if gameplay enter scene exists src = obs.obs_get_source_by_name(playing_scene) if src is None or obs.obs_source_get_type( src) != obs.OBS_SOURCE_TYPE_SCENE: obs.obs_source_release(src) raise FileNotFoundError(f" Could not find scene '{playing_scene}'") obs.obs_source_release(src) obs.script_log(obs.LOG_INFO, f"Scene '{playing_scene}' found!") # check if gameplay exit scene exists src = obs.obs_get_source_by_name(idle_scene) if src is None or obs.obs_source_get_type( src) != obs.OBS_SOURCE_TYPE_SCENE: obs.obs_source_release(src) raise FileNotFoundError(f" Could not find scene '{idle_scene}'") obs.obs_source_release(src) obs.script_log(obs.LOG_INFO, f"Scene '{idle_scene}' found!") obs.script_log(obs.LOG_INFO, 'Script is now active.') obs.timer_add(check_status_and_toggle, 500)
def start_pressed(props, prop): global current_state refresh_manager() obs.script_log(obs.LOG_DEBUG, repr(current_state)) if current_state != 'reading': current_state = 'reading' clean_files() if not pygame.get_init(): pygame.init() if not pygame.mixer.get_init(): pygame.mixer.init() articles_queue = queue.Queue() run_thread_downloader(articles_queue) run_thread_ui(articles_queue)
def update_gst_source(self,source_name, pipeline): source = obs.obs_get_source_by_name(source_name) settings = obs.obs_data_create() obs.obs_data_set_string(settings, "pipeline", pipeline) if source is None: obs.script_log(obs.LOG_INFO,"Creating non-existant GStreamer source: {source_name}".format(source_name=source_name)) source = obs.obs_source_create("gstreamer-source",source_name,None,None) # TODO - this doesn't seem to create sources else: obs.script_log(obs.LOG_INFO,"Updating {source_name} pipeline to: {pipeline}".format(source_name=source_name,pipeline=pipeline)) obs.obs_source_update(source, settings) obs.obs_data_release(settings) obs.obs_source_release(source)
def find_obs_device_pipeline(self): gst_raw_list = obs.obs_data_get_array(self.plugin_settings, "list") num_gst_raw = obs.obs_data_array_count(gst_raw_list) self.devices = {} for i in range(num_gst_raw): # Convert C array to Python list gst_raw_object = obs.obs_data_array_item(gst_raw_list, i) device_id,pipeline = obs.obs_data_get_string(gst_raw_object, "value").split("~") self.devices[device_id]=pipeline for device_id,pipeline in self.devices.items(): print("{device_id}: {pipeline}".format(device_id=device_id,pipeline=pipeline)) if self.device_supplied_id in self.devices: obs.script_log(obs.LOG_INFO,"Device entry found for {device_id}".format(device_id=self.device_supplied_id)) self.pipeline = self.devices[self.device_supplied_id] +" matroskamux name=mux ! queue ! tcpclientsink host={obs_ip_address} port={port}".format(port=self.video_port,obs_ip_address=self.obs_ip_address) else: obs.script_log(obs.LOG_INFO,"No device entry for {device_id}".format(device_id=self.device_supplied_id)) return
def update(): global url try: with urllib.request.urlopen(url) as response: data = response.read() response = json.loads(data) _scenes = zip(obs.obs_frontend_get_scene_names(), obs.obs_frontend_get_scenes()) scenes = {} for scene in _scenes: scenes[scene[0]] = scene[1] if scenes.get(response['camera']) is not None: print("Switching to scene: " + response['camera']) obs.obs_frontend_set_current_scene(scenes[response['camera']]) except urllib.error.URLError as err: obs.script_log(obs.LOG_WARNING, "Error opening URL '" + url + "': " + err.reason) obs.remove_current_callback()
def update_text(text): global text_source global old_text if old_text == text: return source = obs.obs_get_source_by_name(text_source) if source is not None: settings = obs.obs_data_create() obs.obs_data_set_string(settings, "text", text) obs.obs_source_update(source, settings) obs.obs_data_release(settings) obs.obs_source_release(source) old_text = text else: if DEBUG: obs.script_log( obs.LOG_WARNING, f"Source is empty: {source}/{text_source}")
def update_text(): global username global format global interval global source_name global str_format source = obs.obs_get_source_by_name(source_name) if source is not None and obs.obs_source_active(source): try: opener = urllib.request.build_opener() opener.addheaders = [('User-Agent', 'ShowdownELOOBS/1.0')] r = opener.open( "http://play.pokemonshowdown.com/%7e%7eshowdown/action.php?act=ladderget&user="******"?" if len(obj) == 0 else str(obj[0]['gxe']) + '%' wins = 0 if len(obj) == 0 else int(obj[0]['w']) losses = 0 if len(obj) == 0 else int(obj[0]['l']) ties = 0 if len(obj) == 0 else int(obj[0]['t']) games = wins + losses + ties user = username if len(obj) == 0 else obj[0]['username'] text = str_format.format( user=user, elo=f'{float(elo):.2f}', gxe=gxe, w=wins, l=losses, t=ties, g=games, elo_int=int(float(elo))) settings = obs.obs_data_create() obs.obs_data_set_string( settings, "text", text.replace('\\n', '\n')) obs.obs_source_update(source, settings) obs.obs_data_release(settings) except urllib.error.URLError as err: obs.script_log(obs.LOG_WARNING, "Error opening URL: " + err.reason) obs.remove_current_callback() obs.obs_source_release(source)
def call_tally_light(source, color, brightness): addr = light_mapping[source] if not addr: obs.script_log(obs.LOG_INFO, 'No tally light set for: %s' % (source)) return hexColor = hex(color) hexBlue = hexColor[2:4] hexGreen = hexColor[4:6] hexRed = hexColor[6:8] pctBright = brightness / 10 url = 'http://%s:7413/set?color=%s%s%s&brightness=%f' % ( addr, hexRed, hexGreen, hexBlue, pctBright) try: with urllib.request.urlopen(url, None, http_timeout_seconds) as response: data = response.read() text = data.decode('utf-8') obs.script_log(obs.LOG_INFO, 'Set %s tally light: %s' % (source, text)) except urllib.error.URLError as err: obs.script_log( obs.LOG_WARNING, 'Error connecting to tally light URL %s: %s' % (url, err.reason)) obs.remove_current_callback()
def load_stop_url_cb(): global curRec global curStream global enable_rec global enable_stream is_streaming = curStream is_recording = curRec obs.script_log(obs.LOG_DEBUG, "Got 'Stop' Signal") obs.script_log( obs.LOG_DEBUG, "Streaming? " + str(is_streaming) + " Recording? " + str(is_recording)) obs.script_log( obs.LOG_DEBUG, "Streaming enabled? " + str(enable_stream) + " Recording Enabled? " + str(enable_rec)) disable = True if (is_streaming and enable_stream): disable = False if (is_recording and enable_rec): disable = False if disable: load_stop_url()
def do_GET(self): global playlist obs.script_log(obs.LOG_DEBUG, "Got GET!") opts = dict() command = self.path[1:] if "?" in command: split = command.split("?") filename = split[0] options = split[1].split("&") for option in options: splitopt = option.split("=") opts[splitopt[0]] = splitopt[1] obs.script_log(obs.LOG_DEBUG, str(opts)) else: filename = command #obs.script_log(obs.LOG_DEBUG,str(self.path)) if check_for_file(filename): #playsound(filename) playlist.append((filename, opts)) resp = "Played " + filename else: obs.script_log(obs.LOG_DEBUG, filename + " is not present") resp = "Could not find " + filename self.send_response_only(200) self.send_header("Content-type", "text/plain") self.end_headers() resp = resp.encode() self.wfile.write(resp)
def update_text(): global url global interval global source_name source = obs.obs_get_source_by_name(source_name) if source is not None: try: with urllib.request.urlopen(url) as response: data = response.read() text = data.decode('utf-8') settings = obs.obs_data_create() obs.obs_data_set_string(settings, "text", text) obs.obs_source_update(source, settings) obs.obs_data_release(settings) except urllib.error.URLError as err: obs.script_log(obs.LOG_WARNING, "Error opening URL '" + url + "': " + err.reason) obs.remove_current_callback() obs.obs_source_release(source)