Replies: 3 comments 16 replies
-
Like I said in #4 using context managers ensures that you acquire and release in right order. import obspython as obs
import random
from contextlib import contextmanager, ExitStack
@contextmanager
def scene_ar(scene):
scene = obs.obs_scene_from_source(scene)
try:
yield scene
finally:
obs.obs_scene_release(scene)
@contextmanager
def get_source(item):
source = obs.obs_sceneitem_get_source(item)
try:
yield source
finally:
obs.obs_source_release(source)
@contextmanager
def scene_enum(items):
items = obs.obs_scene_enum_items(items)
try:
yield items
finally:
obs.sceneitem_list_release(items)
def get_selected_scene(scene_name):
scenes = obs.obs_frontend_get_scenes()
found = False
for scene in scenes:
name = obs.obs_source_get_name(scene)
if name == scene_name:
found = True
obs.source_list_release(scenes)
if found:
return True
return False
@contextmanager
def source_auto_release(source_name):
source = obs.obs_get_source_by_name(source_name)
try:
yield source
finally:
obs.obs_source_release(source)
def delete_items():
selected_scene_name = "Scene 2"
if get_selected_scene(selected_scene_name):
with ExitStack() as stack:
selected_scene = stack.enter_context(
source_auto_release(selected_scene_name)
)
scene = stack.enter_context(scene_ar(selected_scene))
scene_items = stack.enter_context(scene_enum(scene))
for i in scene_items:
source = stack.enter_context(get_source(i))
name = obs.obs_source_get_name(source)
item_id = obs.obs_sceneitem_get_id(i)
print(name)
print(item_id)
print("name")
if name != None and name.startswith("Color "): # color source
print(
"I'm going to remove sceneitem...!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
)
obs.obs_sceneitem_remove(i)
print("sceneitem removed... CRASH?") # no :)
def script_properties():
props = obs.obs_properties_create()
obs.obs_properties_add_button(
props, "button", "click to delete items", lambda *props: delete_items()
)
return props Use context managers. No crashes on my end. |
Beta Was this translation helpful? Give feedback.
-
Ooops. Script works here... but it happens that I need to erase groups. That's the problem. When sceneitems that I want to remove are inside a group or are groups: it crashes. |
Beta Was this translation helpful? Give feedback.
-
By using ExitStack(), as you used in your code, when run that code several times... OBS finally crashes. It doesn't happen with the way I had my code. Check this: Click to expandimport obspython as obs
from contextlib import contextmanager, ExitStack
import random
@contextmanager
def scene_ar(scene):
scene = obs.obs_scene_from_source(scene)
try:
yield scene
finally:
obs.obs_scene_release(scene)
@contextmanager
def get_source(item):
source = obs.obs_sceneitem_get_source(item)
try:
yield source
finally:
obs.obs_source_release(source)
@contextmanager
def get_filter(source, filter_name):
filter_ = obs.obs_source_get_filter_by_name(source, filter_name)
try:
yield filter_
finally:
obs.obs_source_release(filter_)
@contextmanager
def scene_enum(items):
items = obs.obs_scene_enum_items(items)
try:
yield items
finally:
obs.sceneitem_list_release(items)
@contextmanager
def source_auto_release(source_name):
source = obs.obs_get_source_by_name(source_name)
try:
yield source
finally:
obs.obs_source_release(source)
@contextmanager
def new_settings():
newSettings = obs.obs_data_create()
try:
yield newSettings
finally:
obs.obs_data_release(newSettings)
def get_selected_scene(scene_name):
scenes = obs.obs_frontend_get_scenes()
found = False
for scene in scenes:
name = obs.obs_source_get_name(scene)
if name == scene_name:
found = True
obs.source_list_release(scenes)
return found
def item_set_transform1(unused_addr, scene_name, item_name, pos_x=None, pos_y=None,
scl_x=None, scl_y=None, rot=None, alignment=None, visible=None):
if get_selected_scene(scene_name):
with ExitStack() as stack:
selected_scene = stack.enter_context(source_auto_release(scene_name))
scene = stack.enter_context(scene_ar(selected_scene))
scene_item = obs.obs_scene_find_source_recursive(scene, item_name)
if scene_item:
info = obs.obs_transform_info()
obs.obs_sceneitem_get_info(scene_item, info)
if pos_x != None: info.pos.x = pos_x
if pos_y != None: info.pos.y = pos_y
if scl_x != None: info.scale.x = scl_x
if scl_y != None: info.scale.y = scl_y
if rot != None: info.rot = rot
if alignment != None: info.alignment = alignment
obs.obs_sceneitem_set_info(scene_item, info)
if visible != None:
obs.obs_sceneitem_set_visible(scene_item, bool(visible))
def get_scene_context(scene_name):
scenes_list = obs.obs_frontend_get_scenes()
for scene in scenes_list:
name = obs.obs_source_get_name(scene)
if name == scene_name:
return_scene = obs.obs_scene_from_source(scene)
return return_scene
def item_set_transform2(unused_addr, scene_name, item_name, pos_x=None, pos_y=None,
scl_x=None, scl_y=None, rot=None, alignment=None, visible=None):
scene_item = obs.obs_scene_find_source_recursive(get_scene_context(scene_name), item_name)
if scene_item:
info = obs.obs_transform_info()
obs.obs_sceneitem_get_info(scene_item, info)
if pos_x != None: info.pos.x = pos_x
if pos_y != None: info.pos.y = pos_y
if scl_x != None: info.scale.x = scl_x
if scl_y != None: info.scale.y = scl_y
if rot != None: info.rot = rot
if alignment != None: info.alignment = alignment
obs.obs_sceneitem_set_info(scene_item, info)
if visible != None:
obs.obs_sceneitem_set_visible(scene_item, bool(visible))
def script_properties():
props = obs.obs_properties_create()
obs.obs_properties_add_button(
props, "button1", "click to move 'bolita' 1 (and crash!)",
lambda *props: item_set_transform1(None, 'main-juegos', 'bolita', random.randrange(1920), random.randrange(1080))
)
obs.obs_properties_add_button(
props, "button2", "click to move 'bolita' 2",
lambda *props: item_set_transform2(None, 'main-juegos', 'bolita', random.randrange(1920), random.randrange(1080))
)
return props The first button is your code, second is mine. Watch what happens in this video: |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm trying this code:
But, after removing the first sceneitem, OBS crashes. As I'm playing around with your duplicate/reference code, I have lots of sceneitems in scene with the same name. My logic was using
for
in the list of sceneitmes and remove who has'ytchat-group '
at start of the name. Result of this code, in my scene is like this:I know that it's common to make OBS crash when scripting. I think this code is looking for a pointer data that doesn't exist any more. But my knowledge is up to there. Nothing else.
How should I avoid crashing?
Beta Was this translation helpful? Give feedback.
All reactions