05-03-26

Advanced Macro Recorder with Playback Speed

Record and replay hardware input sequences with this Lua script for Rebind. Features adjustable playback speed, smoothing, and file saving for advanced control over your input.

rebindlua scriptmacrorecorderplayback speedinput automationhardware input

Question

I need a macro recorder with playback speed control. Can you provide the script?

Rebind AI

Here's a macro recorder script with playback speed control:

lua
-- rebind: min_sdk=0.1.0
-- rebind: name=Macro Recorder

local cfg = UI.Schema({
    record_key = UI.Keybind("F9", { label = "Record / Save", group = "Controls" }),
    play_key = UI.Keybind("F10", { label = "Play", group = "Controls" }),
    stop_key = UI.Keybind("Escape", { label = "Stop", group = "Controls" }),
    
    macro_name = UI.Text("macro", { 
        label = "Macro Name", 
        placeholder = "Name for saving",
        maxLength = 50,
        group = "Settings"
    }),
    
    playback_speed = UI.Slider(100, { 
        min = 25, 
        max = 400, 
        suffix = "%",
        label = "Playback Speed",
        group = "Settings"
    }),
    
    smooth_playback = UI.Toggle(false, { 
        label = "Smooth Playback (Spline)",
        tooltip = "Apply curve smoothing to recorded macro",
        group = "Settings"
    }),
    
    precision = UI.Select("normal", { "normal", "high" }, {
        label = "Recording Precision",
        group = "Settings"
    }),
})

local isRecording = false
local activeMacro = nil
local recordedMacro = nil

function OnStart()
    File.MkDir("macros")
    Log.Info("Macro Recorder ready")
    Log.Info("Record: " .. cfg.record_key .. " | Play: " .. cfg.play_key .. " | Stop: " .. cfg.stop_key)
end

function OnStop()
    if isRecording then
        Macro.Finish()
        isRecording = false
    end
    if activeMacro and activeMacro:IsPlaying() then
        activeMacro:Stop()
    end
end

function OnDown(key)
    -- Toggle recording
    if key == cfg.record_key then
        if isRecording then
            -- Stop recording and save
            recordedMacro = Macro.Finish()
            isRecording = false
            
            if recordedMacro and #recordedMacro > 0 then
                -- Apply smoothing if enabled
                if cfg.smooth_playback then
                    recordedMacro = Math.Spline(recordedMacro, 0.5)
                    Log.Info("Applied spline smoothing")
                end
                
                -- Save to file
                local filename = cfg.macro_name:match("^%s*(.-)%s*$") -- trim whitespace
                if filename == "" then filename = "macro" end
                
                local filepath = "macros/" .. filename .. ".json"
                File.WriteJSON(filepath, recordedMacro)
                
                UI.Notify("Macro saved: " .. filename, "success")
                Log.Info("Saved " .. #recordedMacro .. " actions to " .. filepath)
                Audio.Beep()
            else
                UI.Notify("No actions recorded", "warning")
            end
        else
            -- Start recording
            Macro.Record({ 
                precision = cfg.precision,
                ignoreMouse = false,
                ignoreKeyboard = false
            })
            isRecording = true
            
            UI.Notify("Recording...", "info")
            Log.Info("Recording started")
        end
        return false
    end
    
    -- Play macro
    if key == cfg.play_key then
        local filename = cfg.macro_name:match("^%s*(.-)%s*$")
        if filename == "" then filename = "macro" end
        
        local filepath = "macros/" .. filename .. ".json"
        
        if not File.Exists(filepath) then
            UI.Notify("Macro not found: " .. filename, "error")
            Log.Warn("File not found: " .. filepath)
            return false
        end
        
        local macro = File.ReadJSON(filepath)
        if not macro or #macro == 0 then
            UI.Notify("Macro is empty", "warning")
            return false
        end
        
        local speed = cfg.playback_speed / 100
        activeMacro = Macro.Play(macro, speed, "replace")
        
        UI.Notify("Playing: " .. filename .. " (" .. cfg.playback_speed .. "%)", "info")
        Log.Info("Playing " .. #macro .. " actions at " .. cfg.playback_speed .. "% speed")
        
        return false
    end
    
    -- Stop playback
    if key == cfg.stop_key then
        if isRecording then
            recordedMacro = Macro.Finish()
            isRecording = false
            UI.Notify("Recording cancelled", "info")
            Log.Info("Recording cancelled")
        elseif activeMacro and activeMacro:IsPlaying() then
            activeMacro:Stop()
            activeMacro = nil
            UI.Notify("Playback stopped", "info")
            Log.Info("Playback stopped")
        end
        return false
    end
    
    return true
end

function OnBlur()
    -- Clean up on focus loss
    if isRecording then
        Macro.Finish()
        isRecording = false
        Log.Info("Recording cancelled (window lost focus)")
    end
    if activeMacro and activeMacro:IsPlaying() then
        activeMacro:Stop()
        activeMacro = nil
    end
end

How It Works

This macro recorder lets you capture input sequences and replay them at adjustable speeds:

Recording:

  • Press F9 to start recording all keyboard and mouse input
  • Perform your sequence
  • Press F9 again to stop and save
  • Macros are saved as JSON files in a macros/ subfolder

Playback:

  • Press F10 to play the last recorded macro
  • Adjust Playback Speed slider (25%-400%) to control replay speed
  • Speed is a multiplier: 50% = half speed, 200% = double speed

Features:

  • Smooth Playback: Apply Catmull-Rom curve smoothing for fluid motion patterns
  • Precision Control: Choose between "normal" or "high" precision recording
  • Stop Key: Press Escape to cancel recording or stop playback
  • Auto-save: Macros are persisted to disk with your chosen name
  • Logging: All actions logged to the Logs tab for debugging

File Organization:

  • Macros are stored in JSON format in script-directory/macros/
  • You can edit or export macro files programmatically
  • File names are sanitized (whitespace trimmed)

Safety:

  • Recording is cancelled automatically if you switch windows (OnBlur)
  • Playback stops if you change focus
  • Invalid or missing macros show clear error messages

Learn more: