-
-
Save Windows81/76c13c3ec634d4c28ea27323c7da8eab to your computer and use it in GitHub Desktop.
Lua script for Advanced Scene Switcher (on OBS) to make the video scale fully to "Display Capture"; also moving other elements without scaling them
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local obs = obslua | |
| local WIDTH_OFFSET_BEFORE = 0 | |
| local WIDTH_OFFSET_AFTER = 0 | |
| local HEIGHT_OFFSET_BEFORE = 120 | |
| local HEIGHT_OFFSET_AFTER = 0 | |
| local SCREEN_SCALAR = 2 | |
| function transform(sceneitem, x, y, w, h) | |
| local transform_info = obs.obs_transform_info() | |
| obs.vec2_set(transform_info.pos, x, y) | |
| obs.vec2_set(transform_info.scale, w, h) | |
| transform_info.alignment = 5 -- OBS_ALIGN_LEFT | OBS_ALIGN_TOP | |
| obs.obs_sceneitem_set_info2(sceneitem, transform_info) | |
| end | |
| function get_video_scale(config) | |
| local base_width = obs.config_get_uint(config, "Video", "BaseCX") | |
| local base_height = obs.config_get_uint(config, "Video", "BaseCY") | |
| local output_width = obs.config_get_uint(config, "Video", "OutputCX") | |
| local output_height = obs.config_get_uint(config, "Video", "OutputCY") | |
| return { | |
| base = { | |
| w = base_width, | |
| h = base_height, | |
| }, | |
| scale = { | |
| w = output_width / base_width, | |
| h = output_height / base_height, | |
| }, | |
| } | |
| end | |
| function get_sceneitem_transform(sceneitem) | |
| local transform_info = obs.obs_transform_info() | |
| obs.obs_sceneitem_get_info2(sceneitem, transform_info) | |
| return transform_info | |
| end | |
| function get_source_scale(source) | |
| return { | |
| w = obs.obs_source_get_width(source), | |
| h = obs.obs_source_get_height(source), | |
| } | |
| end | |
| function get_all_sceneitems_in_all_scenes() | |
| local result = {} | |
| local scene_list = obs.obs_frontend_get_scenes() | |
| for _, source in next, scene_list do | |
| local sceneitem_list = obs.obs_scene_enum_items(obs.obs_scene_from_source(source)) | |
| obs.script_log(obs.LOG_WARNING, tostring(sceneitem_list)) | |
| for _, sceneitem in next, sceneitem_list do | |
| table.insert(result, sceneitem) | |
| end | |
| obs.obs_source_release(source) | |
| end | |
| return result | |
| end | |
| function calc_new_pos( | |
| transform_info, | |
| old_w, | |
| old_h, | |
| new_w, | |
| new_h, | |
| offset_w_before, | |
| offset_h_before, | |
| offset_w_after, | |
| offset_h_after | |
| ) | |
| local function determine_alpha(pos, size, start, finish) | |
| if pos > finish then | |
| return 1 | |
| end | |
| return 0 | |
| --[[ | |
| local alpha = (pos - start) / (finish - start) - size | |
| if alpha < 0 then | |
| return 0 | |
| elseif alpha > 1 then | |
| return 1 | |
| end | |
| return alpha | |
| ]] | |
| end | |
| local pos_x = transform_info.pos.x | |
| local pos_y = transform_info.pos.y | |
| local scene_w = transform_info.scale.x | |
| local scene_h = transform_info.scale.y | |
| local delta_w = new_w - old_w | |
| local delta_h = new_h - old_h | |
| return { | |
| x = pos_x + delta_w * determine_alpha(pos_x, scene_w, offset_w_before, old_w - offset_w_after), | |
| y = pos_y + delta_h * determine_alpha(pos_y, scene_h, offset_h_before, old_h - offset_h_after), | |
| } | |
| end | |
| function calc_new_scale(transform_info, old_w, old_h, new_w, new_h) | |
| local scalar = old_h / new_h | |
| return { | |
| x = transform_info.scale.x * scalar, | |
| y = transform_info.scale.y * scalar, | |
| } | |
| end | |
| function run() | |
| local scene_source = obs.obs_frontend_get_current_scene() | |
| local scene = obs.obs_scene_from_source(scene_source) | |
| local display_sceneitem = obs.obs_scene_find_source(scene, "Display Capture") | |
| local display_source = obs.obs_sceneitem_get_source(display_sceneitem) | |
| local display_size = get_source_scale(display_source) | |
| local sceneitem_list = get_all_sceneitems_in_all_scenes() | |
| local sceneitem_transform_dict = {} | |
| for i, sceneitem in next, sceneitem_list do | |
| if sceneitem ~= display_sceneitem then | |
| sceneitem_transform_dict[sceneitem] = get_sceneitem_transform(sceneitem) | |
| end | |
| end | |
| local config = obs.obs_frontend_get_profile_config() | |
| local video_scale = get_video_scale(config) | |
| local total_width = SCREEN_SCALAR * display_size.w + WIDTH_OFFSET_BEFORE + WIDTH_OFFSET_AFTER | |
| local total_height = SCREEN_SCALAR * display_size.h + HEIGHT_OFFSET_BEFORE + HEIGHT_OFFSET_AFTER | |
| obs.config_set_uint(config, "Video", "BaseCX", total_width) | |
| obs.config_set_uint(config, "Video", "BaseCY", total_height) | |
| obs.config_set_uint(config, "Video", "OutputCX", total_width) | |
| obs.config_set_uint(config, "Video", "OutputCY", total_height) | |
| obs.obs_frontend_reset_video() | |
| obs.config_save(config) | |
| obs.obs_source_release(scene_source) | |
| for sceneitem, sceneitem_transform in next, sceneitem_transform_dict do | |
| local new_pos = calc_new_pos( | |
| sceneitem_transform, | |
| video_scale.base.w, | |
| video_scale.base.h, | |
| total_width, | |
| total_height, | |
| WIDTH_OFFSET_BEFORE, | |
| HEIGHT_OFFSET_BEFORE, | |
| WIDTH_OFFSET_AFTER, | |
| HEIGHT_OFFSET_AFTER | |
| ) | |
| local new_scale = | |
| calc_new_scale(sceneitem_transform, video_scale.base.w, video_scale.base.h, total_width, total_height) | |
| obs.vec2_set(sceneitem_transform.pos, new_pos.x, new_pos.y) | |
| obs.vec2_set(sceneitem_transform.scale, new_scale.x, new_scale.y) | |
| obs.obs_sceneitem_set_info2(sceneitem, sceneitem_transform) | |
| end | |
| transform(display_sceneitem, WIDTH_OFFSET_BEFORE, HEIGHT_OFFSET_BEFORE, SCREEN_SCALAR, SCREEN_SCALAR) | |
| obs.sceneitem_list_release(sceneitem_list) | |
| --obs.script_log(obs.LOG_WARNING, tostring(obs.config_get_uint(config, "Video", "BaseCY"))) | |
| return true | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment