如何使用 Python 腳本操作 OBS 場景?OBS 場景物件介紹
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_create
和obs_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_create
或obs_scene_create_private
函式建立的 OBS 場景物件,需要通過obs_scene_release
釋放參考,否則 OBS 可能會出現錯誤。
我們嘗試在按鈕的回呼函式test
中,建立一個私用場景sub_scene
,並將其作為場景項新增至場景Scene
,假設Scene
存在。
# 匯入模組 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_REFS
與OBS_SCENE_DUP_REFS
類似,只不過新的場景將是私用的,OBS_SCENE_DUP_PRIVATE_COPY
與OBS_SCENE_DUP_COPY
類似,只不過新的場景將是私用的。
使用 obs_scene_release 函式釋放在 Python 腳本中複製的 OBS 場景物件
對於使用obs_scene_duplicate
函式複製的 OBS 場景物件,需要通過obs_scene_release
釋放參考,否則 OBS 可能會出現錯誤。
在下面的程式碼中,如果場景(來源)Game
不存在,那麽會將場景Scene
複製為Game
,複製的方式為OBS_SCENE_DUP_REFS
。
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
中。
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
中的場景項。
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_create
,obs_scene_create_private
,obs_scene_duplicate
函式所傳回的 OBS 場景物件。
obs_scene_get_ref(scene)
obs_scene_release(scene)
- scene 參數
scene
參數為需要新增或釋放參考的 OBS 場景物件。