def dup(self):
        current_scene = S.obs_scene_from_source(
            S.obs_frontend_get_current_scene())
        scene_item = S.obs_scene_find_source(current_scene, self.source_name)
        info = S.obs_transform_info()
        crop = S.obs_sceneitem_crop()
        S.obs_sceneitem_get_info(scene_item, info)
        S.obs_sceneitem_get_crop(scene_item, crop)
        duplicate = S.obs_sceneitem_get_source(scene_item)
        duplicated = S.obs_source_duplicate(duplicate,
                                            "duplicate" + self.source_name,
                                            False)

        scenes = S.obs_frontend_get_scenes()
        for scene in scenes:
            name = S.obs_source_get_name(scene)
            if name == self.scene_name:
                scene = S.obs_scene_from_source(scene)
                scene_item2 = S.obs_scene_add(scene, duplicated)
                S.obs_sceneitem_set_info(scene_item2, info)
                S.obs_sceneitem_set_crop(scene_item2, crop)
                S.obs_scene_release(scene)

        S.obs_source_release(duplicated)
        S.source_list_release(scenes)
        S.obs_scene_release(current_scene)
def get_order(scene_items=None):
    order = list()
    for i, s in enumerate(scene_items):
        source = obs.obs_sceneitem_get_source(s)
        name = obs.obs_source_get_name(source)
        order.append({"index": i, "name": name, "scene_item": s})
    return order
    def iterSceneItemsByName(self, sourceName):
        """
        Iterator over scene items with a given source name, in the
        scene currently displayed in the frontend
        """
        # This took me a while to figure out, so I'll comment it
        # enough to be understandable.

        # First, we get the source we need to find items of
        with getSourceByName(sourceName) as s:
            if s is None: return []

            # Now we get the entire scene that's currently streaming
            with frontendGetCurrentScene() as currentSceneSource:
                if currentSceneSource is None: return []

                # (and convert it to a scene)
                currentScene = obs.obs_scene_from_source(currentSceneSource)
                if currentScene is None: return []

                # Now we iterate over all the items in that scene
                with sceneEnumItems(currentScene) as items:
                    for item in items:
                        if item is None: continue

                        # Now we find what source this item is using
                        itemSource = obs.obs_sceneitem_get_source(item)
                        # And the name of that source
                        itemSourceName = obs.obs_source_get_name(itemSource)
                        # And if it's what we want, we yield it!
                        if itemSourceName == sourceName:
                            yield item
Exemple #4
0
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)
Exemple #5
0
def get_audio_sources_from_scene(scene, source_dict=None):
    if source_dict is None:
        source_dict = OrderedDict()

    for sceneitem in obspython.obs_scene_enum_items(
            obspython.obs_scene_from_source(scene)):
        item_source = obspython.obs_sceneitem_get_source(sceneitem)
        name = obspython.obs_source_get_name(item_source)

        if obspython.obs_source_get_output_flags(
                item_source) & obspython.OBS_SOURCE_COMPOSITE:
            source_dict = get_audio_sources_from_scene(item_source,
                                                       source_dict)

        if obspython.obs_source_get_output_flags(
                item_source) & obspython.OBS_SOURCE_AUDIO:
            source_active = obspython.obs_source_active(item_source)
            audio_active = obspython.obs_source_audio_active(item_source)
            priv_settings = obspython.obs_source_get_private_settings(
                item_source)
            hidden = obspython.obs_data_get_bool(priv_settings, "mixer_hidden")
            if not source_active or not audio_active or hidden:
                continue

            source_dict[name] = item_source

    return source_dict
Exemple #6
0
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)
Exemple #7
0
def on_visibility_toggle(calldata):
    scenes_as_sources = obs.obs_frontend_get_scenes()
    sceneitem = obs.calldata_sceneitem(calldata, "item")
    visibility = obs.calldata_bool(calldata, "visible")
    name = obs.obs_source_get_name(obs.obs_sceneitem_get_source(sceneitem))
    for scene_as_source in scenes_as_sources:
        scene = obs.obs_scene_from_source(scene_as_source)
        match = obs.obs_scene_find_source(scene, name)
        if match:
            obs.obs_sceneitem_set_visible(match, visibility)
    obs.source_list_release(scenes_as_sources)
Exemple #8
0
def get_item_names_by_scene(source):
    item_names = []
    scene = obs.obs_scene_from_source(source)
    scene_name = obs.obs_source_get_name(source)
    scene_items = obs.obs_scene_enum_items(scene)
    if scene_items is not None:
        for item in scene_items:
            item_source = obs.obs_sceneitem_get_source(item)
            item_name = obs.obs_source_get_name(item_source)
            if item_name in light_mapping:
                item_names.append(item_name)
        obs.sceneitem_list_release(scene_items)

    return item_names
