URLhttps://learnscript.net/en/obs-python-scripting/scripts/
    Copy LinkGo to Instructions  Example

    How to Write Python Scripts that Run in OBS

    Beatme CodeBY-NC-ND
    17:07 read·2227 words· published

    Prerequisites

    The prerequisite for reading this article is that you have already mastered how to run Python scripts in OBS, you can check out the article How to Configure OBS to Run Python Scripts for information on that.

    Python Script Functions Exported to OBS

    When a Python script has functions with specific names and parameters, OBS will find and use those functions to achieve certain effects, such as displaying a piece of text in OBS that explains what the script does. This connection between Python scripts and OBS is officially known as Script Function Exports.

    Exporting script functions to OBS is optional

    Exporting script functions to OBS is an optional behavior; Python scripts you write can have no functions exported, and this will not affect OBS’s ability to execute the script.

    Display Python Script Description in OBS

    Every Python script that is successfully loaded into OBS will have a description in the Scripts Window. By defining a function called script_description in your script, you can set the description text for that script, and of course, script_description should return a string.

    OBS supports the inclusion of whitespace characters in script descriptions

    The string returned by the script_description function can contain certain whitespace characters, e.g., tabs (\t), and they can be displayed normally in the Scripts Window.

    exports.py
    # Import the obspython module
    import obspython as obs
    
    def script_description(): return 'This is a simple but ineffective script\nAuthor:\toops\nVersion:\t0.1\nContact:\txxx'

    Display Python Script Properties in OBS

    The script_description function is very important when you want Python scripts to be interactive with users, and it needs to return a Property Set object that contains information about the script’s relevant properties. OBS will create a series of controls in the Scripts Window based on the Property Set object returned by script_description, such as textboxes, buttons, checkboxes, and so on. With these controls, users can modify and adjust the script’s properties to change the functionality of the script.

    What are the Script Properties in OBS?

    Script Properties in OBS can refer either to the controls that appear in the Scripts Window or to the objects (Script Property objects) used to create them. Each Script Property corresponds to a Script Setting Item that stores the value of the property, except for button controls.

    What are the Script Settings in OBS?

    Script Settings are stored in a Data Settings object, which reads and writes some data in a manner similar to key-value pairs. There is no official term like “Script Settings” in the official OBS documentation, so we’ll use it for convenience. An item in Script Settings does not necessarily correspond to a Script Property, and although you can influence the functionality of Python scripts based on Script Settings, they’re not visible to users.

    For different Scene Collections, OBS will either save the Script Settings locally in some form at the appropriate time, or reverse the process, so that the Script Settings are made permanent. When a Python script file is removed from the Scripts Window, the corresponding Script Settings are also deleted locally.

    In the function script_properties, we create a Property Set object using obs_properties_create and add a Property object corresponding to the numberbox to the Property Set with obs_properties_add_text.

    exports.py
    def script_properties():
    	# Create a Property Set object
    	props = obs.obs_properties_create()
    
    # Add a Script Property object that corresponds to the numberbox for indicating hours obs.obs_properties_add_int(props, 'hours', 'Hours:', 2, 5, 1) return props

    Perform Tasks when Loading or Unloading Python Scripts in OBS

    If you want to perform certain tasks, such as reading or writing data from or to a file, when a Python script is loaded or unloaded by OBS, then you can define the functions script_load, script_unload in your script.

    script_load(settings)

    settings parameter

    The settings parameter is the Script Settings object corresponding to the Python script.

    When does OBS load or unload Python scripts?

    Scripts will be loaded when you add a script to the Scripts Window, reload a script, restore defaults, or when OBS starts. Scripts will be unloaded when you remove a script from the Scripts Window, reload a script, before restoring defaults, or when OBS is closed.

    In the code below, we record and display the last stop time of the script via the functions script_load and script_unload. In fact, this is ineffective when you close OBS directly, for reasons that will be explained later.

    exports.py
    # The data variable represents the Script Settings
    data = None
    
    def script_load(settings): global data data = settings
    # Read the Script Setting Item closed_time, which is the stop time of the script closed_time = obs.obs_data_get_string(data, 'closed_time') if closed_time: obs.script_log(obs.LOG_INFO, f'The script was last stopped at {closed_time}')
    def script_unload(): # Write the current time to the Script Setting Item closed_time as the stop time of the script from datetime import datetime obs.obs_data_set_string(data, 'closed_time', datetime.now().ctime())
    [exports.py] The script was last stopped at Mon Mar 4 07:12:37 2024

    The obs_data_get_string, obs_data_set_string functions of the obspython module

    The obspython module’s obs_data_get_string and obs_data_set_string functions are used to perform read and write operations on Data Items of string type in the Data Settings object.

    Similar functions include obs_data_get_int, obs_data_set_int, etc.

    Perform Tasks after OBS Users Modify Python Script Properties

    If you want to perform certain tasks after a user modifies Script Properties (via the Scripts Window), e.g., adjusting the implemented functionality according to the modified Script Properties, then you can define the function script_update in the Python script, which is executed at a point in time between the script_load function and the script_unload function.

    It should be noted that any modification of the Script Properties will result in the call of the script_update function. If you are only monitoring changes to one Script Property, then you can use the obs_property_set_modified_callback function of the obspython module.

    script_update(settings)

    settings parameter

    The settings parameter is the Script Settings object corresponding to the Python script.

    When does OBS call the script_update function?

    In addition to being called after a user modifies Python Script Properties, the script_update function is also called when adding a script, reloading a script, restoring defaults, or when OBS is started.

    The values displayed by the controls in the Script Window may not be the same as the values corresponding to the Script Setting Items

    Until a user makes a valid edit to a control in the Scripts Window, the value displayed by the control will not be synchronized to the corresponding Script Setting Item. This can be confusing because the value that the user sees from the control may not be the same as the value you read from the Script Settings. Once the window control corresponding to a Script Property has been validly edited, the value in the corresponding control can be safely read from the Script Settings.

    To avoid the above inconsistencies, you can define the script_defaults function and set the default values for the controls’ corresponding Script Setting Items.

    Previously, in the function script_properties, we added a numberbox with a minimum value of 2, but reading its corresponding Script Setting Item could result in 0 if the numberbox has not been validly edited.

    exports.py
    def script_update(settings):
    	# Read the Script Setting Item hours and display it
    	hours = obs.obs_data_get_int(settings, 'hours')
    	obs.script_log(obs.LOG_INFO, f'The current hours are {hours}')
    [exports.py] The current hours are 0

    Write Data to Python Script Settings when OBS is Closed

    The script_save function in Python scripts is called when OBS is closed, at which point some important data can be written to the Script Settings so that they can be read the next time OBS is started.

    script_save(settings)

    settings parameter

    The settings parameter is the Script Settings object corresponding to the Python script.

    Script Settings written via the script_unload function when OBS is closed are not stored locally

    Although OBS calls the script_unload function when it is closed, writes to Script Setting Items may be “invalidated” because they will not be stored locally by OBS, unlike clicking the Reload Scripts Button in the Scripts Window.

    The best way to save important data is to define the function script_save rather than script_unload, although the previous example demonstrated the opposite.

    Instead of the script_unload function, we use the script_save function, which causes the OBS close time to be considered as the script’s stop time, and the time of other user actions (e.g., clicking the Reload Scripts Button) will no longer be considered as the script’s stop time.

    exports.py
    def script_save(settings):
    	# Write the current time to the Script Setting Item closed_time as the stop time of the script
    	from datetime import datetime
    	obs.obs_data_set_string(settings, 'closed_time', datetime.now().ctime())

    Specify Default Values for Python Script Properties

    In the official obspython module provided with OBS, you can’t specify default values for Script Properties directly via parameters, although some functions that add Script Properties can achieve an approximate effect. To set default values for controls in the Scripts Window, you should define the function script_defaults in the Python script and specify default values for the Script Setting Items corresponding to the Script Properties in that function.

    script_defaults(settings)

    settings parameter

    The settings parameter is the Script Settings object corresponding to the Python script.

    The default value of a Script Setting Item is used only when it has no specific value

    It’s important to note that once a Script Setting Item has a specific value, its default value is no longer used, which happens after a user edits a control, or after you assign a value to a Script Setting Item via a function.

    When you click the Defaults Button in the Scripts Window, the default values of the Script Setting Items will come back to work because the specific values of the Script Setting Items have been cleared.

    In the function script_defaults, we specify the default value of the Script Setting Item hours as 3, which will cause the numberbox in the Scripts Window to display 3 by default. If the numberbox has been edited before, then you will need to click the Defaults Button to see the effect.

    exports.py
    def script_defaults(settings):
    	# Set the default value of the Setting Item hours to 3
    	obs.obs_data_set_default_int(settings, 'hours', 3)

    The obs_data_set_default_int function of the obspython module

    The obs_data_set_default_int function of the obspython module is used to set default values for Data Items of integer type in the Data Settings object.

    Perform Tasks at Each Frame Drawn by OBS

    If you want to perform certain tasks as OBS draws each frame, then you can define the function script_tick in your Python script.

    script_tick(seconds)

    seconds parameter

    The seconds parameter is the number of seconds elapsed from the previous frame to this one.

    Using the script_tick function may cause performance issues for OBS

    OBS calls the script_tick function more frequently, so it is not a good idea to use this function for complex tasks, and OBS may not be able to respond to the user after a long run if you keep outputting information to the Script Log Window via the script_log function.

    The obspython module provides some additional functions for timers, which can be used to avoid problems caused by the script_tick function.

    exports.py
    def script_tick(seconds):
    	obs.script_log(obs.LOG_INFO, f'{seconds} OBS is about to become unresponsive!!!')

    Get the Directory where the Python Script is Located

    For added Python scripts, OBS defines a function called script_path (not part of the obspython module) that can be used to get the directory where the current script is located.

    The difference between the script_path function and the __file__ attribute of Python modules

    The __file__ attribute indicates the file path of the Python module, while the script_path function returns the path to the folder where the script file is located.

    We adjust the previous code to call the script_path function in script_load and display the returned directory.

    exports.py
    def script_load(settings):
    	# …
    	obs.script_log(obs.LOG_INFO, script_path())
    # Output in Windows
    [exports.py] /scripts/

    Add or Remove Script Timers for OBS

    With the timer_add and timer_remove functions of the obspython module, you can add or remove Script Timers for OBS. Script Timers will repeatedly call the given callback function or method at specified intervals, unlike the script_tick function.

    Once the timer_add function has been used, the added Script Timer will start working. If you want the Script Timer to stop, you can remove it with the timer_remove function or call the remove_current_callback function of the obspython module in the callback function or method.

    timer_add(callback, milliseconds)
    timer_remove(callback)

    callback parameter

    The callback parameter is the function or method that is called back by the Script Timer, and in the timer_remove function, the Script Timer corresponding to the callback will be removed.

    milliseconds parameter

    The milliseconds parameter is the time interval in milliseconds at which the timer will be triggered, and accepts a value of integer type.

    The timer_remove function cannot remove the Script Timer corresponding to the instance method

    If a Python function in a module is used as a callback target, timer_add and timer_remove will work correctly, and if an instance method of a Python class is used as a callback target, then timer_remove may fail and its corresponding Script Timer will not be removed.

    In the code below, welcome is the callback function of the Script Timer, and we use remove_current_callback to make this function be called only once.

    exports.py
    # Script Timer callback function welcome
    def welcome():
    	obs.script_log(obs.LOG_INFO, 'This is a callback function that is only called once')
    	# Remove the Script Timer corresponding to welcome
    	obs.remove_current_callback()
    
    # Add a Script Timer with a 3-second interval obs.timer_add(welcome, 3000)
    [exports.py] This is a callback function that is only called once

    Source Code

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