From 628317326384dc0201cbad1d768d39b9bc21d75b Mon Sep 17 00:00:00 2001 From: minster586 Date: Wed, 27 Aug 2025 03:03:46 -0400 Subject: [PATCH] master upload --- README.md | 44 ++++++++++++++- obs_uptime_to_file.lua | 125 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 obs_uptime_to_file.lua diff --git a/README.md b/README.md index 6a01d7f..b0e43d2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,42 @@ -# obs-uptime-to-file - +# OBS Uptime to File Lua Script + +This OBS Studio Lua script writes your current stream uptime to a text file, with customizable formatting. You can use this file as a source in OBS (e.g., with a Text GDI+ source) to display your live stream duration. + +## Features +- Writes the current stream uptime to a file while streaming. +- Lets you choose the output file location via the script settings. +- Lets you customize the output format (e.g., `01:23:45`, `1h 23m`, `83 minutes`). +- When the stream stops, the file is automatically erased (emptied). + +## Installation +1. Download or copy the `obs_uptime_to_file.lua` script to your computer. +2. Open OBS Studio. +3. Go to `Tools` > `Scripts`. +4. Click the `+` button and select `obs_uptime_to_file.lua`. +5. Set the `Output File Path` to where you want the uptime to be written. +6. (Optional) Set the `Format String` to customize how the uptime appears. + +## Format String +You can control how the uptime is displayed using the `Format String` property. Use these placeholders: +- `{h}`: Hours (zero-padded, e.g., 01) +- `{m}`: Minutes (zero-padded, e.g., 09) +- `{s}`: Seconds (zero-padded, e.g., 05) +- `{H}`: Hours (no padding, e.g., 1, 12) +- `{M}`: Minutes (no padding, e.g., 9, 23) +- `{S}`: Seconds (no padding, e.g., 5, 45) + +**Examples:** + - `{h}:{m}:{s}` → `01:23:45` + - `{H}:{M}:{S}` → `1:23:5` + - `{H}h {M}m` → `1h 23m` (or just `23m` if under 1 hour) + - `{M} minutes` → `83 minutes` + +## How It Works +- When you start streaming, the script begins writing the uptime to your chosen file every second. +- When you stop streaming, the file is erased (emptied), so nothing will display if you use it as a text source. + +## Use Case +Add the output file as a Text (GDI+) source in OBS to show your stream uptime on your overlay. The file will always be up-to-date while you are live, and will be blank when you are not streaming. + +## License +MIT License. Feel free to use, modify, and share. diff --git a/obs_uptime_to_file.lua b/obs_uptime_to_file.lua new file mode 100644 index 0000000..a773ff3 --- /dev/null +++ b/obs_uptime_to_file.lua @@ -0,0 +1,125 @@ +-- OBS Lua Script: Stream Uptime to File +-- This script writes the current stream uptime to a user-selected file while streaming. + +obs = obslua +source_name = "" + +output_path = "" +format_string = "{h}:{m}:{s}" +interval = 1000 -- ms +start_time = nil +hotkey_id = obs.OBS_INVALID_HOTKEY_ID + +function script_description() + return "Writes the current stream uptime to a file while streaming. Configure the output file path in script settings." +end + +function script_properties() + local props = obs.obs_properties_create() + obs.obs_properties_add_path(props, "output_path", "Output File Path", obs.OBS_PATH_FILE_SAVE, "Text File (*.txt)", nil) + obs.obs_properties_add_text(props, "format_string", "Format String", obs.OBS_TEXT_DEFAULT) + obs.obs_property_set_long_description(obs.obs_properties_get(props, "format_string"), + "Use {h} for hours, {m} for minutes, {s} for seconds. Example: {h}:{m}:{s}, {h}h {m}m, {m} minutes, etc.") + return props +end + +function script_update(settings) + output_path = obs.obs_data_get_string(settings, "output_path") + local fmt = obs.obs_data_get_string(settings, "format_string") + if fmt ~= nil and fmt ~= "" then + format_string = fmt + else + format_string = "{h}:{m}:{s}" + end +end + +function on_event(event) + if event == obs.OBS_FRONTEND_EVENT_STREAMING_STARTED then + start_time = os.time() + obs.timer_add(update_uptime, interval) + elseif event == obs.OBS_FRONTEND_EVENT_STREAMING_STOPPED then + obs.timer_remove(update_uptime) + erase_uptime_file() + start_time = nil + end +end + +function update_uptime() + if start_time and output_path ~= "" then + local elapsed = os.time() - start_time + write_uptime(elapsed) + end +end + + +function write_uptime(seconds) + local file = io.open(output_path, "w") + if file then + file:write(format_time_custom(seconds)) + file:close() + end +end + +function erase_uptime_file() + if output_path ~= "" then + local file = io.open(output_path, "w") + if file then + file:write("") + file:close() + end + end +end + + +function format_time_custom(seconds) + local h = math.floor(seconds / 3600) + local m = math.floor((seconds % 3600) / 60) + local s = seconds % 60 + local fmt = format_string or "{h}:{m}:{s}" + -- Zero-padded + local hh = string.format("%02d", h) + local mm = string.format("%02d", m) + local ss = string.format("%02d", s) + -- Non-padded + local H = tostring(h) + local M = tostring(m) + local S = tostring(s) + + -- Smart removal for non-padded units + -- Remove '0h' or '0h ' or '0h,' etc. if h == 0 + if h == 0 then + -- Remove patterns like '0h ', '0h,', '0h', '0h\n', etc. + fmt = fmt:gsub("0h[ ,]*", "") + fmt = fmt:gsub("0h", "") + fmt = fmt:gsub("0H[ ,]*", "") + fmt = fmt:gsub("0H", "") + fmt = fmt:gsub("{H}h[ ,]*", "") + fmt = fmt:gsub("{H}h", "") + end + if m == 0 then + fmt = fmt:gsub("0m[ ,]*", "") + fmt = fmt:gsub("0m", "") + fmt = fmt:gsub("0M[ ,]*", "") + fmt = fmt:gsub("0M", "") + fmt = fmt:gsub("{M}m[ ,]*", "") + fmt = fmt:gsub("{M}m", "") + end + -- Replace placeholders + fmt = fmt:gsub("{h}", hh) + fmt = fmt:gsub("{m}", mm) + fmt = fmt:gsub("{s}", ss) + fmt = fmt:gsub("{H}", h ~= 0 and H or "") + fmt = fmt:gsub("{M}", m ~= 0 and M or "") + fmt = fmt:gsub("{S}", S) + -- Remove leading/trailing whitespace + fmt = fmt:gsub("^%s+", ""):gsub("%s+$", "") + return fmt +end + +function script_load(settings) + obs.obs_frontend_add_event_callback(on_event) +end + +function script_unload() + obs.timer_remove(update_uptime) +end