A lightweight, web-only audio recorder that captures PCM data and stores it in IndexedDB for persistent local playback.
https://github.com/davidbmar/html-framework-record-ver2.0 · public · shipped
A browser-based JavaScript library for recording audio directly from the microphone. It bypasses standard MediaRecorder blobs in favor of raw PCM capture via ScriptProcessorNode, chunking audio by time intervals, and persisting these chunks in IndexedDB. It includes adapters for both persistent (IndexedDB) and transient (Memory) storage, along with a basic UI harness for testing and playback.
git clone https://github.com/davidbmar/html-framework-record-ver2.0.git cd html-framework-record-ver2.0 # Serve the web directory using any static server, e.g.: npx serve web/record-ver2.0 # Open the provided URL in a modern browser
flowchart TD
User[User] -->|Interacts| UI[UI Harness]
UI -->|Commands| Boot[boot.js]
Boot -->|Imports| Recorder[recorder-box.js]
Boot -->|Imports| Storage[storage-indexeddb.js]
Recorder -->|Web Audio API| Mic[Microphone]
Recorder -->|PCM Chunks| Storage
Storage -->|Persist| IDB[(IndexedDB)]
Recorder -->|Events: status/meter/chunk| UI
The core logic resides in `recorder-box.js`, which manages the Web Audio API graph (AudioContext, AnalyserNode, ScriptProcessorNode). It accumulates Float32 PCM samples, slices them into configurable time chunks (default 2s), and emits events for status, metering, and chunk completion. Storage is abstracted via adapters (`storage-indexeddb.js` for persistence, `storage-memory.js` for tests). The application bootstraps via `boot.js`, which dynamically imports modules and probes for resource availability.
sequenceDiagram
participant U as User
participant UI as UI Harness
participant RB as RecorderBox
participant WA as Web Audio API
participant ST as Storage Adapter
participant DB as IndexedDB
U->>UI: Click Record
UI->>RB: start()
RB->>WA: getUserMedia()
WA-->>RB: MediaStream
RB->>WA: createScriptProcessor()
loop Every Audio Buffer
WA->>RB: onaudioprocess(data)
RB->>RB: Accumulate PCM
alt Chunk Time Reached
RB->>ST: putChunk({blob, index})
ST->>DB: Transaction Write
RB->>UI: emit('chunk')
end
RB->>RB: Calculate RMS/Peak
RB->>UI: emit('meter')
end
U->>UI: Click Stop
UI->>RB: stop()
RB->>WA: disconnect nodes
RB->>ST: markStatus('completed')
RB->>UI: emit('status', 'idle')
Import `createRecorderBox` and a storage adapter (e.g., `createIndexedDbStorage`). Initialize the storage, pass it to the recorder box, and attach event listeners for 'status', 'meter', and 'chunk' events to update your UI. Call `start()` to begin capturing microphone input and `stop()` to finalize the session.
✓ all on main — nothing unmerged.