Exemple #9
0
def get_scene_item(name):
    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:
                        scene_source = obs.obs_sceneitem_get_source(item)
                        if obs.obs_source_get_name(scene_source) == name:
                            sceneItem = obs.obs_scene_find_sceneitem_by_id(scene, obs.obs_sceneitem_get_id(item))
                            obs.source_list_release(scenes)
                            obs.obs_sceneitem_addref(sceneItem)
                            obs.sceneitem_list_release(items)
                            return sceneItem
                obs.sceneitem_list_release(items)
    obs.source_list_release(scenes)
Exemple #10
0
def set_names(source_name, string):
    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) == source_name:
                            source = source_t
                            settings = obs.obs_data_create()
                            obs.obs_data_set_string(settings, "text", str(string))
                            obs.obs_source_update(source, settings)
                            obs.obs_data_release(settings)
                            obs.source_list_release(scenes)
                obs.sceneitem_list_release(items)
Exemple #11
0
def dumpSceneData():
    scene = obs.obs_frontend_get_current_scene()
    sceneObject = obs.obs_scene_from_source(scene)
    items = obs.obs_scene_enum_items(sceneObject)
    itemArray = []
    for item in items:
        sceneItem = obs.obs_sceneitem_get_source(item)
        name = obs.obs_source_get_name(sceneItem)
        if "tweentool:" not in name:
            pos = obs.vec2()
            obs.obs_sceneitem_get_pos(item, pos)
            rot = obs.obs_sceneitem_get_rot(item)
            scale = obs.vec2()
            obs.obs_sceneitem_get_scale(item, scale)
            alignment = obs.obs_sceneitem_get_alignment(item)
            bounds = obs.vec2()
            obs.obs_sceneitem_get_bounds(item, bounds)
            boundsType = obs.obs_sceneitem_get_bounds_type(item)
            boundsAlignment = obs.obs_sceneitem_get_bounds_alignment(item)
            crop = obs.obs_sceneitem_crop()
            obs.obs_sceneitem_get_crop(item, crop)
            itemArray.append({
                "name":
                name,
                "pos": [pos.x, pos.y],
                "rot":
                rot,
                "scale": [scale.x, scale.y],
                "alignment":
                alignment,
                "bounds": [bounds.x, bounds.y],
                "boundsType":
                boundsType,
                "boundsAlignment":
                boundsAlignment,
                "crop": [crop.left, crop.right, crop.top, crop.bottom]
            })
    return itemArray
Exemple #12
0
def printSceneData(pressedState):
    if pressedState:
        nameOfTweener = None
        items = obs.obs_scene_enum_items(
            obs.obs_scene_from_source(obs.obs_frontend_get_current_scene()))
        for item in items:
            sceneItem = obs.obs_sceneitem_get_source(item)
            name = obs.obs_source_get_name(sceneItem)
            if "tweentool:" in name:
                nameOfTweener = name.split(':')[1]
                tweenTime = float(name.split(':')[3])
            name = obs.obs_source_get_name(sceneItem)
        if nameOfTweener:
            print(
                json.dumps({
                    'tweenName': nameOfTweener,
                    'length': tweenTime,
                    'tweenItems': dumpSceneData()
                }))
        else:
            print(
                'Please create the appropriate source at the top of the source list for your naming. See instructions for further details.'
            )
Exemple #13
0
def calculateNewScale(item, width, height):
    src = obs.obs_sceneitem_get_source(item)

    baseWidth = obs.obs_source_get_base_width(src)
    baseHeight = obs.obs_source_get_base_height(src)
    return (width / baseWidth), (height / baseHeight)
Exemple #14
0
def calculateSize(scene_item, scaleX, scaleY):
    src = obs.obs_sceneitem_get_source(scene_item)
    baseWidth = obs.obs_source_get_base_width(src)
    baseHeight = obs.obs_source_get_base_height(src)

    return (int)(baseWidth * scaleX), (int)(baseHeight * scaleY)
Exemple #15
0
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 cache_scenes():

    global scene_win_map
    global cached_items
    global tagRegex
    global dimensions

    clear_cache()

    cached_num = 0

    currentScene = obs.obs_frontend_get_current_scene()
    sceneName = obs.obs_source_get_name(currentScene)
    sceneObject = obs.obs_scene_from_source(currentScene)
    items = obs.obs_scene_enum_items(sceneObject)

    if items is not None:

        for item in items:

            source = obs.obs_sceneitem_get_source(item)

            source_id = obs.obs_source_get_id(source)
            source_name = obs.obs_source_get_name(source)

            #find = re.match(tagRegex, source_name)
            #print(tagRegex, source_name)

            
            if (re.match(tagRegex, source_name) and source_id == "window_capture"):

                modifiers = {}

                flagsSearch = re.findall(tagRegex, source_name)
                flags = flagsSearch[0].split(",")

                for flag in flags:
                    modifiers[flag.lower()] = True

                data = obs.obs_source_get_settings(source)

                windowData = obs.obs_data_get_string(data, "window")
                windowSplit = windowData.split(":")

                windowTitle = windowSplit[0].replace("#3A", ":")
                #print("Window Title: " + windowData[0])
                #print("Window EXE: " + windowData[1])
                
                obs.obs_data_release(data)
                
                try:
                    if (windowData in scene_win_map):
                        myWin = scene_win_map[windowData]
                    else:
                        myWin = win.FindWindow(None, windowTitle)
                        scene_win_map[windowData] = myWin
                except:
                    pass

                cached_items[cached_num] = {
                        "item": item,
                        "source": source,
                        "modifiers": modifiers,
                        "win32gui": myWin
                    }
                cached_num += 1

            else:

                #obs.obs_source_release(source)
                obs.obs_sceneitem_release(item)
                pass

            #obs.obs_source_release(source)
            #obs.obs_sceneitem_release(item)

    obs.obs_scene_release(sceneObject)
    #obs.obs_source_release(currentScene)
    
    #print("Cached %d items." % (cached_num))
    
    dimensions = obs.obs_video_info()
    obs.obs_get_video_info(dimensions)
