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.
-
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