@vidtreo/recorder 1.7.1 → 1.7.2
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 +15 -0
- package/dist/index.js +85 -9
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export type RecoverPendingUploadOptions = {
|
|
2
|
+
match: PendingUploadMatch;
|
|
3
|
+
onProgress?: (progress: number) => void;
|
|
4
|
+
};
|
|
5
|
+
export declare function recoverPendingUpload(options: RecoverPendingUploadOptions): Promise<VideoUploadResult | null>;
|
|
6
|
+
|
|
1
7
|
export type VideoUploadOptions = {
|
|
2
8
|
apiKey: string;
|
|
3
9
|
backendUrl: string;
|
|
@@ -35,6 +41,10 @@ type UploadCallbacks = {
|
|
|
35
41
|
onUploadComplete?: (id: string, result: VideoUploadResult) => void;
|
|
36
42
|
onUploadError?: (id: string, error: Error) => void;
|
|
37
43
|
};
|
|
44
|
+
export type PendingUploadMatch = {
|
|
45
|
+
metadata?: Record<string, unknown>;
|
|
46
|
+
userMetadata?: Record<string, unknown>;
|
|
47
|
+
};
|
|
38
48
|
export declare class UploadQueueManager {
|
|
39
49
|
private readonly storageService;
|
|
40
50
|
private readonly uploadService;
|
|
@@ -50,6 +60,7 @@ export declare class UploadQueueManager {
|
|
|
50
60
|
queueUpload(upload: Omit<PendingUpload, "id" | "createdAt" | "updatedAt" | "status" | "retryCount">): Promise<string>;
|
|
51
61
|
processQueue(): Promise<void>;
|
|
52
62
|
getPendingUploads(): Promise<PendingUpload[]>;
|
|
63
|
+
processMatchingUpload(match: PendingUploadMatch): Promise<VideoUploadResult | null>;
|
|
53
64
|
getStats(): Promise<{
|
|
54
65
|
pending: number;
|
|
55
66
|
uploading: number;
|
|
@@ -58,6 +69,10 @@ export declare class UploadQueueManager {
|
|
|
58
69
|
}>;
|
|
59
70
|
private getOldestUpload;
|
|
60
71
|
private getOldestFailedUpload;
|
|
72
|
+
private recoverStaleUploads;
|
|
73
|
+
private getOldestMatchingUpload;
|
|
74
|
+
private canProcessMatchingUpload;
|
|
75
|
+
private matchesMetadata;
|
|
61
76
|
private processUpload;
|
|
62
77
|
private calculateRetryDelay;
|
|
63
78
|
private scheduleRetry;
|
package/dist/index.js
CHANGED
|
@@ -6305,7 +6305,7 @@ function resolveDeviceError(input) {
|
|
|
6305
6305
|
// package.json
|
|
6306
6306
|
var package_default = {
|
|
6307
6307
|
name: "@vidtreo/recorder",
|
|
6308
|
-
version: "1.7.
|
|
6308
|
+
version: "1.7.2",
|
|
6309
6309
|
type: "module",
|
|
6310
6310
|
description: "Vidtreo SDK for browser-based video recording and transcoding. Features include camera/screen recording, real-time MP4 transcoding, audio level analysis, mute/pause controls, source switching, device selection, and automatic backend uploads. Similar to Ziggeo and Addpipe, Vidtreo provides enterprise-grade video processing capabilities for web applications.",
|
|
6311
6311
|
main: "./dist/index.js",
|
|
@@ -7056,13 +7056,7 @@ class UploadQueueManager {
|
|
|
7056
7056
|
if (!this.storageService.isInitialized()) {
|
|
7057
7057
|
throw new Error("Database not initialized");
|
|
7058
7058
|
}
|
|
7059
|
-
|
|
7060
|
-
const staleUploads = await this.storageService.getPendingUploads("uploading");
|
|
7061
|
-
await Promise.all(staleUploads.map((upload) => this.storageService.updateUploadStatus(upload.id, {
|
|
7062
|
-
status: "pending"
|
|
7063
|
-
})));
|
|
7064
|
-
this.hasRecoveredStaleUploads = true;
|
|
7065
|
-
}
|
|
7059
|
+
await this.recoverStaleUploads();
|
|
7066
7060
|
const pendingUploads = await this.storageService.getPendingUploads("pending");
|
|
7067
7061
|
if (pendingUploads.length > 0) {
|
|
7068
7062
|
const upload = this.getOldestUpload(pendingUploads);
|
|
@@ -7096,6 +7090,27 @@ class UploadQueueManager {
|
|
|
7096
7090
|
getPendingUploads() {
|
|
7097
7091
|
return this.storageService.getPendingUploads();
|
|
7098
7092
|
}
|
|
7093
|
+
async processMatchingUpload(match) {
|
|
7094
|
+
if (this.isProcessing) {
|
|
7095
|
+
return null;
|
|
7096
|
+
}
|
|
7097
|
+
this.isProcessing = true;
|
|
7098
|
+
try {
|
|
7099
|
+
await this.recoverStaleUploads();
|
|
7100
|
+
const uploads = await this.storageService.getPendingUploads();
|
|
7101
|
+
const matchingUpload = this.getOldestMatchingUpload(uploads, match);
|
|
7102
|
+
if (!matchingUpload) {
|
|
7103
|
+
this.isProcessing = false;
|
|
7104
|
+
return null;
|
|
7105
|
+
}
|
|
7106
|
+
const result = await this.processUpload(matchingUpload, true);
|
|
7107
|
+
this.isProcessing = false;
|
|
7108
|
+
return result;
|
|
7109
|
+
} catch (error) {
|
|
7110
|
+
this.isProcessing = false;
|
|
7111
|
+
throw new Error(`Error processing matching upload: ${extractErrorMessage(error)}`);
|
|
7112
|
+
}
|
|
7113
|
+
}
|
|
7099
7114
|
async getStats() {
|
|
7100
7115
|
const all = await this.storageService.getPendingUploads();
|
|
7101
7116
|
const stats = {
|
|
@@ -7127,7 +7142,45 @@ class UploadQueueManager {
|
|
|
7127
7142
|
}
|
|
7128
7143
|
return uploads.sort((a, b) => a.updatedAt - b.updatedAt)[0];
|
|
7129
7144
|
}
|
|
7130
|
-
async
|
|
7145
|
+
async recoverStaleUploads() {
|
|
7146
|
+
if (this.hasRecoveredStaleUploads) {
|
|
7147
|
+
return;
|
|
7148
|
+
}
|
|
7149
|
+
const staleUploads = await this.storageService.getPendingUploads("uploading");
|
|
7150
|
+
await Promise.all(staleUploads.map((upload) => this.storageService.updateUploadStatus(upload.id, {
|
|
7151
|
+
status: "pending"
|
|
7152
|
+
})));
|
|
7153
|
+
this.hasRecoveredStaleUploads = true;
|
|
7154
|
+
}
|
|
7155
|
+
getOldestMatchingUpload(uploads, match) {
|
|
7156
|
+
const matchingUploads = uploads.filter((upload) => this.canProcessMatchingUpload(upload, match));
|
|
7157
|
+
if (matchingUploads.length === 0) {
|
|
7158
|
+
return null;
|
|
7159
|
+
}
|
|
7160
|
+
return matchingUploads.sort((a, b) => a.createdAt - b.createdAt)[0];
|
|
7161
|
+
}
|
|
7162
|
+
canProcessMatchingUpload(upload, match) {
|
|
7163
|
+
if (upload.status === "completed") {
|
|
7164
|
+
return false;
|
|
7165
|
+
}
|
|
7166
|
+
if (upload.status === "failed" && upload.retryCount >= MAX_RETRIES2) {
|
|
7167
|
+
return false;
|
|
7168
|
+
}
|
|
7169
|
+
if (!this.matchesMetadata(upload.metadata, match.metadata)) {
|
|
7170
|
+
return false;
|
|
7171
|
+
}
|
|
7172
|
+
return this.matchesMetadata(upload.userMetadata, match.userMetadata);
|
|
7173
|
+
}
|
|
7174
|
+
matchesMetadata(actual, expected) {
|
|
7175
|
+
if (!expected || Object.keys(expected).length === 0) {
|
|
7176
|
+
return true;
|
|
7177
|
+
}
|
|
7178
|
+
if (!actual) {
|
|
7179
|
+
return false;
|
|
7180
|
+
}
|
|
7181
|
+
return Object.entries(expected).every(([key, value]) => actual[key] === value);
|
|
7182
|
+
}
|
|
7183
|
+
async processUpload(upload, shouldThrowOnError = false) {
|
|
7131
7184
|
try {
|
|
7132
7185
|
await this.storageService.updateUploadStatus(upload.id, {
|
|
7133
7186
|
status: "uploading"
|
|
@@ -7145,6 +7198,7 @@ class UploadQueueManager {
|
|
|
7145
7198
|
});
|
|
7146
7199
|
await this.storageService.deleteUpload(upload.id);
|
|
7147
7200
|
this.callbacks.onUploadComplete?.(upload.id, result);
|
|
7201
|
+
return result;
|
|
7148
7202
|
} catch (error) {
|
|
7149
7203
|
const errorMessage = extractErrorMessage(error);
|
|
7150
7204
|
const retryCount = upload.retryCount + 1;
|
|
@@ -7159,6 +7213,10 @@ class UploadQueueManager {
|
|
|
7159
7213
|
const delay2 = this.calculateRetryDelay(retryCount);
|
|
7160
7214
|
this.scheduleRetry(delay2);
|
|
7161
7215
|
}
|
|
7216
|
+
if (shouldThrowOnError) {
|
|
7217
|
+
throw new Error(errorMessage);
|
|
7218
|
+
}
|
|
7219
|
+
return null;
|
|
7162
7220
|
}
|
|
7163
7221
|
}
|
|
7164
7222
|
calculateRetryDelay(retryCount) {
|
|
@@ -23899,6 +23957,23 @@ class QuotaManager {
|
|
|
23899
23957
|
return quota.percentage >= threshold;
|
|
23900
23958
|
}
|
|
23901
23959
|
}
|
|
23960
|
+
// src/core/upload/pending-upload-recovery.ts
|
|
23961
|
+
async function recoverPendingUpload(options) {
|
|
23962
|
+
const storageService = new VideoStorageService;
|
|
23963
|
+
await storageService.init();
|
|
23964
|
+
const uploadService = new VideoUploadService;
|
|
23965
|
+
const uploadQueueManager = new UploadQueueManager(storageService, uploadService);
|
|
23966
|
+
uploadQueueManager.setCallbacks({
|
|
23967
|
+
onUploadProgress: (_id, progress) => {
|
|
23968
|
+
options.onProgress?.(progress);
|
|
23969
|
+
}
|
|
23970
|
+
});
|
|
23971
|
+
try {
|
|
23972
|
+
return await uploadQueueManager.processMatchingUpload(options.match);
|
|
23973
|
+
} finally {
|
|
23974
|
+
uploadQueueManager.destroy();
|
|
23975
|
+
}
|
|
23976
|
+
}
|
|
23902
23977
|
// src/core/utils/audio-utils.ts
|
|
23903
23978
|
function calculateBarColor(position) {
|
|
23904
23979
|
if (position < 0.25) {
|
|
@@ -24294,6 +24369,7 @@ export {
|
|
|
24294
24369
|
requireInitialized,
|
|
24295
24370
|
requireDefined,
|
|
24296
24371
|
requireActive,
|
|
24372
|
+
recoverPendingUpload,
|
|
24297
24373
|
parseBrowserErrorLinkContent,
|
|
24298
24374
|
mapPresetToConfig,
|
|
24299
24375
|
logger,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vidtreo/recorder",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vidtreo SDK for browser-based video recording and transcoding. Features include camera/screen recording, real-time MP4 transcoding, audio level analysis, mute/pause controls, source switching, device selection, and automatic backend uploads. Similar to Ziggeo and Addpipe, Vidtreo provides enterprise-grade video processing capabilities for web applications.",
|
|
6
6
|
"main": "./dist/index.js",
|