obs = obslua source_name = "" filter_name = "" cut_delay = 1 cut_distance = 1 script_enabled = false filter_duration_ms = 500 props = nil function script_description() return "K_STYER's Dynamic Video Live Cutter: This script randomly jumps through a media source with random delays." end function script_properties() props = obs.obs_properties_create() local source_group = obs.obs_properties_create() obs.obs_properties_add_text(source_group, "source_description", "Description", obs.OBS_TEXT_INFO) obs.obs_property_set_description(obs.obs_properties_get(source_group, "source_description"), "Select a media source and choose a filter to be displayed during the cut.") obs.obs_properties_add_list(source_group, "source_name", "Media Source", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING) obs.obs_properties_add_text(source_group, "filter_name", "Filter on Cut", obs.OBS_TEXT_DEFAULT) obs.obs_properties_add_int(source_group, "filter_duration_ms", "Filter Duration (ms)", 0, 5000, 100) obs.obs_properties_add_group(props, "source_filter", "Media Source and Filter", obs.OBS_GROUP_NORMAL, source_group) local delay_group = obs.obs_properties_create() obs.obs_properties_add_text(delay_group, "delay_description", "Description", obs.OBS_TEXT_INFO) obs.obs_property_set_description(obs.obs_properties_get(delay_group, "delay_description"), "How long should a segment be shown?\nMin: 1 second • Max: 32 seconds.") obs.obs_properties_add_int_slider(delay_group, "cut_delay", "Cut Interval (short <-> long)", 1, 32, 1) obs.obs_properties_add_group(props, "random_cut_delay", "Cut Interval", obs.OBS_GROUP_NORMAL, delay_group) local cut_distance_group = obs.obs_properties_create() obs.obs_properties_add_text(cut_distance_group, "distance_description", "Description", obs.OBS_TEXT_INFO) obs.obs_property_set_description(obs.obs_properties_get(cut_distance_group, "distance_description"), "How far should it cut?\nMin: 30 seconds • Max: 960 seconds.") obs.obs_properties_add_int_slider(cut_distance_group, "cut_distance", "Cut Distance (short <-> long)", 1, 32, 1) obs.obs_properties_add_group(props, "cut_distance", "Cut Distance", obs.OBS_GROUP_NORMAL, cut_distance_group) obs.obs_properties_add_bool(props, "script_enabled", "Enable Dynamic Cutter") local sources = obs.obs_enum_sources() if sources ~= nil then for _, source in ipairs(sources) do local source_type = obs.obs_source_get_type(source) if source_type == obs.OBS_SOURCE_TYPE_INPUT then local source_id = obs.obs_source_get_id(source) if source_id == "ffmpeg_source" or source_id == "vlc_source" or source_id == "media_source" then obs.obs_property_list_add_string(obs.obs_properties_get(props, "source_name"), obs.obs_source_get_name(source), obs.obs_source_get_name(source)) end end end obs.source_list_release(sources) end return props end function script_update(settings) source_name = obs.obs_data_get_string(settings, "source_name") filter_name = obs.obs_data_get_string(settings, "filter_name") cut_delay = obs.obs_data_get_int(settings, "cut_delay") cut_distance = obs.obs_data_get_int(settings, "cut_distance") filter_duration_ms = obs.obs_data_get_int(settings, "filter_duration_ms") script_enabled = obs.obs_data_get_bool(settings, "script_enabled") if script_enabled then stop_script() start_script() else stop_script() end end function start_script() math.randomseed(os.time()) obs.timer_add(skip_media_source, calculate_delay() * 1000) end function stop_script() obs.timer_remove(skip_media_source) end function skip_media_source() if not script_enabled or source_name == "" then return end local source = obs.obs_get_source_by_name(source_name) if source then local duration = get_source_duration(source) local current_position = get_source_position(source) if duration > 0 and current_position >= 0 then local cut_distance_ms = calculate_distance() local next_position = current_position + cut_distance_ms if next_position > duration then next_position = next_position - duration end obs.obs_source_media_set_time(source, next_position) activate_filter() obs.timer_remove(skip_media_source) obs.timer_add(skip_media_source, calculate_delay() * 1000) end obs.obs_source_release(source) end end function calculate_delay() local delay_steps = {} for i = 1, 32 do delay_steps[i] = math.floor(1 + ((32 - 1) / 31) * (i - 1)) end return delay_steps[cut_delay] end function calculate_distance() local distance_steps = {} for i = 1, 32 do distance_steps[i] = math.floor(30000 + ((960000 - 30000) / 31) * (i - 1)) end return distance_steps[cut_distance] end function activate_filter() local source = obs.obs_get_source_by_name(source_name) if source then local filter = obs.obs_source_get_filter_by_name(source, filter_name) if filter then obs.obs_source_set_enabled(filter, true) if filter_duration_ms > 0 then obs.timer_add(deactivate_filter, filter_duration_ms) end obs.obs_source_release(filter) else print("Filter not found: " .. filter_name) end obs.obs_source_release(source) else print("Source not found: " .. source_name) end end function deactivate_filter() local source = obs.obs_get_source_by_name(source_name) if source then local filter = obs.obs_source_get_filter_by_name(source, filter_name) if filter then obs.obs_source_set_enabled(filter, false) obs.obs_source_release(filter) else print("Filter not found: " .. filter_name) end obs.obs_source_release(source) else print("Source not found: " .. source_name) end obs.timer_remove(deactivate_filter) end function get_source_duration(source) local duration = obs.obs_source_media_get_duration(source) if duration == 0 then local vlc_settings = obs.obs_source_get_settings(source) local playlist = obs.obs_data_get_array(vlc_settings, "playlist") for i = 0, obs.obs_data_array_count(playlist) - 1 do local item = obs.obs_data_array_item(playlist, i) local item_duration = obs.obs_data_get_int(item, "duration") if item_duration > duration then duration = item_duration end obs.obs_data_release(item) end obs.obs_data_array_release(playlist) obs.obs_data_release(vlc_settings) end return duration end function get_source_position(source) local status = obs.obs_source_media_get_state(source) if status == obs.OBS_MEDIA_STATE_PLAYING or status == obs.OBS_MEDIA_STATE_PAUSED then return obs.obs_source_media_get_time(source) end return -1 end function script_load(settings) if script_enabled then start_script() end end function script_unload() stop_script() end