def set_logo(blue_config, orange_config): #reused for logo later default_logo = os.path.join(files_path, 'logo.png') blue_config_bun = get_bot_config_bundle(blue_config) orange_config_bun = get_bot_config_bundle(orange_config) blue_logo = blue_config_bun.get_logo_file() if blue_logo is None: blue_logo = default_logo orange_logo = orange_config_bun.get_logo_file() if orange_logo is None: orange_logo = default_logo default_logo_scale = 0.25 default_logo_size = [400*default_logo_scale, 300*default_logo_scale] blue_logo_size = list(Image.open(blue_logo).size) blue_scale = default_logo_size[0]/blue_logo_size[0] orange_logo_size = list(Image.open(orange_logo).size) orange_scale = default_logo_size[0]/orange_logo_size[0] scenes = obs.obs_frontend_get_scenes() if scenes is not None: for scene in scenes: if obs.obs_source_get_name(scene) == 'RLBot - AutoLeague': scene = obs.obs_scene_from_source(scene) items = obs.obs_scene_enum_items(scene) for item in items: if item is not None: source_t = obs.obs_sceneitem_get_source(item) if obs.obs_source_get_name(source_t) == "Logo-0": source = source_t settings = obs.obs_data_create() obs.obs_data_set_string(settings, "file", blue_logo) obs.obs_source_update(source, settings) obs.obs_data_release(settings) vec = obs.vec2() obs.vec2_set(vec, blue_scale, blue_scale) obs.obs_sceneitem_set_scale(item, vec) if obs.obs_source_get_name(source_t) == "Logo-1": source = source_t settings = obs.obs_data_create() obs.obs_data_set_string(settings, "file", orange_logo) obs.obs_source_update(source, settings) obs.obs_data_release(settings) vec = obs.vec2() obs.vec2_set(vec, orange_scale, orange_scale) obs.obs_sceneitem_set_scale(item, vec) obs.source_list_release(scenes) obs.sceneitem_list_release(items)
def boost_bar(boost): boost_bar_pos = [446, 90] boost_bar_size = [210, 20] perc_bar = boost[0] sceneItem = get_scene_item('Blue-Boost-0') scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, perc_bar[0], 1) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec) pos_vec = obs.vec2() obs.vec2_set(pos_vec, boost_bar_pos[0] + boost_bar_size[0] * (1-perc_bar[0]), boost_bar_pos[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec) # obs.obs_sceneitem_release(sceneItem) sceneItem = get_scene_item('Orange-Boost-0') scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, perc_bar[1], 1) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec) pos_vec = obs.vec2() obs.vec2_set(pos_vec, 1920 - boost_bar_size[0] - boost_bar_pos[0], boost_bar_pos[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec)
def set_text_pos(): pos = [119, 14] hardcoded_width = 386 scale = [1.5, 1.5] sceneItem = get_scene_item('Blue-Name') pos_vec = obs.vec2() obs.vec2_set(pos_vec, pos[0], pos[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec) obs.obs_sceneitem_get_scale(sceneItem, pos_vec) scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, scale[0], scale[1]) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec) # obs.obs_sceneitem_release(sceneItem) sceneItem = get_scene_item('Orange-Name') pos_vec = obs.vec2() obs.vec2_set(pos_vec, 1920 - pos[0] - hardcoded_width * scale[0], pos[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec) scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, scale[0], scale[1]) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec)
def auto_setup(props, prop): # Todo: add BO3 and BO5 global game_item global social_item global overlay_item global bar_0_item global blue_cheer_item global orange_cheer_item global bar_1_item global blue_name_item global orange_name_item global blue_dev_name_item global orange_dev_name_item global blue_boost_item global orange_boost_item global boost_0_item global boost_1_item global goal_item global game_source global social_source global overlay_source global bar_0_source global blue_cheer_source global orange_cheer_source global bar_1_source global blue_name_source global orange_name_source global blue_boost_source global orange_boost_source global boost_0_source global boost_1_source global goal_source if not check_for_scene('RLBot - AutoLeague'): main_scene = obs.obs_scene_create('RLBot - AutoLeague') # Game Capture temp_settings = get_settings('Game Capture') game_source = obs.obs_source_create('game_capture', 'Game', temp_settings, None) game_item = obs.obs_scene_add(main_scene, game_source) obs.obs_data_release(temp_settings) obs.obs_source_release(game_source) # obs.obs_sceneitem_release(game_item) # Social temp_settings = get_settings('Social') temp_path = os.path.join(files_path, 'social.png') obs.obs_data_set_string(temp_settings, 'file', temp_path) social_source = obs.obs_source_create('image_source', 'Social', temp_settings, None) social_item = obs.obs_scene_add(main_scene, social_source) obs.obs_data_release(temp_settings) obs.obs_source_release(social_source) # obs.obs_sceneitem_release(social_item) # RLBot Overlay temp_settings = get_settings('RLBot Overlay') temp_path = os.path.join(files_path, 'overlay.png') obs.obs_data_set_string(temp_settings, 'file', temp_path) overlay_source = obs.obs_source_create('image_source', 'Overlay', temp_settings, None) overlay_item = obs.obs_scene_add(main_scene, overlay_source) obs.obs_data_release(temp_settings) obs.obs_source_release(overlay_source) # obs.obs_sceneitem_release(overlay_item) # Blue-Name temp_settings = get_settings('Blue Team Name') blue_name_source = obs.obs_source_create('text_gdiplus', 'Blue-Name', temp_settings, None) blue_name_item = obs.obs_scene_add(main_scene, blue_name_source) obs.obs_data_release(temp_settings) obs.obs_source_release(blue_name_source) # obs.obs_sceneitem_release(blue_name_item) # Orange-Name temp_settings = get_settings('Orange Team Name') orange_name_source = obs.obs_source_create('text_gdiplus', 'Orange-Name', temp_settings, None) orange_name_item = obs.obs_scene_add(main_scene, orange_name_source) obs.obs_data_release(temp_settings) obs.obs_source_release(orange_name_source) # obs.obs_sceneitem_release(orange_name_item) # Blue-Dev-Name temp_settings = get_settings('Blue Dev Name') blue_dev_name_source = obs.obs_source_create('text_gdiplus', 'Blue-Dev-Name', temp_settings, None) blue_dev_name_item = obs.obs_scene_add(main_scene, blue_dev_name_source) obs.obs_data_release(temp_settings) obs.obs_source_release(blue_dev_name_source) # obs.obs_sceneitem_release(blue_name_item) # Orange-Dev-Name temp_settings = get_settings('Orange Dev Name') orange_dev_name_source = obs.obs_source_create('text_gdiplus', 'Orange-Dev-Name', temp_settings, None) orange_dev_name_item = obs.obs_scene_add(main_scene, orange_dev_name_source) obs.obs_data_release(temp_settings) obs.obs_source_release(orange_dev_name_source) # obs.obs_sceneitem_release(orange_name_item) logo_pos = [300, 10] logo_scale = 0.25 # Logo-0 temp_settings = get_settings('Logo') temp_path = os.path.join(files_path, 'logo.png') obs.obs_data_set_string(temp_settings, 'file', temp_path) logo_0_source = obs.obs_source_create('image_source', 'Logo-0', temp_settings, None) logo_0_item = obs.obs_scene_add(main_scene, logo_0_source) obs.obs_data_release(temp_settings) obs.obs_source_release(logo_0_source) vec = obs.vec2() obs.vec2_set(vec, logo_pos[0], logo_pos[1]) obs.obs_sceneitem_set_pos(logo_0_item, vec) obs.vec2_set(vec, logo_scale, logo_scale) obs.obs_sceneitem_set_scale(logo_0_item, vec) # obs.obs_sceneitem_release(social_item) # Logo-1 temp_settings = get_settings('Logo') temp_path = os.path.join(files_path, 'logo.png') obs.obs_data_set_string(temp_settings, 'file', temp_path) logo_0_source = obs.obs_source_create('image_source', 'Logo-1', temp_settings, None) logo_0_item = obs.obs_scene_add(main_scene, logo_0_source) obs.obs_data_release(temp_settings) obs.obs_source_release(logo_0_source) vec = obs.vec2() obs.vec2_set(vec, 1920-100-logo_pos[0], logo_pos[1]) obs.obs_sceneitem_set_pos(logo_0_item, vec) obs.vec2_set(vec, logo_scale, logo_scale) obs.obs_sceneitem_set_scale(logo_0_item, vec) # obs.obs_sceneitem_release(social_item) # Goal temp_settings = get_settings('Goal') temp_path = os.path.join(files_path, 'goal.mov') obs.obs_data_set_string(temp_settings, 'local_file', temp_path) goal_source = obs.obs_source_create('ffmpeg_source', 'Goal', temp_settings, None) goal_item = obs.obs_scene_add(main_scene, goal_source) obs.obs_data_release(temp_settings) obs.obs_source_release(goal_source) # obs.obs_sceneitem_release(goal_item) obs.obs_scene_release(main_scene) set_text_pos() do_reset_bar() else: print('Scene already exists, please delete or rename RLBot scene before continuing')
def set_text_pos(): pos = [290+100, 14] hardcoded_width = 250 hardcoded_height = 26 scale = [1.5, 1.5] #math should make it mirrored but doesnt, gotta add a bit more so looks mirrored bit_to_right = 5 sceneItem = get_scene_item('Blue-Name') pos_vec = obs.vec2() obs.vec2_set(pos_vec, pos[0], pos[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec) obs.obs_sceneitem_get_scale(sceneItem, pos_vec) scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, scale[0], scale[1]) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec) # obs.obs_sceneitem_release(sceneItem) sceneItem = get_scene_item('Orange-Name') pos_vec = obs.vec2() obs.vec2_set(pos_vec, 1920-pos[0]-hardcoded_width*scale[0] + bit_to_right, pos[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec) scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, scale[0], scale[1]) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec) # obs.obs_sceneitem_release(sceneItem) sceneItem = get_scene_item('Blue-Dev-Name') pos_vec = obs.vec2() obs.vec2_set(pos_vec, pos[0], pos[1]+hardcoded_height*scale[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec) obs.obs_sceneitem_get_scale(sceneItem, pos_vec) scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, scale[0], scale[1]) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec) # obs.obs_sceneitem_release(sceneItem) sceneItem = get_scene_item('Orange-Dev-Name') pos_vec = obs.vec2() obs.vec2_set(pos_vec, 1920-pos[0]-hardcoded_width*scale[0] + bit_to_right, pos[1]+hardcoded_height*scale[1]) obs.obs_sceneitem_set_pos(sceneItem, pos_vec) scale2_vec = obs.vec2() obs.vec2_set(scale2_vec, scale[0], scale[1]) obs.obs_sceneitem_set_scale(sceneItem, scale2_vec)
def script_tick(seconds): # OBS script interface. global discord_source source_name = obs.obs_data_get_string(settings, 'discord_source') if source_name != obs.obs_source_get_name(discord_source): obs.obs_source_release( discord_source) # Doesn’t error even if discord_source == None. discord_source = obs.obs_get_source_by_name(source_name) if not client: return # NOTE: These are 0 when the source isn’t visible at all in the current scene. Not that it matters, but I was just weirded out by it until I got it. source_width = obs.obs_source_get_width(discord_source) source_height = obs.obs_source_get_height(discord_source) margin_top = MARGIN_TOP if not obs.obs_data_get_bool(settings, 'full_screen'): margin_top = margin_top + TITLE_BAR # Get Discord call layout distribution and caller size. people = [x for x in client.video] # Mutability and shiz. nonvideo = obs.obs_data_get_bool(settings, 'show_nonvideo_participants') if nonvideo: people += client.audio count = len(people) if count == 1 and (not client.audio or not client.video and nonvideo): count = 2 # Discord adds a call to action that occupies the same space as a second caller. rows = None cols = None width = 0 height = None offsetx = 0 offsety = 0 offset_last = None if source_width and source_height: totalw = source_width - MARGIN_SIDES * 2 totalh = source_height - margin_top - MARGIN_BTM if totalw > 0 and totalh > 0: wide = None # Discord packs the callers in as many columns as possible, unless their videos appear bigger with fewer columns. for c in reversed(range(1, count + 1)): r = math.ceil(count / c) w = (totalw - CALLER_SPACING * (c - 1)) / c h = (totalh - CALLER_SPACING * (r - 1)) / r wi = w / h > CALLER_ASPECT if wi: w = h * CALLER_ASPECT if w > width: rows = r cols = c width = w height = h wide = wi if rows: # If the window is wider or taller than the callers fit in, Discord will center them as a whole. inner_width = (width * cols + CALLER_SPACING * (cols - 1)) if wide: # Wider than needed, therefore center horizontally. offsetx = (totalw - inner_width) / 2 else: # Taller than needed, therefore center vertically. height = width / CALLER_ASPECT # We compared using widths only before, so height needs to be adjusted. offsety = (totalh - (height * rows + CALLER_SPACING * (rows - 1))) / 2 # If last row contains fewer callers than columns, Discord will center it. offset_last = count % cols if offset_last > 0: offset_last = (inner_width - (width * offset_last + CALLER_SPACING * (offset_last - 1))) / 2 # Apply necessary changes to relevant scene items. scene_sources = obs.obs_frontend_get_scenes() for scene_src in scene_sources: scene = obs.obs_scene_from_source(scene_src) # Shouldn’t be released. items = obs.obs_scene_enum_items(scene) i = 0 next_vis = None for item in reversed(items): _next_vis = None if obs.obs_sceneitem_get_source( item) == discord_source: # Shouldn’t be released. uid = int( obs.obs_data_get_string(settings, f'participant{i}') or -1) visible = True try: index = people.index(uid) except (IndexError, ValueError): visible = False i += 1 obs.obs_sceneitem_set_visible(item, visible) if visible and rows: crop = obs.obs_sceneitem_crop() obs.obs_sceneitem_get_crop(item, crop) scale = obs.vec2() obs.obs_sceneitem_get_scale(item, scale) bounds = obs.vec2() obs.obs_sceneitem_get_bounds(item, bounds) # If item was set to not use a bounding box policy, calculate it from its other transform properties. if obs.obs_sceneitem_get_bounds_type( item) == obs.OBS_BOUNDS_NONE: obs.vec2_set( bounds, scale.x * (source_width - crop.right - crop.left), scale.y * (source_height - crop.bottom - crop.top)) obs.obs_sceneitem_set_bounds(item, bounds) obs.obs_sceneitem_set_bounds_type( item, obs.OBS_BOUNDS_SCALE_OUTER) obs.obs_sceneitem_set_bounds_alignment( item, 0 ) # obs.OBS_ALIGN_CENTER doesn’t seem to be implemented. # Get top left corner of this caller. r = math.ceil((index + 1) / cols) c = index % cols + 1 x = MARGIN_SIDES + offsetx + (width + CALLER_SPACING) * (c - 1) if r == rows: x = x + offset_last y = margin_top + offsety + (height + CALLER_SPACING) * (r - 1) # Make sure the crop doesn’t overflow the item bounds. aspect = bounds.x / bounds.y clipx = 0 clipy = 0 if aspect > CALLER_ASPECT: clipy = (height - width / aspect) / 2 else: clipx = (width - height * aspect) / 2 crop.left = math.ceil(x + CALLER_BORDER + clipx) crop.top = math.ceil(y + CALLER_BORDER + clipy) crop.right = source_width - int(x + width - CALLER_BORDER - clipx) crop.bottom = source_height - int(y + height - CALLER_BORDER - clipy) obs.obs_sceneitem_set_crop(item, crop) sx = abs(scale.x) if uid == int( obs.obs_data_get_string(settings, 'myself') or -1) and uid in client.video: sx = -sx sy = scale.y obs.vec2_set(scale, sx, sy) obs.obs_sceneitem_set_scale(item, scale) if not nonvideo and obs.obs_data_get_bool( settings, 'item_right_below'): _next_vis = uid in client.audio elif next_vis is not None: obs.obs_sceneitem_set_visible(item, next_vis) next_vis = _next_vis obs.sceneitem_list_release(items) obs.source_list_release(scene_sources)
def process_items(): global setting_offsetX global setting_offsetY global setting_offsetXMod global setting_offsetYMod global cached_items global dimensions if (cached_items == None): return for key, objects in cached_items.items(): item = objects["item"] source = objects["source"] modifiers = objects["modifiers"] myWin = objects["win32gui"] #sourceData = source.get_properties() #print("My id: %s" % sourceData.id) try: rect = win.GetWindowRect(myWin) x = rect[0] + setting_offsetX y = rect[1] + setting_offsetY w = rect[2] - x h = rect[3] - y if ("offset+" in modifiers or "offset" in modifiers): x += setting_offsetXMod y += setting_offsetYMod if ("offset-" in modifiers): x -= setting_offsetXMod y -= setting_offsetYMod if ("offsetx+" in modifiers or "offsetx" in modifiers): x += setting_offsetXMod if ("offsetx-" in modifiers): x -= setting_offsetXMod if ("offsety+" in modifiers or "offsety" in modifiers): y += setting_offsetYMod if ("offsety-" in modifiers): y -= setting_offsetYMod if ("snap" in modifiers): if (x < 0): x = 0 elif (x + w > dimensions.base_width): x = dimensions.base_width - w if (y < 0): y = 0 elif (y + h > dimensions.base_height): y = dimensions.base_height - h if ("snapx" in modifiers): if (x < 0): x = 0 elif (x + w > dimensions.base_width): x = dimensions.base_width - w if ("snapy" in modifiers): if (y < 0): y = 0 elif (y + h > dimensions.base_height): y = dimensions.base_height - h if ("loop" in modifiers): if (x < (0 - w / 2)): x += dimensions.base_width elif (x > (dimensions.base_width - w / 2)): x -= dimensions.base_width if (y < (0 - h / 2)): y += dimensions.base_height elif (y > (dimensions.base_height - h / 2)): y -= dimensions.base_height if ("loopx" in modifiers): if (x < (0 - w / 2)): x += dimensions.base_width elif (x > (dimensions.base_width - w / 2)): x -= dimensions.base_width if ("loopy" in modifiers): if (y < (0 - h / 2)): y += dimensions.base_height elif (y > (dimensions.base_height - h / 2)): y -= dimensions.base_height #print("\tLocation: (%d, %d)" % (x, y)) #print("\t Size: (%d, %d)" % (w, h)) # Move scene? pos_win = obs.vec2() obs.vec2_set(pos_win, x, y) obs.obs_sceneitem_set_pos(item, pos_win) except: print("Failed to track window: %s" % windowTitle) pass