Esempio n. 1
0
def SetDestinationPositionAndSize(props, p):
    global Animations

    # Base the index off of the name since callbacks don't work well.
    name = obs.obs_property_name(p)
    indexStr = re.sub("[^0-9]", "", name)

    animationIndex = int(indexStr)
    scene_item = getSceneItem()

    posV = obs.vec2()
    scaleV = obs.vec2()
    obs.obs_sceneitem_get_pos(scene_item, posV)
    obs.obs_sceneitem_get_scale(scene_item, scaleV)

    width, height = calculateSize(scene_item, scaleV.x, scaleV.y)
    Animations[animationIndex].destinationX = posV.x
    Animations[animationIndex].destinationY = posV.y
    Animations[animationIndex].destinationWidth = width
    Animations[animationIndex].destinationHeight = height
    obs.obs_data_set_int(settings,
                         Animations[animationIndex].destinationXStorage,
                         (int)(Animations[animationIndex].destinationX))
    obs.obs_data_set_int(settings,
                         Animations[animationIndex].destinationYStorage,
                         (int)(Animations[animationIndex].destinationY))
    obs.obs_data_set_int(settings,
                         Animations[animationIndex].destinationWidthStorage,
                         (int)(Animations[animationIndex].destinationWidth))
    obs.obs_data_set_int(settings,
                         Animations[animationIndex].destinationHeightStorage,
                         (int)(Animations[animationIndex].destinationHeight))
Esempio n. 2
0
def getTransformationList(sceneitems):
    transformations = []
    for sceneitem in sceneitems:
        pos = obs.vec2()
        obs.obs_sceneitem_get_pos(sceneitem, pos)
        rot = obs.obs_sceneitem_get_rot(sceneitem)
        scale = obs.vec2()
        obs.obs_sceneitem_get_scale(sceneitem, scale)
        alignment = obs.obs_sceneitem_get_alignment(sceneitem)
        bounds = obs.vec2()
        obs.obs_sceneitem_get_bounds(sceneitem, bounds)
        boundsType = obs.obs_sceneitem_get_bounds_type(sceneitem)
        boundsAlignment = obs.obs_sceneitem_get_bounds_alignment(sceneitem)
        crop = obs.obs_sceneitem_crop()
        obs.obs_sceneitem_get_crop(sceneitem, crop)
        transformations.append({
            "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]
        })
        obs.obs_sceneitem_release(sceneitem)
    return transformations
    def update_cursor(self):
        source = obs.obs_get_source_by_name(self.source_name)
        settings = obs.obs_data_create()
        if source is not None:
            scene_source = obs.obs_frontend_get_current_scene()
            scene_width = obs.obs_source_get_width(source)
            scene_height = obs.obs_source_get_height(source)
            scene = obs.obs_scene_from_source(scene_source)
            scene_item = obs.obs_scene_find_source(scene, self.source_name)
            if scene_item:
                scale = obs.vec2()
                obs.obs_sceneitem_get_scale(scene_item, scale)
                scene_width, scene_height = apply_scale(
                    scale.x, scale.y, scene_width, scene_height
                )
                next_pos = obs.vec2()
                next_pos.x, next_pos.y = get_position()
                next_pos.x -= scene_width / 2
                next_pos.y -= scene_height / 2
                # set position to center of source where cursor is
                obs.obs_sceneitem_set_pos(scene_item, next_pos)

            obs.obs_data_release(settings)
            obs.obs_scene_release(scene)
            obs.obs_source_release(source)
