html-framework-record-ver2.0

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

What it is

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.

Features

Quickstart

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

Architecture

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

How it's built

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.

How it runs

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')

How to apply & reuse

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.

At a glance

CapabilitiesAudio RecordingLocal PersistenceReal-time MeteringChunked StoragePCM Processing
Componentsrecorder-box.jsstorage-indexeddb.jsstorage-memory.jsboot.jsui/harness.jsui/player-mse.js
TechJavaScriptWeb Audio APIIndexedDBScriptProcessorNodeES Modules
Depends onModern BrowserMicrophone Access
Integrates withStatic Web ServersCustom UI Frameworks
PatternsAdapter PatternEvent EmitterModule PatternAsync/Await
Reuse tagsaudio-recordingindexeddbweb-audiopcmno-dependencies

Repo hygiene

✓ all on main — nothing unmerged.