Package: keystroke-transcriber
keystroke_transcriber: records your keystrokes and writes an Arduino sketch to replay the same keystrokesIf you need to write arduino sketches for USB HID keyboard emulation (Digispark, Teensy, Ducky USB), then
this module might be useful to you.This module records global keystroke events on your PC (when you tell it to),
and uses the recorded keystroke sequence to write the sketch for you.Simply tell it which programmable USB HID keyboard platform you’re using, and start
pressing keys. keystroke_transcriber will generate a sketch file for you. You can
even choose to maintain the timing between your original keypresses, if you want.LimitationsCurrently only supports Digispark: Support for Ducky USB and Teensy devices will be coming soonInstallInstall from pypi:pip install keystroke_transcriberkeystroke_transcriber command-line argumentsusage: keystroke_transcriber [-h] [-p {oneshot,repeat-forever,repeat-n}]
                             [-t {digispark}] [-o OUTPUT_FILE]
                             [-n REPEAT_COUNT] [-D REPEAT_DELAY_MS]
                             [-d EVENT_DELAY_MS] [-m] [-r RECORD_SECONDS] [-s]
                             [-q]

Records global keypress events until Ctrl-C is pressed (or until a fixed time
has elapsed), and translates them into a program that replays those keypress
events on some programmable USB HID device (e.g. Digispark)

optional arguments:
  -h, --help            show this help message and exit
  -p {oneshot,repeat-forever,repeat-n}, --playback-type {oneshot,repeat-forever,repeat-n}
                        Set the playback style for recorded keystroke
                        sequences (default: oneshot)
  -t {digispark}, --target-type {digispark}
                        Set the type of programmable USB HID device to
                        generate output for (default: digispark)
  -o OUTPUT_FILE, --output-file OUTPUT_FILE
                        Write output to this file, instead of printing output
                        to the terminal (default: None)
  -n REPEAT_COUNT, --repeat-count REPEAT_COUNT
                        Sets how many times the recorded keystroke sequence
                        should be repeated (only used if --playback-type is
                        repeat-n) (default: 1)
  -D REPEAT_DELAY_MS, --repeat-delay-ms REPEAT_DELAY_MS
                        Sets delay between recorded keystroke sequence
                        repetitions, in milliseconds (only used if --playback-
                        type is repeat-n or repeat-forever) (default: 0)
  -d EVENT_DELAY_MS, --event-delay-ms EVENT_DELAY_MS
                        Sets delay between individual keystroke events, in
                        milliseconds (only used if --maintain-timing is False)
                        (default: 0)
  -m, --maintain-timing
                        Maintain timing between recorded keystrokes (default:
                        False)
  -r RECORD_SECONDS, --record-seconds RECORD_SECONDS
                        Record for this many seconds, instead of recording
                        until Ctrl-C is seen (default: None)
  -s, --translate-scan-codes
                        Attempt to translate PS/2 scan codes to USB HID usage
                        ID codes (default: True)
  -q, --quiet-keypresses
                        Don't print detected keypresses to the terminal
                        (default: False)Example Digispark sketch generated by keystroke_transcriberFor this example, I ran keystroke_transcriber with the following arguments to record
keypress events until Ctrl+C, and generate a sketch for Digispark devices:python -m keystroke_transcriber -p oneshot -t digispark -mThen, I performed the following keyboard / mouse actions:Typed Ctrl+R (to open the “run” program)Typed “notepad”, followed by the Enter key (to open the Notepad application)Typed “Hello, from keystroke_transcriber!!!!”Clicked on the terminal window in which I originally ran keystroke_transcriber, to
bring it back into focus, so the Ctrl+C signal in the next step would be sent to the
program, instead of being sent to notepad (This step will not be recorded/replicated by
keystroke_transcriber, since keystroke_transcriber records keypresses and not mouse activity,
but it is necessary to successfully record keystroke sequences so I am including it anyway)Typed Ctrl+C (to stop the recording)After I pressed Ctrl+C, keystroke_transcriber provided the following Digispark sketch:// Auto-generated by keystroke_transcriber. Do not modify!

#include "DigiKeyboard.h"

#define NUM_EVENTS (83u)

// Holds all information required to replay a single keypress
struct key_event
{
    uint8_t key;
    uint8_t mods;
    uint16_t delay_before_ms;
};

