obs = obslua -- Teletype News Ticker Script -- By Phoebe Zeitler -- phoebe.zeitler@gmail.com -- Support: https://obsproject.com/forum/resources/teletype-news-ticker.725/ -- begin user configurable options default_path = "C:\\" -- IMPORTANT: use only basic ASCII characters here-- UTF-8 not yet supported rand_cursor_chars = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890-=+_)(*&^%$#@![]{}|,<.>/? " -- end user configurable options -- begin user configurable functions -- A function to allow the user to specify custom replacements to be -- performed on the line, after default replacements have been made. -- The line currently being readied for display is processed_line . function user_process_line() -- EXAMPLE: this is the date processing used in the default process_line function. -- processed_line = string.gsub(processed_line, "%[date%]", os.date(date_format)) end -- end user configurable functions -- begin properties variables source_name = "" file_name = "" teletype_delay_ds = 1 full_display_s = 10 reload_on_loop = true prefix_chars = "" use_cursor = false use_rand_cursor = false use_cursor_char = "_" date_format = "%d %B %Y" -- end properties variables -- begin internal use variables lines_stack = {} current_delay = 0 current_line = 1 current_char = 1 teletype_mode = false timer_deployed = false processed_line = "" -- end internal use variables -- begin imported functions -- function courtesy Dirk Laurie -- http://lua-users.org/lists/lua-l/2014-04/msg00590.html --[[ function utf8.sub(s,i,j) i = i or 1 j = j or -1 if i<1 or j<1 then local n = utf8.len(s) if not n then return nil end if i<0 then i = n+1+i end if j<0 then j = n+1+j end if i<0 then i = 1 elseif i>n then i = n end if j<0 then j = 1 elseif j>n then j = n end end if j 0 then obs.timer_add(timer_callback, 100) timer_deployed = true end end function timer_callback() if not source_is_active(source_name) then --print("Source " .. source_name .. " is not active") return end current_delay = current_delay - 1 if current_delay <= 0 then if not teletype_mode then next_line() else current_char = current_char + 1 if current_char > string.len(processed_line) then teletype_mode = false current_delay = full_display_s * 10 end end end update_display() end function next_line() local is_valid_line = false while (is_valid_line == false) do current_line = current_line + 1 if current_line > #lines_stack then if reload_on_loop then lines_stack = lines_from(file_name) end current_line = 1 end current_char = 1 teletype_mode = true current_delay = teletype_delay_ds if string.sub(lines_stack[current_line], 1,1) == "#" then is_valid_line = false else is_valid_line = true end end process_line() end function process_line() processed_line = lines_stack[current_line] processed_line = string.gsub(processed_line, "%[date%]", os.date(date_format)) user_process_line() end function update_display() local text_to_display = "" if teletype_mode then text_to_display = string.sub(processed_line, 1, current_char) if use_cursor then text_to_display = text_to_display .. get_cursor_char() end else text_to_display = processed_line end text_to_display = prefix_chars .. text_to_display local source = obs.obs_get_source_by_name(source_name) if source ~= nil then local settings = obs.obs_data_create() obs.obs_data_set_string(settings, "text", text_to_display) obs.obs_source_update(source, settings) obs.obs_data_release(settings) obs.obs_source_release(source) end end function get_cursor_char() local retval = use_cursor_char if use_rand_cursor then local charnum = math.random(string.len(rand_cursor_chars)) retval = string.sub(rand_cursor_chars, charnum, charnum) end return retval end -- end application-specific functions