URLhttps://learnscript.net/zh/obs-python-scripting/scenes/
    复制链接转到说明  示例

    如何操作 OBS 场景?场景对象介绍

    我被代码海扁署名-非商业-禁演绎
    阅读 9:25·字数 2828·更新 

    OBS 场景对象

    场景对象(Scene Objects)与obspython模块提供的场景函数,可用于操作场景。比如,将来源作为场景项添加至场景,或将场景项从场景移除。

    什么是 OBS 场景?

    场景(Scenes)是一种特殊的 OBS 来源,他可以管理由来源产生的场景项,这些场景项可能引用不同或相同的来源,场景项显示的名称即为其对应来源的名称。当多个场景项引用同一个来源时,他们的某些表现将是一致的,比如,显示在来源栏的名称。

    什么是 OBS 私有场景?

    私有场景与私有来源类似,无法被用户直接创建。通过 Python 脚本创建的私有场景不会出现在场景栏,在被添加至非私有场景后可显示在来源栏中。私有场景会在重启后消失,场景集合导出操作将忽略他。

    需要特别指出,如果私有场景拥有非私有来源,那么这些非私有来源可能不会被清除。

    私有场景和非私有场景的命名冲突问题

    由于场景本身就是 OBS 来源,因此,私有场景与非私有场景在命名的问题上,遵守与来源一样的规则。

    来源

    关于 OBS 来源的命名冲突问题,你可以查看OBS 来源对象一段。

    创建 OBS 场景

    与创建 OBS 来源有所不同,创建场景只需要指定场景的名称即可。

    obspython模块的obs_scene_createobs_scene_create_private函数,均可用于创建场景,两者的区别在于,obs_source_create_private函数创建的来源是私有的。

    obs_scene_create(name)
    obs_scene_create_private(name)

    name 参数

    name参数为创建场景的期望名称,当发生命名冲突时,OBS 会修改期望名称,直到冲突消失。

    使用 obs_scene_release 函数释放创建的场景对象

    对于使用obs_scene_createobs_scene_create_private函数创建的场景对象,需要通过obs_scene_release释放引用,否则 OBS 可能会出现错误。

    我们尝试在按钮的回调函数test中,创建一个私有场景sub_scene,并将其作为场景项添加至场景Scene,假设Scene存在。

    scenes.py
    # 导入模块 obspython
    import obspython as obs
    
    def test(props, prop): # 创建一个名称为 sub_scene 的私有场景 scene_sub = obs.obs_scene_create_private('scene_sub') # 获取场景 Scene 对应的场景对象 source_scene = obs.obs_get_source_by_name('Scene') scene = obs.obs_scene_from_source(source_scene) # 将私有场景 sub_scene 添加至场景 Scene obs.obs_scene_add(scene, obs.obs_scene_get_source(scene_sub))
    # 释放场景对象和来源对象 obs.obs_source_release(source_scene) obs.obs_scene_release(scene_sub)
    # 为脚本添加一个用于测试的按钮,回调函数为 test def script_properties(): props = obs.obs_properties_create() obs.obs_properties_add_button(props, 'test', '测试', test) return props

    复制 OBS 场景

    obspython模块的obs_scene_duplicate函数,可用于复制场景,新场景的场景项对应的来源,可能是原场景中场景项对应来源的完全复制或阴影复制。对于阴影复制,新的场景项将与原有场景项共享同一个 OBS 来源,这意味着他们在某些方面的表现会相同。对于原场景中的私有来源,在其被复制到新场景后,依然为私有来源。对于原场景中的非私有来源,在其被复制到新场景后,依然为非私有来源。

    obs_scene_duplicate(scene, name, type)

    scene 参数

    scene参数为被复制的场景对象。

    name 参数

    name参数为新场景的期望名称,当发生命名冲突时,OBS 会修改期望名称,直到冲突消失。

    type 参数

    type参数为场景的复制方式,可使用如下obspython模块变量进行设置,OBS_SCENE_DUP_REFS表示场景中的来源将采用阴影复制,OBS_SCENE_DUP_COPY表示场景中的来源将尝试采用完全复制(对于不支持完全复制的来源,依然采用阴影复制),OBS_SCENE_DUP_PRIVATE_REFSOBS_SCENE_DUP_REFS类似,只不过新的场景将是私有的,OBS_SCENE_DUP_PRIVATE_COPYOBS_SCENE_DUP_COPY类似,只不过新的场景将是私有的。

    使用 obs_scene_release 函数释放复制的场景对象

    对于使用obs_scene_duplicate函数复制的场景对象,需要通过obs_scene_release释放引用,否则 OBS 可能会出现错误。

    在下面的代码中,如果场景(来源)Game不存在,那么会将场景Scene复制为Game,复制的方式为OBS_SCENE_DUP_REFS

    scenes.py
    def test(props, prop):
    	# …
    	# 将场景 Scene 复制为场景 Game,如果场景 Game 不存在
    	source_game = obs.obs_get_source_by_name('Game')
    	if not source_game:
    		scene_game = obs.obs_scene_duplicate(scene, 'Game', obs.OBS_SCENE_DUP_REFS)
    		# 释放场景对象
    		obs.obs_scene_release(scene_game)
    	else:
    		# 释放来源对象
    		obs.obs_source_release(source_game)

    转换 OBS 场景对象与来源对象

    在 OBS Python 脚本中,场景对象一般不与来源对象互换使用,想要获取场景对象对应的来源对象,或来源对象对应的场景对象,需要进行转换。

    obspython模块的obs_scene_get_source函数,可用于获取场景对象对应的来源对象。obspython模块的obs_scene_from_source函数,可用于获取来源对象对应的场景对象,前提是该来源是一个场景。

    obs_scene_get_source(scene)
    obs_scene_from_source(source)

    scene 参数

    scene参数为需要获取来源对象的场景对象。

    source 参数

    source参数为需要获取场景对象的来源对象。

    为 OBS 场景添加来源

    obspython模块的obs_scene_add函数,可用于将 OBS 来源作为场景项添加至场景,并返回一个场景项对象。

    obs_scene_add(scene, source)

    scene 参数

    scene参数为需要添加场景项的场景对象。

    source 参数

    source参数为添加场景项对应的来源对象。

    在下面的代码中,我们创建了一个名称为message的私有文字(GDI+)来源,并通过函数obs_scene_add将其添加到了场景scene_sub中。

    scenes.py
    def test(props, prop):
    	# …
    	# 创建一个文字(GDI+)来源
    	settings = obs.obs_data_create_from_json('{"text":"新消息"}')
    	source_text = obs.obs_source_create_private('text_gdiplus_v2', 'message', settings)
    	# 将文字(GDI+)添加至场景 scene_sub
    	obs.obs_scene_add(scene_sub, source_text)
    	# …

    清除已移除 OBS 场景中的来源

    当一个场景被移除时,其场景项对应的非私有来源依然可能存在,此时可以调用obspython模块的obs_scene_prune_sources函数,来移除这些非私有来源,如果他们没有任何引用的话。

    obs_scene_prune_sources(scene)

    scene 参数

    scene参数为已经被移除的场景对象。

    在下面的代码中,我们对场景项Welcome进行了两次查询,一次包括分组,一次不包括,假设Welcome是分组Group中的场景项。

    scenes.py
    def test(props, prop):
    	# …
    	# 在移除场景 World 之后,尝试移除不再使用的其他来源
    	source_world = obs.obs_get_source_by_name('World')
    	scene_world = obs.obs_scene_from_source(source_world)
    	obs.obs_source_remove(source_world)
    	obs.obs_scene_prune_sources(scene_world)
    	obs.obs_source_release(source_world)
    	# …

    添加和释放对 OBS 场景的引用

    作为一种来源,当场景不存在任何引用时,他将被销毁,如果你没有或过多的进行了场景的释放,那么 OBS 可能会出现错误。obspython模块提供了以下与场景引用相关的函数。

    obs_scene_get_ref函数,可用于为场景对象添加引用。每当你额外调用一次obs_scene_get_ref函数,就需要对等增加一次obs_scene_release函数的调用。

    OBS 27.2.0 之前,应使用函数obs_scene_addref,而非obs_scene_get_ref

    obs_scene_release函数,可用于为场景对象释放引用,他适用于obs_scene_createobs_scene_create_privateobs_scene_duplicate函数所返回的场景对象。

    obs_scene_get_ref(scene)
    obs_scene_release(scene)

    scene 参数

    scene参数为需要添加或释放引用的场景对象。

    内容分类

    源码

    scenes.py·codebeatme/obs-python-scripting·GitHub