@ohm_studio/sdk 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/persist.d.ts +70 -0
- package/dist/persist.d.ts.map +1 -0
- package/dist/persist.js +119 -0
- package/dist/persist.js.map +1 -0
- package/dist/react/index.d.ts +89 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +241 -1
- package/dist/react/index.js.map +1 -1
- package/dist/recorder.d.ts +138 -22
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +446 -44
- package/dist/recorder.js.map +1 -1
- package/package.json +15 -5
package/dist/recorder.d.ts
CHANGED
|
@@ -1,30 +1,105 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Browser
|
|
3
|
-
* stream tracks, chunk collection, and cleanup so customers can ship a
|
|
4
|
-
* working recorder UI in three lines:
|
|
2
|
+
* Browser audio recorder for clinical consults.
|
|
5
3
|
*
|
|
6
|
-
*
|
|
4
|
+
* Wraps `MediaRecorder` + `getUserMedia` + `AudioContext` + `Wake Lock`
|
|
5
|
+
* with clinically-tuned defaults (16 kHz mono, echo-cancel, noise-suppress,
|
|
6
|
+
* auto-gain) and a codec cascade that works on iOS Safari, Firefox, and
|
|
7
|
+
* every Chromium browser.
|
|
8
|
+
*
|
|
9
|
+
* const rec = new Recorder({
|
|
10
|
+
* onLevel: (rms) => setVu(rms),
|
|
11
|
+
* onError: (e) => toast(e.message),
|
|
12
|
+
* maxDurationMs: 10 * 60_000, // hard cap at 10 min
|
|
13
|
+
* silenceAutoStop: { ms: 6000 }, // stop after 6 s of silence
|
|
14
|
+
* wakeLock: true,
|
|
15
|
+
* });
|
|
7
16
|
* await rec.start();
|
|
8
|
-
* const blob = await rec.stop();
|
|
17
|
+
* const blob = await rec.stop(); // → ohm.audio.extract({ file: blob, ... })
|
|
9
18
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* this module doesn't break server bundles.
|
|
19
|
+
* SSR-safe — every browser-only API is touched inside method bodies, never
|
|
20
|
+
* at module scope. Importing this file from a Next.js server bundle is OK.
|
|
13
21
|
*/
|
|
22
|
+
export type RecorderState = "idle" | "starting" | "recording" | "paused" | "stopping";
|
|
23
|
+
export type RecorderErrorCode = "NotSupported" | "PermissionDenied" | "NoMicrophone" | "MicrophoneBusy" | "OverConstrained" | "DeviceLost" | "InvalidState" | "Unknown";
|
|
24
|
+
export declare class RecorderError extends Error {
|
|
25
|
+
code: RecorderErrorCode;
|
|
26
|
+
cause?: unknown;
|
|
27
|
+
constructor(code: RecorderErrorCode, message: string, cause?: unknown);
|
|
28
|
+
}
|
|
14
29
|
export interface RecorderOptions {
|
|
15
30
|
/**
|
|
16
|
-
* MIME type to request from the
|
|
17
|
-
*
|
|
18
|
-
*
|
|
31
|
+
* MIME type to request. Default: best supported from the cascade
|
|
32
|
+
* `audio/webm;codecs=opus` → `audio/mp4;codecs=mp4a.40.2` →
|
|
33
|
+
* `audio/ogg;codecs=opus` → `audio/mp4` → `audio/webm`.
|
|
34
|
+
* Pass an explicit value only if your pipeline needs a specific format.
|
|
19
35
|
*/
|
|
20
36
|
mimeType?: string;
|
|
21
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Audio bitrate in bits-per-second. Default 32 000 (32 kbps Opus is
|
|
39
|
+
* plenty for clinical speech and keeps files tiny).
|
|
40
|
+
*/
|
|
41
|
+
audioBitsPerSecond?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Selected microphone deviceId. Use `Recorder.listMicrophones()` to enumerate.
|
|
44
|
+
*/
|
|
45
|
+
deviceId?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Override `getUserMedia` constraints entirely. If omitted, the SDK applies
|
|
48
|
+
* clinically-tuned defaults: 16 kHz mono, echo cancellation on,
|
|
49
|
+
* noise suppression on, auto-gain on.
|
|
50
|
+
*/
|
|
22
51
|
audioConstraints?: MediaTrackConstraints;
|
|
23
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* If true (default), sets `sampleRate: { ideal: 16000 }`, `channelCount: 1`,
|
|
54
|
+
* and the three voice-cleanup flags. STT models expect 16 kHz mono.
|
|
55
|
+
*/
|
|
56
|
+
clinicalDefaults?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Emit a `dataavailable` chunk every N ms. Required for streaming uploads.
|
|
59
|
+
* Default 0 (one final chunk on stop).
|
|
60
|
+
*/
|
|
61
|
+
timesliceMs?: number;
|
|
62
|
+
/**
|
|
63
|
+
* Hard cap — auto-stop after this many ms of recording. Default off.
|
|
64
|
+
*/
|
|
65
|
+
maxDurationMs?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Auto-stop after sustained silence. RMS below `threshold` for `ms`
|
|
68
|
+
* continuous milliseconds triggers stop. Default off.
|
|
69
|
+
*/
|
|
70
|
+
silenceAutoStop?: {
|
|
71
|
+
/** ms of continuous silence before auto-stop. Default 6000. */
|
|
72
|
+
ms?: number;
|
|
73
|
+
/** Linear-RMS threshold 0–1. Default 0.012 (≈ -38 dBFS). */
|
|
74
|
+
threshold?: number;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Hold a screen Wake Lock while recording, so phones / tablets don't dim.
|
|
78
|
+
* Default false. Falls back silently when the API isn't available.
|
|
79
|
+
*/
|
|
80
|
+
wakeLock?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Pause recording when the tab becomes hidden. Default false.
|
|
83
|
+
* (We never auto-resume — the user has to come back and tap.)
|
|
84
|
+
*/
|
|
85
|
+
pauseOnHidden?: boolean;
|
|
86
|
+
/** Recording state changes. */
|
|
24
87
|
onStateChange?: (state: RecorderState) => void;
|
|
88
|
+
/** Periodic linear RMS level 0–1 (≈ 60 Hz). Wire to a VU meter. */
|
|
89
|
+
onLevel?: (rms: number) => void;
|
|
90
|
+
/** Each `dataavailable` chunk. Useful for streaming uploads. */
|
|
91
|
+
onChunk?: (chunk: Blob) => void;
|
|
92
|
+
/** All recorder errors flow through here in addition to throwing on the awaited call. */
|
|
93
|
+
onError?: (err: RecorderError) => void;
|
|
94
|
+
/** Microphone disconnected (cable unplugged, OS revoked permission). */
|
|
95
|
+
onDeviceLost?: () => void;
|
|
96
|
+
}
|
|
97
|
+
export interface MicrophoneInfo {
|
|
98
|
+
deviceId: string;
|
|
99
|
+
label: string;
|
|
100
|
+
groupId: string;
|
|
25
101
|
}
|
|
26
|
-
|
|
27
|
-
/** Returns true if the runtime supports recording (browser with MediaRecorder). */
|
|
102
|
+
/** True if the runtime supports recording (browser with MediaRecorder + getUserMedia). */
|
|
28
103
|
export declare function isRecordingSupported(): boolean;
|
|
29
104
|
export declare class Recorder {
|
|
30
105
|
private rec;
|
|
@@ -32,23 +107,64 @@ export declare class Recorder {
|
|
|
32
107
|
private stream;
|
|
33
108
|
private state;
|
|
34
109
|
private opts;
|
|
110
|
+
private mime;
|
|
111
|
+
private startedAt;
|
|
112
|
+
private pausedAccumMs;
|
|
113
|
+
private pauseStartedAt;
|
|
114
|
+
private maxStopTimer;
|
|
115
|
+
private audioCtx;
|
|
116
|
+
private analyser;
|
|
117
|
+
private levelSource;
|
|
118
|
+
private levelRafId;
|
|
119
|
+
private levelBuffer;
|
|
120
|
+
private silenceSinceMs;
|
|
121
|
+
private wakeLockSentinel;
|
|
122
|
+
private visibilityHandler;
|
|
35
123
|
constructor(opts?: RecorderOptions);
|
|
36
|
-
/**
|
|
124
|
+
/** Static support check. */
|
|
125
|
+
static isSupported(): boolean;
|
|
126
|
+
/** Pick the best supported MIME type for this browser. */
|
|
127
|
+
static getSupportedMimeType(prefer?: string): string | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* Probe microphone permission *without* requesting it. Returns:
|
|
130
|
+
* "granted" — already allowed
|
|
131
|
+
* "denied" — user has blocked access; calling start() will reject
|
|
132
|
+
* "prompt" — browser will show the dialog on next start()
|
|
133
|
+
* "unknown" — browser doesn't support the Permissions API
|
|
134
|
+
*/
|
|
135
|
+
static probePermission(): Promise<"granted" | "denied" | "prompt" | "unknown">;
|
|
136
|
+
/** Enumerate microphones. Empty `label` until permission is granted at least once. */
|
|
137
|
+
static listMicrophones(): Promise<MicrophoneInfo[]>;
|
|
138
|
+
/** Current state. */
|
|
37
139
|
get currentState(): RecorderState;
|
|
140
|
+
/** Final MIME type the browser is producing (set after `start`). */
|
|
141
|
+
get mimeType(): string | undefined;
|
|
142
|
+
/** Recorded duration in ms (excluding paused time). 0 when idle. */
|
|
143
|
+
getDuration(): number;
|
|
38
144
|
/**
|
|
39
145
|
* Request microphone access and begin recording. Resolves once the
|
|
40
|
-
* underlying MediaRecorder
|
|
41
|
-
* denial or unsupported runtime.
|
|
146
|
+
* underlying MediaRecorder has fired `start`.
|
|
42
147
|
*/
|
|
43
148
|
start(): Promise<void>;
|
|
149
|
+
/** Pause recording. Resumable via `resume()`. */
|
|
150
|
+
pause(): void;
|
|
151
|
+
/** Resume after `pause()`. */
|
|
152
|
+
resume(): void;
|
|
44
153
|
/**
|
|
45
|
-
* Stop recording and
|
|
46
|
-
*
|
|
47
|
-
* Stops all media tracks so the browser's mic indicator clears.
|
|
154
|
+
* Stop recording and return the assembled Blob, ready to pass to
|
|
155
|
+
* `ohm.audio.extract({ file: blob, … })`. Releases mic, wake lock, AudioContext.
|
|
48
156
|
*/
|
|
49
157
|
stop(): Promise<Blob>;
|
|
50
|
-
/**
|
|
158
|
+
/** Stop after `ms` from now. Returns the same promise as `stop()`. */
|
|
159
|
+
stopAfter(ms: number): Promise<Blob>;
|
|
160
|
+
/** Abort — releases everything, no Blob. */
|
|
51
161
|
cancel(): void;
|
|
162
|
+
private startLevelMeter;
|
|
163
|
+
private acquireWakeLock;
|
|
164
|
+
private releaseWakeLock;
|
|
165
|
+
private attachVisibility;
|
|
166
|
+
private detachVisibility;
|
|
167
|
+
private cleanupStream;
|
|
52
168
|
private cleanup;
|
|
53
169
|
private setState;
|
|
54
170
|
}
|
package/dist/recorder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"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"}
|