Esempio n. 4
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)
Esempio n. 5
0
def startCountClick(props, prop):
    global itemSource
    global xCoord
    global yCoord
    global Debug_Mode
    global jsonItemData
    global imagePath
    global imageName
    global widthCount
    global heightCount

    if (obs.obs_frontend_preview_program_mode_active()):
        sceneSource = obs.obs_frontend_get_current_preview_scene()
    else:
        sceneSource = obs.obs_frontend_get_current_scene()
    sceneWidth = obs.obs_source_get_width(sceneSource)
    sceneHeight = obs.obs_source_get_height(sceneSource)

    xWidth = math.ceil(sceneWidth / widthCount)
    yHeight = math.ceil(sceneHeight / heightCount)
    blankImage = np.zeros(shape=[yHeight, xWidth, 4], dtype=np.uint8)
    cv2.rectangle(blankImage, (0, 0), (xWidth, yHeight), (169, 169, 169, 255),
                  2)

    if (os.path.isfile(imagePath + imageName)):
        os.remove(imagePath + imageName)

    cv2.imwrite(imagePath + imageName, blankImage)
    if Debug_Mode:
        print("startCount")
        print(imagePath + imageName)

    gridWidth = 0
    gridHeight = 0
    scene = obs.obs_scene_from_source(sceneSource)
    itemData = obs.obs_data_create_from_json(jsonItemData)
    itemSource = obs.obs_load_source(itemData)

    vec2 = obs.vec2()
    position = 0
    if itemSource != None:
        item = obs.obs_scene_find_source(scene, "OBSWindowGridItem")
        while item != None:
            obs.obs_sceneitem_remove(item)
            item = obs.obs_scene_find_source(scene, "OBSWindowGridItem")

        vec2.y = 0
        while gridHeight < sceneHeight:
            gridWidth = 0
            vec2.x = 0
            while gridWidth < sceneWidth:
                newItem = obs.obs_scene_add(scene, itemSource)
                obs.obs_sceneitem_set_pos(newItem, vec2)
                obs.obs_sceneitem_set_locked(newItem, True)
                obs.obs_sceneitem_set_order_position(newItem, position)
                position += 1
                vec2.x += xWidth
                gridWidth += xWidth
            vec2.y += yHeight
            gridHeight += yHeight
Esempio n. 6
0
def update_position():
    global source_name
    global counter
    source = obs.obs_frontend_get_current_scene()
    if source is not None:
        scene_object = obs.obs_scene_from_source(source)
        scene_item = obs.obs_scene_find_source(scene_object, source_name)
        pos = obs.vec2()
        obs.obs_sceneitem_get_pos(scene_item, pos)
        next_pos = obs.vec2()
        next_pos.x = pos.x
        y_adjust = math.sin(math.radians(counter))
        next_pos.y = pos.y + y_adjust / 4
        counter += 0.5
        if counter == 360:
            counter = 0
        obs.obs_sceneitem_set_pos(scene_item, next_pos)
        obs.obs_source_release(source)
def add_random_text_source(scene):
    r = " random text # " + str(randint(0, 10))
    with data_ar() as settings:
        S.obs_data_set_string(settings, "text", f"random text value {r}")
        with source_create_ar("text_ft2_source", f"random text{r}", settings) as source:
            pos = S.vec2()
            pos.x = randint(0, 1920)
            pos.y = randint(0, 1080)
            scene_item = S.obs_scene_add(scene, source)
            S.obs_sceneitem_set_pos(scene_item, pos)
Esempio n. 8
0
def InitializeSource(animation, positionSpecified, sizeSpecified):
    #scene_item = None
    global source_name
    scene_item = getSceneItem()
    #scene_item = findSceneItem(source_name)
    print("InitializeSource::scene_item: %s" % (scene_item))
    if scene_item != None:
        posV = obs.vec2()
        scaleV = obs.vec2()

        obs.obs_sceneitem_get_pos(scene_item, posV)
        obs.obs_sceneitem_get_scale(scene_item, scaleV)
        Source.scale.x = scaleV.x
        Source.scale.y = scaleV.y
        width, height = calculateSize(scene_item, Source.scale.x,
                                      Source.scale.y)
        Source.pos = posV
        Source.size.x = width
        Source.size.y = height

        Source.posSpeed = animation.posSpeed
        if positionSpecified:
            Source.targetPos.x = animation.destinationX
            Source.targetPos.y = animation.destinationY
        else:
            Source.targetPos.x = posV.x
            Source.targetPos.y = posV.y

        if sizeSpecified:
            Source.targetSize.x = animation.destinationWidth
            Source.targetSize.y = animation.destinationHeight
            scaleV.x, scaleV.y = calculateNewScale(scene_item,
                                                   Source.targetSize.x,
                                                   Source.targetSize.y)
            Source.targetScale.x = scaleV.x
            Source.targetScale.y = scaleV.y
        else:
            Source.targetSize.x = Source.size.x
            Source.targetSize.y = Source.size.y
            Source.targetScale.x = Source.scale.x
            Source.targetScale.y = Source.scale.y
Esempio n. 9
0
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)
Esempio n. 10
0
 def fullscreenTransform(self, direction):
     sceneItem = zoom.getCurrentSceneItem(zoom.source_name)
     if direction == 'zoom':
         size = obs.vec2()
         size.x = self.output_w
         size.y = self.output_h
         obs.obs_sceneitem_set_bounds_type(sceneItem,
                                           1)  # 1 -> OBS_BOUNDS_STRETCH
         obs.obs_sceneitem_set_bounds_alignment(sceneItem,
                                                1)  # 1 -> OBS_ALIGN_LEFT
         obs.obs_sceneitem_set_bounds(sceneItem, size)
     else:
         obs.obs_sceneitem_set_bounds_type(sceneItem, 0)  # 0 -> None
Esempio n. 11
0
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)
Esempio n. 12
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
Esempio n. 13
0
    def updateSettings(self, settings):
        """
        Update the settings with the given obs_data_t settings object.
        """

        # Update the owl source name
        newOwlName = obs.obs_data_get_string(settings, PROP_ID_OWL_SOURCE)
        if self.owlSourceName != newOwlName:
            for item in self.iterSceneItemsByName(newOwlName):
                pos = obs.vec2()
                obs.obs_sceneitem_get_pos(item, pos)
                self.owlBaseY = pos.y
                break
        self.owlSourceName = newOwlName

        # Update the label and counter source names
        self.labelSourceName = obs.obs_data_get_string(settings,
                                                       PROP_ID_LABEL_SOURCE)
        newCounterSourceName = obs.obs_data_get_string(settings,
                                                       PROP_ID_COUNTER_SOURCE)
        if self.counterSourceName != newCounterSourceName:
            with getSourceByName(newCounterSourceName) as source:
                if source is not None:
                    with getSourceSettings(source) as settings:
                        text = obs.obs_data_get_string(settings, 'text')
                        try:
                            self.textColor, self.outlineColor = \
                                colorsForNum(int(text))
                            self.setSourceTextColorByName(
                                newCounterSourceName, self.textColor,
                                self.outlineColor)
                        except ValueError:
                            pass
        self.counterSourceName = newCounterSourceName

        # Update the ding source names
        self.ding1SourceName = obs.obs_data_get_string(settings,
                                                       PROP_ID_DING1_SOURCE)
        self.ding10SourceName = obs.obs_data_get_string(
            settings, PROP_ID_DING10_SOURCE)
        self.ding50SourceName = obs.obs_data_get_string(
            settings, PROP_ID_DING50_SOURCE)

        # Update the owl Y position and movement distance
        self.owlBaseX = obs.obs_data_get_double(settings, PROP_ID_OWL_X_POS)
        self.owlBaseY = obs.obs_data_get_double(settings, PROP_ID_OWL_Y_POS)
        self.owlXDistance = obs.obs_data_get_double(settings,
                                                    PROP_ID_OWL_X_DISTANCE)
        self.owlYDistance = obs.obs_data_get_double(settings,
                                                    PROP_ID_OWL_Y_DISTANCE)
