obs = obslua -- User-defined settings settings = { text_source_name = "", prefix = "Next Stream: ", separator = " • ", even_week_time = "20:00", odd_week_time = "21:00", suffix = "Uhr", days = { {enabled = false, auto_time = true, custom_time = ""}, -- Monday {enabled = false, auto_time = true, custom_time = ""}, -- Tuesday {enabled = false, auto_time = true, custom_time = ""}, -- Wednesday {enabled = false, auto_time = true, custom_time = ""}, -- Thursday {enabled = false, auto_time = true, custom_time = ""}, -- Friday {enabled = false, auto_time = true, custom_time = ""}, -- Saturday {enabled = false, auto_time = true, custom_time = ""} -- Sunday }, day_format = "full" -- Options: "full" or "short" } -- Helper function to get the current week number function get_week_number(day_offset) day_offset = day_offset or 0 local current_time = os.time() + (day_offset * 24 * 60 * 60) local year_start = os.time{year=os.date("%Y", current_time), month=1, day=1} local day_of_year = os.date("%j", current_time) local week_num = math.ceil(day_of_year / 7) return week_num end -- Helper function to check if a given week number is even function is_even_week(week_num) return week_num % 2 == 0 end -- Helper function to format time as HH:MM function format_time(time_str) local hours, minutes = time_str:match("^(%d+):?(%d*)$") hours = tonumber(hours) or 0 minutes = tonumber(minutes) or 0 return string.format("%02d:%02d", hours, minutes) end -- Function to determine the next stream day and time function get_next_stream() local days_of_week = settings.day_format == "full" and {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"} or {"Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"} local current_time = os.time() local current_day = (os.date("*t").wday + 5) % 7 + 1 -- Adjusting to make Monday=1, ..., Sunday=7 for i = 0, 6 do local index = (current_day + i - 1) % 7 + 1 local day_setting = settings.days[index] if day_setting.enabled then local day_offset = i local week_num = get_week_number(day_offset) local is_even = is_even_week(week_num) local time if day_setting.auto_time then time = is_even and settings.even_week_time or settings.odd_week_time else time = day_setting.custom_time end local stream_time = os.time{year=os.date("%Y", current_time), month=os.date("%m", current_time), day=os.date("%d", current_time) + day_offset, hour=tonumber(time:sub(1, 2)), min=tonumber(time:sub(4, 5))} if stream_time > current_time then local day_name if i == 0 then day_name = "Heute" elseif i == 1 then day_name = "Morgen" else day_name = days_of_week[index] end return day_name .. settings.separator .. format_time(time) end end end return nil end -- Function to update the text source function update_text_source() local next_stream = get_next_stream() local text = next_stream and (settings.prefix .. next_stream .. " " .. settings.suffix) or "Kein Stream geplant" local source = obs.obs_get_source_by_name(settings.text_source_name) if source then local source_settings = obs.obs_source_get_settings(source) obs.obs_data_set_string(source_settings, "text", text) obs.obs_source_update(source, source_settings) obs.obs_data_release(source_settings) obs.obs_source_release(source) end end -- Function to populate the dropdown list with text sources function add_text_sources(property) local sources = obs.obs_enum_sources() if sources ~= nil then for _, source in ipairs(sources) do local source_id = obs.obs_source_get_unversioned_id(source) if source_id == "text_gdiplus" or source_id == "text_ft2_source" then local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(property, name, name) end end end obs.source_list_release(sources) end -- Script properties function script_properties() local props = obs.obs_properties_create() -- Display current time, date, and week number local current_time = os.date("%A %H:%M") local week_num = get_week_number() local is_even = is_even_week(week_num) and "gerade" or "ungerade" local header = string.format("%s, (KW %d)", current_time, week_num) obs.obs_properties_add_text(props, "header", header, obs.OBS_TEXT_INFO) local text_source_list = obs.obs_properties_add_list(props, "text_source_name", "Textquelle", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING) add_text_sources(text_source_list) -- Group for prefix, separator, and suffix local format_group = obs.obs_properties_create() obs.obs_properties_add_text(format_group, "prefix", "Präfix", obs.OBS_TEXT_DEFAULT) obs.obs_property_set_long_description(obs.obs_properties_get(format_group, "prefix"), "Text, der vor dem nächsten Stream angezeigt wird.") obs.obs_properties_add_text(format_group, "separator", "Trennzeichen", obs.OBS_TEXT_DEFAULT) obs.obs_property_set_long_description(obs.obs_properties_get(format_group, "separator"), "Zeichen, das zwischen Tag und Zeit des nächsten Streams angezeigt wird.") obs.obs_properties_add_text(format_group, "suffix", "Suffix", obs.OBS_TEXT_DEFAULT) obs.obs_property_set_long_description(obs.obs_properties_get(format_group, "suffix"), "Text, der nach der Zeit des nächsten Streams angezeigt wird.") obs.obs_properties_add_group(props, "format_settings", "Format Einstellungen", obs.OBS_GROUP_NORMAL, format_group) -- Group for stream times local time_group = obs.obs_properties_create() obs.obs_properties_add_text(time_group, "even_week_time", "Streamstart (gerade Wochen)", obs.OBS_TEXT_DEFAULT) obs.obs_property_set_long_description(obs.obs_properties_get(time_group, "even_week_time"), "Automatischer Streamstart für gerade Wochen.") obs.obs_properties_add_text(time_group, "odd_week_time", "Streamstart (ungerade Wochen)", obs.OBS_TEXT_DEFAULT) obs.obs_property_set_long_description(obs.obs_properties_get(time_group, "odd_week_time"), "Automatischer Streamstart für ungerade Wochen.") obs.obs_properties_add_group(props, "time_settings", "Streamstart Einstellungen", obs.OBS_GROUP_NORMAL, time_group) -- Day format settings local day_format = obs.obs_properties_add_list(props, "day_format", "Wochentagsformat", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING) obs.obs_property_list_add_string(day_format, "Vollständig", "full") obs.obs_property_list_add_string(day_format, "Kurz", "short") obs.obs_property_set_long_description(day_format, "Wählen Sie zwischen vollständigem oder kurzem Wochentagsformat.") -- Group for each day settings local days = {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"} for i, day in ipairs(days) do local day_group = obs.obs_properties_create() obs.obs_properties_add_bool(day_group, day:lower() .. "_enabled", day .. " streamen") obs.obs_property_set_long_description(obs.obs_properties_get(day_group, day:lower() .. "_enabled"), "Aktivieren, um an diesem Tag zu streamen.") local time_choice = obs.obs_properties_add_list(day_group, day:lower() .. "_time_choice", "Streamstart", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING) obs.obs_property_list_add_string(time_choice, "Automatisch (nach Woche)", "auto") obs.obs_property_list_add_string(time_choice, "Manuell", "custom") obs.obs_property_set_long_description(time_choice, "Wählen Sie, ob der Streamstart automatisch (abhängig von der Woche) oder manuell festgelegt wird.") obs.obs_properties_add_text(day_group, day:lower() .. "_custom_time", "Streamstart manuell", obs.OBS_TEXT_DEFAULT) obs.obs_property_set_long_description(obs.obs_properties_get(day_group, day:lower() .. "_custom_time"), "Manuell festgelegter Streamstart für diesen Tag.") obs.obs_properties_add_group(props, day:lower(), day, obs.OBS_GROUP_NORMAL, day_group) end return props end -- Update settings when changed function script_update(new_settings) settings.text_source_name = obs.obs_data_get_string(new_settings, "text_source_name") settings.prefix = obs.obs_data_get_string(new_settings, "prefix") settings.separator = obs.obs_data_get_string(new_settings, "separator") settings.even_week_time = format_time(obs.obs_data_get_string(new_settings, "even_week_time")) settings.odd_week_time = format_time(obs.obs_data_get_string(new_settings, "odd_week_time")) settings.suffix = obs.obs_data_get_string(new_settings, "suffix") settings.day_format = obs.obs_data_get_string(new_settings, "day_format") local days = {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"} for i, day in ipairs(days) do local day_lower = day:lower() settings.days[i].enabled = obs.obs_data_get_bool(new_settings, day_lower .. "_enabled") settings.days[i].auto_time = obs.obs_data_get_string(new_settings, day_lower .. "_time_choice") == "auto" settings.days[i].custom_time = format_time(obs.obs_data_get_string(new_settings, day_lower .. "_custom_time")) end update_text_source() end -- Initialize the script function script_description() return "'K_STYER's Dynamic Next Stream Version 1.3' aktualisiert eine Textquelle mit dem nächsten Streamtag und Streamstart. Automatische oder manuelle Einstellungen für jeden Tag sind möglich. Erstelle zuerst eine Text-Quelle in OBS und wähle sie aus der Dropdown-Liste bei 'Textquelle' aus." end function script_load(new_settings) script_update(new_settings) obs.timer_add(update_text_source, 10000) -- Update every 10 seconds end function script_unload() obs.timer_remove(update_text_source) end