Skip to content

Instantly share code, notes, and snippets.

@patrickmineault
Last active June 23, 2020 04:57
Show Gist options
  • Save patrickmineault/a59f792b28c0016e57fcaf19e4bf1086 to your computer and use it in GitHub Desktop.
Save patrickmineault/a59f792b28c0016e57fcaf19e4bf1086 to your computer and use it in GitHub Desktop.
Place things
--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