// Holds a sequence of one or more keypress events to be replayed
const struct key_event key_events[NUM_EVENTS] PROGMEM =
{
    {0, MOD_GUI_LEFT, 0u}, {21u, MOD_GUI_LEFT, 235u}, {0, MOD_GUI_LEFT, 95u},
    {0, 0, 47u}, {17u, 0, 284u}, {18u, 0, 46u}, {0, 0, 108u}, {23u, 0, 16u},
    {8u, 0, 79u}, {0, 0, 78u}, {19u, 0, 47u}, {0, 0, 94u}, {4u, 0, 61u},
    {7u, 0, 47u}, {0, 0, 93u}, {40u, 0, 188u}, {0, 0, 31u},
    {0, MOD_SHIFT_LEFT, 710u}, {11u, MOD_SHIFT_LEFT, 141u}, {0, 0, 143u},
    {8u, 0, 15u}, {0, 0, 63u}, {15u, 0, 15u}, {0, 0, 62u}, {15u, 0, 31u},
    {18u, 0, 47u}, {0, 0, 142u}, {54u, 0, 63u}, {44u, 0, 46u}, {0, 0, 78u},
    {9u, 0, 15u}, {0, 0, 94u}, {21u, 0, 78u}, {0, 0, 47u}, {18u, 0, 31u},
    {16u, 0, 78u}, {44u, 0, 94u}, {0, 0, 125u}, {14u, 0, 94u}, {0, 0, 48u},
    {8u, 0, 78u}, {0, 0, 31u}, {28u, 0, 62u}, {0, 0, 47u}, {22u, 0, 63u},
    {0, 0, 31u}, {23u, 0, 173u}, {21u, 0, 30u}, {0, 0, 95u}, {18u, 0, 62u},
    {14u, 0, 31u}, {0, 0, 79u}, {8u, 0, 30u}, {0, 0, 94u},
    {0, MOD_SHIFT_LEFT, 46u}, {45u, MOD_SHIFT_LEFT, 31u},
    {0, MOD_SHIFT_LEFT, 31u}, {0, 0, 62u}, {23u, 0, 141u}, {21u, 0, 61u},
    {4u, 0, 108u}, {0, 0, 140u}, {17u, 0, 15u}, {22u, 0, 31u}, {0, 0, 47u},
    {6u, 0, 111u}, {0, 0, 94u}, {21u, 0, 46u}, {0, 0, 47u}, {12u, 0, 31u},
    {5u, 0, 95u}, {0, 0, 139u}, {8u, 0, 46u}, {21u, 0, 47u}, {0, 0, 109u},
    {0, MOD_SHIFT_LEFT, 62u}, {30u, MOD_SHIFT_LEFT, 46u},
    {0, MOD_SHIFT_LEFT, 63u}, {30u, MOD_SHIFT_LEFT, 93u},
    {0, MOD_SHIFT_LEFT, 31u}, {30u, MOD_SHIFT_LEFT, 31u},
    {0, MOD_SHIFT_LEFT, 46u}, {0, 0, 15u}
};

// Send a single keypress event to the USB host
void send_key_event(const struct key_event *event)
{
    // millis() timestamp of the last sent event
    static unsigned long last_event_time_ms = 0u;

    unsigned long elapsed_ms = millis() - last_event_time_ms;

    if (event->delay_before_ms > elapsed_ms)
    {
    DigiKeyboard.delay(event->delay_before_ms - elapsed_ms);
}

last_event_time_ms = millis();
DigiKeyboard.sendKeyPress(event->key, event->mods);

}

// Replay all keypress events stored in PROGMEM
void replay_key_events()
{
    for (unsigned i = 0u; i < NUM_EVENTS; i++)
    {
        struct key_event event;

        event.key = pgm_read_byte_near(&key_events[i].key);
        event.mods = pgm_read_byte_near(&key_events[i].mods);
        event.delay_before_ms = pgm_read_word_near(&key_events[i].delay_before_ms);

        send_key_event(&event);
    }
}

void setup()
{
    replay_key_events();
}

void loop()
{

    DigiKeyboard.update();
}If you flash this sketch on to your Digispark, and plug the Digispark into a Windows
PC, you will see the keyboard activity I just described, complete with the timing of my original keypresses.