URLhttps://learnscript.net/zh-hant/obs-python-scripting/sources/
    複製連結移至說明  範例

    如何操作 OBS 來源?來源物件介紹

    閱讀 24:50·字數 7453·發佈 
    Youtube 頻道
    訂閱 375

    OBS 來源物件

    通過 OBS 來源物件(Source Objects)以及obspython模組提供的函式,你可以在 Python 腳本中操作 OBS 來源。

    什麽是 OBS 來源?

    OBS 中的來源(Sources)主要用於算繪視訊串流和音訊串流,這包括顯示器擷取,視窗擷取,圖片,場景,濾鏡,轉場特效等。

    什麽是 OBS 私用來源?

    與一般來源不同,使用者無法直接建立私用來源。私用來源無法被obs_enum_sources函式列舉,也無法被obs_save_sources函式儲存,這意味任何涉及儲存場景群組的操作,都將忽略私用來源和由其產生的場景項。

    私用來源和非私用來源的命名沖突問題

    由於存在 OBS 來源的建立和複製操作,因此來源之間可能會發生命名上的沖突,無論這是來自於使用者還是 Python 腳本,他們大體上會遵守以下規則。私用來源之間,以及私用來源與非私用來源之間不會檢測命名沖突。非私用來源之間會檢測命名沖突,不同的非私用來源不能具有相同的名稱。

    雖然允許私用來源與非私用來源同名,但這種情況應盡量避免,因為他們可能導致一些詭異的問題。

    建立 OBS 來源

    obspython模組提供了以下函式,用於建立新的來源。

    obs_source_createobs_source_create_private函式,可以使用指定的來源類型和來源設定建立來源,建立失敗時會傳回空值None。兩者的區別在於,obs_source_create_private函式會建立私用來源。

    obs_source_create(id, name, settings, hotkey_data)
    obs_source_create_private(id, name, settings)

    id 參數

    id參數為來源類型識別碼,他將決定建立來源的類型。

    name 參數

    name參數為建立來源的期望名稱,當發生命名沖突時,OBS 會修改期望名稱,直到沖突消失。

    settings 參數

    settings參數是一個資料設定物件,他表示了來源的設定,其包含的內容由來源類型確定。如果指定為None,則會采用來源的預設設定。

    hotkey_data 參數

    hotkey_data參數是一個資料設定物件,他表示了來源對應的快速鍵,可以被指定為None

    什麽是 OBS 來源設定?

    和腳本設定類似,OBS 來源設定也是一個資料設定物件,顧名思義,他決定了來源的相關設定,比如,圖片來源對應的圖片檔案路徑。

    什麽是 OBS 來源類型識別碼?

    OBS 的每一種來源都對應了一個來源類型識別碼(Source Type Identifiers),該識別碼可以有效區分不同類型的來源。比如,文字(GDI+)的來源類型識別碼為text_gdiplus,圖片的來源類型識別碼為image_source

    使用 obs_source_release 函式釋放建立的來源物件

    對於使用obs_source_createobs_source_create_private函式建立的來源物件,需要通過obs_source_release釋放參考,否則 OBS 可能會出現錯誤。

    我們嘗試在按鈕的回呼函式test中,建立一個私用文字(GDI+)來源,並通過資料設定物件對來源進行設定,最後將文字(GDI+)作為場景項新增到場景Scene中,假設Scene存在。這裏涉及到與場景相關的函式,但由於篇幅限製,不再進行說明。

    sources.py
    # 匯入模組 obspython
    import obspython as obs
    
    def test(props, prop): # 建立一個名稱為 my_text 的私用文字(GDI+)來源,並將字串 "今天天氣不錯!" 設定為文字 settings = obs.obs_data_create_from_json('{"text":"今天天氣不錯!"}') source_text = obs.obs_source_create_private('text_gdiplus', 'my_text', settings)
    # 將文字(GDI+)來源,新增至名為 Scene 的場景 source_scene = obs.obs_get_source_by_name('Scene') scene = obs.obs_scene_from_source(source_scene) obs.obs_scene_add(scene, source_text)
    # 釋放來源物件和來源設定物件 obs.obs_source_release(source_scene) obs.obs_source_release(source_text) obs.obs_data_release(settings)
    # 為腳本新增一個用於測試的按鈕,回呼函式為 test def script_properties(): props = obs.obs_properties_create() obs.obs_properties_add_button(props, 'test', '測試', test) return props

    複製 OBS 來源

    obspython模組的obs_source_duplicate函式,可用於複製來源。

    這裏需要指出,如果來源不支援完全複製,那麽obs_source_duplicate函式所傳回的來源是對原有來源的參考。

    obs_source_duplicate(source, desired_name, create_private)

    source 參數

    source參數為被複製的來源物件。

    desired_name 參數

    desired_name參數為新來源的期望名稱,當發生命名沖突時,OBS 會修改期望名稱,直到沖突消失。

    create_private 參數

    create_private參數表示新來源是否為私用來源,僅對完全複製的來源生效,采用參考方式得到的新來源無法成為私用來源。

    使用 obs_source_release 函式釋放複製的來源物件

    對於使用obs_source_duplicate函式複製的來源物件,需要通過obs_source_release釋放參考,否則 OBS 可能會出現錯誤。

    在下面的程式碼中,我們對已有的來源Welcome進行了複製,由於並未將複製得到的新來源新增至場景,因此他無法作為場景項顯示在 OBS 視窗中。

    sources.py
    def test(props, prop):
    	# …
    	# 複製名稱為 Welcome 的來源,並指定新名稱 Bye
    	welcome = obs.obs_get_source_by_name('Welcome')
    	bye = obs.obs_source_duplicate(welcome, 'Bye', False)
    
    # 釋放來源 Welcome 和 Bye obs.obs_source_release(welcome) obs.obs_source_release(bye)

    取得 OBS 來源

    obspython模組的obs_get_source_by_name函式,可用於取得指定名稱的來源(物件)。

    obs_get_source_by_name(name)

    name 參數

    name參數為來源的名稱。

    obspython模組的obs_get_source_by_uuid函式,可用於取得指定 UUID 的 OBS 來源(物件),UUID 會在來源被建立時自動分配,不同來源的 UUID 不會相同。

    obs_get_source_by_uuid(uuid)

    uuid 參數

    uuid參數為來源的 UUID。

    如何取得私用來源?

    你需要使用obs_get_source_by_uuid函式而非obs_get_source_by_name來取得一個私用來源,因此,通過obs_source_get_uuid函式記錄所建立的私用來源的 UUID 是必要的。

    使用 obs_data_release 函式釋放取得的來源物件

    對於使用obs_get_source_by_nameobs_get_source_by_uuid函式取得的來源物件,需要通過obs_source_release釋放參考,否則 OBS 可能會出現錯誤。

    取得和設定 OBS 來源的設定

    正如之前提到的,OBS 來源設定是一個資料設定物件,該物件的作用類似於 Python 腳本的腳本設定物件,他是實作通過腳本操作來源的關鍵要素之一,不同類型的來源,其來源設定物件所包含的內容會有所差異。obspython模組提供了以下關於來源設定的函式。

    obs_source_get_settings函式,可用於取得來源對應的來源設定物件,obs_source_get_private_settings函式,可用於取得來源對應的私用來源設定物件,該物件應存放不希望對使用者公開的設定。

    obs_source_get_settings(source)
    obs_source_get_private_settings(item)

    source 參數

    source參數為需要取得來源設定物件的來源物件。

    item 參數

    item參數為需要取得私用來源設定物件的來源物件。

    obs_source_update函式,可用於更新來源的來源設定物件,這將直接改變來源在 OBS 中的行為或表現,當然,對於某些類型的來源,改變帶來的效果可能不會立即顯現。

    obs_source_reset_settings函式,可用於重設和更新來源的來源設定物件,清除現有來源設定的工作會首先進行,這意味著所有的設定都將恢復為預設。

    obs_source_update(source, settings)
    obs_source_reset_settings(source, settings)

    source 參數

    source參數為需要更新或重設更新來源設定物件的來源物件。

    settings 參數

    settings參數為用於更新來源設定物件的資料設定物件。

    obs_get_source_defaults函式,可用於取得某類型來源的來源設定預設值,預設值將被包含在一個新的 OBS 來源設定物件(資料設定物件)中傳回。

    obs_get_source_defaults(id)

    id 參數

    id參數為來源類型識別碼,obs_get_source_defaults函式將傳回該識別碼對應的來源類型的來源設定預設值。

    使用 obs_data_release 函式釋放取得的來源設定物件

    對於使用obs_source_get_settingsobs_source_get_private_settingsobs_get_source_defaults函式取得的來源設定物件,需要通過obs_data_release釋放參考,否則 OBS 可能會出現錯誤。

    調整之前的程式碼,我們通過obs_source_get_settingsobs_source_update函式,更新了Welcome來源的文字。

    sources.py
    def test(props, prop):
    	# …
    	# 通過 Welcome 的來源設定物件,修改其對應的文字
    	settings = obs.obs_source_get_settings(welcome)
    	obs.obs_data_set_string(settings, 'text', '你好,歡迎!')
    	obs.obs_source_update(welcome, settings)
    	# 釋放來源設定物件
    	obs.obs_data_release(settings)
    	# …

    取得 OBS 來源的原始寬度和高度

    obspython模組的obs_source_get_widthobs_source_get_height函式,可用於取得來源的原始寬度和高度,這並不會將轉場特效計算在內,因此obs_source_get_widthobs_source_get_height函式所傳回的並非來源對應場景項的實際顯示大小。

    obs_source_get_width(source)
    obs_source_get_height(source)

    source 參數

    source參數為需要取得原始寬度或高度的來源物件。

    sources.py
    def test(props, prop):
    	# …
    	# 顯示 Weclome 來源的大小
    	width = obs.obs_source_get_width(welcome)
    	height = obs.obs_source_get_height(welcome)
    	obs.script_log(obs.LOG_INFO, f'Welcome 的大小 {width}x{height}')
    	# …
    [sources.py] Welcome 的大小 1520x264

    判斷 OBS 來源是否有效

    OBS 來源的有效狀態用於指示其是否被用於算繪輸出,處於無效狀態的來源並未真正的參與算繪,比如,當使用者將場景項隱藏時,其對應的來源可能將處於無效狀態。需要說明的是,是否處於有效狀態與來源是否可用無關。

    obspython模組的obs_source_active函式,可用於判斷來源是否處於有效狀態,傳回True表示來源處於有效狀態,傳回False表示來源處於無效狀態。

    obs_source_active(source)

    source 參數

    source參數為需要判斷有效狀態的來源物件。

    取得和設定 OBS 來源是否可用

    obspython模組的obs_source_enabledobs_source_set_enabled函式,可用於取得和設定來源是否可用(啟用或停用)。對於不可用的來源,不會在算繪中產生任何效果。需要說明的是,是否可用並不影響來源的有效狀態。

    obs_source_enabled(source)
    obs_source_set_enabled(source, enabled)

    source 參數

    source參數為需要取得或設定是否可用的來源物件。

    enabled 參數

    enabled參數為True時,將啟用來源,為False時,將停用來源。

    取得和設定 OBS 來源是否可見

    obspython模組的obs_source_showing函式與obs_source_active類似,可判斷來源是否已經被算繪至最終輸出,只不過obs_source_showing的傳回結果,可以通過obs_source_inc_showingobs_source_dec_showing函式進行幹預。

    obs_source_showing(source)

    source 參數

    source參數為需要判斷是否可見的來源物件。

    obspython模組的obs_source_inc_showingobs_source_dec_showing函式,可增加或減少來源的可見計數,這將最終影響obs_source_showing的傳回結果。需要說明的是,雖然可通過obs_source_inc_showingobs_source_dec_showing控製obs_source_showing的傳回結果,但最終輸出可能不會改變。

    obs_source_inc_showing(source)
    obs_source_dec_showing(source)

    source 參數

    source參數為需要增加或減少可見計數的來源物件。

    取得和設定 OBS 來源的名稱

    obspython模組的obs_source_get_nameobs_source_set_name函式,可用於取得或設定來源的名稱,該名稱可顯示在 OBS 的相關視窗中。

    obs_source_get_name(source)
    obs_source_set_name(source, name)

    source 參數

    source參數為需要取得或設定名稱的來源物件。

    name 參數

    name參數為修改後的名稱,如果存在命名沖突,那麽 OBS 會對名稱進行修改,直到沖突消失。

    下面的程式碼,通過obs_source_set_name函式將名稱為Groups的來源改名為Group,假設存在群組來源Groups

    sources.py
    def test(props, prop):
    	# …
    	# 如果存在名稱為 Groups 的來源,則將其改名為 Group
    	groups = obs.obs_get_source_by_name('Groups')
    	if groups:
    		obs.obs_source_set_name(groups, 'Group')
    		obs.obs_source_release(groups)

    取得 OBS 來源的類型

    obspython模組的obs_source_get_type函式,可用於取得來源的類型,其傳回值可能對應以下某個obspython模組變數,OBS_SOURCE_TYPE_INPUT(輸入,一般來源均為此類型),OBS_SOURCE_TYPE_FILTER(濾鏡),OBS_SOURCE_TYPE_TRANSITION(轉場特效),OBS_SOURCE_TYPE_SCENE(場景)。

    obs_source_get_type(source)

    source 參數

    source參數為需要取得類型的來源物件。

    另外,obspython模組的obs_source_is_scene函式,可用於判斷來源是否為場景,obspython模組的obs_source_is_group函式,可用於判斷來源是否為群組。

    obs_source_is_scene(source)
    obs_source_is_group(source)

    source 參數

    source參數為需要判斷是否為場景或群組的來源物件。

    在下面的程式碼中,我們取得了來源Groups的類型,並判斷其是否為群組。從輸出的結果可以得知,群組的類型為OBS_SOURCE_TYPE_SCENE

    sources.py
    def test(props, prop):
    	# …
    	# 顯示 Group 來源的類型,並判斷是否為群組
    	group = obs.obs_get_source_by_name('Group')
    	group_type = obs.obs_source_get_type(group)
    	obs.script_log(obs.LOG_INFO, f'Group 的類型 {group_type},等於 OBS_SOURCE_TYPE_SCENE?{group_type == obs.OBS_SOURCE_TYPE_SCENE}')
    	obs.script_log(obs.LOG_INFO, f'Group 是群組?{obs.obs_source_is_group(group)}')
    	obs.obs_source_release(group)
    [sources.py] Group 的類型 3,等於 OBS_SOURCE_TYPE_SCENE?True
    [sources.py] Group 是群組?True

    取得和設定 OBS 來源的 ID

    obspython模組的obs_source_get_idobs_source_get_unversioned_id函式,可用於取得來源的來源類型識別碼,二者的區別在於是否帶有版本資訊。

    obs_source_get_id(source)
    obs_source_get_unversioned_id(source)

    source 參數

    source參數為需要取得來源類型識別碼的來源物件。

    obspython模組的obs_source_get_uuid函式,可用於取得來源的 UUID,每一個來源都擁有一個唯一的 UUID。

    obs_source_get_uuid(source)

    source 參數

    source參數為需要取得 UUID 的來源物件。

    sources.py
    def test(props, prop):
    	# …
    	# 顯示 Weclome 來源的來源類型識別碼和 UUID
    	v_id = obs.obs_source_get_id(welcome)
    	id = obs.obs_source_get_unversioned_id(welcome)
    	obs.script_log(obs.LOG_INFO, f'Welcome 的 id {v_id} {id}')
    	uuid = obs.obs_source_get_uuid(welcome)
    	obs.script_log(obs.LOG_INFO, f'Welcome 的 uuid {uuid}')
    	# …
    [sources.py] Welcome 的 id text_gdiplus_v2 text_gdiplus
    [sources.py] Welcome 的 uuid 84808b04-9373-4c21-b3b8-c506bbc8effb

    移除 OBS 來源

    當你不再需要某個來源時,可以使用obspython模組的obs_source_remove函式將其移除,這會使該來源以及該來源產生的場景項立即從 OBS 的相關視窗中消失,比如來源列

    obs_source_remove(source)

    source 參數

    source參數為需要移除的來源物件。

    obspython模組的obs_source_removed函式,可用於判斷來源是否已經被移除,傳回True表示已經被移除。

    obs_source_removed(source)

    source 參數

    source參數為需要判斷是否被移除的來源物件。

    被 obs_source_remove 函式移除的來源依然可能存在

    這裏需要指出,被obs_source_remove函式移除的來源,如果未釋放所有的參考,那麽他依然可以在 Python 腳本中存取,比如,通過obs_get_source_by_name取得。

    下面的程式碼,移除了來源Screen,假設群組Group包含該來源。

    sources.py
    def test(props, prop):
    	# …
    	# 來源 Screen 如果存在,則將其移除
    	screen = obs.obs_get_source_by_name('Screen')
    	if screen:
    		obs.obs_source_remove(screen)
    		obs.script_log(obs.LOG_INFO, f'Screen 被移除?{obs.obs_source_removed(screen)}')
    [sources.py] Screen 被移除?True

    新增和釋放對 OBS 來源的參考

    如果一個來源(物件)不存在任何參考,那麽該來源將被終結,毫無疑問,這增加了 Python 腳本的編寫難度,沒有或過多的釋放參考,均可能導致 OBS 發生例外狀況。假設,你不小心對來源進行了過多的釋放,那麽一個錯誤視窗可能在所難免。obspython模組提供了以下與來源參考相關的函式。

    obs_source_get_ref函式(OBS 27.2.0 之前為obs_source_addref函式),可用於為來源物件新增參考。每當你額外呼叫一次obs_source_get_ref函式,就需要對等增加一次obs_source_release函式的呼叫。

    OBS 27.2.0 之前,應使用函式obs_source_addref,而非obs_source_get_ref

    obs_source_release函式,可用於為來源物件釋放參考,他適用於obs_source_createobs_source_create_privateobs_source_duplicateobs_get_source_by_nameobs_get_source_by_uuidobs_source_get_filter_by_nameobs_get_transition_by_name函式所傳回的來源物件。

    obs_source_get_ref(source)
    obs_source_release(source)

    source 參數

    source參數為需要新增或釋放參考的來源物件。

    取得和設定 OBS 來源是否隱藏

    如果希望新增一些對使用者不公開的來源,那麽可將其設定為隱藏,隱藏來源產生的場景項不會出現在來源列中,也不會作為場景的一部分儲存,這意味著你總是需要在適當的時機建立並新增他們。

    obspython模組的obs_source_is_hidden函式,可用於判斷來源是否對使用者隱藏,傳回False表示不隱藏,True表示隱藏。obspython模組的obs_source_set_hidden函式,可用於設定來源是否對使用者隱藏,該函式需要在場景項顯示在來源列之前呼叫,否則其效果不會是立即的。

    obs_source_is_hidden(source)
    obs_source_set_hidden(source, hidden)

    source 參數

    source參數為需要設定是否隱藏的來源物件。

    hidden 參數

    hidden參數表示是否隱藏,False表示不隱藏,True表示隱藏。

    取得和設定 OBS 來源的輸出旗標

    obspython模組的obs_source_get_output_flagsobs_get_source_output_flags函式,可用於取得來源類型的輸出旗標,輸出旗標表示了該類型的來源所具備的功能,你可以將其視為一組列舉成員的組合(雖然並不是真正的列舉)。由於篇幅限製,這裏不再詳細解釋他們。

    obs_source_get_output_flags(source)
    obs_get_source_output_flags(id)

    source 參數

    source參數是一個來源物件,obs_source_get_output_flags函式將傳回該物件對應的來源類型的輸出旗標。

    id 參數

    id參數為來源類型識別碼,obs_get_source_output_flags函式將傳回該識別碼對應的來源類型的輸出旗標。

    在下面的程式碼中,我們通過obs_source_get_output_flags函式取得了媒體來源Video的輸出旗標,並判斷其是否具有視訊和音訊功能。

    sources.py
    def test(props, prop):
    	# …
    	# 判斷來源 Video 的輸出旗標
    	video = obs.obs_get_source_by_name('Video')
    	flags = obs.obs_source_get_output_flags(video)
    	obs.script_log(obs.LOG_INFO, f'Video 具有視訊功能?{flags & obs.OBS_SOURCE_VIDEO == obs.OBS_SOURCE_VIDEO}')
    	obs.script_log(obs.LOG_INFO, f'Video 具有音訊功能?{flags & obs.OBS_SOURCE_AUDIO == obs.OBS_SOURCE_AUDIO}')
    	obs.obs_source_release(video)
    [sources.py] Video 具有視訊功能?True
    [sources.py] Video 具有音訊功能?True

    取得 OBS 來源類型的顯示名稱

    obspython模組的obs_source_get_display_name函式,可用於取得指定來源類型對應的顯示名稱,該函式的傳回值由目前 OBS 的語言來確定。

    obs_source_get_display_name(id)

    id 參數

    id參數為某個來源類型識別碼,比如text_gdiplus,這將使obs_source_get_display_name函式傳回字串'文字 (GDI+)',如果 OBS 語言為中文的話。

    內容分類

    原始碼

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