@usefy/screen-recorder 0.1.3
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/README.md +631 -0
- package/dist/index.d.mts +1092 -0
- package/dist/index.d.ts +1092 -0
- package/dist/index.js +3473 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3410 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +1267 -0
- package/package.json +80 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1092 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, FC } from 'react';
|
|
3
|
+
import { ClassValue } from 'clsx';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Possible states of the screen recording process
|
|
7
|
+
*/
|
|
8
|
+
type RecordingState$1 = "idle" | "requesting" | "countdown" | "recording" | "paused" | "stopped" | "error";
|
|
9
|
+
/**
|
|
10
|
+
* Error codes for screen recording errors
|
|
11
|
+
*/
|
|
12
|
+
type ScreenRecorderErrorCode = "PERMISSION_DENIED" | "NOT_SUPPORTED" | "MEDIA_RECORDER_ERROR" | "STREAM_ENDED" | "NO_STREAM" | "ENCODING_ERROR" | "UNKNOWN";
|
|
13
|
+
/**
|
|
14
|
+
* Error object for screen recording errors
|
|
15
|
+
*/
|
|
16
|
+
interface ScreenRecorderError {
|
|
17
|
+
/** Error code for programmatic handling */
|
|
18
|
+
code: ScreenRecorderErrorCode;
|
|
19
|
+
/** Human-readable error message */
|
|
20
|
+
message: string;
|
|
21
|
+
/** Original error if available */
|
|
22
|
+
originalError?: Error;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Result of a completed recording
|
|
26
|
+
*/
|
|
27
|
+
interface RecordingResult {
|
|
28
|
+
/** Recorded video blob */
|
|
29
|
+
blob: Blob;
|
|
30
|
+
/** Blob URL for preview/playback */
|
|
31
|
+
url: string;
|
|
32
|
+
/** Duration in seconds */
|
|
33
|
+
duration: number;
|
|
34
|
+
/** File size in bytes */
|
|
35
|
+
size: number;
|
|
36
|
+
/** MIME type */
|
|
37
|
+
mimeType: string;
|
|
38
|
+
/** Recording timestamp */
|
|
39
|
+
timestamp: Date;
|
|
40
|
+
/** Whether audio was included */
|
|
41
|
+
hasAudio: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Quality preset configuration
|
|
45
|
+
*/
|
|
46
|
+
interface QualityPreset {
|
|
47
|
+
/** Video bitrate in bits per second */
|
|
48
|
+
videoBitsPerSecond: number;
|
|
49
|
+
/** Video width (optional, uses source resolution if not specified) */
|
|
50
|
+
width?: number;
|
|
51
|
+
/** Video height (optional, uses source resolution if not specified) */
|
|
52
|
+
height?: number;
|
|
53
|
+
/** Frame rate */
|
|
54
|
+
frameRate?: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Quality option - can be a preset name or custom configuration
|
|
58
|
+
*/
|
|
59
|
+
type QualityOption = "low" | "medium" | "high" | QualityPreset;
|
|
60
|
+
/**
|
|
61
|
+
* Audio configuration options
|
|
62
|
+
*/
|
|
63
|
+
interface AudioConfig {
|
|
64
|
+
/** Capture system/tab audio */
|
|
65
|
+
system?: boolean;
|
|
66
|
+
/** Capture microphone input */
|
|
67
|
+
microphone?: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Audio option - can be boolean or detailed configuration
|
|
71
|
+
*/
|
|
72
|
+
type AudioOption = boolean | AudioConfig;
|
|
73
|
+
/**
|
|
74
|
+
* Position of the floating trigger button
|
|
75
|
+
*/
|
|
76
|
+
type TriggerPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
77
|
+
/**
|
|
78
|
+
* Theme setting for the component
|
|
79
|
+
*/
|
|
80
|
+
type ThemeOption = "light" | "dark" | "system";
|
|
81
|
+
/**
|
|
82
|
+
* Render mode for floating UI elements
|
|
83
|
+
*/
|
|
84
|
+
type RenderMode = "portal" | "inline";
|
|
85
|
+
/**
|
|
86
|
+
* Props for the ScreenRecorder component
|
|
87
|
+
*/
|
|
88
|
+
interface ScreenRecorderProps {
|
|
89
|
+
/**
|
|
90
|
+
* Maximum recording duration in seconds
|
|
91
|
+
* Set to Infinity for unlimited duration
|
|
92
|
+
* @default 300 (5 minutes)
|
|
93
|
+
*/
|
|
94
|
+
maxDuration?: number;
|
|
95
|
+
/**
|
|
96
|
+
* Countdown seconds before recording starts
|
|
97
|
+
* Set to false to disable countdown
|
|
98
|
+
* @default 3
|
|
99
|
+
*/
|
|
100
|
+
countdown?: number | false;
|
|
101
|
+
/**
|
|
102
|
+
* Include audio in recording
|
|
103
|
+
* @default false
|
|
104
|
+
*/
|
|
105
|
+
audio?: AudioOption;
|
|
106
|
+
/**
|
|
107
|
+
* Video quality settings
|
|
108
|
+
* @default 'medium'
|
|
109
|
+
*/
|
|
110
|
+
quality?: QualityOption;
|
|
111
|
+
/**
|
|
112
|
+
* Output format
|
|
113
|
+
* @default 'webm'
|
|
114
|
+
*/
|
|
115
|
+
format?: "webm" | "mp4";
|
|
116
|
+
/**
|
|
117
|
+
* MIME type for MediaRecorder
|
|
118
|
+
* @default 'video/webm;codecs=vp9'
|
|
119
|
+
*/
|
|
120
|
+
mimeType?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Position of the floating trigger button
|
|
123
|
+
* @default 'bottom-right'
|
|
124
|
+
*/
|
|
125
|
+
position?: TriggerPosition;
|
|
126
|
+
/**
|
|
127
|
+
* Custom trigger button content
|
|
128
|
+
*/
|
|
129
|
+
triggerContent?: ReactNode;
|
|
130
|
+
/**
|
|
131
|
+
* Show preview modal after recording
|
|
132
|
+
* @default true
|
|
133
|
+
*/
|
|
134
|
+
showPreview?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Show timer during recording
|
|
137
|
+
* @default true
|
|
138
|
+
*/
|
|
139
|
+
showTimer?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Z-index for floating elements
|
|
142
|
+
* @default 9999
|
|
143
|
+
*/
|
|
144
|
+
zIndex?: number;
|
|
145
|
+
/**
|
|
146
|
+
* Theme override
|
|
147
|
+
* @default 'system'
|
|
148
|
+
*/
|
|
149
|
+
theme?: ThemeOption;
|
|
150
|
+
/**
|
|
151
|
+
* Custom class name
|
|
152
|
+
*/
|
|
153
|
+
className?: string;
|
|
154
|
+
/**
|
|
155
|
+
* Default filename for download (without extension)
|
|
156
|
+
* Can be a string or a function that receives the timestamp
|
|
157
|
+
* @default 'screen-recording'
|
|
158
|
+
*/
|
|
159
|
+
filename?: string | ((timestamp: Date) => string);
|
|
160
|
+
/**
|
|
161
|
+
* Called when recording starts
|
|
162
|
+
*/
|
|
163
|
+
onRecordingStart?: () => void;
|
|
164
|
+
/**
|
|
165
|
+
* Called when recording stops with the result
|
|
166
|
+
*/
|
|
167
|
+
onRecordingStop?: (result: RecordingResult) => void;
|
|
168
|
+
/**
|
|
169
|
+
* Called when recording is paused
|
|
170
|
+
*/
|
|
171
|
+
onPause?: () => void;
|
|
172
|
+
/**
|
|
173
|
+
* Called when recording is resumed
|
|
174
|
+
*/
|
|
175
|
+
onResume?: () => void;
|
|
176
|
+
/**
|
|
177
|
+
* Called when user downloads the recording
|
|
178
|
+
*/
|
|
179
|
+
onDownload?: (result: RecordingResult) => void;
|
|
180
|
+
/**
|
|
181
|
+
* Called when an error occurs
|
|
182
|
+
*/
|
|
183
|
+
onError?: (error: ScreenRecorderError) => void;
|
|
184
|
+
/**
|
|
185
|
+
* Called when user denies screen share permission
|
|
186
|
+
*/
|
|
187
|
+
onPermissionDenied?: () => void;
|
|
188
|
+
/**
|
|
189
|
+
* Called on each recording tick (every second)
|
|
190
|
+
*/
|
|
191
|
+
onTick?: (elapsed: number, remaining: number | null) => void;
|
|
192
|
+
/**
|
|
193
|
+
* Auto-download after recording stops
|
|
194
|
+
* @default false
|
|
195
|
+
*/
|
|
196
|
+
autoDownload?: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Disable the component
|
|
199
|
+
*/
|
|
200
|
+
disabled?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Render mode for floating UI
|
|
203
|
+
* @default 'portal'
|
|
204
|
+
*/
|
|
205
|
+
renderMode?: RenderMode;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Options for the useScreenRecorder hook
|
|
209
|
+
*/
|
|
210
|
+
interface UseScreenRecorderOptions {
|
|
211
|
+
/**
|
|
212
|
+
* Maximum recording duration in seconds
|
|
213
|
+
* Set to Infinity for unlimited duration
|
|
214
|
+
* @default 300 (5 minutes)
|
|
215
|
+
*/
|
|
216
|
+
maxDuration?: number;
|
|
217
|
+
/**
|
|
218
|
+
* Countdown seconds before recording starts
|
|
219
|
+
* Set to false to disable countdown
|
|
220
|
+
* @default 3
|
|
221
|
+
*/
|
|
222
|
+
countdown?: number | false;
|
|
223
|
+
/**
|
|
224
|
+
* Include audio in recording
|
|
225
|
+
* @default false
|
|
226
|
+
*/
|
|
227
|
+
audio?: AudioOption;
|
|
228
|
+
/**
|
|
229
|
+
* Video quality settings
|
|
230
|
+
* @default 'medium'
|
|
231
|
+
*/
|
|
232
|
+
quality?: QualityOption;
|
|
233
|
+
/**
|
|
234
|
+
* MIME type for MediaRecorder
|
|
235
|
+
* @default 'video/webm;codecs=vp9'
|
|
236
|
+
*/
|
|
237
|
+
mimeType?: string;
|
|
238
|
+
/**
|
|
239
|
+
* Called when an error occurs
|
|
240
|
+
*/
|
|
241
|
+
onError?: (error: ScreenRecorderError) => void;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Return type for the useScreenRecorder hook
|
|
245
|
+
*/
|
|
246
|
+
interface UseScreenRecorderReturn {
|
|
247
|
+
/** Current recording state */
|
|
248
|
+
state: RecordingState$1;
|
|
249
|
+
/** Whether currently recording */
|
|
250
|
+
isRecording: boolean;
|
|
251
|
+
/** Whether recording is paused */
|
|
252
|
+
isPaused: boolean;
|
|
253
|
+
/** Whether in countdown phase */
|
|
254
|
+
isCountingDown: boolean;
|
|
255
|
+
/** Current countdown value (null when not counting) */
|
|
256
|
+
countdownValue: number | null;
|
|
257
|
+
/** Elapsed recording time in seconds */
|
|
258
|
+
elapsed: number;
|
|
259
|
+
/** Remaining time if maxDuration set (null if no limit) */
|
|
260
|
+
remaining: number | null;
|
|
261
|
+
/** Formatted elapsed time (MM:SS) */
|
|
262
|
+
elapsedFormatted: string;
|
|
263
|
+
/** Recording result after stop (null until recording completes) */
|
|
264
|
+
result: RecordingResult | null;
|
|
265
|
+
/** Current error if any */
|
|
266
|
+
error: ScreenRecorderError | null;
|
|
267
|
+
/** Whether browser supports screen recording */
|
|
268
|
+
isSupported: boolean;
|
|
269
|
+
/** Start screen recording (opens browser picker) */
|
|
270
|
+
start: () => Promise<void>;
|
|
271
|
+
/** Stop recording */
|
|
272
|
+
stop: () => void;
|
|
273
|
+
/** Pause recording */
|
|
274
|
+
pause: () => void;
|
|
275
|
+
/** Resume paused recording */
|
|
276
|
+
resume: () => void;
|
|
277
|
+
/** Toggle pause/resume */
|
|
278
|
+
togglePause: () => void;
|
|
279
|
+
/** Download the recording */
|
|
280
|
+
download: (filename?: string) => void;
|
|
281
|
+
/** Reset state for new recording */
|
|
282
|
+
reset: () => void;
|
|
283
|
+
/** Get blob URL for preview */
|
|
284
|
+
getPreviewUrl: () => string | null;
|
|
285
|
+
/** Revoke blob URL (cleanup) */
|
|
286
|
+
revokePreviewUrl: () => void;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Browser support detection result
|
|
290
|
+
*/
|
|
291
|
+
interface BrowserSupport {
|
|
292
|
+
/** Whether screen recording is fully supported */
|
|
293
|
+
isSupported: boolean;
|
|
294
|
+
/** Whether getDisplayMedia is available */
|
|
295
|
+
hasDisplayMedia: boolean;
|
|
296
|
+
/** Whether MediaRecorder is available */
|
|
297
|
+
hasMediaRecorder: boolean;
|
|
298
|
+
/** List of supported MIME types */
|
|
299
|
+
supportedMimeTypes: string[];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* ScreenRecorder component for capturing screen recordings
|
|
304
|
+
*
|
|
305
|
+
* A complete UI solution for screen recording with floating trigger,
|
|
306
|
+
* recording controls, countdown, and preview modal.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```tsx
|
|
310
|
+
* function App() {
|
|
311
|
+
* return (
|
|
312
|
+
* <div>
|
|
313
|
+
* <h1>My Application</h1>
|
|
314
|
+
* <ScreenRecorder
|
|
315
|
+
* onRecordingStop={(result) => {
|
|
316
|
+
* console.log('Recording complete:', result);
|
|
317
|
+
* }}
|
|
318
|
+
* />
|
|
319
|
+
* </div>
|
|
320
|
+
* );
|
|
321
|
+
* }
|
|
322
|
+
* ```
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```tsx
|
|
326
|
+
* // Bug report integration
|
|
327
|
+
* function BugReportForm() {
|
|
328
|
+
* const [recording, setRecording] = useState<RecordingResult | null>(null);
|
|
329
|
+
*
|
|
330
|
+
* return (
|
|
331
|
+
* <form>
|
|
332
|
+
* <textarea placeholder="Describe the bug..." />
|
|
333
|
+
* <ScreenRecorder
|
|
334
|
+
* position="bottom-left"
|
|
335
|
+
* maxDuration={60}
|
|
336
|
+
* onRecordingStop={setRecording}
|
|
337
|
+
* triggerContent={
|
|
338
|
+
* recording ? "✓ Recording attached" : "📹 Record screen"
|
|
339
|
+
* }
|
|
340
|
+
* />
|
|
341
|
+
* <button type="submit">Submit</button>
|
|
342
|
+
* </form>
|
|
343
|
+
* );
|
|
344
|
+
* }
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
declare const ScreenRecorder: react.ForwardRefExoticComponent<ScreenRecorderProps & react.RefAttributes<HTMLDivElement>>;
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Main hook for screen recording functionality
|
|
351
|
+
*
|
|
352
|
+
* Combines display media capture, media recording, timer, and countdown
|
|
353
|
+
* into a unified state machine for screen recording.
|
|
354
|
+
*
|
|
355
|
+
* @param options - Configuration options
|
|
356
|
+
* @returns Screen recorder state and controls
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```tsx
|
|
360
|
+
* function CustomRecorder() {
|
|
361
|
+
* const {
|
|
362
|
+
* state,
|
|
363
|
+
* isRecording,
|
|
364
|
+
* elapsed,
|
|
365
|
+
* elapsedFormatted,
|
|
366
|
+
* result,
|
|
367
|
+
* start,
|
|
368
|
+
* stop,
|
|
369
|
+
* pause,
|
|
370
|
+
* resume,
|
|
371
|
+
* download,
|
|
372
|
+
* reset,
|
|
373
|
+
* isSupported,
|
|
374
|
+
* error,
|
|
375
|
+
* } = useScreenRecorder({
|
|
376
|
+
* maxDuration: 120,
|
|
377
|
+
* audio: true,
|
|
378
|
+
* countdown: 3,
|
|
379
|
+
* });
|
|
380
|
+
*
|
|
381
|
+
* if (!isSupported) {
|
|
382
|
+
* return <p>Screen recording is not supported.</p>;
|
|
383
|
+
* }
|
|
384
|
+
*
|
|
385
|
+
* return (
|
|
386
|
+
* <div>
|
|
387
|
+
* <p>State: {state}</p>
|
|
388
|
+
* <p>Time: {elapsedFormatted}</p>
|
|
389
|
+
* {state === 'idle' && <button onClick={start}>Start</button>}
|
|
390
|
+
* {isRecording && <button onClick={stop}>Stop</button>}
|
|
391
|
+
* {result && <video src={result.url} controls />}
|
|
392
|
+
* </div>
|
|
393
|
+
* );
|
|
394
|
+
* }
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
397
|
+
declare function useScreenRecorder(options?: UseScreenRecorderOptions): UseScreenRecorderReturn;
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Predefined quality presets for recording
|
|
401
|
+
*/
|
|
402
|
+
declare const QUALITY_PRESETS: Record<"low" | "medium" | "high", QualityPreset>;
|
|
403
|
+
/**
|
|
404
|
+
* Default values for screen recorder options
|
|
405
|
+
*/
|
|
406
|
+
declare const DEFAULT_OPTIONS: {
|
|
407
|
+
/** Default maximum recording duration (5 minutes) */
|
|
408
|
+
readonly maxDuration: 300;
|
|
409
|
+
/** Default countdown duration (3 seconds) */
|
|
410
|
+
readonly countdown: 3;
|
|
411
|
+
/** Default audio setting */
|
|
412
|
+
readonly audio: false;
|
|
413
|
+
/** Default quality preset */
|
|
414
|
+
readonly quality: "medium";
|
|
415
|
+
/** Default output format */
|
|
416
|
+
readonly format: "webm";
|
|
417
|
+
/** Default MIME type for recording */
|
|
418
|
+
readonly mimeType: "video/webm;codecs=vp9";
|
|
419
|
+
/** Default filename */
|
|
420
|
+
readonly filename: "screen-recording";
|
|
421
|
+
/** Default position */
|
|
422
|
+
readonly position: "bottom-right";
|
|
423
|
+
/** Default z-index */
|
|
424
|
+
readonly zIndex: 9999;
|
|
425
|
+
/** Default theme */
|
|
426
|
+
readonly theme: "system";
|
|
427
|
+
/** Default render mode */
|
|
428
|
+
readonly renderMode: "portal";
|
|
429
|
+
/** Default show preview */
|
|
430
|
+
readonly showPreview: true;
|
|
431
|
+
/** Default show timer */
|
|
432
|
+
readonly showTimer: true;
|
|
433
|
+
/** Default auto download */
|
|
434
|
+
readonly autoDownload: false;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* MIME types to check for browser support, in order of preference
|
|
438
|
+
*/
|
|
439
|
+
declare const SUPPORTED_MIME_TYPES: readonly ["video/webm;codecs=vp9,opus", "video/webm;codecs=vp9", "video/webm;codecs=vp8,opus", "video/webm;codecs=vp8", "video/webm", "video/mp4"];
|
|
440
|
+
/**
|
|
441
|
+
* Human-readable error messages for each error code
|
|
442
|
+
*/
|
|
443
|
+
declare const ERROR_MESSAGES: Record<ScreenRecorderErrorCode, string>;
|
|
444
|
+
/**
|
|
445
|
+
* Timer warning threshold (30 seconds remaining)
|
|
446
|
+
*/
|
|
447
|
+
declare const TIMER_WARNING_THRESHOLD = 30;
|
|
448
|
+
/**
|
|
449
|
+
* Timer critical threshold (10 seconds remaining)
|
|
450
|
+
*/
|
|
451
|
+
declare const TIMER_CRITICAL_THRESHOLD = 10;
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Gets the best supported MIME type
|
|
455
|
+
*/
|
|
456
|
+
declare function getBestMimeType(): string | null;
|
|
457
|
+
/**
|
|
458
|
+
* Hook to detect browser support for screen recording
|
|
459
|
+
*
|
|
460
|
+
* @returns Browser support information
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```tsx
|
|
464
|
+
* function RecorderComponent() {
|
|
465
|
+
* const { isSupported, hasDisplayMedia, supportedMimeTypes } = useBrowserSupport();
|
|
466
|
+
*
|
|
467
|
+
* if (!isSupported) {
|
|
468
|
+
* return <p>Screen recording is not supported</p>;
|
|
469
|
+
* }
|
|
470
|
+
*
|
|
471
|
+
* return <button>Start Recording</button>;
|
|
472
|
+
* }
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
declare function useBrowserSupport(): BrowserSupport;
|
|
476
|
+
/**
|
|
477
|
+
* Checks browser support without React hooks (for one-time checks)
|
|
478
|
+
*/
|
|
479
|
+
declare function checkBrowserSupport(): BrowserSupport;
|
|
480
|
+
|
|
481
|
+
interface UseDisplayMediaOptions {
|
|
482
|
+
/**
|
|
483
|
+
* Audio configuration
|
|
484
|
+
*/
|
|
485
|
+
audio?: AudioOption;
|
|
486
|
+
/**
|
|
487
|
+
* Called when an error occurs
|
|
488
|
+
*/
|
|
489
|
+
onError?: (error: ScreenRecorderError) => void;
|
|
490
|
+
/**
|
|
491
|
+
* Called when the stream ends (user stops sharing via browser)
|
|
492
|
+
*/
|
|
493
|
+
onStreamEnded?: () => void;
|
|
494
|
+
}
|
|
495
|
+
interface UseDisplayMediaReturn {
|
|
496
|
+
/** Current media stream (null if not capturing) */
|
|
497
|
+
stream: MediaStream | null;
|
|
498
|
+
/** Whether stream is active */
|
|
499
|
+
isStreaming: boolean;
|
|
500
|
+
/** Request screen capture from user */
|
|
501
|
+
requestStream: () => Promise<MediaStream | null>;
|
|
502
|
+
/** Stop the current stream */
|
|
503
|
+
stopStream: () => void;
|
|
504
|
+
/** Current error if any */
|
|
505
|
+
error: ScreenRecorderError | null;
|
|
506
|
+
/** Whether audio is being captured */
|
|
507
|
+
hasAudio: boolean;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Hook to manage screen capture using getDisplayMedia API
|
|
511
|
+
*
|
|
512
|
+
* @param options - Configuration options
|
|
513
|
+
* @returns Display media state and controls
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```tsx
|
|
517
|
+
* function ScreenCapture() {
|
|
518
|
+
* const { stream, requestStream, stopStream, error } = useDisplayMedia({
|
|
519
|
+
* audio: true,
|
|
520
|
+
* onStreamEnded: () => console.log('User stopped sharing'),
|
|
521
|
+
* });
|
|
522
|
+
*
|
|
523
|
+
* return (
|
|
524
|
+
* <button onClick={stream ? stopStream : requestStream}>
|
|
525
|
+
* {stream ? 'Stop' : 'Start'} Sharing
|
|
526
|
+
* </button>
|
|
527
|
+
* );
|
|
528
|
+
* }
|
|
529
|
+
* ```
|
|
530
|
+
*/
|
|
531
|
+
declare function useDisplayMedia(options?: UseDisplayMediaOptions): UseDisplayMediaReturn;
|
|
532
|
+
|
|
533
|
+
interface UseMediaRecorderOptions {
|
|
534
|
+
/**
|
|
535
|
+
* Quality preset or custom configuration
|
|
536
|
+
*/
|
|
537
|
+
quality?: QualityOption;
|
|
538
|
+
/**
|
|
539
|
+
* MIME type for recording
|
|
540
|
+
*/
|
|
541
|
+
mimeType?: string;
|
|
542
|
+
/**
|
|
543
|
+
* Time slice for data events (ms)
|
|
544
|
+
* @default 1000
|
|
545
|
+
*/
|
|
546
|
+
timeslice?: number;
|
|
547
|
+
/**
|
|
548
|
+
* Called when recording data is available
|
|
549
|
+
*/
|
|
550
|
+
onDataAvailable?: (data: Blob) => void;
|
|
551
|
+
/**
|
|
552
|
+
* Called when recording starts
|
|
553
|
+
*/
|
|
554
|
+
onStart?: () => void;
|
|
555
|
+
/**
|
|
556
|
+
* Called when recording stops
|
|
557
|
+
*/
|
|
558
|
+
onStop?: (blob: Blob) => void;
|
|
559
|
+
/**
|
|
560
|
+
* Called when an error occurs
|
|
561
|
+
*/
|
|
562
|
+
onError?: (error: ScreenRecorderError) => void;
|
|
563
|
+
}
|
|
564
|
+
interface UseMediaRecorderReturn {
|
|
565
|
+
/** MediaRecorder instance */
|
|
566
|
+
recorder: MediaRecorder | null;
|
|
567
|
+
/** Current recording state */
|
|
568
|
+
state: RecordingState;
|
|
569
|
+
/** Start recording */
|
|
570
|
+
start: () => void;
|
|
571
|
+
/** Stop recording */
|
|
572
|
+
stop: () => void;
|
|
573
|
+
/** Pause recording */
|
|
574
|
+
pause: () => void;
|
|
575
|
+
/** Resume recording */
|
|
576
|
+
resume: () => void;
|
|
577
|
+
/** Recorded blob (available after stop) */
|
|
578
|
+
blob: Blob | null;
|
|
579
|
+
/** MIME type being used */
|
|
580
|
+
mimeType: string;
|
|
581
|
+
/** Current error if any */
|
|
582
|
+
error: ScreenRecorderError | null;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Hook to manage MediaRecorder for video recording
|
|
586
|
+
*
|
|
587
|
+
* @param stream - MediaStream to record
|
|
588
|
+
* @param options - Configuration options
|
|
589
|
+
* @returns MediaRecorder state and controls
|
|
590
|
+
*
|
|
591
|
+
* @example
|
|
592
|
+
* ```tsx
|
|
593
|
+
* function Recorder({ stream }) {
|
|
594
|
+
* const { state, start, stop, pause, resume, blob } = useMediaRecorder(stream, {
|
|
595
|
+
* quality: 'high',
|
|
596
|
+
* onStop: (blob) => console.log('Recording complete:', blob),
|
|
597
|
+
* });
|
|
598
|
+
*
|
|
599
|
+
* return (
|
|
600
|
+
* <div>
|
|
601
|
+
* <p>State: {state}</p>
|
|
602
|
+
* <button onClick={start}>Start</button>
|
|
603
|
+
* <button onClick={stop}>Stop</button>
|
|
604
|
+
* </div>
|
|
605
|
+
* );
|
|
606
|
+
* }
|
|
607
|
+
* ```
|
|
608
|
+
*/
|
|
609
|
+
declare function useMediaRecorder(stream: MediaStream | null, options?: UseMediaRecorderOptions): UseMediaRecorderReturn;
|
|
610
|
+
|
|
611
|
+
interface UseTimerOptions {
|
|
612
|
+
/**
|
|
613
|
+
* Maximum duration in seconds (timer will auto-stop at this limit)
|
|
614
|
+
*/
|
|
615
|
+
maxDuration?: number;
|
|
616
|
+
/**
|
|
617
|
+
* Callback fired every second with elapsed time
|
|
618
|
+
*/
|
|
619
|
+
onTick?: (elapsed: number, remaining: number | null) => void;
|
|
620
|
+
/**
|
|
621
|
+
* Callback fired when max duration is reached
|
|
622
|
+
*/
|
|
623
|
+
onComplete?: () => void;
|
|
624
|
+
}
|
|
625
|
+
interface UseTimerReturn {
|
|
626
|
+
/** Elapsed time in seconds */
|
|
627
|
+
elapsed: number;
|
|
628
|
+
/** Formatted elapsed time (MM:SS) */
|
|
629
|
+
elapsedFormatted: string;
|
|
630
|
+
/** Remaining time if maxDuration set (null if no limit) */
|
|
631
|
+
remaining: number | null;
|
|
632
|
+
/** Whether timer is currently running */
|
|
633
|
+
isRunning: boolean;
|
|
634
|
+
/** Start the timer */
|
|
635
|
+
start: () => void;
|
|
636
|
+
/** Stop the timer */
|
|
637
|
+
stop: () => void;
|
|
638
|
+
/** Pause the timer (keeps elapsed time) */
|
|
639
|
+
pause: () => void;
|
|
640
|
+
/** Resume a paused timer */
|
|
641
|
+
resume: () => void;
|
|
642
|
+
/** Reset the timer to zero */
|
|
643
|
+
reset: () => void;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Format seconds as MM:SS
|
|
647
|
+
*/
|
|
648
|
+
declare function formatTime(seconds: number): string;
|
|
649
|
+
/**
|
|
650
|
+
* Hook to manage a timer for recording duration
|
|
651
|
+
*
|
|
652
|
+
* @param options - Configuration options
|
|
653
|
+
* @returns Timer state and controls
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```tsx
|
|
657
|
+
* function RecordingTimer() {
|
|
658
|
+
* const { elapsed, elapsedFormatted, remaining, start, stop, reset, isRunning } = useTimer({
|
|
659
|
+
* maxDuration: 60,
|
|
660
|
+
* onTick: (elapsed) => console.log(`Recording: ${elapsed}s`),
|
|
661
|
+
* onComplete: () => console.log('Max duration reached'),
|
|
662
|
+
* });
|
|
663
|
+
*
|
|
664
|
+
* return (
|
|
665
|
+
* <div>
|
|
666
|
+
* <p>{elapsedFormatted}</p>
|
|
667
|
+
* <button onClick={isRunning ? stop : start}>
|
|
668
|
+
* {isRunning ? 'Stop' : 'Start'}
|
|
669
|
+
* </button>
|
|
670
|
+
* </div>
|
|
671
|
+
* );
|
|
672
|
+
* }
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
declare function useTimer(options?: UseTimerOptions): UseTimerReturn;
|
|
676
|
+
|
|
677
|
+
interface UseCountdownOptions {
|
|
678
|
+
/**
|
|
679
|
+
* Initial countdown value in seconds
|
|
680
|
+
* @default 3
|
|
681
|
+
*/
|
|
682
|
+
initialValue?: number;
|
|
683
|
+
/**
|
|
684
|
+
* Called when countdown completes
|
|
685
|
+
*/
|
|
686
|
+
onComplete?: () => void;
|
|
687
|
+
/**
|
|
688
|
+
* Called on each tick of the countdown
|
|
689
|
+
*/
|
|
690
|
+
onTick?: (value: number) => void;
|
|
691
|
+
}
|
|
692
|
+
interface UseCountdownReturn {
|
|
693
|
+
/** Current countdown value (null when not counting) */
|
|
694
|
+
value: number | null;
|
|
695
|
+
/** Whether countdown is active */
|
|
696
|
+
isActive: boolean;
|
|
697
|
+
/** Start the countdown */
|
|
698
|
+
start: (onComplete?: () => void) => void;
|
|
699
|
+
/** Cancel the countdown */
|
|
700
|
+
cancel: () => void;
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Hook to manage a countdown timer (e.g., 3-2-1 before recording)
|
|
704
|
+
*
|
|
705
|
+
* @param options - Configuration options
|
|
706
|
+
* @returns Countdown state and controls
|
|
707
|
+
*
|
|
708
|
+
* @example
|
|
709
|
+
* ```tsx
|
|
710
|
+
* function RecordingCountdown() {
|
|
711
|
+
* const { value, isActive, start, cancel } = useCountdown({
|
|
712
|
+
* initialValue: 3,
|
|
713
|
+
* onComplete: () => console.log('Countdown finished!'),
|
|
714
|
+
* });
|
|
715
|
+
*
|
|
716
|
+
* return (
|
|
717
|
+
* <div>
|
|
718
|
+
* {isActive && <div className="countdown">{value}</div>}
|
|
719
|
+
* <button onClick={() => start()}>Start Countdown</button>
|
|
720
|
+
* <button onClick={cancel}>Cancel</button>
|
|
721
|
+
* </div>
|
|
722
|
+
* );
|
|
723
|
+
* }
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
declare function useCountdown(options?: UseCountdownOptions): UseCountdownReturn;
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Utility function to merge Tailwind CSS classes with clsx
|
|
730
|
+
*
|
|
731
|
+
* Combines clsx's conditional class merging with tailwind-merge's
|
|
732
|
+
* intelligent Tailwind class deduplication.
|
|
733
|
+
*
|
|
734
|
+
* @param inputs - Class values to merge
|
|
735
|
+
* @returns Merged class string
|
|
736
|
+
*
|
|
737
|
+
* @example
|
|
738
|
+
* ```ts
|
|
739
|
+
* cn('px-2 py-1', 'px-4') // => 'py-1 px-4'
|
|
740
|
+
* cn('bg-red-500', isActive && 'bg-blue-500') // => 'bg-blue-500' (if isActive)
|
|
741
|
+
* ```
|
|
742
|
+
*/
|
|
743
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Download a blob as a file
|
|
747
|
+
*
|
|
748
|
+
* @param blob - The blob to download
|
|
749
|
+
* @param filename - The filename to save as
|
|
750
|
+
*
|
|
751
|
+
* @example
|
|
752
|
+
* ```ts
|
|
753
|
+
* const blob = new Blob(['hello'], { type: 'text/plain' });
|
|
754
|
+
* downloadBlob(blob, 'hello.txt');
|
|
755
|
+
* ```
|
|
756
|
+
*/
|
|
757
|
+
declare function downloadBlob(blob: Blob, filename: string): void;
|
|
758
|
+
/**
|
|
759
|
+
* Generate a default filename for recordings
|
|
760
|
+
*
|
|
761
|
+
* @param timestamp - The recording timestamp
|
|
762
|
+
* @param extension - The file extension (default: 'webm')
|
|
763
|
+
* @returns Generated filename
|
|
764
|
+
*
|
|
765
|
+
* @example
|
|
766
|
+
* ```ts
|
|
767
|
+
* generateFilename(new Date()) // => 'screen-recording-2024-01-15-143052.webm'
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
declare function generateFilename(timestamp?: Date, extension?: string): string;
|
|
771
|
+
/**
|
|
772
|
+
* Format bytes to human-readable size
|
|
773
|
+
*
|
|
774
|
+
* @param bytes - Size in bytes
|
|
775
|
+
* @param decimals - Number of decimal places
|
|
776
|
+
* @returns Formatted size string
|
|
777
|
+
*
|
|
778
|
+
* @example
|
|
779
|
+
* ```ts
|
|
780
|
+
* formatBytes(1024) // => '1 KB'
|
|
781
|
+
* formatBytes(1048576) // => '1 MB'
|
|
782
|
+
* formatBytes(1536, 1) // => '1.5 KB'
|
|
783
|
+
* ```
|
|
784
|
+
*/
|
|
785
|
+
declare function formatBytes(bytes: number, decimals?: number): string;
|
|
786
|
+
|
|
787
|
+
interface TriggerProps {
|
|
788
|
+
/**
|
|
789
|
+
* Position of the trigger button
|
|
790
|
+
*/
|
|
791
|
+
position?: TriggerPosition;
|
|
792
|
+
/**
|
|
793
|
+
* Custom content for the trigger button
|
|
794
|
+
*/
|
|
795
|
+
children?: ReactNode;
|
|
796
|
+
/**
|
|
797
|
+
* Click handler
|
|
798
|
+
*/
|
|
799
|
+
onClick?: () => void;
|
|
800
|
+
/**
|
|
801
|
+
* Whether the trigger is disabled
|
|
802
|
+
*/
|
|
803
|
+
disabled?: boolean;
|
|
804
|
+
/**
|
|
805
|
+
* Custom class name
|
|
806
|
+
*/
|
|
807
|
+
className?: string;
|
|
808
|
+
/**
|
|
809
|
+
* Z-index for positioning
|
|
810
|
+
*/
|
|
811
|
+
zIndex?: number;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Floating trigger button to start screen recording
|
|
815
|
+
*/
|
|
816
|
+
declare const Trigger: FC<TriggerProps>;
|
|
817
|
+
|
|
818
|
+
interface TriggerIconProps {
|
|
819
|
+
className?: string;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Recording trigger icon (video camera with record dot)
|
|
823
|
+
*/
|
|
824
|
+
declare const TriggerIcon: FC<TriggerIconProps>;
|
|
825
|
+
/**
|
|
826
|
+
* Recording state icon (pulsing red dot)
|
|
827
|
+
*/
|
|
828
|
+
declare const RecordingIcon: FC<TriggerIconProps>;
|
|
829
|
+
/**
|
|
830
|
+
* Stop icon (square)
|
|
831
|
+
*/
|
|
832
|
+
declare const StopIcon: FC<TriggerIconProps>;
|
|
833
|
+
/**
|
|
834
|
+
* Pause icon (two vertical bars)
|
|
835
|
+
*/
|
|
836
|
+
declare const PauseIcon: FC<TriggerIconProps>;
|
|
837
|
+
/**
|
|
838
|
+
* Play/Resume icon (triangle)
|
|
839
|
+
*/
|
|
840
|
+
declare const PlayIcon: FC<TriggerIconProps>;
|
|
841
|
+
/**
|
|
842
|
+
* Download icon
|
|
843
|
+
*/
|
|
844
|
+
declare const DownloadIcon: FC<TriggerIconProps>;
|
|
845
|
+
/**
|
|
846
|
+
* Close/X icon
|
|
847
|
+
*/
|
|
848
|
+
declare const CloseIcon: FC<TriggerIconProps>;
|
|
849
|
+
/**
|
|
850
|
+
* Refresh/Re-record icon
|
|
851
|
+
*/
|
|
852
|
+
declare const RefreshIcon: FC<TriggerIconProps>;
|
|
853
|
+
/**
|
|
854
|
+
* Check/Done icon
|
|
855
|
+
*/
|
|
856
|
+
declare const CheckIcon: FC<TriggerIconProps>;
|
|
857
|
+
/**
|
|
858
|
+
* Warning/Error icon
|
|
859
|
+
*/
|
|
860
|
+
declare const WarningIcon: FC<TriggerIconProps>;
|
|
861
|
+
|
|
862
|
+
interface TimerProps {
|
|
863
|
+
/**
|
|
864
|
+
* Elapsed time in seconds
|
|
865
|
+
*/
|
|
866
|
+
elapsed: number;
|
|
867
|
+
/**
|
|
868
|
+
* Formatted elapsed time (MM:SS)
|
|
869
|
+
*/
|
|
870
|
+
elapsedFormatted: string;
|
|
871
|
+
/**
|
|
872
|
+
* Remaining time (null if no limit)
|
|
873
|
+
*/
|
|
874
|
+
remaining?: number | null;
|
|
875
|
+
/**
|
|
876
|
+
* Maximum duration (for calculating remaining)
|
|
877
|
+
*/
|
|
878
|
+
maxDuration?: number;
|
|
879
|
+
/**
|
|
880
|
+
* Whether recording is paused
|
|
881
|
+
*/
|
|
882
|
+
isPaused?: boolean;
|
|
883
|
+
/**
|
|
884
|
+
* Custom class name
|
|
885
|
+
*/
|
|
886
|
+
className?: string;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Timer display component showing elapsed recording time
|
|
890
|
+
*/
|
|
891
|
+
declare const Timer: FC<TimerProps>;
|
|
892
|
+
|
|
893
|
+
interface RecordingControlsProps {
|
|
894
|
+
/**
|
|
895
|
+
* Elapsed time in seconds
|
|
896
|
+
*/
|
|
897
|
+
elapsed: number;
|
|
898
|
+
/**
|
|
899
|
+
* Formatted elapsed time (MM:SS)
|
|
900
|
+
*/
|
|
901
|
+
elapsedFormatted: string;
|
|
902
|
+
/**
|
|
903
|
+
* Remaining time if maxDuration set
|
|
904
|
+
*/
|
|
905
|
+
remaining?: number | null;
|
|
906
|
+
/**
|
|
907
|
+
* Maximum duration
|
|
908
|
+
*/
|
|
909
|
+
maxDuration?: number;
|
|
910
|
+
/**
|
|
911
|
+
* Whether recording is paused
|
|
912
|
+
*/
|
|
913
|
+
isPaused?: boolean;
|
|
914
|
+
/**
|
|
915
|
+
* Whether recording is active (not paused)
|
|
916
|
+
*/
|
|
917
|
+
isRecording?: boolean;
|
|
918
|
+
/**
|
|
919
|
+
* Pause handler
|
|
920
|
+
*/
|
|
921
|
+
onPause?: () => void;
|
|
922
|
+
/**
|
|
923
|
+
* Resume handler
|
|
924
|
+
*/
|
|
925
|
+
onResume?: () => void;
|
|
926
|
+
/**
|
|
927
|
+
* Stop handler
|
|
928
|
+
*/
|
|
929
|
+
onStop?: () => void;
|
|
930
|
+
/**
|
|
931
|
+
* Position of controls
|
|
932
|
+
*/
|
|
933
|
+
position?: TriggerPosition;
|
|
934
|
+
/**
|
|
935
|
+
* Custom class name
|
|
936
|
+
*/
|
|
937
|
+
className?: string;
|
|
938
|
+
/**
|
|
939
|
+
* Z-index for positioning
|
|
940
|
+
*/
|
|
941
|
+
zIndex?: number;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Recording controls bar with timer, pause, and stop buttons
|
|
945
|
+
*/
|
|
946
|
+
declare const RecordingControls: FC<RecordingControlsProps>;
|
|
947
|
+
|
|
948
|
+
interface CountdownProps {
|
|
949
|
+
/**
|
|
950
|
+
* Current countdown value
|
|
951
|
+
*/
|
|
952
|
+
value: number;
|
|
953
|
+
/**
|
|
954
|
+
* Cancel handler
|
|
955
|
+
*/
|
|
956
|
+
onCancel?: () => void;
|
|
957
|
+
/**
|
|
958
|
+
* Custom class name
|
|
959
|
+
*/
|
|
960
|
+
className?: string;
|
|
961
|
+
/**
|
|
962
|
+
* Z-index for overlay
|
|
963
|
+
*/
|
|
964
|
+
zIndex?: number;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Fullscreen countdown overlay (3-2-1 before recording)
|
|
968
|
+
*/
|
|
969
|
+
declare const Countdown: FC<CountdownProps>;
|
|
970
|
+
|
|
971
|
+
interface VideoPlayerProps {
|
|
972
|
+
/**
|
|
973
|
+
* Video source URL
|
|
974
|
+
*/
|
|
975
|
+
src: string;
|
|
976
|
+
/**
|
|
977
|
+
* Custom class name
|
|
978
|
+
*/
|
|
979
|
+
className?: string;
|
|
980
|
+
/**
|
|
981
|
+
* Whether to show controls
|
|
982
|
+
*/
|
|
983
|
+
showControls?: boolean;
|
|
984
|
+
/**
|
|
985
|
+
* Auto-play on mount
|
|
986
|
+
*/
|
|
987
|
+
autoPlay?: boolean;
|
|
988
|
+
/**
|
|
989
|
+
* Known duration in seconds (fallback for WebM files where duration may be Infinity)
|
|
990
|
+
*/
|
|
991
|
+
knownDuration?: number;
|
|
992
|
+
}
|
|
993
|
+
interface VideoPlayerRef {
|
|
994
|
+
play: () => void;
|
|
995
|
+
pause: () => void;
|
|
996
|
+
togglePlay: () => void;
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Video player component with custom controls
|
|
1000
|
+
*/
|
|
1001
|
+
declare const VideoPlayer: react.ForwardRefExoticComponent<VideoPlayerProps & react.RefAttributes<VideoPlayerRef>>;
|
|
1002
|
+
|
|
1003
|
+
interface PreviewModalProps {
|
|
1004
|
+
/**
|
|
1005
|
+
* Recording result to preview
|
|
1006
|
+
*/
|
|
1007
|
+
result: RecordingResult;
|
|
1008
|
+
/**
|
|
1009
|
+
* Whether the modal is open
|
|
1010
|
+
*/
|
|
1011
|
+
isOpen: boolean;
|
|
1012
|
+
/**
|
|
1013
|
+
* Download handler
|
|
1014
|
+
*/
|
|
1015
|
+
onDownload?: () => void;
|
|
1016
|
+
/**
|
|
1017
|
+
* Re-record handler
|
|
1018
|
+
*/
|
|
1019
|
+
onReRecord?: () => void;
|
|
1020
|
+
/**
|
|
1021
|
+
* Done/Close handler
|
|
1022
|
+
*/
|
|
1023
|
+
onClose?: () => void;
|
|
1024
|
+
/**
|
|
1025
|
+
* Custom class name
|
|
1026
|
+
*/
|
|
1027
|
+
className?: string;
|
|
1028
|
+
/**
|
|
1029
|
+
* Z-index for modal
|
|
1030
|
+
*/
|
|
1031
|
+
zIndex?: number;
|
|
1032
|
+
/**
|
|
1033
|
+
* Use portal for rendering
|
|
1034
|
+
*/
|
|
1035
|
+
usePortal?: boolean;
|
|
1036
|
+
/**
|
|
1037
|
+
* Theme for the modal
|
|
1038
|
+
*/
|
|
1039
|
+
theme?: ThemeOption;
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Preview modal for recorded video
|
|
1043
|
+
*/
|
|
1044
|
+
declare const PreviewModal: FC<PreviewModalProps>;
|
|
1045
|
+
|
|
1046
|
+
interface StatusBadgeProps {
|
|
1047
|
+
/**
|
|
1048
|
+
* Current recording state
|
|
1049
|
+
*/
|
|
1050
|
+
state: RecordingState$1;
|
|
1051
|
+
/**
|
|
1052
|
+
* Custom class name
|
|
1053
|
+
*/
|
|
1054
|
+
className?: string;
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Status badge showing current recording state
|
|
1058
|
+
*/
|
|
1059
|
+
declare const StatusBadge: FC<StatusBadgeProps>;
|
|
1060
|
+
|
|
1061
|
+
interface ErrorMessageProps {
|
|
1062
|
+
/**
|
|
1063
|
+
* Error to display
|
|
1064
|
+
*/
|
|
1065
|
+
error: ScreenRecorderError;
|
|
1066
|
+
/**
|
|
1067
|
+
* Retry handler
|
|
1068
|
+
*/
|
|
1069
|
+
onRetry?: () => void;
|
|
1070
|
+
/**
|
|
1071
|
+
* Dismiss handler
|
|
1072
|
+
*/
|
|
1073
|
+
onDismiss?: () => void;
|
|
1074
|
+
/**
|
|
1075
|
+
* Position of the error message
|
|
1076
|
+
*/
|
|
1077
|
+
position?: TriggerPosition;
|
|
1078
|
+
/**
|
|
1079
|
+
* Custom class name
|
|
1080
|
+
*/
|
|
1081
|
+
className?: string;
|
|
1082
|
+
/**
|
|
1083
|
+
* Z-index for positioning
|
|
1084
|
+
*/
|
|
1085
|
+
zIndex?: number;
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Error message component for screen recording errors
|
|
1089
|
+
*/
|
|
1090
|
+
declare const ErrorMessage: FC<ErrorMessageProps>;
|
|
1091
|
+
|
|
1092
|
+
export { type AudioConfig, type AudioOption, type BrowserSupport, CheckIcon, CloseIcon, Countdown, type CountdownProps, DEFAULT_OPTIONS, DownloadIcon, ERROR_MESSAGES, ErrorMessage, type ErrorMessageProps, PauseIcon, PlayIcon, PreviewModal, type PreviewModalProps, QUALITY_PRESETS, type QualityOption, type QualityPreset, RecordingControls, type RecordingControlsProps, RecordingIcon, type RecordingResult, type RecordingState$1 as RecordingState, RefreshIcon, type RenderMode, SUPPORTED_MIME_TYPES, ScreenRecorder, type ScreenRecorderError, type ScreenRecorderErrorCode, type ScreenRecorderProps, StatusBadge, type StatusBadgeProps, StopIcon, TIMER_CRITICAL_THRESHOLD, TIMER_WARNING_THRESHOLD, type ThemeOption, Timer, type TimerProps, Trigger, TriggerIcon, type TriggerPosition, type TriggerProps, type UseCountdownOptions, type UseCountdownReturn, type UseDisplayMediaOptions, type UseDisplayMediaReturn, type UseMediaRecorderOptions, type UseMediaRecorderReturn, type UseScreenRecorderOptions, type UseScreenRecorderReturn, type UseTimerOptions, type UseTimerReturn, VideoPlayer, type VideoPlayerProps, type VideoPlayerRef, WarningIcon, checkBrowserSupport, cn, downloadBlob, formatBytes, formatTime, generateFilename, getBestMimeType, useBrowserSupport, useCountdown, useDisplayMedia, useMediaRecorder, useScreenRecorder, useTimer };
|