@vidtreo/recorder 0.0.1 → 0.8.1

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 CHANGED
@@ -1,206 +1,144 @@
1
- export declare const FILE_SIZE_UNITS: readonly ["Bytes", "KB", "MB", "GB"];
2
- export declare const FILE_SIZE_BASE = 1024;
3
- export declare const TIMESTAMP_REGEX: RegExp;
4
- export declare const DEFAULT_COUNTDOWN_DURATION = 5000;
5
- export declare const AUDIO_LEVEL_INTERVAL = 100;
6
- export declare const AUDIO_LEVEL_BARS = 15;
7
- export declare const CLEANUP_INTERVAL: number;
8
- export declare const DEFAULT_BACKEND_URL = "https://api.vidtreo.com";
9
-
10
- import { DeviceManager as CoreDeviceManager } from "../../core/device/device-manager";
11
- export declare class DeviceManager extends CoreDeviceManager {
12
- updateDeviceSelects(shadowRoot: ShadowRoot): void;
1
+ export type VidtreoRecorderConfig = {
2
+ apiKey: string;
3
+ apiUrl: string;
4
+ enableSourceSwitching?: boolean;
5
+ enableMute?: boolean;
6
+ enablePause?: boolean;
7
+ enableDeviceChange?: boolean;
8
+ maxRecordingTime?: number;
9
+ countdownDuration?: number;
10
+ userMetadata?: Record<string, unknown>;
11
+ onUploadComplete?: (result: {
12
+ recordingId: string;
13
+ uploadUrl: string;
14
+ }) => void;
15
+ onUploadProgress?: (progress: number) => void;
16
+ onUploadError?: (error: Error) => void;
17
+ onRecordingStart?: () => void;
18
+ onRecordingStop?: () => void;
19
+ onError?: (error: Error) => void;
20
+ };
21
+ export type RecordingStartOptions = {
22
+ video?: boolean | CameraConstraints;
23
+ audio?: boolean | MediaTrackConstraints;
24
+ };
25
+ export type RecordingStopResult = {
26
+ recordingId: string;
27
+ uploadUrl: string;
28
+ blob: Blob;
29
+ };
30
+ export declare class VidtreoRecorder {
31
+ private readonly controller;
32
+ private readonly config;
33
+ private readonly uploadService;
34
+ private isInitialized;
35
+ constructor(config: VidtreoRecorderConfig);
36
+ initialize(): Promise<void>;
37
+ startPreview(sourceType?: SourceType): Promise<MediaStream>;
38
+ startRecording(_options?: RecordingStartOptions, sourceType?: SourceType): Promise<void>;
39
+ switchSource(sourceType: SourceType): Promise<void>;
40
+ stopRecording(): Promise<RecordingStopResult>;
41
+ getAvailableDevices(): Promise<import(".").AvailableDevices>;
42
+ muteAudio(): void;
43
+ unmuteAudio(): void;
44
+ toggleMute(): void;
45
+ isMuted(): boolean;
46
+ pauseRecording(): void;
47
+ resumeRecording(): void;
48
+ isPaused(): boolean;
49
+ getRecordingState(): import(".").RecordingState;
50
+ getStream(): MediaStream | null;
51
+ cleanup(): void;
52
+ private ensureInitialized;
13
53
  }
14
54
 
15
- export declare class AudioLevelVisualizer {
16
- private barsContainer;
17
- initializeBars(shadowRoot: ShadowRoot): void;
18
- updateBars(level: number, isMuted: boolean): void;
19
- private queryElement;
20
- private createBar;
21
- private updateBar;
22
- private calculateThreshold;
23
- private setBarHeight;
24
- private setBarStyle;
25
- }
55
+ import type { UploadResult } from "../types/recorder-types";
56
+ export type UploadCallbacks = {
57
+ onProgress: (progress: number) => void;
58
+ onSuccess: (result: UploadResult) => void;
59
+ onError: (error: Error) => void;
60
+ onClearStatus: () => void;
61
+ };
26
62
 
27
- import type { RecordingState, SourceType, UploadResult } from "../../core/types/recorder-types";
28
- export declare class UIStateManager {
29
- private readonly shadowRoot;
30
- constructor(shadowRoot: ShadowRoot);
31
- private queryElement;
32
- private setText;
33
- private toggleClass;
34
- private setStyle;
35
- private setDisplay;
36
- private setDisabled;
37
- showError(message: string): void;
38
- hideError(): void;
39
- showProgress(): void;
40
- hideProgress(): void;
41
- updateProgress(percentage: number, text: string): void;
42
- updateRecordingTimer(formatted: string): void;
43
- updateMuteState(muted: boolean, onAudioLevelUpdate: (level: number, isMuted: boolean) => void, audioLevel: number): void;
44
- updatePauseState(isPaused: boolean): void;
45
- updateCountdownOverlay(recordingState: RecordingState, countdownRemaining: number): void;
46
- showSourceTransition(message: string): void;
47
- hideSourceTransition(): void;
48
- handleStreamStart(recordingState: RecordingState, onInitializeAudioBars: () => void): void;
49
- handleStreamStop(onStopAudioTracking: () => void): void;
50
- handleRecordingStart(isPaused: boolean): void;
51
- updateRecordingControlsAfterStop(): void;
52
- updateSwitchButtonText(currentSourceType: SourceType): void;
53
- toggleSettings(currentState: boolean): boolean;
54
- showUploadProgress(): void;
55
- updateUploadProgress(progress: number): void;
56
- hideUploadProgress(): void;
57
- showUploadSuccess(result: UploadResult): void;
58
- showUploadError(message: string): void;
59
- clearUploadStatus(): void;
60
- updateVideoPreview(stream: MediaStream | null): void;
61
- getShadowRoot(): ShadowRoot;
63
+ import type { PendingUpload, VideoStorageService } from "../storage/video-storage";
64
+ type UploadCallbacks = {
65
+ onUploadProgress?: (id: string, progress: number) => void;
66
+ onUploadComplete?: (id: string, result: VideoUploadResult) => void;
67
+ onUploadError?: (id: string, error: Error) => void;
68
+ };
69
+ export declare class UploadQueueManager {
70
+ private readonly storageService;
71
+ private readonly uploadService;
72
+ private readonly processingIntervalId;
73
+ private readonly networkOnlineHandler;
74
+ private isProcessing;
75
+ private retryTimeoutId;
76
+ private callbacks;
77
+ constructor(storageService: VideoStorageService, uploadService: VideoUploadService);
78
+ destroy(): void;
79
+ setCallbacks(callbacks: UploadCallbacks): void;
80
+ queueUpload(upload: Omit<PendingUpload, "id" | "createdAt" | "updatedAt" | "status" | "retryCount">): Promise<string>;
81
+ processQueue(): Promise<void>;
82
+ getPendingUploads(): Promise<PendingUpload[]>;
83
+ getStats(): Promise<{
84
+ pending: number;
85
+ uploading: number;
86
+ failed: number;
87
+ total: number;
88
+ }>;
89
+ private getOldestUpload;
90
+ private getOldestFailedUpload;
91
+ private processUpload;
92
+ private calculateRetryDelay;
93
+ private scheduleRetry;
94
+ private clearTimer;
62
95
  }
96
+ export {};
63
97
 
64
- export declare function getTemplate(isMuted: boolean, currentSourceType?: "camera" | "screen"): string;
65
-
66
- export type ConfigFromAttributes = {
67
- apiKey: string | null;
98
+ export type VideoUploadOptions = {
99
+ apiKey: string;
68
100
  backendUrl: string;
69
- countdownDuration?: number;
70
- maxRecordingTime?: number;
101
+ filename?: string;
102
+ metadata?: Record<string, unknown>;
71
103
  userMetadata?: Record<string, unknown>;
104
+ duration?: number;
105
+ onProgress?: (progress: number) => void;
72
106
  };
73
- export declare function normalizeBackendUrl(url: string | null | undefined): string;
74
- export declare function buildConfigFromAttributes(element: HTMLElement, userMetadata: Record<string, unknown>): ConfigFromAttributes;
75
-
76
- export declare function queryElement<T extends HTMLElement>(shadowRoot: ShadowRoot, selector: string): T;
107
+ export type VideoUploadInitResponse = {
108
+ videoId: string;
109
+ uploadUrl: string;
110
+ };
111
+ export type VideoUploadResult = {
112
+ videoId: string;
113
+ status: string;
114
+ uploadUrl: string;
115
+ };
116
+ export declare class VideoUploadService {
117
+ uploadVideo(blob: Blob, options: VideoUploadOptions): Promise<VideoUploadResult>;
118
+ private initVideoUpload;
119
+ private extractErrorFromResponse;
120
+ private parseJsonResponse;
121
+ private uploadVideoFile;
122
+ private parseSuccessResponse;
123
+ private parseErrorResponse;
124
+ private safeParseJsonFromXhr;
125
+ }
77
126
 
78
- export declare const STYLES: string;
127
+ export declare function extractVideoDuration(blob: Blob): Promise<number>;
79
128
 
80
- import { RecorderController } from "../core/recorder/recorder-controller";
81
- export declare class VidtreoRecorder extends HTMLElement {
82
- static observedAttributes: string[];
83
- private readonly controller;
84
- private readonly uiStateManager;
85
- private readonly deviceManager;
86
- private readonly audioLevelVisualizer;
87
- private recordedBlob;
88
- private processedBlob;
89
- private isProcessing;
90
- private isMuted;
91
- private showSettings;
92
- private readonly userMetadata;
93
- constructor();
94
- connectedCallback(): Promise<void>;
95
- attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
96
- disconnectedCallback(): void;
97
- private get shadow();
98
- checkPendingUploads(): Promise<void>;
99
- startCamera(): Promise<void>;
100
- startRecording(): Promise<void>;
101
- stopRecording(): Promise<void>;
102
- pauseRecording(): void;
103
- resumeRecording(): void;
104
- processVideo(): Promise<void>;
105
- downloadVideo(): void;
106
- playVideo(): void;
107
- toggleMute(): void;
108
- toggleSource(): Promise<void>;
109
- toggleSettings(): void;
110
- handleCameraChange(value: string): Promise<void>;
111
- handleMicChange(value: string): Promise<void>;
112
- handleStateChange(state: string, previousState: string): void;
113
- handleStreamStart(stream: MediaStream): void;
114
- handleStreamStop(): void;
115
- handleRecordingStart(): void;
116
- handleRecordingStop(blob: Blob): Promise<void>;
117
- updateRecordingTimer(formatted: string): void;
118
- updateMuteState(muted: boolean): void;
119
- updateVideoPreview(stream: MediaStream): void;
129
+ import type { UploadResult } from "../types/recorder-types";
130
+ export declare class UploadManager {
131
+ private readonly callbacks;
132
+ private uploadQueueManager;
133
+ constructor(callbacks: UploadCallbacks);
134
+ setUploadQueueManager(uploadQueueManager: UploadQueueManager | null): void;
135
+ uploadVideo(blob: Blob, apiKey: string, backendUrl: string, userMetadata: Record<string, unknown>): Promise<void>;
136
+ updateProgress(progress: number): void;
137
+ showSuccess(result: UploadResult): void;
120
138
  showError(message: string): void;
121
- extractErrorMessage(error: unknown): string;
122
- getStreamManager(): import("..").CameraStreamManager;
123
- getShadowRoot(): ShadowRoot;
124
- getController(): RecorderController;
125
- getUIStateManager(): UIStateManager;
126
- getDeviceManager(): DeviceManager;
127
- getAudioLevelVisualizer(): AudioLevelVisualizer;
128
- getRecordedBlob(): Blob | null;
129
- setRecordedBlob(blob: Blob | null): void;
130
- getProcessedBlob(): Blob | null;
131
- setProcessedBlob(blob: Blob | null): void;
132
- getIsProcessing(): boolean;
133
- setIsProcessing(value: boolean): void;
134
- getIsMuted(): boolean;
135
- setIsMuted(value: boolean): void;
136
- getShowSettings(): boolean;
137
- setShowSettings(value: boolean): void;
138
- getUserMetadata(): Record<string, unknown>;
139
- getNormalizedBackendUrl(url: string | null | undefined): string;
140
- }
141
-
142
- export declare function downloadVideo(blob: Blob): void;
143
- export declare function playVideo(blob: Blob): void;
144
-
145
- import type { VidtreoRecorder } from "../vidtreo-recorder.wc";
146
- export declare function handleStartRecording(component: VidtreoRecorder): Promise<void>;
147
- export declare function handleStopRecording(component: VidtreoRecorder): Promise<Blob>;
148
- export declare function handlePauseRecording(component: VidtreoRecorder): void;
149
- export declare function handleResumeRecording(component: VidtreoRecorder): void;
150
- export declare function handleProcessVideo(component: VidtreoRecorder): Promise<void>;
151
-
152
- import type { SourceType } from "../../core/types/recorder-types";
153
- export declare function updatePreviewAfterSourceSwitch(videoPreview: HTMLVideoElement, stream: MediaStream, sourceType: SourceType): Promise<void>;
154
- export declare function updatePreviewAfterDeviceSwitch(videoPreview: HTMLVideoElement, stream: MediaStream): Promise<void>;
155
-
156
- import type { VidtreoRecorder } from "../vidtreo-recorder.wc";
157
- export declare function attachEventListeners(component: VidtreoRecorder): void;
158
-
159
- import type { RecorderCallbacks } from "../../core/recorder/types";
160
- import type { VidtreoRecorder } from "../vidtreo-recorder.wc";
161
- export declare function createRecorderCallbacks(component: VidtreoRecorder): RecorderCallbacks;
162
-
163
- import type { VidtreoRecorder } from "../vidtreo-recorder.wc";
164
- export declare function showPreviewSkeleton(shadowRoot: ShadowRoot, message: string): void;
165
- export declare function hidePreviewSkeleton(shadowRoot: ShadowRoot): void;
166
- export declare function handleCameraChange(component: VidtreoRecorder, value: string): Promise<void>;
167
- export declare function handleMicChange(component: VidtreoRecorder, value: string): Promise<void>;
168
-
169
- import type { CameraStreamManager } from "../../core/stream/stream";
170
- import type { SourceType } from "../../core/types/recorder-types";
171
- import type { DeviceManager } from "../managers/device-manager";
172
- import type { UIStateManager } from "../managers/ui-state-manager";
173
- export declare class SourceSwitchHandler {
174
- private currentSourceType;
175
- private originalCameraStream;
176
- private readonly streamManager;
177
- private readonly uiStateManager;
178
- private readonly deviceManager;
179
- private readonly onShowError;
180
- private screenShareTrackEndHandler;
181
- constructor(streamManager: CameraStreamManager, uiStateManager: UIStateManager, deviceManager: DeviceManager, onShowError: (message: string) => void);
182
- getCurrentSourceType(): SourceType;
183
- setCurrentSourceType(type: SourceType): void;
184
- getOriginalCameraStream(): MediaStream | null;
185
- setOriginalCameraStream(stream: MediaStream | null): void;
186
- private stopStreamTracks;
187
- switchToScreenCapture(): Promise<MediaStream>;
188
- setupScreenShareTrackHandler(newStream: MediaStream, onSwitchToCamera: () => Promise<void>): void;
189
- removeScreenShareTrackHandler(stream: MediaStream | null): void;
190
- getCameraStream(): Promise<MediaStream>;
191
- switchToCamera(): Promise<void>;
192
- updatePreviewAfterSourceSwitch(newStream: MediaStream): Promise<void>;
193
- toggleSource(): Promise<void>;
194
- cleanup(): void;
195
- private completePlaySuccess;
196
- private handlePlayError;
197
- private retryPlay;
198
- private completePlayError;
139
+ clearStatus(): void;
199
140
  }
200
141
 
201
- import type { VidtreoRecorder } from "../vidtreo-recorder.wc";
202
- export declare function setupEventListeners(component: VidtreoRecorder): void;
203
-
204
142
  export type RecordingState = "idle" | "countdown" | "recording";
205
143
  export type SourceType = "camera" | "screen";
206
144
  export type AvailableDevices = {
@@ -212,307 +150,193 @@ export type UploadResult = {
212
150
  uploadUrl: string;
213
151
  };
214
152
 
215
- import type { TranscodeConfig } from "../processor/types";
216
- export declare class ConfigManager {
217
- private configService;
218
- private currentConfig;
219
- private configFetchPromise;
220
- initialize(apiKey: string | null, backendUrl: string | null): void;
221
- fetchConfig(): Promise<void>;
222
- getConfig(): Promise<TranscodeConfig>;
223
- clearCache(): void;
224
- }
153
+ export declare function calculateBarColor(position: number): string;
225
154
 
226
- import type { TranscodeConfig } from "../processor/types";
227
- export declare const DEFAULT_TRANSCODE_CONFIG: Readonly<TranscodeConfig>;
155
+ export declare function extractErrorMessage(error: unknown): string;
228
156
 
229
- import type { TranscodeConfig } from "../processor/types";
230
- export type BackendPreset = "sd" | "hd" | "fhd" | "4k";
231
- export type BackendConfigResponse = {
232
- presetEncoding: BackendPreset;
233
- max_width: number;
234
- max_height: number;
157
+ export declare const FILE_SIZE_UNITS: readonly ["Bytes", "KB", "MB", "GB"];
158
+ export declare const FILE_SIZE_BASE = 1024;
159
+ export declare function formatFileSize(bytes: number): string;
160
+ export declare function formatTime(totalSeconds: number): string;
161
+
162
+ export type StorageQuota = {
163
+ usage: number;
164
+ quota: number;
165
+ available: number;
166
+ percentage: number;
235
167
  };
236
- export declare function mapPresetToConfig(preset: BackendPreset, maxWidth: number, maxHeight: number): TranscodeConfig;
168
+ export declare class QuotaManager {
169
+ getQuota(): Promise<StorageQuota>;
170
+ hasSpaceFor(sizeInBytes: number): Promise<boolean>;
171
+ requestPersistentStorage(): Promise<boolean>;
172
+ isPersistent(): Promise<boolean>;
173
+ formatBytes(bytes: number): string;
174
+ shouldWarn(threshold?: number): Promise<boolean>;
175
+ isCritical(threshold?: number): Promise<boolean>;
176
+ private checkThreshold;
177
+ }
237
178
 
238
- import type { TranscodeConfig } from "../processor/types";
239
- export type ConfigServiceOptions = {
179
+ import type { UploadResult } from "../types/recorder-types";
180
+ export type UploadCallbacks = {
181
+ onUploadProgress: (id: string, progress: number) => void;
182
+ onUploadComplete: (id: string, result: UploadResult) => void;
183
+ onUploadError: (id: string, error: Error) => void;
184
+ };
185
+
186
+ export type PendingUpload = {
187
+ id: string;
188
+ blob: Blob;
240
189
  apiKey: string;
241
190
  backendUrl: string;
242
- cacheTimeout?: number;
191
+ filename: string;
192
+ duration?: number;
193
+ metadata?: Record<string, unknown>;
194
+ userMetadata?: Record<string, unknown>;
195
+ status: "pending" | "uploading" | "failed" | "completed";
196
+ retryCount: number;
197
+ lastError?: string;
198
+ createdAt: number;
199
+ updatedAt: number;
243
200
  };
244
- export declare class ConfigService {
245
- private cachedConfig;
246
- private cacheTimestamp;
247
- private readonly cacheTimeout;
248
- private fetchPromise;
249
- private readonly options;
250
- constructor(options: ConfigServiceOptions);
251
- fetchConfig(): Promise<TranscodeConfig>;
252
- clearCache(): void;
253
- getCurrentConfig(): TranscodeConfig;
254
- private fetchConfigFromBackend;
201
+ export declare class VideoStorageService {
202
+ private db;
203
+ init(): Promise<void>;
204
+ isInitialized(): boolean;
205
+ savePendingUpload(upload: Omit<PendingUpload, "id" | "createdAt" | "updatedAt" | "status" | "retryCount">): Promise<string>;
206
+ getPendingUploads(status?: PendingUpload["status"]): Promise<PendingUpload[]>;
207
+ updateUploadStatus(id: string, updates: Partial<PendingUpload>): Promise<void>;
208
+ deleteUpload(id: string): Promise<void>;
209
+ cleanupPermanentlyFailedUploads(retentionHours?: number): Promise<number>;
210
+ getTotalStorageSize(): Promise<number>;
211
+ private generateUploadId;
212
+ private executeTransaction;
255
213
  }
256
214
 
257
- import { StreamProcessor } from "../processor/stream-processor";
258
- import type { CameraStreamManager } from "../stream/stream";
259
- import type { RecordingState } from "../types/recorder-types";
260
- export declare class RecordingManager {
261
- private recordingState;
262
- private countdownDuration;
263
- private countdownRemaining;
264
- private countdownTimeoutId;
265
- private countdownIntervalId;
266
- private countdownStartTime;
267
- private isPaused;
268
- private maxRecordingTime;
269
- private maxTimeTimer;
270
- private recordingSeconds;
271
- private recordingIntervalId;
272
- private pauseStartTime;
273
- private totalPausedTime;
274
- private readonly streamManager;
275
- private readonly callbacks;
276
- private streamProcessor;
277
- private originalCameraStream;
278
- constructor(streamManager: CameraStreamManager, callbacks: RecordingCallbacks);
279
- setCountdownDuration(duration: number): void;
280
- setMaxRecordingTime(maxTime: number | null): void;
281
- getRecordingState(): RecordingState;
282
- isPausedState(): boolean;
283
- getRecordingSeconds(): number;
284
- getStreamProcessor(): StreamProcessor | null;
285
- setOriginalCameraStream(stream: MediaStream | null): void;
286
- getOriginalCameraStream(): MediaStream | null;
287
- startRecording(): Promise<void>;
288
- private startCountdown;
289
- private doStartRecording;
290
- stopRecording(): Promise<Blob>;
291
- pauseRecording(): void;
292
- resumeRecording(): void;
293
- cancelCountdown(): void;
294
- cleanup(): void;
295
- private resetRecordingState;
296
- private resetPauseState;
297
- private updatePausedDuration;
298
- private startRecordingTimer;
299
- private clearTimer;
300
- private handleError;
215
+ import { UploadQueueManager } from "../upload/upload-queue-manager";
216
+ import type { VideoUploadService } from "../upload/video-upload-service";
217
+ export declare class StorageManager {
218
+ private storageService;
219
+ private uploadQueueManager;
220
+ private cleanupIntervalId;
221
+ initialize(uploadService: VideoUploadService | null, callbacks: UploadCallbacks, onCleanupError: (error: string) => void): Promise<void>;
222
+ checkPendingUploads(): Promise<{
223
+ pending: number;
224
+ uploading: number;
225
+ }>;
226
+ performCleanup(): Promise<void>;
227
+ getUploadQueueManager(): UploadQueueManager | null;
228
+ getStorageService(): VideoStorageService | null;
229
+ destroy(): void;
301
230
  }
302
231
 
303
- import type { TranscodeConfig } from "../processor/types";
304
- import type { RecordingState } from "../types/recorder-types";
305
- export type RecordingCallbacks = {
306
- onStateChange: (state: RecordingState) => void;
307
- onCountdownUpdate: (state: RecordingState, remaining: number) => void;
308
- onTimerUpdate: (formatted: string) => void;
309
- onError: (error: Error) => void;
310
- onRecordingComplete: (blob: Blob) => void;
311
- onClearUploadStatus: () => void;
312
- onStopAudioTracking: () => void;
313
- onGetConfig: () => Promise<TranscodeConfig>;
314
- };
232
+ import type { AudioLevelAnalyzer } from "../audio/audio-level-analyzer";
233
+ import type { ConfigManager } from "../config/config-manager";
234
+ import type { DeviceManager } from "../device/device-manager";
235
+ import type { RecordingCallbacks } from "../recording/types";
236
+ import type { SourceSwitchCallbacks } from "../stream/source-switch";
237
+ export declare function createRecordingCallbacks(callbacks: RecorderCallbacks, audioLevelAnalyzer: AudioLevelAnalyzer, configManager: ConfigManager): RecordingCallbacks;
238
+ export declare function createSourceSwitchCallbacks(callbacks: RecorderCallbacks, deviceManager: DeviceManager): SourceSwitchCallbacks;
315
239
 
316
- export type CameraConstraints = {
317
- width?: number | {
318
- ideal?: number;
319
- min?: number;
320
- max?: number;
321
- };
322
- height?: number | {
323
- ideal?: number;
324
- min?: number;
325
- max?: number;
326
- };
327
- frameRate?: number | {
328
- ideal?: number;
329
- min?: number;
330
- max?: number;
331
- };
332
- };
333
- export type StreamConfig = {
334
- video: boolean | CameraConstraints;
335
- audio: boolean | MediaTrackConstraints;
336
- };
337
- export type RecordingOptions = {
338
- mimeType?: string;
339
- videoBitsPerSecond?: number;
340
- audioBitsPerSecond?: number;
341
- bitsPerSecond?: number;
240
+ import type { AudioLevelCallbacks } from "../audio/types";
241
+ import type { DeviceCallbacks } from "../device/types";
242
+ import type { RecordingCallbacks } from "../recording/types";
243
+ import type { UploadCallbacks as StorageUploadCallbacks } from "../storage/types";
244
+ import type { SourceType } from "../types/recorder-types";
245
+ import type { UploadCallbacks } from "../upload/types";
246
+ export type RecorderConfig = {
247
+ apiKey?: string | null;
248
+ backendUrl?: string | null;
249
+ countdownDuration?: number;
250
+ maxRecordingTime?: number | null;
251
+ userMetadata?: Record<string, unknown>;
252
+ enableSourceSwitching?: boolean;
253
+ enableMute?: boolean;
254
+ enablePause?: boolean;
255
+ enableDeviceChange?: boolean;
342
256
  };
343
- export type StreamState = "idle" | "starting" | "active" | "recording" | "stopping" | "error";
344
- export type StreamEventMap = {
345
- statechange: {
346
- state: StreamState;
347
- previousState: StreamState;
348
- };
349
- streamstart: {
350
- stream: MediaStream;
351
- };
352
- streamstop: undefined;
353
- recordingstart: {
354
- recorder: MediaRecorder | null;
355
- };
356
- recordingstop: {
357
- blob: Blob;
358
- mimeType: string;
359
- };
360
- recordingdata: {
361
- data: Blob;
362
- };
363
- error: {
364
- error: Error;
365
- };
366
- recordingtimeupdate: {
367
- elapsed: number;
368
- formatted: string;
369
- };
370
- recordingbufferupdate: {
371
- size: number;
372
- formatted: string;
373
- };
374
- audiomutetoggle: {
375
- muted: boolean;
257
+ export type RecorderCallbacks = {
258
+ recording?: Partial<RecordingCallbacks>;
259
+ audioLevel?: AudioLevelCallbacks;
260
+ device?: DeviceCallbacks;
261
+ upload?: UploadCallbacks;
262
+ storage?: StorageUploadCallbacks;
263
+ sourceSwitch?: {
264
+ onSourceChange?: (sourceType: SourceType) => void;
265
+ onPreviewUpdate?: (stream: MediaStream) => Promise<void>;
266
+ onError?: (error: Error) => void;
267
+ onTransitionStart?: (message: string) => void;
268
+ onTransitionEnd?: () => void;
376
269
  };
377
- videosourcechange: {
378
- stream: MediaStream;
270
+ stream?: {
271
+ onStreamStart?: (stream: MediaStream) => void;
272
+ onStreamStop?: () => void;
273
+ onError?: (error: Error) => void;
379
274
  };
275
+ onStorageCleanupError?: (error: string) => void;
380
276
  };
381
- export type StreamEventListener<T extends keyof StreamEventMap> = (data: StreamEventMap[T]) => void;
382
-
383
- export declare const DEFAULT_CAMERA_CONSTRAINTS: Readonly<CameraConstraints>;
384
- export declare const DEFAULT_STREAM_CONFIG: Readonly<StreamConfig>;
385
- export declare const DEFAULT_RECORDING_OPTIONS: Readonly<RecordingOptions>;
386
277
 
278
+ import type { AudioLevelCallbacks } from "../audio/types";
279
+ import { DeviceManager } from "../device/device-manager";
280
+ import { CameraStreamManager } from "../stream/stream";
387
281
  import type { SourceType } from "../types/recorder-types";
388
- export type SourceSwitchCallbacks = {
389
- onSourceChange?: (sourceType: SourceType) => void;
390
- onPreviewUpdate?: (stream: MediaStream) => Promise<void>;
391
- onError?: (error: Error) => void;
392
- onTransitionStart?: (message: string) => void;
393
- onTransitionEnd?: () => void;
394
- getSelectedCameraDeviceId?: () => string | null;
395
- getSelectedMicDeviceId?: () => string | null;
396
- };
397
- export declare class SourceSwitchManager {
398
- private currentSourceType;
399
- private originalCameraStream;
400
- private originalCameraConstraints;
401
- private screenShareStream;
402
- private screenShareTrackEndHandler;
282
+ export declare class RecorderController {
403
283
  private readonly streamManager;
404
- private callbacks;
405
- constructor(streamManager: CameraStreamManager, callbacks?: SourceSwitchCallbacks);
406
- getCurrentSourceType(): SourceType;
407
- getOriginalCameraStream(): MediaStream | null;
408
- private stopStreamTracks;
409
- private isTrackLive;
410
- private areTracksLive;
411
- private storeOriginalCameraConstraints;
412
- private storeOriginalCameraStream;
413
- private createError;
414
- private waitForTracksToEnd;
415
- switchToScreenCapture(): Promise<MediaStream>;
416
- private setupScreenShareTrackHandler;
417
- removeScreenShareTrackHandler(stream: MediaStream | null): void;
418
- private canReuseOriginalStream;
419
- private canReuseManagerStream;
420
- private buildVideoConstraints;
421
- private buildAudioConstraints;
422
- private createNewCameraStreamForRecording;
423
- getCameraStream(): Promise<MediaStream>;
424
- switchToCamera(): Promise<void>;
425
- private notifyTransitionStart;
426
- private notifyTransitionEnd;
427
- private handleScreenShareStop;
428
- private applyCameraStream;
429
- toggleSource(): Promise<void>;
430
- private switchToScreen;
431
- private handleToggleError;
432
- handleRecordingStop(): Promise<void>;
433
- cleanup(): void;
434
- setCallbacks(callbacks: SourceSwitchCallbacks): void;
435
- }
436
-
437
- import type { StreamProcessor } from "../processor/stream-processor";
438
- import type { TranscodeConfig } from "../processor/types";
439
- export declare class CameraStreamManager {
440
- private mediaStream;
441
- private mediaRecorder;
442
- private recordedChunks;
443
- private recordedMimeType;
444
- private state;
445
- private recordingStartTime;
446
- private recordingTimer;
447
- private pauseStartTime;
448
- private totalPausedTime;
449
- private readonly eventListeners;
450
- private readonly streamConfig;
451
- private readonly recordingOptions;
452
- private streamProcessor;
453
- private bufferSizeUpdateInterval;
454
- private selectedAudioDeviceId;
455
- private selectedVideoDeviceId;
456
- constructor(streamConfig?: Partial<StreamConfig>, recordingOptions?: Partial<RecordingOptions>);
457
- getState(): StreamState;
458
- getStream(): MediaStream | null;
459
- getAudioStreamForAnalysis(): MediaStream | null;
460
- getRecorder(): MediaRecorder | null;
461
- isRecording(): boolean;
462
- isActive(): boolean;
463
- on<T extends keyof StreamEventMap>(event: T, listener: StreamEventListener<T>): () => void;
464
- off<T extends keyof StreamEventMap>(event: T, listener: StreamEventListener<T>): void;
465
- once<T extends keyof StreamEventMap>(event: T, listener: StreamEventListener<T>): () => void;
466
- private emit;
467
- private setState;
468
- setAudioDevice(deviceId: string | null): void;
469
- setVideoDevice(deviceId: string | null): void;
470
- getAudioDevice(): string | null;
471
- getVideoDevice(): string | null;
472
- getAvailableDevices(): Promise<{
473
- audioinput: MediaDeviceInfo[];
474
- videoinput: MediaDeviceInfo[];
475
- }>;
476
- private buildVideoConstraints;
477
- private buildAudioConstraints;
478
- startStream(): Promise<MediaStream>;
479
- stopStream(): void;
480
- private stopStreamTracks;
481
- private isTrackLive;
482
- private tryReplaceTrack;
483
- private recreateStreamWithNewTrack;
284
+ private readonly configManager;
285
+ private readonly storageManager;
286
+ private readonly deviceManager;
287
+ private readonly audioLevelAnalyzer;
288
+ private readonly uploadManager;
289
+ private readonly recordingManager;
290
+ private readonly sourceSwitchManager;
291
+ private readonly uploadService;
292
+ private readonly muteStateManager;
293
+ private isInitialized;
294
+ constructor(callbacks?: RecorderCallbacks);
295
+ initialize(config: RecorderConfig): Promise<void>;
296
+ startStream(): Promise<void>;
297
+ stopStream(): Promise<void>;
484
298
  switchVideoDevice(deviceId: string | null): Promise<MediaStream>;
485
299
  switchAudioDevice(deviceId: string | null): Promise<MediaStream>;
486
- startRecordingWithMediaRecorder(): void;
487
- stopRecordingWithMediaRecorder(): void;
488
- startRecording(processor: StreamProcessor, config: TranscodeConfig): Promise<void>;
300
+ startRecording(): Promise<void>;
489
301
  stopRecording(): Promise<Blob>;
490
302
  pauseRecording(): void;
491
303
  resumeRecording(): void;
492
- toggleMute(): void;
493
- private setAudioTracksEnabled;
304
+ switchSource(_sourceType: SourceType): Promise<void>;
305
+ setCameraDevice(deviceId: string | null): void;
306
+ setMicDevice(deviceId: string | null): void;
307
+ getAvailableDevices(): Promise<import("../..").AvailableDevices>;
494
308
  muteAudio(): void;
495
309
  unmuteAudio(): void;
496
- isMuted(): boolean;
497
- switchVideoSource(newStream: MediaStream): Promise<void>;
498
- setMediaStream(stream: MediaStream): void;
499
- getCurrentVideoSource(): MediaStream;
500
- private formatTimeElapsed;
501
- private startRecordingTimer;
502
- private clearRecordingTimer;
503
- private clearBufferSizeInterval;
504
- private resetRecordingState;
505
- private resetPauseState;
506
- getRecordedBlob(): Blob;
507
- destroy(): void;
310
+ toggleMute(): void;
311
+ getIsMuted(): boolean;
312
+ startAudioLevelTracking(stream: MediaStream, callbacks?: AudioLevelCallbacks): Promise<void>;
313
+ stopAudioLevelTracking(): void;
314
+ getAudioLevel(): number;
315
+ uploadVideo(blob: Blob, apiKey: string, backendUrl: string, metadata: Record<string, unknown>): Promise<void>;
316
+ getStream(): MediaStream | null;
317
+ getRecordingState(): import("../..").RecordingState;
318
+ isPaused(): boolean;
319
+ getCurrentSourceType(): SourceType;
320
+ getOriginalCameraStream(): MediaStream | null;
321
+ getStreamManager(): CameraStreamManager;
322
+ getAudioStreamForAnalysis(): MediaStream | null;
323
+ getDeviceManager(): DeviceManager;
324
+ getConfig(): Promise<import("../..").TranscodeConfig>;
325
+ isRecording(): boolean;
326
+ isActive(): boolean;
327
+ cleanup(): void;
508
328
  }
509
329
 
510
- export declare class CanvasRenderer {
511
- private readonly canvasContext;
512
- constructor(canvasContext: OffscreenCanvasRenderingContext2D);
513
- clear(): void;
514
- drawFrame(videoElement: HTMLVideoElement): void;
515
- getContext(): OffscreenCanvasRenderingContext2D;
330
+ import type { CameraStreamManager } from "../stream/stream";
331
+ export declare class MuteStateManager {
332
+ private isMuted;
333
+ private readonly streamManager;
334
+ constructor(streamManager: CameraStreamManager);
335
+ mute(): void;
336
+ unmute(): void;
337
+ toggle(): void;
338
+ getIsMuted(): boolean;
339
+ getMutedStateCallback(): () => boolean;
516
340
  }
517
341
 
518
342
  export declare class StreamProcessor {
@@ -543,28 +367,6 @@ export declare class StreamProcessor {
543
367
  cancel(): Promise<void>;
544
368
  }
545
369
 
546
- export type TranscodeConfig = {
547
- format: "mp4";
548
- fps: number;
549
- width: number;
550
- height: number;
551
- bitrate: number;
552
- audioCodec: "aac";
553
- preset: "medium";
554
- packetCount: number;
555
- audioBitrate?: number;
556
- };
557
- export type TranscodeInput = Blob | File | string;
558
- export type TranscodeResult = {
559
- buffer: ArrayBuffer;
560
- blob: Blob;
561
- };
562
- export type StreamProcessorResult = {
563
- blob: Blob;
564
- totalSize: number;
565
- };
566
- export type StreamProcessorOptions = Record<string, never>;
567
-
568
370
  import { Output } from "mediabunny";
569
371
  export declare class OutputManager {
570
372
  private output;
@@ -581,8 +383,6 @@ export declare class OutputManager {
581
383
  getTotalSize(): number;
582
384
  }
583
385
 
584
- export declare function transcodeVideo(input: TranscodeInput, config?: Partial<TranscodeConfig>, onProgress?: (progress: number) => void): Promise<TranscodeResult>;
585
-
586
386
  export declare class VideoElementManager {
587
387
  private videoElement;
588
388
  private isActive;
@@ -598,6 +398,28 @@ export declare class VideoElementManager {
598
398
  private waitForVideoReady;
599
399
  }
600
400
 
401
+ export type TranscodeConfig = {
402
+ format: "mp4";
403
+ fps: number;
404
+ width: number;
405
+ height: number;
406
+ bitrate: number;
407
+ audioCodec: "aac";
408
+ preset: "medium";
409
+ packetCount: number;
410
+ audioBitrate?: number;
411
+ };
412
+ export type TranscodeInput = Blob | File | string;
413
+ export type TranscodeResult = {
414
+ buffer: ArrayBuffer;
415
+ blob: Blob;
416
+ };
417
+ export type StreamProcessorResult = {
418
+ blob: Blob;
419
+ totalSize: number;
420
+ };
421
+ export type StreamProcessorOptions = Record<string, never>;
422
+
601
423
  import type { CanvasSource } from "mediabunny";
602
424
  export declare class FrameCapturer {
603
425
  private timeoutId;
@@ -651,314 +473,364 @@ export declare class AudioTrackManager {
651
473
  cleanup(): void;
652
474
  }
653
475
 
654
- export declare function calculateBarColor(position: number): string;
476
+ export declare class CanvasRenderer {
477
+ private readonly canvasContext;
478
+ constructor(canvasContext: OffscreenCanvasRenderingContext2D);
479
+ clear(): void;
480
+ drawFrame(videoElement: HTMLVideoElement): void;
481
+ getContext(): OffscreenCanvasRenderingContext2D;
482
+ }
655
483
 
656
- export declare const FILE_SIZE_UNITS: readonly ["Bytes", "KB", "MB", "GB"];
657
- export declare const FILE_SIZE_BASE = 1024;
658
- export declare function formatFileSize(bytes: number): string;
659
- export declare function formatTime(totalSeconds: number): string;
484
+ export declare const workletCode = "class AudioCaptureProcessor extends AudioWorkletProcessor {\n process(inputs, outputs) {\n const input = inputs[0];\n\n if (!input?.length) {\n return true;\n }\n\n const bufferLength = input[0].length;\n const numberOfChannels = input.length;\n const combinedBuffer = new Float32Array(bufferLength * numberOfChannels);\n\n for (let channel = 0; channel < numberOfChannels; channel++) {\n combinedBuffer.set(input[channel], channel * bufferLength);\n }\n\n const arrayBuffer = combinedBuffer.buffer.slice(\n 0,\n combinedBuffer.length * Float32Array.BYTES_PER_ELEMENT\n );\n\n this.port.postMessage(\n {\n type: \"audioData\",\n data: arrayBuffer,\n sampleRate: sampleRate,\n numberOfChannels,\n duration: bufferLength / sampleRate,\n bufferLength: combinedBuffer.length,\n },\n [arrayBuffer]\n );\n\n if (outputs && outputs[0] && outputs[0].length > 0) {\n for (let channel = 0; channel < numberOfChannels; channel++) {\n if (outputs[0][channel] && input[channel]) {\n outputs[0][channel].set(input[channel]);\n }\n }\n }\n\n return true;\n }\n}\n\nregisterProcessor(\"audio-capture-processor\", AudioCaptureProcessor);\n";
660
485
 
661
- export declare function extractErrorMessage(error: unknown): string;
486
+ export declare function transcodeVideo(input: TranscodeInput, config?: Partial<TranscodeConfig>, onProgress?: (progress: number) => void): Promise<TranscodeResult>;
662
487
 
663
- export type PendingUpload = {
664
- id: string;
665
- blob: Blob;
666
- apiKey: string;
667
- backendUrl: string;
668
- filename: string;
669
- duration?: number;
670
- metadata?: Record<string, unknown>;
671
- userMetadata?: Record<string, unknown>;
672
- status: "pending" | "uploading" | "failed" | "completed";
673
- retryCount: number;
674
- lastError?: string;
675
- createdAt: number;
676
- updatedAt: number;
488
+ import type { AvailableDevices } from "../types/recorder-types";
489
+ export type DeviceCallbacks = {
490
+ onDevicesChanged: (devices: AvailableDevices) => void;
491
+ onDeviceSelected: (type: "camera" | "mic", deviceId: string | null) => void;
677
492
  };
678
- export declare class VideoStorageService {
679
- private db;
680
- init(): Promise<void>;
681
- isInitialized(): boolean;
682
- savePendingUpload(upload: Omit<PendingUpload, "id" | "createdAt" | "updatedAt" | "status" | "retryCount">): Promise<string>;
683
- getPendingUploads(status?: PendingUpload["status"]): Promise<PendingUpload[]>;
684
- updateUploadStatus(id: string, updates: Partial<PendingUpload>): Promise<void>;
685
- deleteUpload(id: string): Promise<void>;
686
- cleanupPermanentlyFailedUploads(retentionHours?: number): Promise<number>;
687
- getTotalStorageSize(): Promise<number>;
688
- private generateUploadId;
689
- private executeTransaction;
690
- }
691
493
 
692
- import type { UploadResult } from "../types/recorder-types";
693
- export type UploadCallbacks = {
694
- onUploadProgress: (id: string, progress: number) => void;
695
- onUploadComplete: (id: string, result: UploadResult) => void;
696
- onUploadError: (id: string, error: Error) => void;
697
- };
494
+ import type { CameraStreamManager } from "../stream/stream";
495
+ import type { AvailableDevices } from "../types/recorder-types";
496
+ export declare class DeviceManager {
497
+ private readonly streamManager;
498
+ private readonly callbacks?;
499
+ private availableDevices;
500
+ private selectedCameraDeviceId;
501
+ private selectedMicDeviceId;
502
+ constructor(streamManager: CameraStreamManager, callbacks?: DeviceCallbacks);
503
+ getAvailableDevices(): Promise<AvailableDevices>;
504
+ setCameraDevice(deviceId: string | null): void;
505
+ setMicDevice(deviceId: string | null): void;
506
+ getSelectedCameraDeviceId(): string | null;
507
+ getSelectedMicDeviceId(): string | null;
508
+ getAvailableDevicesList(): AvailableDevices;
509
+ }
698
510
 
699
- import { UploadQueueManager } from "../upload/upload-queue-manager";
700
- import type { VideoUploadService } from "../upload/video-upload-service";
701
- export declare class StorageManager {
702
- private storageService;
703
- private uploadQueueManager;
704
- private cleanupIntervalId;
705
- initialize(uploadService: VideoUploadService | null, callbacks: UploadCallbacks, onCleanupError: (error: string) => void): Promise<void>;
706
- checkPendingUploads(): Promise<{
707
- pending: number;
708
- uploading: number;
511
+ import type { StreamProcessor } from "../processor/stream-processor";
512
+ import type { TranscodeConfig } from "../processor/types";
513
+ export declare class CameraStreamManager {
514
+ private mediaStream;
515
+ private mediaRecorder;
516
+ private recordedChunks;
517
+ private recordedMimeType;
518
+ private state;
519
+ private recordingStartTime;
520
+ private recordingTimer;
521
+ private pauseStartTime;
522
+ private totalPausedTime;
523
+ private readonly eventListeners;
524
+ private readonly streamConfig;
525
+ private readonly recordingOptions;
526
+ private streamProcessor;
527
+ private bufferSizeUpdateInterval;
528
+ private selectedAudioDeviceId;
529
+ private selectedVideoDeviceId;
530
+ constructor(streamConfig?: Partial<StreamConfig>, recordingOptions?: Partial<RecordingOptions>);
531
+ getState(): StreamState;
532
+ getStream(): MediaStream | null;
533
+ getAudioStreamForAnalysis(): MediaStream | null;
534
+ getRecorder(): MediaRecorder | null;
535
+ isRecording(): boolean;
536
+ isActive(): boolean;
537
+ on<T extends keyof StreamEventMap>(event: T, listener: StreamEventListener<T>): () => void;
538
+ off<T extends keyof StreamEventMap>(event: T, listener: StreamEventListener<T>): void;
539
+ once<T extends keyof StreamEventMap>(event: T, listener: StreamEventListener<T>): () => void;
540
+ private emit;
541
+ private setState;
542
+ setAudioDevice(deviceId: string | null): void;
543
+ setVideoDevice(deviceId: string | null): void;
544
+ getAudioDevice(): string | null;
545
+ getVideoDevice(): string | null;
546
+ getAvailableDevices(): Promise<{
547
+ audioinput: MediaDeviceInfo[];
548
+ videoinput: MediaDeviceInfo[];
709
549
  }>;
710
- performCleanup(): Promise<void>;
711
- getUploadQueueManager(): UploadQueueManager | null;
712
- getStorageService(): VideoStorageService | null;
550
+ private buildDeviceConstraints;
551
+ private buildVideoConstraints;
552
+ private buildAudioConstraints;
553
+ startStream(): Promise<MediaStream>;
554
+ stopStream(): void;
555
+ private stopStreamTracks;
556
+ private isTrackLive;
557
+ private tryReplaceTrack;
558
+ private recreateStreamWithNewTrack;
559
+ private switchDeviceTrack;
560
+ switchVideoDevice(deviceId: string | null): Promise<MediaStream>;
561
+ switchAudioDevice(deviceId: string | null): Promise<MediaStream>;
562
+ startRecordingWithMediaRecorder(): void;
563
+ stopRecordingWithMediaRecorder(): void;
564
+ startRecording(processor: StreamProcessor, config: TranscodeConfig): Promise<void>;
565
+ stopRecording(): Promise<Blob>;
566
+ pauseRecording(): void;
567
+ resumeRecording(): void;
568
+ toggleMute(): void;
569
+ private setAudioTracksEnabled;
570
+ muteAudio(): void;
571
+ unmuteAudio(): void;
572
+ isMuted(): boolean;
573
+ switchVideoSource(newStream: MediaStream): Promise<void>;
574
+ setMediaStream(stream: MediaStream): void;
575
+ getCurrentVideoSource(): MediaStream;
576
+ private formatTimeElapsed;
577
+ private startRecordingTimer;
578
+ private clearRecordingTimer;
579
+ private clearBufferSizeInterval;
580
+ private resetRecordingState;
581
+ private resetPauseState;
582
+ getRecordedBlob(): Blob;
713
583
  destroy(): void;
714
584
  }
715
585
 
716
- export type StorageQuota = {
717
- usage: number;
718
- quota: number;
719
- available: number;
720
- percentage: number;
586
+ export type CameraConstraints = {
587
+ width?: number | {
588
+ ideal?: number;
589
+ min?: number;
590
+ max?: number;
591
+ };
592
+ height?: number | {
593
+ ideal?: number;
594
+ min?: number;
595
+ max?: number;
596
+ };
597
+ frameRate?: number | {
598
+ ideal?: number;
599
+ min?: number;
600
+ max?: number;
601
+ };
721
602
  };
722
- export declare class QuotaManager {
723
- getQuota(): Promise<StorageQuota>;
724
- hasSpaceFor(sizeInBytes: number): Promise<boolean>;
725
- requestPersistentStorage(): Promise<boolean>;
726
- isPersistent(): Promise<boolean>;
727
- formatBytes(bytes: number): string;
728
- shouldWarn(threshold?: number): Promise<boolean>;
729
- isCritical(threshold?: number): Promise<boolean>;
730
- private checkThreshold;
731
- }
732
-
733
- export type AudioLevelCallbacks = {
734
- onLevelUpdate: (level: number, isMuted: boolean) => void;
603
+ export type StreamConfig = {
604
+ video: boolean | CameraConstraints;
605
+ audio: boolean | MediaTrackConstraints;
735
606
  };
736
-
737
- export declare class AudioLevelAnalyzer {
738
- private audioContext;
739
- private analyser;
740
- private audioLevelIntervalId;
741
- private audioLevel;
742
- private getMutedState;
743
- private currentStream;
744
- startTracking(stream: MediaStream, callbacks: AudioLevelCallbacks, getMutedState?: () => boolean): void;
745
- stopTracking(): void;
746
- getAudioLevel(): number;
747
- private getAudioContextClass;
748
- private calculateAudioLevel;
749
- private checkMutedState;
750
- }
751
-
752
- import type { AudioLevelCallbacks } from "../audio/types";
753
- import type { DeviceCallbacks } from "../device/types";
754
- import type { RecordingCallbacks } from "../recording/types";
755
- import type { UploadCallbacks as StorageUploadCallbacks } from "../storage/types";
756
- import type { SourceType } from "../types/recorder-types";
757
- import type { UploadCallbacks } from "../upload/types";
758
- export type RecorderConfig = {
759
- apiKey?: string | null;
760
- backendUrl?: string | null;
761
- countdownDuration?: number;
762
- maxRecordingTime?: number | null;
763
- userMetadata?: Record<string, unknown>;
607
+ export type RecordingOptions = {
608
+ mimeType?: string;
609
+ videoBitsPerSecond?: number;
610
+ audioBitsPerSecond?: number;
611
+ bitsPerSecond?: number;
764
612
  };
765
- export type RecorderCallbacks = {
766
- recording?: RecordingCallbacks;
767
- audioLevel?: AudioLevelCallbacks;
768
- device?: DeviceCallbacks;
769
- upload?: UploadCallbacks;
770
- storage?: StorageUploadCallbacks;
771
- sourceSwitch?: {
772
- onSourceChange?: (sourceType: SourceType) => void;
773
- onPreviewUpdate?: (stream: MediaStream) => Promise<void>;
774
- onError?: (error: Error) => void;
775
- onTransitionStart?: (message: string) => void;
776
- onTransitionEnd?: () => void;
613
+ export type StreamState = "idle" | "starting" | "active" | "recording" | "stopping" | "error";
614
+ export type StreamEventMap = {
615
+ statechange: {
616
+ state: StreamState;
617
+ previousState: StreamState;
777
618
  };
778
- stream?: {
779
- onStreamStart?: (stream: MediaStream) => void;
780
- onStreamStop?: () => void;
781
- onError?: (error: Error) => void;
619
+ streamstart: {
620
+ stream: MediaStream;
621
+ };
622
+ streamstop: undefined;
623
+ recordingstart: {
624
+ recorder: MediaRecorder | null;
625
+ };
626
+ recordingstop: {
627
+ blob: Blob;
628
+ mimeType: string;
629
+ };
630
+ recordingdata: {
631
+ data: Blob;
632
+ };
633
+ error: {
634
+ error: Error;
635
+ };
636
+ recordingtimeupdate: {
637
+ elapsed: number;
638
+ formatted: string;
639
+ };
640
+ recordingbufferupdate: {
641
+ size: number;
642
+ formatted: string;
643
+ };
644
+ audiomutetoggle: {
645
+ muted: boolean;
646
+ };
647
+ videosourcechange: {
648
+ stream: MediaStream;
782
649
  };
783
- onStorageCleanupError?: (error: string) => void;
784
650
  };
651
+ export type StreamEventListener<T extends keyof StreamEventMap> = (data: StreamEventMap[T]) => void;
785
652
 
786
- import type { AudioLevelAnalyzer } from "../audio/audio-level-analyzer";
787
- import type { ConfigManager } from "../config/config-manager";
788
- import type { DeviceManager } from "../device/device-manager";
789
- import type { RecordingCallbacks } from "../recording/types";
790
- import type { SourceSwitchCallbacks } from "../stream/source-switch";
791
- export declare function createRecordingCallbacks(callbacks: RecorderCallbacks, audioLevelAnalyzer: AudioLevelAnalyzer, configManager: ConfigManager): RecordingCallbacks;
792
- export declare function createSourceSwitchCallbacks(callbacks: RecorderCallbacks, deviceManager: DeviceManager): SourceSwitchCallbacks;
653
+ export declare const DEFAULT_CAMERA_CONSTRAINTS: Readonly<CameraConstraints>;
654
+ export declare const DEFAULT_STREAM_CONFIG: Readonly<StreamConfig>;
655
+ export declare const DEFAULT_RECORDING_OPTIONS: Readonly<RecordingOptions>;
793
656
 
794
- import type { AudioLevelCallbacks } from "../audio/types";
795
- import { DeviceManager } from "../device/device-manager";
796
- import { CameraStreamManager } from "../stream/stream";
797
657
  import type { SourceType } from "../types/recorder-types";
798
- export declare class RecorderController {
799
- private readonly streamManager;
800
- private readonly configManager;
801
- private readonly storageManager;
802
- private readonly deviceManager;
803
- private readonly audioLevelAnalyzer;
804
- private readonly uploadManager;
805
- private readonly recordingManager;
806
- private readonly sourceSwitchManager;
807
- private readonly uploadService;
808
- private readonly muteStateManager;
809
- private isInitialized;
810
- constructor(callbacks?: RecorderCallbacks);
811
- initialize(config: RecorderConfig): Promise<void>;
812
- startStream(): Promise<void>;
813
- stopStream(): Promise<void>;
814
- switchVideoDevice(deviceId: string | null): Promise<MediaStream>;
815
- switchAudioDevice(deviceId: string | null): Promise<MediaStream>;
816
- startRecording(): Promise<void>;
817
- stopRecording(): Promise<Blob>;
818
- pauseRecording(): void;
819
- resumeRecording(): void;
820
- switchSource(_sourceType: SourceType): Promise<void>;
821
- setCameraDevice(deviceId: string | null): void;
822
- setMicDevice(deviceId: string | null): void;
823
- getAvailableDevices(): Promise<import("../..").AvailableDevices>;
824
- muteAudio(): void;
825
- unmuteAudio(): void;
826
- toggleMute(): void;
827
- getIsMuted(): boolean;
828
- startAudioLevelTracking(stream: MediaStream, callbacks?: AudioLevelCallbacks): Promise<void>;
829
- stopAudioLevelTracking(): void;
830
- getAudioLevel(): number;
831
- uploadVideo(blob: Blob, apiKey: string, backendUrl: string, metadata: Record<string, unknown>): Promise<void>;
832
- getStream(): MediaStream | null;
833
- getRecordingState(): import("../..").RecordingState;
834
- isPaused(): boolean;
658
+ export type SourceSwitchCallbacks = {
659
+ onSourceChange?: (sourceType: SourceType) => void;
660
+ onPreviewUpdate?: (stream: MediaStream) => Promise<void>;
661
+ onError?: (error: Error) => void;
662
+ onTransitionStart?: (message: string) => void;
663
+ onTransitionEnd?: () => void;
664
+ getSelectedCameraDeviceId?: () => string | null;
665
+ getSelectedMicDeviceId?: () => string | null;
666
+ };
667
+ export declare class SourceSwitchManager {
668
+ private currentSourceType;
669
+ private originalCameraStream;
670
+ private originalCameraConstraints;
671
+ private screenShareStream;
672
+ private screenShareTrackEndHandler;
673
+ private readonly streamManager;
674
+ private callbacks;
675
+ constructor(streamManager: CameraStreamManager, callbacks?: SourceSwitchCallbacks);
835
676
  getCurrentSourceType(): SourceType;
836
677
  getOriginalCameraStream(): MediaStream | null;
837
- getStreamManager(): CameraStreamManager;
838
- getAudioStreamForAnalysis(): MediaStream | null;
839
- getDeviceManager(): DeviceManager;
840
- getConfig(): Promise<import("../..").TranscodeConfig>;
841
- isRecording(): boolean;
842
- isActive(): boolean;
678
+ private stopLiveTracks;
679
+ private stopStreamTracks;
680
+ private stopStreamVideoTracks;
681
+ private isTrackLive;
682
+ private areTracksLive;
683
+ private storeOriginalCameraConstraints;
684
+ private storeOriginalCameraStream;
685
+ private createError;
686
+ private waitForTracksToEnd;
687
+ private combineScreenShareWithOriginalAudio;
688
+ switchToScreenCapture(): Promise<MediaStream | null>;
689
+ private setupScreenShareTrackHandler;
690
+ removeScreenShareTrackHandler(stream: MediaStream | null): void;
691
+ private canReuseStream;
692
+ private canReuseOriginalStream;
693
+ private canReuseManagerStream;
694
+ private getSelectedCameraDeviceId;
695
+ private getSelectedMicDeviceId;
696
+ private buildVideoConstraints;
697
+ private buildAudioConstraints;
698
+ private validateTrack;
699
+ private createCameraStreamWithOriginalAudio;
700
+ private createCameraStreamWithNewAudio;
701
+ private createNewCameraStreamForRecording;
702
+ getCameraStream(): Promise<MediaStream>;
703
+ switchToCamera(): Promise<void>;
704
+ private notifyTransitionStart;
705
+ private notifyTransitionEnd;
706
+ private stopScreenShareStreamTracks;
707
+ private handleScreenShareStop;
708
+ private applyCameraStream;
709
+ toggleSource(): Promise<void>;
710
+ private switchToScreen;
711
+ private handleToggleError;
712
+ handleRecordingStop(): Promise<void>;
843
713
  cleanup(): void;
714
+ setCallbacks(callbacks: SourceSwitchCallbacks): void;
844
715
  }
845
716
 
846
- import type { CameraStreamManager } from "../stream/stream";
847
- export declare class MuteStateManager {
848
- private isMuted;
849
- private readonly streamManager;
850
- constructor(streamManager: CameraStreamManager);
851
- mute(): void;
852
- unmute(): void;
853
- toggle(): void;
854
- getIsMuted(): boolean;
855
- getMutedStateCallback(): () => boolean;
856
- }
717
+ export type AudioLevelCallbacks = {
718
+ onLevelUpdate: (level: number, isMuted: boolean) => void;
719
+ };
857
720
 
858
- import type { CameraStreamManager } from "../stream/stream";
859
- import type { AvailableDevices } from "../types/recorder-types";
860
- export declare class DeviceManager {
861
- private readonly streamManager;
862
- private readonly callbacks?;
863
- private availableDevices;
864
- private selectedCameraDeviceId;
865
- private selectedMicDeviceId;
866
- constructor(streamManager: CameraStreamManager, callbacks?: DeviceCallbacks);
867
- getAvailableDevices(): Promise<AvailableDevices>;
868
- setCameraDevice(deviceId: string | null): void;
869
- setMicDevice(deviceId: string | null): void;
870
- getSelectedCameraDeviceId(): string | null;
871
- getSelectedMicDeviceId(): string | null;
872
- getAvailableDevicesList(): AvailableDevices;
721
+ export declare class AudioLevelAnalyzer {
722
+ private audioContext;
723
+ private analyser;
724
+ private audioLevelIntervalId;
725
+ private audioLevel;
726
+ private getMutedState;
727
+ private currentStream;
728
+ startTracking(stream: MediaStream, callbacks: AudioLevelCallbacks, getMutedState?: () => boolean): void;
729
+ stopTracking(): void;
730
+ getAudioLevel(): number;
731
+ private getAudioContextClass;
732
+ private calculateAudioLevel;
733
+ private checkMutedState;
873
734
  }
874
735
 
875
- import type { AvailableDevices } from "../types/recorder-types";
876
- export type DeviceCallbacks = {
877
- onDevicesChanged: (devices: AvailableDevices) => void;
878
- onDeviceSelected: (type: "camera" | "mic", deviceId: string | null) => void;
736
+ import type { TranscodeConfig } from "../processor/types";
737
+ export type ConfigServiceOptions = {
738
+ apiKey: string;
739
+ backendUrl: string;
740
+ cacheTimeout?: number;
879
741
  };
742
+ export declare class ConfigService {
743
+ private readonly cacheTimeout;
744
+ private readonly options;
745
+ private cachedConfig;
746
+ private cacheTimestamp;
747
+ private fetchPromise;
748
+ private constructor();
749
+ static getInstance(options: ConfigServiceOptions): ConfigService;
750
+ fetchConfig(): Promise<TranscodeConfig>;
751
+ clearCache(): void;
752
+ static clearAllInstances(): void;
753
+ getCurrentConfig(): TranscodeConfig;
754
+ private fetchConfigFromBackend;
755
+ }
880
756
 
881
- import type { UploadResult } from "../types/recorder-types";
882
- export declare class UploadManager {
883
- private readonly callbacks;
884
- private uploadQueueManager;
885
- constructor(callbacks: UploadCallbacks);
886
- setUploadQueueManager(uploadQueueManager: UploadQueueManager | null): void;
887
- uploadVideo(blob: Blob, apiKey: string, backendUrl: string, userMetadata: Record<string, unknown>): Promise<void>;
888
- updateProgress(progress: number): void;
889
- showSuccess(result: UploadResult): void;
890
- showError(message: string): void;
891
- clearStatus(): void;
757
+ import type { TranscodeConfig } from "../processor/types";
758
+ export declare class ConfigManager {
759
+ private configService;
760
+ private currentConfig;
761
+ initialize(apiKey: string | null, backendUrl: string | null): void;
762
+ fetchConfig(): Promise<void>;
763
+ getConfig(): Promise<TranscodeConfig>;
764
+ clearCache(): void;
892
765
  }
893
766
 
894
- import type { PendingUpload, VideoStorageService } from "../storage/video-storage";
895
- type UploadCallbacks = {
896
- onUploadProgress?: (id: string, progress: number) => void;
897
- onUploadComplete?: (id: string, result: VideoUploadResult) => void;
898
- onUploadError?: (id: string, error: Error) => void;
767
+ import type { TranscodeConfig } from "../processor/types";
768
+ export type BackendPreset = "sd" | "hd" | "fhd" | "4k";
769
+ export type BackendConfigResponse = {
770
+ presetEncoding: BackendPreset;
771
+ max_width: number;
772
+ max_height: number;
899
773
  };
900
- export declare class UploadQueueManager {
901
- private readonly storageService;
902
- private readonly uploadService;
903
- private readonly processingIntervalId;
904
- private readonly networkOnlineHandler;
905
- private isProcessing;
906
- private retryTimeoutId;
907
- private callbacks;
908
- constructor(storageService: VideoStorageService, uploadService: VideoUploadService);
909
- destroy(): void;
910
- setCallbacks(callbacks: UploadCallbacks): void;
911
- queueUpload(upload: Omit<PendingUpload, "id" | "createdAt" | "updatedAt" | "status" | "retryCount">): Promise<string>;
912
- processQueue(): Promise<void>;
913
- getPendingUploads(): Promise<PendingUpload[]>;
914
- getStats(): Promise<{
915
- pending: number;
916
- uploading: number;
917
- failed: number;
918
- total: number;
919
- }>;
920
- private getOldestUpload;
921
- private getOldestFailedUpload;
922
- private processUpload;
923
- private calculateRetryDelay;
924
- private scheduleRetry;
925
- private clearTimer;
926
- }
927
- export {};
774
+ export declare function mapPresetToConfig(preset: BackendPreset, maxWidth: number, maxHeight: number): TranscodeConfig;
928
775
 
929
- export declare function extractVideoDuration(blob: Blob): Promise<number>;
776
+ import type { TranscodeConfig } from "../processor/types";
777
+ export declare const DEFAULT_TRANSCODE_CONFIG: Readonly<TranscodeConfig>;
930
778
 
931
- import type { UploadResult } from "../types/recorder-types";
932
- export type UploadCallbacks = {
933
- onProgress: (progress: number) => void;
934
- onSuccess: (result: UploadResult) => void;
779
+ import type { TranscodeConfig } from "../processor/types";
780
+ import type { RecordingState } from "../types/recorder-types";
781
+ export type RecordingCallbacks = {
782
+ onStateChange: (state: RecordingState) => void;
783
+ onCountdownUpdate: (state: RecordingState, remaining: number) => void;
784
+ onTimerUpdate: (formatted: string) => void;
935
785
  onError: (error: Error) => void;
936
- onClearStatus: () => void;
786
+ onRecordingComplete: (blob: Blob) => void;
787
+ onClearUploadStatus: () => void;
788
+ onStopAudioTracking: () => void;
789
+ onGetConfig: () => Promise<TranscodeConfig>;
937
790
  };
938
791
 
939
- export type VideoUploadOptions = {
940
- apiKey: string;
941
- backendUrl: string;
942
- filename?: string;
943
- metadata?: Record<string, unknown>;
944
- userMetadata?: Record<string, unknown>;
945
- duration?: number;
946
- onProgress?: (progress: number) => void;
947
- };
948
- export type VideoUploadInitResponse = {
949
- videoId: string;
950
- uploadUrl: string;
951
- };
952
- export type VideoUploadResult = {
953
- videoId: string;
954
- status: string;
955
- uploadUrl: string;
956
- };
957
- export declare class VideoUploadService {
958
- uploadVideo(blob: Blob, options: VideoUploadOptions): Promise<VideoUploadResult>;
959
- private initVideoUpload;
960
- private extractErrorFromResponse;
961
- private uploadVideoFile;
962
- private parseSuccessResponse;
963
- private parseErrorResponse;
792
+ import { StreamProcessor } from "../processor/stream-processor";
793
+ import type { CameraStreamManager } from "../stream/stream";
794
+ import type { RecordingState } from "../types/recorder-types";
795
+ export declare class RecordingManager {
796
+ private recordingState;
797
+ private countdownDuration;
798
+ private countdownRemaining;
799
+ private countdownTimeoutId;
800
+ private countdownIntervalId;
801
+ private countdownStartTime;
802
+ private isPaused;
803
+ private maxRecordingTime;
804
+ private maxTimeTimer;
805
+ private recordingSeconds;
806
+ private recordingIntervalId;
807
+ private pauseStartTime;
808
+ private totalPausedTime;
809
+ private readonly streamManager;
810
+ private readonly callbacks;
811
+ private streamProcessor;
812
+ private originalCameraStream;
813
+ constructor(streamManager: CameraStreamManager, callbacks: RecordingCallbacks);
814
+ setCountdownDuration(duration: number): void;
815
+ setMaxRecordingTime(maxTime: number | null): void;
816
+ getRecordingState(): RecordingState;
817
+ isPausedState(): boolean;
818
+ getRecordingSeconds(): number;
819
+ getStreamProcessor(): StreamProcessor | null;
820
+ setOriginalCameraStream(stream: MediaStream | null): void;
821
+ getOriginalCameraStream(): MediaStream | null;
822
+ startRecording(): Promise<void>;
823
+ private startCountdown;
824
+ private doStartRecording;
825
+ stopRecording(): Promise<Blob>;
826
+ pauseRecording(): void;
827
+ resumeRecording(): void;
828
+ cancelCountdown(): void;
829
+ cleanup(): void;
830
+ private resetRecordingState;
831
+ private resetPauseState;
832
+ private updatePausedDuration;
833
+ private startRecordingTimer;
834
+ private clearTimer;
835
+ private handleError;
964
836
  }