@epic-web/workshop-utils 6.57.0 → 6.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -85,10 +85,13 @@ export declare function downloadOfflineVideo({ playbackId, title, url, }: {
|
|
|
85
85
|
url: string;
|
|
86
86
|
}): Promise<{
|
|
87
87
|
readonly status: "error";
|
|
88
|
+
readonly message: string;
|
|
88
89
|
} | {
|
|
89
90
|
readonly status: "ready";
|
|
91
|
+
readonly message?: undefined;
|
|
90
92
|
} | {
|
|
91
93
|
readonly status: "downloaded";
|
|
94
|
+
readonly message?: undefined;
|
|
92
95
|
}>;
|
|
93
96
|
export declare function deleteOfflineVideo(playbackId: string, options?: {
|
|
94
97
|
workshopId?: string;
|
|
@@ -358,14 +358,26 @@ async function downloadMuxVideo({ playbackId, filePath, key, iv, resolution, })
|
|
|
358
358
|
status: 'downloading',
|
|
359
359
|
});
|
|
360
360
|
for (const url of urls) {
|
|
361
|
+
log.info('Attempting mux download', { playbackId, url });
|
|
361
362
|
const response = await fetch(url).catch((error) => {
|
|
362
363
|
lastError = error;
|
|
364
|
+
log.warn('Mux download request failed', {
|
|
365
|
+
playbackId,
|
|
366
|
+
url,
|
|
367
|
+
message: lastError.message,
|
|
368
|
+
});
|
|
363
369
|
return null;
|
|
364
370
|
});
|
|
365
371
|
if (!response)
|
|
366
372
|
continue;
|
|
367
373
|
if (!response.ok || !response.body) {
|
|
368
374
|
lastError = new Error(`Failed to download ${playbackId} from ${url} (${response.status})`);
|
|
375
|
+
log.warn('Mux download response not ok', {
|
|
376
|
+
playbackId,
|
|
377
|
+
url,
|
|
378
|
+
status: response.status,
|
|
379
|
+
hasBody: Boolean(response.body),
|
|
380
|
+
});
|
|
369
381
|
continue;
|
|
370
382
|
}
|
|
371
383
|
// Get content-length if available for progress tracking
|
|
@@ -403,6 +415,11 @@ async function downloadMuxVideo({ playbackId, filePath, key, iv, resolution, })
|
|
|
403
415
|
totalBytes: stat.size,
|
|
404
416
|
status: 'complete',
|
|
405
417
|
});
|
|
418
|
+
log.info('Mux download complete', {
|
|
419
|
+
playbackId,
|
|
420
|
+
url,
|
|
421
|
+
size: stat.size,
|
|
422
|
+
});
|
|
406
423
|
return { size: stat.size };
|
|
407
424
|
}
|
|
408
425
|
emitDownloadProgress({
|
|
@@ -421,6 +438,10 @@ async function runOfflineVideoDownloads({ videos, index, keyInfo, workshop, reso
|
|
|
421
438
|
title: video.title,
|
|
422
439
|
};
|
|
423
440
|
downloadState.updatedAt = updatedAt;
|
|
441
|
+
log.info('Downloading offline video', {
|
|
442
|
+
playbackId: video.playbackId,
|
|
443
|
+
title: video.title,
|
|
444
|
+
});
|
|
424
445
|
const iv = createOfflineVideoIv();
|
|
425
446
|
const entry = {
|
|
426
447
|
playbackId: video.playbackId,
|
|
@@ -551,6 +572,10 @@ export async function startOfflineVideoDownload({ request, } = {}) {
|
|
|
551
572
|
allowUserIdUpdate: true,
|
|
552
573
|
});
|
|
553
574
|
if (!keyInfo) {
|
|
575
|
+
log.warn('Offline video download unavailable: missing key info', {
|
|
576
|
+
available: videos.length,
|
|
577
|
+
unavailable,
|
|
578
|
+
});
|
|
554
579
|
return {
|
|
555
580
|
state: downloadState,
|
|
556
581
|
available: videos.length,
|
|
@@ -590,6 +615,11 @@ export async function startOfflineVideoDownload({ request, } = {}) {
|
|
|
590
615
|
current: null,
|
|
591
616
|
errors: [],
|
|
592
617
|
};
|
|
618
|
+
log.info('Offline video downloads queued', {
|
|
619
|
+
queued: downloads.length,
|
|
620
|
+
skipped: alreadyDownloaded,
|
|
621
|
+
unavailable,
|
|
622
|
+
});
|
|
593
623
|
if (downloads.length > 0) {
|
|
594
624
|
const resolution = await getOfflineVideoDownloadResolution();
|
|
595
625
|
void runOfflineVideoDownloads({
|
|
@@ -613,6 +643,7 @@ export async function startOfflineVideoDownload({ request, } = {}) {
|
|
|
613
643
|
};
|
|
614
644
|
}
|
|
615
645
|
export async function downloadOfflineVideo({ playbackId, title, url, }) {
|
|
646
|
+
log.info('Offline video download requested', { playbackId, title, url });
|
|
616
647
|
const workshop = getWorkshopIdentity();
|
|
617
648
|
const index = await readOfflineVideoIndex();
|
|
618
649
|
const authInfo = await getAuthInfo();
|
|
@@ -620,8 +651,16 @@ export async function downloadOfflineVideo({ playbackId, title, url, }) {
|
|
|
620
651
|
userId: authInfo?.id ?? null,
|
|
621
652
|
allowUserIdUpdate: true,
|
|
622
653
|
});
|
|
623
|
-
if (!keyInfo)
|
|
624
|
-
|
|
654
|
+
if (!keyInfo) {
|
|
655
|
+
log.warn('Offline video download failed: missing key info', {
|
|
656
|
+
playbackId,
|
|
657
|
+
});
|
|
658
|
+
const message = `Unable to download "${title}". Try again later.`;
|
|
659
|
+
return {
|
|
660
|
+
status: 'error',
|
|
661
|
+
message,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
625
664
|
const resolution = await getOfflineVideoDownloadResolution();
|
|
626
665
|
const existing = index[playbackId];
|
|
627
666
|
if (existing?.status === 'ready' &&
|
|
@@ -665,18 +704,21 @@ export async function downloadOfflineVideo({ playbackId, title, url, }) {
|
|
|
665
704
|
updatedAt: new Date().toISOString(),
|
|
666
705
|
};
|
|
667
706
|
await writeOfflineVideoIndex(index);
|
|
707
|
+
log.info('Offline video download complete', { playbackId, size });
|
|
668
708
|
return { status: 'downloaded' };
|
|
669
709
|
}
|
|
670
710
|
catch (error) {
|
|
671
|
-
const
|
|
711
|
+
const detailedMessage = error instanceof Error ? error.message : 'Download failed';
|
|
712
|
+
const message = `Failed to download "${title}". Please try again.`;
|
|
713
|
+
log.error(`Offline video download failed for ${playbackId}`, error);
|
|
672
714
|
index[playbackId] = {
|
|
673
715
|
...entry,
|
|
674
716
|
status: 'error',
|
|
675
|
-
error:
|
|
717
|
+
error: detailedMessage,
|
|
676
718
|
updatedAt: new Date().toISOString(),
|
|
677
719
|
};
|
|
678
720
|
await writeOfflineVideoIndex(index);
|
|
679
|
-
return { status: 'error' };
|
|
721
|
+
return { status: 'error', message };
|
|
680
722
|
}
|
|
681
723
|
}
|
|
682
724
|
export async function deleteOfflineVideo(playbackId, options) {
|