Skip to content

Instantly share code, notes, and snippets.

@upgradeQ
Last active November 16, 2020 03:08
Show Gist options
  • Save upgradeQ/c553ee6a561d82397058d319055dcb25 to your computer and use it in GitHub Desktop.
Save upgradeQ/c553ee6a561d82397058d319055dcb25 to your computer and use it in GitHub Desktop.
local obs = obslua
local coroutine = require 'coroutine'
local math = require 'math'
local Timer = {}
function Timer:init(o)
o = o or {}
setmetatable(o,self)
self.__index = self
return o
end
function Timer:update(dt)
self.current_time = self.current_time + dt
if self.current_time >= self.delay then
self.finished = true
end
end
function Timer:enter()
self.finished = false
self.current_time = 0
end
function Timer:exit()
--print('on exit')
end
function Timer:launch()
self:enter()
while not self.finished do
local dt = coroutine.yield()
self:update(dt)
end
self:exit()
end
function time_sleep(s)
local action = Timer:init{delay=s}
action:launch()
end
---[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]
function current_scene()
print('start current scene')
time_sleep(1)
print('end waiting one second / starting to wait again')
time_sleep(4)
print('end waiting [current] for four seconds')
end
function infinity_scene()
while true do
n = math.random(1,3)
print('random sleep [' .. n .. '] seconds')
time_sleep(n)
end
end
local scene_item
local source_name = 'c2c2'
function find_scene_item()
local source = obs.obs_frontend_get_current_scene()
if not source then
print('there is no current scene')
return
end
scene_width = obs.obs_source_get_width(source)
scene_height = obs.obs_source_get_height(source)
local scene = obs.obs_scene_from_source(source)
obs.obs_source_release(source)
scene_item = obs.obs_scene_find_source(scene, source_name)
if scene_item then
original_pos = get_scene_item_pos(scene_item)
return true
end
print(source_name..' not found')
return false
end
function get_scene_item_pos(scene_item)
local pos = obs.vec2()
obs.obs_sceneitem_get_pos(scene_item, pos)
return pos
end
local x,y = 0,0
function move_scene_item(scene_item,absolute_progress)
absolute_progress = absolute_progress or false
if not scene_item then return end
local next_pos = obs.vec2()
if not absolute_progress then
x = x + 30
y = y + 30
else
x = absolute_progress
y = absolute_progress
end
next_pos.x,next_pos.y = x,y
obs.obs_sceneitem_set_pos(scene_item, next_pos)
end
function second_scene()
local tries = 15
--print('start second scene')
repeat
time_sleep(0.3)
move_scene_item(scene_item)
tries = tries - 1
until tries == 0
--print('end second')
end
local pow = math.pow
-- https://github.com/EmmanuelOga/easing/blob/master/lib/easing.lua
function inOutExpo(t, b, c, d)
if t == 0 then return b end
if t == d then return b + c end
t = t / d * 2
if t < 1 then
return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005
else
t = t - 1
return c / 2 * 1.0005 * (-pow(2, -10 * t) + 2) + b
end
end
function inOutQuart(t, b, c, d)
t = t / d * 2
if t < 1 then
return c / 2 * pow(t, 4) + b
else
t = t - 2
return -c / 2 * (pow(t, 4) - 2) + b
end
end
function easing_scene_item_movement(begin,end_val,duration)
local begin = begin or 500
local end_val = end_val or 0
local duration = duration or 0.6
local current = 0
local interval = 0.02
local change = end_val - begin
repeat
--local absolute_progress = inOutExpo(current,begin,change,duration)
local absolute_progress = inOutQuart(current,begin,change,duration)
move_scene_item(scene_item,absolute_progress)
time_sleep(interval)
current = current + interval
until current >= duration
end
function easing_scene_loop()
while true do
easing_scene_item_movement(900,0,0.16)
easing_scene_item_movement(0,300)
time_sleep(0.1)
easing_scene_item_movement(300,600,0.8)
time_sleep(0.3)
easing_scene_item_movement(600,900,0.23)
end
end
local c1 = coroutine.create(current_scene)
--local c2 = coroutine.create(second_scene) -- move some source on scene with name c2c2
local c2 = coroutine.create(easing_scene_loop)
local c3 = coroutine.create(infinity_scene)
local c4 = coroutine.create(function() coroutine.yield() end)
function delayed_print_logic()
print('hello')
time_sleep(3)
print('world')
end
function delayed_print()
if coroutine.status(c4) == 'dead' then
c4 = coroutine.create(delayed_print_logic)
end
end
function cancel_delayed_print()
print('abort printing')
c4 = nil
c4 = coroutine.create(function() coroutine.yield() end)
end
---[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]
function script_tick(dt)
-- set c2c2 as source name within current scene
if not scene_item then find_scene_item() end
coroutine.resume(c1,dt)
coroutine.resume(c2,dt)
coroutine.resume(c3,dt)
coroutine.resume(c4,dt)
end
---[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]
function htk_1_cb(pressed)
if pressed then
delayed_print()
end
end
function htk_2_cb(pressed)
if pressed then
cancel_delayed_print()
end
end
key_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ],'
key_2 = '"htk_2": [ { "key": "OBS_KEY_2" } ]}'
json_s = key_1 .. key_2
default_hotkeys = {
{id='htk_1',des='print with delay',callback=htk_1_cb},
{id='htk_2',des='cancel delayed print',callback=htk_2_cb},
}
function script_load(settings)
s = obs.obs_data_create_from_json(json_s)
for _,v in pairs(default_hotkeys) do
local a = obs.obs_data_get_array(s,v.id)
h = obs.obs_hotkey_register_frontend(v.id,v.des,v.callback)
obs.obs_hotkey_load(h,a)
obs.obs_data_array_release(a)
end
obs.obs_data_release(s)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment