如何使用 Python 脚本操作 OBS 场景?OBS 场景对象介绍

我被代码海扁署名-非商业-禁演绎
阅读 9:45·字数 2926·发布 
Bilibili 空间
关注 960

Python 脚本中的 OBS 场景对象

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

什么是 OBS 场景?

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

什么是 OBS 私有场景?

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

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

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

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

来源

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

使用 Python 脚本创建 OBS 场景

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

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

obs_scene_create(name)
obs_scene_create_private(name)

name 参数

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

使用 obs_scene_release 函数释放在 Python 脚本中创建的 OBS 场景对象

对于使用obs_scene_createobs_scene_create_private函数创建的 OBS 场景对象,需要通过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

使用 Python 脚本复制 OBS 场景

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

obs_scene_duplicate(scene, name, type)

scene 参数

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

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 函数释放在 Python 脚本中复制的 OBS 场景对象

对于使用obs_scene_duplicate函数复制的 OBS 场景对象,需要通过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)

使用 Python 脚本转换 OBS 场景对象与来源对象

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

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

obs_scene_get_source(scene)
obs_scene_from_source(source)

scene 参数

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

source 参数

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

使用 Python 脚本为 OBS 场景添加来源

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

obs_scene_add(scene, source)

scene 参数

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

source 参数

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

在下面的代码中,我们创建了一个名称为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)
	# …

使用 Python 脚本清除已移除 OBS 场景中的来源

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

obs_scene_prune_sources(scene)

scene 参数

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

在下面的代码中,我们对场景项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)
	# …

使用 Python 脚本添加和释放对 OBS 场景的引用

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

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

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

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

obs_scene_get_ref(scene)
obs_scene_release(scene)

scene 参数

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

内容分类

源码

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