Esempio n. 14
0
    def setSourcePosByName(self, sourceName, x=None, y=None):
        """
        Set the position of the given source by name. If either
        coordinate is None, that coordinate will not be modified.
        """
        if x == y == None: return

        for item in self.iterSceneItemsByName(sourceName):
            pos = obs.vec2()
            obs.obs_sceneitem_get_pos(item, pos)
            if x is not None:
                pos.x = x
            if y is not None:
                pos.y = y
            obs.obs_sceneitem_set_pos(item, pos)
Esempio n. 15
0
def fit_to_screen(scene_item):
  # see ~/Library/Application Support/obs-studio/basic/profiles/Untitled/basic.ini
  # which contains
  # BaseCX=1680
  # BaseCY=1050
  # OutputCX=1120
  # OutputCY=700
  # 1680 x 1050 appear to be the dimensions we want, to completely fill the scren.
  video_info = obs.obs_video_info()
  obs.obs_get_video_info(video_info)

  bounds = obs.vec2()
  bounds.x = video_info.base_width # output_width # 1680 # source_width
  bounds.y = video_info.base_height # output_height # 1050 # source_height
  obs.obs_sceneitem_set_bounds(scene_item, bounds)

  # fit video to screen
  # https://obsproject.com/docs/reference-scenes.html?highlight=bounds#c.obs_transform_info.bounds
  obs.obs_sceneitem_set_bounds_type(scene_item, obs.OBS_BOUNDS_SCALE_INNER)

  scale = obs.vec2()
  scale.x = 1
  scale.y = 1
  obs.obs_sceneitem_set_scale(scene_item, scale)
Esempio n. 16
0
def add_text_to_scene(scene, text_element):
    """Places text source into some location within scene
    returns width and height to align next scene items later """

    with data_ar() as settings:
        set_text_source_settings(settings, text_element.text)
        with source_create_ar("text_ft2_source", text_element.name,
                              settings) as source:
            pos = obs.vec2()
            pos.x = text_element.x
            pos.y = text_element.y
            scene_item = obs.obs_scene_add(scene, source)
            obs.obs_sceneitem_set_pos(scene_item, pos)
            height = obs.obs_source_get_height(source)
            width = obs.obs_source_get_width(source)
            return width, height
Esempio n. 17
0
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)
Esempio n. 18
0
 def __init__(self):
     self.pos = obs.vec2()
     # This is needed to store the remainder values since position is integer only.
     self.posRemainder = obs.vec2()
     self.size = obs.vec2()
     self.scale = obs.vec2()
     self.targetPos = obs.vec2()
     self.targetSize = obs.vec2()
     self.targetScale = obs.vec2()
     self.posSpeed = 1
     self.processingAnimation = False
     self.forceX = 0
     self.forceY = 0
     self.forceW = 0
     self.forceH = 0
Esempio n. 19
0
def setup_source(source_name, height, width):
    # Get the current scene
    current_scene = obs.obs_frontend_get_current_scene()
    scene = obs.obs_scene_from_source(current_scene)
    obs.obs_source_release(current_scene)

    # Grab the source
    source = obs.obs_scene_find_source(scene, source_name)

    # This makes sure that the scaling is done right
    obs.obs_sceneitem_set_bounds_type(source, obs.OBS_BOUNDS_SCALE_INNER)

    # Set the bounding box size
    new_scale = obs.vec2()
    new_scale.x = height
    new_scale.y = width
    obs.obs_sceneitem_set_bounds(source, new_scale)
Esempio n. 20
0
 def _obs_sceneitem_set_pos(self, scene_name, source_name, pos):
     with self._sceneitem_by_name(scene_name, source_name) as si:
         p = _obs.vec2()
         p.x, p.y = pos
         _obs.obs_sceneitem_set_pos(si, p)
Esempio n. 21
0
 def _obs_sceneitem_get_pos(self, scene_name, source_name):
     with self._sceneitem_by_name(scene_name, source_name) as si:
         p = _obs.vec2()
         _obs.obs_sceneitem_get_pos(si, p)
         return p.x, p.y
    def tremor_effect(self):

        flag = next(self.position_swap)
        if flag:
            self.update_text(self.scripted_text)
            current_scene = obs.obs_frontend_get_current_scene()
            with source_ar(self.source_name) as source, scene_ar(
                    current_scene) as scene:
                scene_item = obs.obs_scene_find_source(scene, self.source_name)
                pos = obs.vec2()
                self.location = pos
                obs.obs_sceneitem_get_pos(
                    scene_item, self.location
                )  # update to last position if its changed from OBS

                if not self.last_jump_x == 0:
                    if self.last_jump_x < 0:
                        # minus minus
                        self.location.x -= self.last_jump_x
                    if self.last_jump_x > 0:
                        self.location.x -= self.last_jump_x

                if not self.last_jump_y == 0:
                    if self.last_jump_y < 0:
                        self.location.y -= self.last_jump_y
                    if self.last_jump_y > 0:
                        self.location.y -= self.last_jump_y

                if scene_item:
                    obs.obs_sceneitem_set_pos(scene_item, self.location)

        else:
            self.update_text(self.scripted_text)
            current_scene = obs.obs_frontend_get_current_scene()
            with source_ar(self.source_name) as source, scene_ar(
                    current_scene) as scene:
                scene_item = obs.obs_scene_find_source(scene, self.source_name)
                pos = obs.vec2()
                self.location = pos
                obs.obs_sceneitem_get_pos(
                    scene_item, self.location
                )  # update to last position if its changed from OBS

                if scene_item:
                    # finish early , and set to default
                    if self.duration // self.refresh_rate <= 3:
                        self.duration = 0
                        obs.obs_sceneitem_set_pos(scene_item, self.location)

                    else:
                        next_pos = obs.vec2()
                        withoutzero = list(range(-101, 0)) + list(range(
                            1, 101))
                        self.last_jump_x = choice(withoutzero)
                        self.last_jump_y = choice(withoutzero)
                        dx, dy = self.last_jump_x, self.last_jump_y
                        next_pos.x, next_pos.y = (
                            self.location.x + dx,
                            self.location.y + dy,
                        )
                        obs.obs_sceneitem_set_pos(scene_item, next_pos)
Esempio n. 23
0
def sad_threaded(props, prop):
    # 1. Make it grayscale
    cam_source = obs.obs_get_source_by_name("Shitty Webcam")
    grayscale_filter = obs.obs_source_get_filter_by_name(cam_source, "Gray")

    data = obs.obs_data_create()
    obs.obs_data_set_double(data, "clut_amount", 1.0)
    obs.obs_source_update(grayscale_filter, data)

    # 2. Save initial props
    current_scene_source = obs.obs_frontend_get_current_scene()
    obs.obs_frontend_set_current_preview_scene(current_scene_source)
    current_scene = obs.obs_scene_from_source(current_scene_source)
    cam_sceneitem = obs.obs_scene_find_source(current_scene, "Shitty Webcam")

    initial_scale = obs.vec2()
    obs.obs_sceneitem_get_scale(cam_sceneitem, initial_scale)

    initial_pos = obs.vec2()
    obs.obs_sceneitem_get_pos(cam_sceneitem, initial_pos)

    initial_box_transform = obs.matrix4()
    obs.obs_sceneitem_get_box_transform(cam_sceneitem, initial_box_transform)

    initial_crop = obs.obs_sceneitem_crop()
    obs.obs_sceneitem_get_crop(cam_sceneitem, initial_crop)
    # matrix4.x.x -> x size
    # matrix4.y.y -> y size
    # matrix4.t.x -> x position
    # matrix4.t.y -> y position
    # for prop in ["x", "y", "z", "t"]:
    #   print(f"Matrix property {prop}")
    #   vec = getattr(initial_box_transform, prop)
    #   print(dir(vec))
    #   for vec_prop in ["m", "w", "x", "y", "z"]:
    #     print(f"Vec Property {vec_prop}: {getattr(vec, vec_prop)}")
    size_x = initial_box_transform.x.x
    size_y = initial_box_transform.y.y

    initial_draw_transform = obs.matrix4()
    obs.obs_sceneitem_get_draw_transform(cam_sceneitem, initial_draw_transform)
    print(dir(initial_draw_transform))

    # 3. Mute desktop audio, play sound of silence
    desktop_audio = obs.obs_get_output_source(4)
    obs.obs_source_set_muted(desktop_audio, True)

    song = obs.obs_source_create("ffmpeg_source", "Sound of Silence", None,
                                 None)
    song_settings = obs.obs_data_create()
    obs.obs_data_set_string(
        song_settings, "local_file",
        "C:\\Users\\avikn\\Downloads\\sound_of_silence.mp3")
    obs.obs_source_update(song, song_settings)
    obs.obs_data_release(song_settings)
    song_item = obs.obs_scene_add(current_scene, song)

    # 4. Scale up / reposition the camera.
    # It's gross but it works don't touch it.
    dynamic_scale = obs.vec2()
    obs.vec2_copy(dynamic_scale, initial_scale)

    increment = obs.vec2()
    increment.x = 0.0015
    increment.y = 0.0015

    crop = (initial_crop.top, initial_crop.right, initial_crop.bottom,
            initial_crop.left)
    size_x, size_y = get_size(cam_sceneitem)
    dynamic_crop = obs.obs_sceneitem_crop()

    bounds = obs.vec2()
    bounds.x = size_x
    bounds.y = size_y
    obs.obs_sceneitem_set_bounds(cam_sceneitem, bounds)

    for _ in range(240):
        obs.obs_sceneitem_set_bounds_type(cam_sceneitem, 0)
        obs.vec2_add(dynamic_scale, dynamic_scale, increment)
        obs.obs_sceneitem_set_scale(cam_sceneitem, dynamic_scale)
        nsize_x, nsize_y = get_size(cam_sceneitem)
        x_delta = nsize_x - size_x + (dynamic_crop.right * 2)
        y_delta = nsize_y - size_y + (dynamic_crop.top * 2)

        dynamic_crop.top = int(y_delta / 2)
        dynamic_crop.right = int(x_delta / 2)
        dynamic_crop.bottom = int(y_delta / 2)
        dynamic_crop.left = int(x_delta / 2)

        obs.obs_sceneitem_set_crop(cam_sceneitem, dynamic_crop)

        obs.obs_sceneitem_set_bounds_type(cam_sceneitem, 1)
        obs.obs_frontend_preview_program_trigger_transition()
        time.sleep(0.1)

    # 5. Cleanup
    obs.obs_source_set_muted(desktop_audio, False)

    obs.obs_sceneitem_set_scale(cam_sceneitem, initial_scale)
    obs.obs_sceneitem_set_crop(cam_sceneitem, initial_crop)
    obs.obs_data_set_double(data, "clut_amount", 0.0)
    obs.obs_source_update(grayscale_filter, data)
    obs.obs_sceneitem_remove(song_item)
    obs.obs_source_release(song)
    time.sleep(0.1)
    obs.obs_frontend_preview_program_trigger_transition()
Esempio n. 24
0
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')
Esempio n. 25
0
VARIATION_SIZE = (1 << 1)
VARIATION_BOTH = VARIATION_POSITION | VARIATION_SIZE
VARIATION_POSITION_FREE = (1 << 2)
VARIATION_SIZE_FREE = (1 << 3)
VARIATION_POSITION_FREE_ALL = (1 << 4)

