How to Add a Datetime Overlay (DD-MM-YYYY HH:MM:SS) to OBS Studio?

CCTV add datetime to OBS

This tutorial explains how to overlay a dynamic datetime stamp in the format DD-MM-YYYY (e.g., 03-05-2025) on your webcam feed in OBS Studio, creating a CCTV-style look, and broadcast it as a virtual webcam. The datetime updates every second using a Lua script.

Requirements

  • OBS Studio: Version 26.1 or newer (download from obsproject.com).

  • Webcam: A connected webcam recognized by OBS.

  • Lua Script: A custom script to display the updating datetime.

cctv

  • Save the Script:
    • Copy the script content below into a file named cctv.lua.
    • Place it in your OBS scripts folder:
      • Windows: C:\Program Files\obs-studio\data\obs-plugins\frontend-tools\scripts
      • macOS: ~/Library/Application Support/obs-studio/scripts
      • Linux: ~/.config/obs-studio/scripts
  • Set Up OBS:
    • Open OBS Studio.
    • Create a scene and add your webcam as a Video Capture Device source.
    • Add a Text (GDI+/FreeType2) source (e.g., named “Timestamp”) and configure its appearance (e.g., font: Courier New, white text, black outline, positioned in the top-left corner).
  • Load the Script:
    • Go to Tools > Scripts in OBS.
    • Click the “+” button, select realtime_clock.lua, and load it.
    • In the script properties, set the “Text Source” to your text source (e.g., “Timestamp”).
  • Performance: The script is lightweight and shouldn’t affect OBS performance.

  • Customization: To include time (e.g., DD-MM-YYYY HH:MM:SS), modify the os.date format in the script to “%d-%m-%Y %H:%M:%S”.

This setup creates a professional CCTV-style webcam feed with a dynamic DD-MM-YYYY datetime overlay, perfect for streaming or video calls via OBS’s virtual webcam.

cctv.lua 
obs = obslua

source_name = ""

activated = false

-- Function to set the time text

function set_time_text()

    local text = os.date("%Y-%m-%d %H:%M:%S")

   

    local source = obs.obs_get_source_by_name(source_name)

    if source ~= nil then

        local settings = obs.obs_data_create()

        obs.obs_data_set_string(settings, "text", text)

        obs.obs_source_update(source, settings)

        obs.obs_data_release(settings)

        obs.obs_source_release(source)

    end

end

-- Timer callback to update time every second

function timer_callback()

    set_time_text()

end

-- Activate or deactivate the timer

function activate(activating)

    if activated == activating then

        return

    end

    activated = activating

    if activating then

        set_time_text()

        obs.timer_add(timer_callback, 1000)

    else

        obs.timer_remove(timer_callback)

    end

end

-- Called when a source is activated/deactivated

function source_activated(cd)

    local source = obs.calldata_source(cd, "source")

    if source ~= nil then

        local name = obs.obs_source_get_name(source)

        if name == source_name then

            activate(true)

        end

    end

end

function source_deactivated(cd)

    local source = obs.calldata_source(cd, "source")

    if source ~= nil then

        local name = obs.obs_source_get_name(source)

        if name == source_name then

            activate(false)

        end

    end

end

-- Defines the properties that the user can change

function script_properties()

    local props = obs.obs_properties_create()

   

    local p = obs.obs_properties_add_list(props, "source", "Text Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)

    local sources = obs.obs_enum_sources()

    if sources ~= nil then

        for _, source in ipairs(sources) do

            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(p, name, name)

            end

        end

    end

    obs.source_list_release(sources)

   

    return props

end

-- Returns the description shown to the user

function script_description()

    return "Sets a text source to display the current local machine time in the format YYYY-MM-DD HH:MM:SS.\n\nModified from a script by Lain"

end

-- Called when settings are changed

function script_update(settings)

    activate(false)

    source_name = obs.obs_data_get_string(settings, "source")

   

    local source = obs.obs_get_source_by_name(source_name)

    if source ~= nil then

        local active = obs.obs_source_active(source)

        obs.obs_source_release(source)

        activate(active)

    end

end

-- Called to set default settings

function script_defaults(settings)

end

-- Called on script startup

function script_load(settings)

    local sh = obs.obs_get_signal_handler()

    obs.signal_handler_connect(sh, "source_activate", source_activated)

    obs.signal_handler_connect(sh, "source_deactivate", source_deactivated)

end

Leave a Reply

Your email address will not be published. Required fields are marked *