Exemple #17
0
def script_tick(tick):
    if scriptSettings['anim']['animating']:
        scriptSettings['anim']['time'] += tick
        scriptSettings['anim']['time'] = min(scriptSettings['anim']['time'],
                                             scriptSettings['anim']['length'])
        initial = scriptSettings['anim']['src']
        destination = scriptSettings['anim']['dest']
        tScale = easeInOutQuad(
            scriptSettings['anim']['time'] / scriptSettings['anim']['length'],
            0, 1, 1)
        scene = obs.obs_frontend_get_current_scene()
        sceneObject = obs.obs_scene_from_source(scene)
        tweenItems = scriptSettings['anim']['tweener']['tweenItems']
        sceneItems = obs.obs_scene_enum_items(sceneObject)
        for sItem in sceneItems:
            sceneItem = obs.obs_sceneitem_get_source(sItem)
            sName = obs.obs_source_get_name(sceneItem)
            for tItem in tweenItems:
                if sName == tItem['name']:
                    pos = obs.vec2()
                    pos.x = tScale * (
                        destination[sName]["pos"][0] -
                        initial[sName]["pos"][0]) + initial[sName]["pos"][0]
                    pos.y = tScale * (
                        destination[sName]["pos"][1] -
                        initial[sName]["pos"][1]) + initial[sName]["pos"][1]
                    rot = tScale * (destination[sName]["rot"] - initial[sName]
                                    ["rot"]) + initial[sName]["rot"]
                    scale = obs.vec2()
                    scale.x = tScale * (destination[sName]["scale"][0] -
                                        initial[sName]["scale"][0]
                                        ) + initial[sName]["scale"][0]
                    scale.y = tScale * (destination[sName]["scale"][1] -
                                        initial[sName]["scale"][1]
                                        ) + initial[sName]["scale"][1]
                    alignment = destination[sName]["alignment"]
                    bounds = obs.vec2()
                    bounds.x = tScale * (destination[sName]["bounds"][0] -
                                         initial[sName]["bounds"][0]
                                         ) + initial[sName]["bounds"][0]
                    bounds.y = tScale * (destination[sName]["bounds"][1] -
                                         initial[sName]["bounds"][1]
                                         ) + initial[sName]["bounds"][1]
                    boundsType = destination[sName]["boundsType"]
                    boundsAlignment = destination[sName]["boundsAlignment"]
                    crop = obs.obs_sceneitem_crop()
                    crop.left = math.floor(tScale *
                                           (destination[sName]["crop"][0] -
                                            initial[sName]["crop"][0]) +
                                           initial[sName]["crop"][0])
                    crop.right = math.floor(tScale *
                                            (destination[sName]["crop"][1] -
                                             initial[sName]["crop"][1]) +
                                            initial[sName]["crop"][1])
                    crop.top = math.floor(tScale *
                                          (destination[sName]["crop"][2] -
                                           initial[sName]["crop"][2]) +
                                          initial[sName]["crop"][2])
                    crop.bottom = math.floor(tScale *
                                             (destination[sName]["crop"][3] -
                                              initial[sName]["crop"][3]) +
                                             initial[sName]["crop"][3])
                    obs.obs_sceneitem_set_pos(sItem, pos)
                    obs.obs_sceneitem_set_rot(sItem, rot)
                    obs.obs_sceneitem_set_scale(sItem, scale)
                    obs.obs_sceneitem_set_alignment(sItem, alignment)
                    obs.obs_sceneitem_set_bounds(sItem, bounds)
                    obs.obs_sceneitem_set_bounds_type(sItem, boundsType)
                    obs.obs_sceneitem_set_bounds_alignment(
                        sItem, boundsAlignment)
                    obs.obs_sceneitem_set_crop(sItem, crop)
        if scriptSettings['anim']['time'] >= scriptSettings['anim']['length']:
            scriptSettings['anim']['src'] = None
            scriptSettings['anim']['dest'] = None
            scriptSettings['anim']['time'] = math.inf
            scriptSettings['anim']['length'] = 10000
            scriptSettings['anim']['tweener'] = None
            scriptSettings['anim']['animating'] = False