Last active
June 23, 2020 04:57
-
-
Save patrickmineault/a59f792b28c0016e57fcaf19e4bf1086 to your computer and use it in GitHub Desktop.
Place things
This file contains 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
--Made by a completely reasonable person for 100% legitimate reasons. | |
obs = obslua | |
screen = "" | |
webcam = "" | |
-- A very useful debug method | |
function log(message) | |
obs.script_log(obs.LOG_INFO, message) | |
end | |
function script_update(settings) | |
screen = obs.obs_data_get_string(settings, "screen") | |
webcam = obs.obs_data_get_string(settings, "webcam") | |
end | |
function script_properties() | |
local props = obs.obs_properties_create() | |
local p = obs.obs_properties_add_list(props, "screen", "Full screen capture", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) | |
local q = obs.obs_properties_add_list(props, "webcam", "Webcam", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) | |
local sources = obs.obs_enum_sources() | |
if sources ~= nil then | |
for _, source in ipairs(sources) do | |
local source_id = obs.obs_source_get_id(source) | |
-- Win name or Mac name | |
if (source_id == "monitor_capture") or (source_id == "display_capture") or (source_if == 'window_capture') then | |
local name = obs.obs_source_get_name(source) | |
obs.obs_property_list_add_string(p, name, name) | |
end | |
-- Win name or Mac name | |
if (source_id == "dshow_input") or (source_id == "av_capture_input") then | |
local name = obs.obs_source_get_name(source) | |
obs.obs_property_list_add_string(q, name, name) | |
end | |
end | |
end | |
obs.source_list_release(sources) | |
obs.obs_properties_add_button(props, "my_button", "Place things", place_things_just_right) | |
return props | |
end | |
function place_things_just_right() | |
local source = obs.obs_get_source_by_name(screen) | |
if source ~= nil then | |
--Place the full screen image | |
local video_info = obs.obs_video_info() | |
obs.obs_get_video_info(video_info) | |
local the_scene_item = find_scene_item_from_source(source) | |
if the_scene_item ~= nil then | |
local scale = obs.vec2() | |
local w = obs.obs_source_get_width(source) | |
local h = obs.obs_source_get_height(source) | |
local mult = video_info.base_width / w | |
scale.x = mult | |
scale.y = mult | |
obs.obs_sceneitem_set_scale(the_scene_item, scale) | |
local pos = obs.vec2() | |
pos.x = 0 | |
pos.y = 0 | |
obs.obs_sceneitem_set_pos(the_scene_item, pos) | |
local dy = h - video_info.base_height / scale.y | |
if dy >= 0 then | |
crp = obs.obs_sceneitem_crop() | |
crp.top = math.floor(dy / 2.0) | |
-- Leave it out because it doesn't really matter | |
--crp.bottom = math.floor(dy / 2.0) | |
crp.left = 0 | |
crp.right = 0 | |
obs.obs_sceneitem_set_crop(the_scene_item, crp) | |
end | |
end | |
end | |
local source = obs.obs_get_source_by_name(webcam) | |
if source ~= nil then | |
local video_info = obs.obs_video_info() | |
obs.obs_get_video_info(video_info) | |
local the_scene_item = find_scene_item_from_source(source) | |
if the_scene_item ~= nil then | |
local w = obs.obs_source_get_width(source) | |
local h = obs.obs_source_get_height(source) | |
local target_w = 381 * video_info.base_width / 1920 | |
local target_h = 253 * video_info.base_height / 1080 | |
local aspect_ratio = w / h | |
local scale = 1 | |
if aspect_ratio > target_w / target_h then | |
-- Crop from the left and right | |
scale = target_h / h | |
local to_crop = (w - h * target_w / target_h) / 2 | |
crp = obs.obs_sceneitem_crop() | |
crp.left = math.floor(to_crop) | |
crp.right = math.floor(to_crop) | |
crp.top = 0 | |
crp.bottom = 0 | |
obs.obs_sceneitem_set_crop(the_scene_item, crp) | |
end | |
if aspect_ratio < target_w / target_h then | |
-- Crop from the top and bottom | |
scale = target_w / w | |
local to_crop = (h - w * target_h / target_w) / 2 | |
crp = obs.obs_sceneitem_crop() | |
crp.bottom = math.floor(to_crop) | |
crp.top = math.floor(to_crop) | |
obs.obs_sceneitem_set_crop(the_scene_item, crp) | |
end | |
local total_scale = obs.vec2() | |
total_scale.x = scale | |
total_scale.y = scale | |
obs.obs_sceneitem_set_scale(the_scene_item, total_scale) | |
local pos = obs.vec2() | |
pos.x = video_info.base_width - target_w | |
pos.y = 0 | |
obs.obs_sceneitem_set_pos(the_scene_item, pos) | |
end | |
end | |
end | |
-- OBS has a roundabout way of going through the scene, but as long as there are no | |
-- duplicate names this should work. | |
function find_scene_item_from_source(source) | |
local current_scene_source = obs.obs_frontend_get_current_scene() | |
local current_scene = obs.obs_scene_from_source(current_scene_source) | |
local scene_items = obs.obs_scene_enum_items(current_scene) | |
local the_scene_item = nil | |
local source_name = obs.obs_source_get_name(source) | |
for i, scene_item in ipairs(scene_items) do | |
if obs.obs_source_get_name(obs.obs_sceneitem_get_source(scene_item)) == source_name then | |
the_scene_item = scene_item | |
end | |
end | |
obs.sceneitem_list_release(scene_items) | |
return the_scene_item | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment