MarioMey / obs-osc-pythonscript

Receive/send OSC messages from/to OBS.
GNU General Public License v3.0
0 stars 0 forks source link

Control OBS-shaderfilter plugin color #2

Open baesek opened 2 years ago

baesek commented 2 years ago

Hi, I am trying to set the color of the shaderfilter plugin via osc. @MarioMey MarioMey, you hinted me to this page.

Check https://github.com/upgradeQ/OBS-Studio-Python-Scripting-Cheatsheet-obspython-Examples-of-API for more commands.

Do you think it is possible to control the color input value that filter with your plugin? I tried to understand the contents of the obs_api.py file but I couldnt really understand.... Is it perhaps possible to just set and delete filters, but adding default settings to it while setting?

Thanks in advance,

MarioMey commented 2 years ago

I think you can do it, but I can't test it here. Booting in Windows gets me sick. Do something: make a scene collection very simple with a scene and a source. Assign the filter to the source and change color by hand. Once you do it, close OBS and copy-paste here the contents of the scene collection JSON file. Look for it in /????/basic/scenes/scene_collection_name.json (I don't know where it should be in your computer, I have in a portable path).

By seeing what's inside that file, we gonna know if you can change that value.

baesek commented 2 years ago

Wow, thanks for your help, i am really in need of it, because I am trying to finish my exam project and I am not really capable of doing it at the moment.

I did what you said and exported the testscene.json : {"current_program_scene":"Szene","current_scene":"Szene","current_transition":"Überblende","groups":[],"modules":{"auto-scene-switcher":{"active":false,"interval":300,"non_matching_scene":"","switch_if_not_matching":false,"switches":[]},"captions":{"enabled":false,"lang_id":1031,"provider":"mssapi","source":""},"decklink_captions":{"source":""},"output-timer":{"autoStartRecordTimer":false,"autoStartStreamTimer":false,"pauseRecordTimer":true,"recordTimerHours":0,"recordTimerMinutes":0,"recordTimerSeconds":30,"streamTimerHours":0,"streamTimerMinutes":0,"streamTimerSeconds":30},"scripts-tool":[{"path":"C:/Users/User/automat-display/obs/obs-osc/obs-osc-pythonscript-main/obs_osc_pythonscript.py","settings":{}}]},"name":"testscene","preview_locked":true,"quick_transitions":[{"duration":300,"fade_to_black":false,"hotkeys":[],"id":4,"name":"Schnitt"},{"duration":300,"fade_to_black":false,"hotkeys":[],"id":5,"name":"Überblende"},{"duration":300,"fade_to_black":true,"hotkeys":[],"id":6,"name":"Überblende"}],"saved_projectors":[],"scaling_enabled":false,"scaling_level":0,"scaling_off_x":0.0,"scaling_off_y":0.0,"scene_order":[{"name":"Szene"}],"sources":[{"balance":0.5,"deinterlace_field_order":0,"deinterlace_mode":0,"enabled":true,"filters":[{"balance":0.5,"deinterlace_field_order":0,"deinterlace_mode":0,"enabled":true,"flags":0,"hotkeys":{},"id":"shader_filter","mixers":0,"monitoring_type":0,"muted":false,"name":"ShaderFilter","prev_ver":452984833,"private_settings":{},"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"settings":{"color":4282795775,"from_file":true,"shader_file_name":"C:/Users/User/automat-display/obs/obs-shaderfilter-custom-plugins/blue-green-test.shader"},"sync":0,"versioned_id":"shader_filter","volume":1.0}],"flags":0,"hotkeys":{},"id":"image_source","mixers":0,"monitoring_type":0,"muted":false,"name":"Bild","prev_ver":452984833,"private_settings":{},"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"settings":{"file":"C:/Users/User/automat-display/encode-16bit-exr/test.png"},"sync":0,"versioned_id":"image_source","volume":1.0},{"balance":0.5,"deinterlace_field_order":0,"deinterlace_mode":0,"enabled":true,"flags":0,"hotkeys":{"OBSBasic.SelectScene":[],"libobs.hide_scene_item.Bild":[],"libobs.show_scene_item.Bild":[]},"id":"scene","mixers":0,"monitoring_type":0,"muted":false,"name":"Szene","prev_ver":452984833,"private_settings":{},"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"settings":{"custom_size":false,"id_counter":1,"items":[{"align":5,"bounds":{"x":0.0,"y":0.0},"bounds_align":0,"bounds_type":0,"crop_bottom":0,"crop_left":0,"crop_right":0,"crop_top":0,"group_item_backup":false,"hide_transition":{"duration":0},"id":1,"locked":false,"name":"Bild","pos":{"x":0.0,"y":0.0},"private_settings":{},"rot":0.0,"scale":{"x":1.0,"y":1.0},"scale_filter":"disable","show_transition":{"duration":0},"visible":true}]},"sync":0,"versioned_id":"scene","volume":1.0}],"transition_duration":300,"transitions":[]}

before I did that I already tried this python: client.send_message("/source_filter_set_value", ["Bild", "shader_filter", "color", '\x1b[38;5;129m']) and I got this in the obs python scriptlog: [Unknown Script] Filter no existe: shader_filter actually I also dont know what kind of color value that is in the testscene.json 4282795775 ? (I selected the color #FF4646)

crazy!! It worked but I only dont know what kind of color value it is this is the code client.send_message("/source_filter_set_value", ["Bild", "ShaderFilter", "color", 22222 ])

Finally I could solve it by calculating the color like described here : lient.send_message("/source_filter_set_value", ["Bild", "ShaderFilter", "color", int("0xFF0000", 0) ])

But ATTENTION!!!: the Color Values are ordered BGR not RGB so this color is a Blue

Thank you so much for the hint, with that procedure of creating the empty testscene!

MarioMey commented 2 years ago

Pull this git again and use like this: client.send_message("/source_filter_set_value", ["Bild", "ShaderFilter", "color", [1,0,0,1]) Send color in a list as [R,G,B,A]. It uses rgb2decimal() function (that I made) that converts RGBA list to that "magic" number.

baesek commented 2 years ago

I cannot do this on windows, otherwise I would have to repeat all those changes I mentioned here: https://github.com/MarioMey/obs-osc-pythonscript/issues/1#issuecomment-897470698

I get the following message again scriptlog under windows 10 [obs_osc_pythonscript.py] ModuleNotFoundError: No module named 'obs_osc_pythonscript' [obs_osc_pythonscript.py] Traceback (most recent call last): [obs_osc_pythonscript.py] File "C:/Users/User/automat-display/obs/obs-osc/obs-osc-pythonscript-main\obs_osc_pythonscript.py", line 36, in <module> [obs_osc_pythonscript.py] from obs_osc_api import ( [obs_osc_pythonscript.py] ModuleNotFoundError: No module named 'obs_osc_api'

I just manually updated my obs_osc_api.py with that function (rgba2decimal) thanks for that hint too.

MarioMey commented 2 years ago

Ok, the manual fix is to update source_set_setting() to this:

def source_set_setting(unused_addr, source_name, setting, value, private=False):
    c2(f'source_set_setting(source_name="{source_name}", setting="{setting}", value="{value}", private={private})')
    with ExitStack() as stack:

        if not private:
            source = stack.enter_context(source_auto_release(source_name))
        else:
            source = globals()[source_name]

        if source:
            newSettings = stack.enter_context(new_settings())
            if   type(value) == bool:
                obs.obs_data_set_bool(newSettings, setting, value)

            elif type(value) == str and (value == 'true' or value == 'True'):
                obs.obs_data_set_bool(newSettings, setting, True)

            elif type(value) == str and (value == 'false' or value == 'False'):
                obs.obs_data_set_bool(newSettings, setting, False)

            elif type(value) == str:
                obs.obs_data_set_string(newSettings, setting, value)

            elif type(value) == int:
                obs.obs_data_set_int(newSettings, setting, value)

            elif type(value) == float:
                obs.obs_data_set_double(newSettings, setting, value)

            # The new part!!!
            elif type(value) == list:
                value = rgba2decimal(value)
                obs.obs_data_set_int(newSettings, setting, value)

            obs.obs_source_update(source, newSettings)
        else: print(f'Source no existe: {source_name}')

The new part is the value argument as a list. So, you call the function with a RGBA list, function converts it with rgba2decimal() and set the setting as an int.