obs = obslua -- Réglages (modifiables depuis l'UI OBS > Outils > Scripts) source_name = "" -- Sélection de la source texte (GDI+ ou Freetype 2) h_input = 0 -- Heures m_input = 5 -- Minutes (par défaut 5 min) s_input = 0 -- Secondes end_text = "LET'S GOOO !!" -- Texte à la fin auto_start = false -- Démarrer automatiquement au chargement -- État interne running = false current_time = 0 ---------------------------------------------------------- -- Utilitaires ---------------------------------------------------------- local function total_duration_sec() local h = math.max(0, tonumber(h_input) or 0) local m = math.max(0, tonumber(m_input) or 0) local s = math.max(0, tonumber(s_input) or 0) return h*3600 + m*60 + s end local function format_hms(seconds) local h = math.floor(seconds / 3600) local rem = seconds % 3600 local m = math.floor(rem / 60) local s = rem % 60 if h > 0 then return string.format("%02d:%02d:%02d", h, m, s) else return string.format("%02d:%02d", m, s) end end local function set_text(txt) local src = obs.obs_get_source_by_name(source_name) if src ~= nil then local s = obs.obs_data_create() obs.obs_data_set_string(s, "text", txt) obs.obs_source_update(src, s) obs.obs_data_release(s) obs.obs_source_release(src) end end ---------------------------------------------------------- -- Timer ---------------------------------------------------------- local function tick() if not running then return end if current_time > 0 then current_time = current_time - 1 set_text(format_hms(current_time)) else obs.timer_remove(tick) running = false set_text(end_text) end end ---------------------------------------------------------- -- Commandes ---------------------------------------------------------- local function start_countdown() if source_name == nil or source_name == "" then print("[countdown] Aucune source texte sélectionnée.") return end local dur = total_duration_sec() if dur <= 0 then print("[countdown] Durée invalide (<= 0).") return end -- Évite les doublons de timers if running then obs.timer_remove(tick) running = false end current_time = dur running = true set_text(format_hms(current_time)) -- affiche immédiatement obs.timer_add(tick, 1000) end local function stop_reset_countdown() if running then obs.timer_remove(tick) running = false end local dur = math.max(0, total_duration_sec()) if dur > 0 then set_text(format_hms(dur)) end end ---------------------------------------------------------- -- Callbacks UI (boutons) ---------------------------------------------------------- local function on_click_start(props, p) start_countdown() return true end local function on_click_stop(props, p) stop_reset_countdown() return true end ---------------------------------------------------------- -- OBS Script API ---------------------------------------------------------- function script_description() return "Décompte manuel (H:M:S) pour OBS\n" .. "- Lancer/Arrêter via boutons\n" .. "- Affiche \"" .. end_text .. "\" à la fin\n" .. "Régle la couleur (noir) dans les propriétés de la source texte." end function script_properties() local props = obs.obs_properties_create() -- Remplacement du label par un champ texte désactivé (compatibilité API) local lbl = obs.obs_properties_add_text(props, "perzik_label", "Développé par Perzik", obs.OBS_TEXT_DEFAULT) obs.obs_property_set_enabled(lbl, false) -- Sélecteur de source texte local p_src = obs.obs_properties_add_list( props, "source", "Source texte", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING ) local sources = obs.obs_enum_sources() if sources ~= nil then for _, src in ipairs(sources) do local id = obs.obs_source_get_unversioned_id(src) if id == "text_gdiplus" or id == "text_ft2_source" then local name = obs.obs_source_get_name(src) obs.obs_property_list_add_string(p_src, name, name) end end obs.source_list_release(sources) end -- Durée H:M:S obs.obs_properties_add_int(props, "h_input", "Heures", 0, 99, 1) obs.obs_properties_add_int(props, "m_input", "Minutes", 0, 59, 1) obs.obs_properties_add_int(props, "s_input", "Secondes", 0, 59, 1) -- Texte de fin obs.obs_properties_add_text(props, "end_text", "Texte à la fin", obs.OBS_TEXT_DEFAULT) -- Auto-start obs.obs_properties_add_bool(props, "auto_start", "Démarrer automatiquement au chargement") -- Boutons obs.obs_properties_add_button(props, "btn_start", "Lancer le décompte", on_click_start) obs.obs_properties_add_button(props, "btn_stop", "Arrêter / Réinitialiser", on_click_stop) return props end function script_update(settings) source_name = obs.obs_data_get_string(settings, "source") h_input = obs.obs_data_get_int(settings, "h_input") m_input = obs.obs_data_get_int(settings, "m_input") s_input = obs.obs_data_get_int(settings, "s_input") end_text = obs.obs_data_get_string(settings, "end_text") auto_start = obs.obs_data_get_bool(settings, "auto_start") end function script_load(settings) -- Affiche la durée initiale si une source est déjà choisie if source_name ~= nil and source_name ~= "" then local dur = total_duration_sec() if dur > 0 then set_text(format_hms(dur)) end end if auto_start then start_countdown() end end function script_unload() if running then obs.timer_remove(tick) running = false end end