Records keypress events and converts them for replay on programmable USB HID devices
Project description
keystroke_transcriber: records your keystrokes and writes an Arduino sketch to replay the same keystrokes
If 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.
Limitations
Currently only supports Digispark: Support for Ducky USB and Teensy devices will be coming soon
Install
Install from pypi:
pip install keystroke_transcriber
keystroke_transcriber command-line arguments
usage: 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_transcriber
For 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 -m
Then, 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file keystroke_transcriber-1.0.1-py3-none-any.whl
.
File metadata
- Download URL: keystroke_transcriber-1.0.1-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.24.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cd585efc0a461414ce5db977f27206ae05f3874446c6211e06ad4a1ab9761ed9 |
|
MD5 | 0d6893a0e3db158218afed6b5128dd4a |
|
BLAKE2b-256 | 25f1360f88012a85e3d238ed552d6dc42732edd2ffc675d3e7b7131a5a742be8 |