91 lines
2.2 KiB
Markdown
91 lines
2.2 KiB
Markdown
# sfxkeeb
|
|
|
|
Annotate keyboard key presses on a video timeline and preview/export mechanical switch sounds mixed with the video audio.
|
|
|
|
## Requirements
|
|
|
|
- [uv](https://docs.astral.sh/uv/) (Python package manager)
|
|
- Node.js 18+ and npm
|
|
- **ffmpeg** on your PATH (required by pydub for audio export)
|
|
|
|
```bash
|
|
# macOS
|
|
brew install ffmpeg
|
|
```
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
# Python dependencies
|
|
uv sync
|
|
|
|
# Frontend dependencies
|
|
cd frontend && npm install
|
|
```
|
|
|
|
## Development
|
|
|
|
Run both servers in separate terminals:
|
|
|
|
```bash
|
|
# Terminal 1 — FastAPI backend (audio export API)
|
|
uv run uvicorn backend.main:app --reload
|
|
|
|
# Terminal 2 — Vite dev server (proxies /api to :8000)
|
|
cd frontend && npm run dev
|
|
```
|
|
|
|
Open http://localhost:5173
|
|
|
|
## Production-like run
|
|
|
|
```bash
|
|
cd frontend && npm run build
|
|
uv run uvicorn backend.main:app --host 127.0.0.1 --port 8000
|
|
```
|
|
|
|
Open http://127.0.0.1:8000
|
|
|
|
## Usage
|
|
|
|
1. **Open Video** — load an MP4 file
|
|
2. Press keys while the playhead is at the desired time to add markers (works while playing or paused)
|
|
3. Select markers to override keys, nudge with arrow keys, or multi-select with marquee drag
|
|
4. Choose a mechanical switch sound from the dropdown
|
|
5. **Save Project** / **Open Project** — JSON with version, markers, and switch setting (no video path)
|
|
6. **Export Audio** — download a WAV file of keyboard sounds only, full video length
|
|
|
|
### Keyboard shortcuts
|
|
|
|
| Shortcut | Action |
|
|
|----------|--------|
|
|
| Ctrl+Space | Play / pause |
|
|
| Arrow keys | Nudge selected marker(s) one frame |
|
|
| Alt+Scroll | Zoom timeline (centers on playhead) |
|
|
| Backspace / Delete | Delete selected marker(s) |
|
|
| Ctrl+A | Select all markers |
|
|
|
|
## Project file format
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"switch": "cherry-mx-blue",
|
|
"markers": [
|
|
{ "id": "m1", "time": 1.234, "key": "a" }
|
|
]
|
|
}
|
|
```
|
|
|
|
Re-open the video manually after loading a project file.
|
|
|
|
## Switch samples
|
|
|
|
Bundled samples are short synthetic click sounds representing Cherry MX Blue (clicky), Red (linear), and Brown (tactile) switches.
|
|
|
|
## Known limitations
|
|
|
|
- Frame stepping uses `video.currentTime` and may land on nearest keyframes for some MP4 encodings
|
|
- Project files do not reference the video file path
|
|
- Very long videos may take longer to export via pydub in-memory overlay
|