05-03-26

Play Music on Key Press with Volume Control

This Lua script for hardware input allows you to play different songs by pressing keys, with real-time volume control. Customize key mappings and song files for a personalized audio experience.

rebindlua scriptaudiomusickeybindvolume controlhardware input

Question

Sound alert when key held too long

Rebind AI

luau
-- rebind: name=Hold Time Alert

local cfg = UI.Schema({
    enabled = UI.Toggle(true, { label = "Enable" }),
    target_key = UI.Keybind("W", { label = "Key to Monitor" }),
    max_hold_time = UI.Slider(3000, { min = 500, max = 10000, step = 100, suffix = "ms", label = "Max Hold Time" }),
    alert_sound = UI.Toggle(true, { label = "Play Alert Sound" }),
})

local holdStart = nil
local alerted = false

function OnDown(key)
    if not cfg.enabled or key ~= cfg.target_key then
        return true
    end
    
    holdStart = System.Time()
    alerted = false
    return true
end

function OnUp(key, duration)
    if key == cfg.target_key then
        holdStart = nil
        alerted = false
    end
    return true
end

function OnTick()
    if not cfg.enabled or not holdStart then
        return
    end
    
    local elapsed = System.Time() - holdStart
    
    if elapsed >= cfg.max_hold_time and not alerted then
        alerted = true
        if cfg.alert_sound then
            Audio.Beep()
        end
        UI.Notify("Key held too long!", "warning")
    end
end

function OnStop()
    holdStart = nil
    alerted = false
    Audio.StopAll()
end

function OnBlur()
    holdStart = nil
    alerted = false
end

How it works:

  1. OnDown — tracks when the monitored key is pressed and resets the alert flag
  2. OnTick — every frame, checks if the key has been held past the configured threshold
  3. When the threshold is exceeded, plays a system beep and shows a notification
  4. OnUp — clears the tracking when the key is released
  5. OnBlur/OnStop — cleanup to prevent memory leaks

The script monitors a single configurable key (default "W") and alerts once if held beyond the max duration (default 3 seconds). The alert sound is only played once per hold, even if the key stays pressed.

You can customize:

  • target_key — which key to monitor
  • max_hold_time — how long before alerting (in milliseconds)
  • alert_sound — toggle the beep on/off

Learn more

Question

If I had a list of music in a songs/ directory could I have individual keys play different songs if they were held down too long and stop when I let go?

Rebind AI

luau
-- rebind: name=Hold to Play Music

local cfg = UI.Schema({
    enabled = UI.Toggle(true, { label = "Enable" }),
    volume = UI.Slider(0.5, { min = 0, max = 1, step = 0.1, label = "Volume" }),
})

-- Map keys to song filenames in the songs/ directory
local KEY_SONGS = {
    ["W"] = "songs/track1.mp3",
    ["A"] = "songs/track2.mp3",
    ["S"] = "songs/track3.mp3",
    ["D"] = "songs/track4.mp3",
    ["E"] = "songs/track5.mp3",
    ["Q"] = "songs/track6.mp3",
}

-- Track which sound is playing for each key
local activeSounds = {}

function OnDown(key)
    if not cfg.enabled or not KEY_SONGS[key] then
        return true
    end
    
    -- Play the song associated with this key
    if File.Exists(KEY_SONGS[key]) then
        local sound = Audio.Play(KEY_SONGS[key], { volume = cfg.volume, loop = false })
        activeSounds[key] = sound
    end
    
    return true
end

function OnUp(key)
    if not cfg.enabled then
        return true
    end
    
    -- Stop the song when key is released
    if activeSounds[key] then
        activeSounds[key]:Stop()
        activeSounds[key] = nil
    end
    
    return true
end

function OnTick()
    -- Update volume for all playing sounds if it changed
    for key, sound in pairs(activeSounds) do
        if sound and sound:IsPlaying() then
            sound:SetVolume(cfg.volume)
        else
            activeSounds[key] = nil
        end
    end
end

function OnStop()
    -- Clean up all sounds
    for key, sound in pairs(activeSounds) do
        if sound then
            sound:Stop()
        end
    end
    activeSounds = {}
    Audio.StopAll()
end

function OnBlur()
    -- Stop all sounds when window loses focus
    for key, sound in pairs(activeSounds) do
        if sound then
            sound:Stop()
        end
    end
    activeSounds = {}
    Audio.StopAll()
end

How it works:

  1. KEY_SONGS table — maps keys to song file paths in the songs/ directory. Add or modify entries as needed.
  2. OnDown — when a key is pressed, plays the corresponding song file
  3. OnUp — when the key is released, stops the currently playing song
  4. OnTick — updates volume in real-time if the user adjusts the slider, and cleans up finished sounds
  5. OnBlur/OnStop — stops all sounds for cleanup

Setup:

  • Create a songs/ folder in the same directory as your script
  • Add MP3, WAV, OGG, or FLAC files to it
  • Update KEY_SONGS to map keys to your filenames

Features:

  • Multiple keys can play different songs simultaneously (each key has its own sound handle)
  • Volume slider adjusts all playing sounds in real-time
  • Songs stop immediately when the key is released
  • Graceful cleanup on script stop or window blur

Learn more