obs = obslua --local icon1 = "base64-image-data" local description = [[ Set up a death counter on your scene, which responds to configurable hotkeys to increment and decrement the counter (see OBS File > Settings > Hotkey, scroll down to Increment/Decrement Counter hotkeys). To set up the death counter, create a Text Source on your scene. If you want to play sound(s) when you hit the hotkeys, create additional Media Source(s), pointing to valid audio files. Note: if you want to hear the sounds on your end, configure the Audio Mixer settings in OBS (in the main window, under the audio panel, hit the Advanced Audio Properties cog wheel icon), and set Audio Monitoring for those media sources to "Monitor and Output". In my script's configuration screen, use the fields "Media Source Increment" and "Media Source Decrement" to point to the media sources you wish to hear when you press the death counter hotkeys, or select the option "--None--" to play no sound. You can manually change the death counter number using the script's configuration panel All settings pertaining to this script are saved, so you can close OBS safely, and when you start OBS again, everything should be as you left it. Note: the number on the script's configuration panel doesn't change when you press the hotkeys to change the counter, but the number you see on the scene is saved when you close OBS. Author: tonebacas ]] local increment_counter_hotkey_id = obs.OBS_INVALID_HOTKEY_ID local decrement_counter_hotkey_id = obs.OBS_INVALID_HOTKEY_ID local increment_count_media_source_name = "" local decrement_count_media_source_name = "" local text_source_name = "" local script_settings = nil -- To the user: these you can touch local min_num_deaths = 0 local max_num_deaths = 99999 -- To the user: no further function find_sources(ids_to_find, sources) local result = {} for i, source in ipairs(sources) do local source_id = obs.obs_source_get_id(source) for _, id_to_find in ipairs(ids_to_find) do if source_id == id_to_find then table.insert(result, source) end end end return result end function find_text_sources(sources) local source_types_names = { "text_gdiplus", "text_gdiplus_v2", "text_ft2_source", "text_ft2_source_v2" } return find_sources(source_types_names, sources) end function increment_counter_on_keypress(pressed) if pressed then change_counter(1) local counter_text = obs.obs_data_get_string(script_settings, "deathcounter_deathstext") local num_deaths = obs.obs_data_get_int(script_settings, "deathcounter_numdeaths") local text = counter_text .. num_deaths set_text_source_text(text_source_name, text) play_media_sound(increment_count_media_source_name) end end function decrement_counter_on_keypress(pressed) if pressed then change_counter(-1) local counter_text = obs.obs_data_get_string(script_settings, "deathcounter_deathstext") local counter_numdeaths = obs.obs_data_get_int(script_settings, "deathcounter_numdeaths") local text = counter_text .. counter_numdeaths set_text_source_text(text_source_name, text) play_media_sound(decrement_count_media_source_name) end end function change_counter(increment) local counter_numdeaths = obs.obs_data_get_int(script_settings, "deathcounter_numdeaths") counter_numdeaths = counter_numdeaths + increment counter_numdeaths = clamp_value(counter_numdeaths, min_num_deaths, max_num_deaths) obs.obs_data_set_int(script_settings, "deathcounter_numdeaths", counter_numdeaths) end function clamp_value(v, min_v, max_v) if v < min_v then return min_v elseif v > max_v then return max_v end return v end function play_media_sound(media_source_name) if media_source_name == "" then return end local media_source = obs.obs_get_source_by_name(media_source_name) if media_source == nil then return end --[[ local source_settings = obs.obs_source_get_settings(media_source) local json_dump = obs.obs_data_get_json(source_settings) print(json_dump) obs.obs_data_release(source_settings) ]] obs.obs_source_media_stop(media_source) obs.obs_source_media_restart(media_source) obs.obs_source_release(media_source) end function set_text_source_text(source_name, text) if source_name == "" then return end local text_source = obs.obs_get_source_by_name(source_name) if text_source == nil then return end local source_settings = obs.obs_source_get_settings(text_source) --[[ -- dump the json local json_dump = obs.obs_data_get_json(source_settings) ]] obs.obs_data_set_string(source_settings, "text", text) obs.obs_source_update(text_source, source_settings) obs.obs_data_release(source_settings) obs.obs_source_release(text_source) end function script_description() return description end function script_properties() local props = obs.obs_properties_create() local text_sources_prop = obs.obs_properties_add_list( props, "deathcounter_text", "Text source", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING ) local deaths_counter_prop = obs.obs_properties_add_text( props, "deathcounter_deathstext", "Counter text", obs.OBS_TEXT_DEFAULT ) local deaths_counter_prop = obs.obs_properties_add_int( props, "deathcounter_numdeaths", "Number of deaths", min_num_deaths, max_num_deaths, 1 ) local increment_media_source_props = obs.obs_properties_add_list( props, "deathcounter_sound_increment", "Media Source Increment", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING ) local decrement_media_source_props = obs.obs_properties_add_list( props, "deathcounter_sound_decrement", "Media Source Decrement", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING ) -- obs.script_log(obs.LOG_INFO, "test log") --[[ local media_files_prop = obs.obs_properties_add_path( props, "media_files", "Pick media files", obs.OBS_PATH_FILE, "*.mp3 *.ogg *.wav", nil ) ]] --[[ do local all_scenes = obs.obs_frontend_get_scenes() for i, scene in ipairs(all_scenes) do local scene_name = obs.obs_source_get_name(scene) print("Scene " .. i .. ": " .. scene_name) local scene_items = obs.obs_scene_enum_items(scene) if scene_items ~= nil then for j, scene_item in ipairs(scene_items) do local scene_item_name = obs.obs_source_get_name(scene_item) print("\tScene Item " .. j .. ": " .. scene_item_name) end obs.obs_sceneitem_list_release(scene_items) else print("\tNo items for this scene") end end obs.obs_frontend_get_scenes(all_scenes) end ]] local all_sources = obs.obs_enum_sources() do local text_sources = find_text_sources(all_sources) for _, source in ipairs(text_sources) do local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(text_sources_prop, name, name) end end do local media_sources = find_sources({ "ffmpeg_source" }, all_sources) -- add an empty option local none_label = "--None--" obs.obs_property_list_add_string(increment_media_source_props, none_label, "") obs.obs_property_list_add_string(decrement_media_source_props, none_label, "") for _, source in ipairs(media_sources) do local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(increment_media_source_props, name, name) obs.obs_property_list_add_string(decrement_media_source_props, name, name) end end obs.source_list_release(all_sources) return props end function script_load(settings) script_settings = settings do increment_counter_hotkey_id = obs.obs_hotkey_register_frontend("deathcounter.incrementcounter", "Increment Counter", increment_counter_on_keypress) local increment_hotkey_save_array = obs.obs_data_get_array(settings, "deathcounter.incrementcounter") obs.obs_hotkey_load(increment_counter_hotkey_id, increment_hotkey_save_array) obs.obs_data_array_release(increment_hotkey_save_array) end do decrement_counter_hotkey_id = obs.obs_hotkey_register_frontend("deathcounter.decrementcounter", "Decrement Counter", decrement_counter_on_keypress) local decrement_hotkey_save_array = obs.obs_data_get_array(settings, "deathcounter.decrementcounter") obs.obs_hotkey_load(decrement_counter_hotkey_id, decrement_hotkey_save_array) obs.obs_data_array_release(decrement_hotkey_save_array) end end function script_save(settings) script_settings = settings do local increment_hotkey_save_array = obs.obs_hotkey_save(increment_counter_hotkey_id) obs.obs_data_set_array(settings, "deathcounter.incrementcounter", increment_hotkey_save_array) obs.obs_data_array_release(increment_hotkey_save_array) end do local decrement_hotkey_save_array = obs.obs_hotkey_save(decrement_counter_hotkey_id) obs.obs_data_set_array(settings, "deathcounter.decrementcounter", decrement_hotkey_save_array) obs.obs_data_array_release(decrement_hotkey_save_array) end end function script_update(settings) script_settings = settings text_source_name = obs.obs_data_get_string(settings, "deathcounter_text") increment_count_media_source_name = obs.obs_data_get_string(settings, "deathcounter_sound_increment") decrement_count_media_source_name = obs.obs_data_get_string(settings, "deathcounter_sound_decrement") local counter_text = obs.obs_data_get_string(settings, "deathcounter_deathstext") local counter_numdeaths = obs.obs_data_get_int(settings, "deathcounter_numdeaths") local text = counter_text .. counter_numdeaths set_text_source_text(text_source_name, text) end --[[ function script_unload() local media_source = obs.obs_get_source_by_name(media_source_name) if media_source ~= nil then obs.obs_source_set_muted(media_source, true) obs.obs_source_release(media_source) --obs.obs_source_media_restart(source) --obs.obs_source_set_enabled(source, true) end end function script_tick(seconds) end ]]