MOVEMENT_SPEED = (1 << 0)
MOVEMENT_DURATION = (1 << 1)
MOVEMENT_QUICKEST = MOVEMENT_SPEED | MOVEMENT_DURATION

DefaultUpdatePerSecond = 60
UpdatesPerSecond = 60
TickFactor = DefaultUpdatePerSecond / UpdatesPerSecond
UpdateRateMs = int(1000 / UpdatesPerSecond)
Animations = []  # type: List[Animation]
source_pos = obs.vec2()


class ServerClass:
    def __init__(self):
        self.address = "localhost"
        self.port = "12345"

        self.addressStorage = "addressStorage"
        self.portStorage = "portStorage"
        self.thread = None

        self.run = False
        # If Ping time exceed
        self.lastPingTime = time.clock()
        self.closeIfNoPingInXSeconds = 8
 def __init__(self):
     pos = obs.vec2()
     self.location = pos
Esempio n. 27
0
 def _scale(self):
     ratio = obs.vec2()
     obs.obs_sceneitem_get_scale(self.sceneitem, ratio)
     return ratio
Esempio n. 28
0
def adjustCameraTick():
    global source_name
    global source_pos
    global UpdatesPerSecond
    global scene_item

    # Do not control any aspect of the source if no animation is currently playing or if the server is not connected.
    if (not Source.processingAnimation) or (
            not Server.run) or scene_item is None:
        return

    #scene_item = findSceneItem(source_name)
    # Only make adjustments if our server is currently running.
    #print("adjustCameraTick::scene_item: %s" % (scene_item))

    posV = obs.vec2()
    scaleV = obs.vec2()

    obs.obs_sceneitem_get_pos(scene_item, posV)
    obs.obs_sceneitem_get_scale(scene_item, scaleV)
    width, height = calculateSize(scene_item, Source.scale.x, Source.scale.y)
    Source.pos = posV
    Source.size.x = width
    Source.size.y = height

    if Source.pos.x != Source.targetPos.x:
        fractionX = (float(Source.forceX) /
                     float(UpdatesPerSecond)) + Source.posRemainder.x
        integerX = int(math.floor(fractionX))
        Source.posRemainder.x = fractionX - integerX
        Source.pos.x += integerX
        if (integerX > 0 and Source.pos.x > Source.targetPos.x) or (
                integerX < 0 and Source.pos.x < Source.targetPos.x):
            Source.pos.x = Source.targetPos.x

    if Source.pos.y != Source.targetPos.y:
        fractionY = (Source.forceY / UpdatesPerSecond) + Source.posRemainder.y
        integerY = int(math.floor(fractionY))
        Source.posRemainder.y = fractionY - integerY
        Source.pos.y += integerY
        if (integerY > 0 and Source.pos.y > Source.targetPos.y) or (
                integerY < 0 and Source.pos.y < Source.targetPos.y):
            Source.pos.y = Source.targetPos.y

    if Source.scale.x != Source.targetScale.x:
        fractionX = (float(Source.forceW) / float(UpdatesPerSecond))
        Source.scale.x += fractionX
        if (fractionX > 0 and Source.scale.x > Source.targetScale.x) or (
                fractionX < 0 and Source.scale.x < Source.targetScale.x):
            Source.scale.x = Source.targetScale.x

    if Source.scale.y != Source.targetScale.y:
        fractionY = (float(Source.forceH) / float(UpdatesPerSecond))
        Source.scale.y += fractionY
        if (fractionY > 0 and Source.scale.y > Source.targetScale.y) or (
                fractionY < 0 and Source.scale.y < Source.targetScale.y):
            Source.scale.y = Source.targetScale.y

    if Source.pos.x == Source.targetPos.x and Source.pos.y == Source.targetPos.y and Source.scale.x == Source.targetScale.x and Source.scale.y == Source.targetScale.y:
        Source.processingAnimation = False

    # Update the position and size of the source based on speed/
    obs.obs_sceneitem_set_pos(scene_item, Source.pos)
    obs.obs_sceneitem_set_scale(scene_item, Source.scale)
Esempio n. 29
0
def script_tick(tick):
    global globSettings
    global animationInfo
    global animationRunning
    global app
    global currentScene

    if animationRunning:
        animationInfo["animTime"] += tick
        animationInfo["animTime"] = min(animationInfo["animTime"],
                                        animationInfo["stopTime"])
        scaleFactor = easeInOutQuad(
            animationInfo["animTime"] / animationInfo["stopTime"], 0, 1, 1)

        animScene = animationInfo["animScene"]
        initial = animationInfo["initial"]
        destination = animationInfo["destination"]

        result = []
        sceneObject = obs.obs_scene_from_source(animScene)
        if obs.obs_source_get_name(
                animScene) in obs.obs_frontend_get_scene_names():
            items = obs.obs_scene_enum_items(sceneObject)
            for i in range(len(initial)):
                pos = obs.vec2()
                pos.x = scaleFactor * (destination[i]["pos"][0] - initial[i]
                                       ["pos"][0]) + initial[i]["pos"][0]
                pos.y = scaleFactor * (destination[i]["pos"][1] - initial[i]
                                       ["pos"][1]) + initial[i]["pos"][1]
                rot = scaleFactor * (destination[i]["rot"] -
                                     initial[i]["rot"]) + initial[i]["rot"]
                scale = obs.vec2()
                scale.x = scaleFactor * (
                    destination[i]["scale"][0] -
                    initial[i]["scale"][0]) + initial[i]["scale"][0]
                scale.y = scaleFactor * (
                    destination[i]["scale"][1] -
                    initial[i]["scale"][1]) + initial[i]["scale"][1]
                alignment = destination[i]["alignment"]
                bounds = obs.vec2()
                bounds.x = scaleFactor * (
                    destination[i]["bounds"][0] -
                    initial[i]["bounds"][0]) + initial[i]["bounds"][0]
                bounds.y = scaleFactor * (
                    destination[i]["bounds"][1] -
                    initial[i]["bounds"][1]) + initial[i]["bounds"][1]
                boundsType = destination[i]["boundsType"]
                boundsAlignment = destination[i]["boundsAlignment"]
                crop = obs.obs_sceneitem_crop()
                crop.left = math.floor(
                    scaleFactor *
                    (destination[i]["crop"][0] - initial[i]["crop"][0]) +
                    initial[i]["crop"][0])
                crop.right = math.floor(
                    scaleFactor *
                    (destination[i]["crop"][1] - initial[i]["crop"][1]) +
                    initial[i]["crop"][1])
                crop.top = math.floor(
                    scaleFactor *
                    (destination[i]["crop"][2] - initial[i]["crop"][2]) +
                    initial[i]["crop"][2])
                crop.bottom = math.floor(
                    scaleFactor *
                    (destination[i]["crop"][3] - initial[i]["crop"][3]) +
                    initial[i]["crop"][3])
                obs.obs_sceneitem_set_pos(items[i], pos)
                obs.obs_sceneitem_set_rot(items[i], rot)
                obs.obs_sceneitem_set_scale(items[i], scale)
                obs.obs_sceneitem_set_alignment(items[i], alignment)
                obs.obs_sceneitem_set_bounds(items[i], bounds)
                obs.obs_sceneitem_set_bounds_type(items[i], boundsType)
                obs.obs_sceneitem_set_bounds_alignment(items[i],
                                                       boundsAlignment)
                obs.obs_sceneitem_set_crop(items[i], crop)
            obs.sceneitem_list_release(items)

        #obs.obs_scene_release(sceneObject)

        if animationInfo["animTime"] == animationInfo["stopTime"]:
            obs.obs_source_release(animScene)
            animationInfo["animScene"] = None
            animationRunning = False
Esempio n. 30
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)