@mux/ai 0.10.0 → 0.12.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.
@@ -1,3 +1,3 @@
1
- export { D as DEFAULT_STORYBOARD_WIDTH, H as HeatmapOptions, a as HeatmapResponse, b as Hotspot, c as HotspotOptions, d as HotspotResponse, T as ThumbnailOptions, e as TranscriptFetchOptions, f as TranscriptResult, V as VTTCue, g as VTTCueBudgetChunkingOptions, h as VTTDurationChunk, j as VTTDurationChunkingOptions, k as buildTranscriptUrl, l as buildVttFromCueBlocks, m as buildVttFromTranslatedCueBlocks, n as chunkByTokens, o as chunkText, p as chunkVTTCues, q as chunkVTTCuesByBudget, r as chunkVTTCuesByDuration, s as concatenateVttSegments, t as estimateTokenCount, u as extractTextFromVTT, v as extractTimestampedTranscript, w as fetchTranscriptForAsset, x as findCaptionTrack, y as getHeatmapForAsset, z as getHeatmapForPlaybackId, A as getHeatmapForVideo, B as getHotspotsForAsset, C as getHotspotsForPlaybackId, E as getHotspotsForVideo, F as getReadyTextTracks, G as getStoryboardUrl, I as getThumbnailUrls, J as parseVTTCues, K as replaceCueText, L as secondsToTimestamp, M as splitVttPreambleAndCueBlocks, N as vttTimestampToSeconds } from '../index-C8-E3VR9.js';
1
+ export { C as CompletedShotsResult, D as DEFAULT_STORYBOARD_WIDTH, E as ErroredShotsResult, H as HeatmapOptions, a as HeatmapResponse, b as Hotspot, c as HotspotOptions, d as HotspotResponse, P as PendingShotsResult, S as Shot, e as ShotRequestOptions, f as ShotsResult, T as ThumbnailOptions, g as TranscriptFetchOptions, h as TranscriptResult, V as VTTCue, j as VTTCueBudgetChunkingOptions, k as VTTDurationChunk, l as VTTDurationChunkingOptions, W as WaitForShotsOptions, m as buildTranscriptUrl, n as buildVttFromCueBlocks, o as buildVttFromTranslatedCueBlocks, p as chunkByTokens, q as chunkText, r as chunkVTTCues, s as chunkVTTCuesByBudget, t as chunkVTTCuesByDuration, u as concatenateVttSegments, v as estimateTokenCount, w as extractTextFromVTT, x as extractTimestampedTranscript, y as fetchTranscriptForAsset, z as findCaptionTrack, A as getHeatmapForAsset, B as getHeatmapForPlaybackId, F as getHeatmapForVideo, G as getHotspotsForAsset, I as getHotspotsForPlaybackId, J as getHotspotsForVideo, K as getReadyTextTracks, L as getShotsForAsset, M as getStoryboardUrl, N as getThumbnailUrls, O as parseVTTCues, Q as replaceCueText, R as requestShotsForAsset, U as secondsToTimestamp, X as splitVttPreambleAndCueBlocks, Y as vttTimestampToSeconds, Z as waitForShotsForAsset } from '../index-DLhfJsOd.js';
2
2
  import '../types-BRbaGW3t.js';
3
3
  import '@mux/mux-node';
@@ -592,6 +592,142 @@ async function fetchHotspots(identifierType, id, options) {
592
592
  return transformHotspotResponse(response);
593
593
  }
594
594
 
595
+ // src/primitives/shots.ts
596
+ var DEFAULT_POLL_INTERVAL_MS = 2e3;
597
+ var MIN_POLL_INTERVAL_MS = 1e3;
598
+ var DEFAULT_MAX_ATTEMPTS = 60;
599
+ var SHOTS_ALREADY_REQUESTED_MESSAGE = "shots generation has already been requested";
600
+ function getShotsPath(assetId) {
601
+ return `/video/v1/assets/${assetId}/shots`;
602
+ }
603
+ function mapManifestShots(shots) {
604
+ return shots.map((shot, index) => {
605
+ const { startTime, imageUrl } = shot;
606
+ if (typeof startTime !== "number" || !Number.isFinite(startTime)) {
607
+ throw new TypeError(`Invalid shot startTime in shots manifest at index ${index}`);
608
+ }
609
+ if (typeof imageUrl !== "string" || imageUrl.length === 0) {
610
+ throw new TypeError(`Invalid shot imageUrl in shots manifest at index ${index}`);
611
+ }
612
+ return {
613
+ startTime,
614
+ imageUrl
615
+ };
616
+ });
617
+ }
618
+ async function fetchShotsFromManifest(shotsManifestUrl) {
619
+ const response = await fetch(shotsManifestUrl);
620
+ if (!response.ok) {
621
+ throw new Error(
622
+ `Failed to fetch shots manifest: ${response.status} ${response.statusText}`
623
+ );
624
+ }
625
+ const manifest = await response.json();
626
+ if (!Array.isArray(manifest.shots)) {
627
+ throw new TypeError("Invalid shots manifest response: missing shots array");
628
+ }
629
+ return mapManifestShots(manifest.shots);
630
+ }
631
+ async function transformShotsResponse(response) {
632
+ switch (response.data.status) {
633
+ case "pending":
634
+ return {
635
+ status: "pending",
636
+ createdAt: response.data.created_at
637
+ };
638
+ case "errored":
639
+ return {
640
+ status: "errored",
641
+ createdAt: response.data.created_at,
642
+ error: response.data.error
643
+ };
644
+ case "completed":
645
+ return {
646
+ status: "completed",
647
+ createdAt: response.data.created_at,
648
+ shots: await fetchShotsFromManifest(response.data.shots_manifest_url)
649
+ };
650
+ default: {
651
+ const exhaustiveCheck = response.data;
652
+ throw new Error(`Unsupported shots response: ${JSON.stringify(exhaustiveCheck)}`);
653
+ }
654
+ }
655
+ }
656
+ function sleep(ms) {
657
+ return new Promise((resolve) => setTimeout(resolve, ms));
658
+ }
659
+ function isShotsAlreadyRequestedError(error) {
660
+ const statusCode = error?.status ?? error?.statusCode;
661
+ const messages = error?.error?.messages;
662
+ const lowerCaseMessages = messages?.map((message) => message.toLowerCase()) ?? [];
663
+ const errorMessage = error instanceof Error ? error.message.toLowerCase() : "";
664
+ return statusCode === 400 && (lowerCaseMessages.some((message) => message.includes(SHOTS_ALREADY_REQUESTED_MESSAGE)) || errorMessage.includes(SHOTS_ALREADY_REQUESTED_MESSAGE));
665
+ }
666
+ async function requestShotsForAsset(assetId, options = {}) {
667
+ "use step";
668
+ const { credentials } = options;
669
+ const muxClient = await getMuxClientFromEnv(credentials);
670
+ const mux = await muxClient.createClient();
671
+ const response = await mux.post(
672
+ getShotsPath(assetId),
673
+ { body: {} }
674
+ );
675
+ const result = await transformShotsResponse(response);
676
+ if (result.status !== "pending") {
677
+ throw new Error(
678
+ `Expected pending status after requesting shots for asset '${assetId}', received '${result.status}'`
679
+ );
680
+ }
681
+ return result;
682
+ }
683
+ async function getShotsForAsset(assetId, options = {}) {
684
+ "use step";
685
+ const { credentials } = options;
686
+ const muxClient = await getMuxClientFromEnv(credentials);
687
+ const mux = await muxClient.createClient();
688
+ const response = await mux.get(
689
+ getShotsPath(assetId)
690
+ );
691
+ return await transformShotsResponse(response);
692
+ }
693
+ async function waitForShotsForAsset(assetId, options = {}) {
694
+ "use step";
695
+ const {
696
+ pollIntervalMs = DEFAULT_POLL_INTERVAL_MS,
697
+ maxAttempts = DEFAULT_MAX_ATTEMPTS,
698
+ createIfMissing = true,
699
+ credentials
700
+ } = options;
701
+ if (createIfMissing) {
702
+ try {
703
+ await requestShotsForAsset(assetId, { credentials });
704
+ } catch (error) {
705
+ if (!isShotsAlreadyRequestedError(error)) {
706
+ throw error;
707
+ }
708
+ }
709
+ }
710
+ const normalizedMaxAttempts = Math.max(1, maxAttempts);
711
+ const normalizedPollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, pollIntervalMs);
712
+ let lastStatus;
713
+ for (let attempt = 0; attempt < normalizedMaxAttempts; attempt++) {
714
+ const result = await getShotsForAsset(assetId, { credentials });
715
+ lastStatus = result.status;
716
+ if (result.status === "completed") {
717
+ return result;
718
+ }
719
+ if (result.status === "errored") {
720
+ throw new Error(`Shots generation errored for asset '${assetId}'`);
721
+ }
722
+ if (attempt < normalizedMaxAttempts - 1) {
723
+ await sleep(normalizedPollIntervalMs);
724
+ }
725
+ }
726
+ throw new Error(
727
+ `Timed out waiting for shots for asset '${assetId}' after ${normalizedMaxAttempts} attempts. Last status: ${lastStatus ?? "unknown"}`
728
+ );
729
+ }
730
+
595
731
  // src/lib/mux-image-url.ts
596
732
  var DEFAULT_MUX_IMAGE_ORIGIN = "https://image.mux.com";
597
733
  function normalizeMuxImageOrigin(value) {
@@ -1314,12 +1450,15 @@ export {
1314
1450
  getHotspotsForPlaybackId,
1315
1451
  getHotspotsForVideo,
1316
1452
  getReadyTextTracks,
1453
+ getShotsForAsset,
1317
1454
  getStoryboardUrl,
1318
1455
  getThumbnailUrls,
1319
1456
  parseVTTCues,
1320
1457
  replaceCueText,
1458
+ requestShotsForAsset,
1321
1459
  secondsToTimestamp,
1322
1460
  splitVttPreambleAndCueBlocks,
1323
- vttTimestampToSeconds
1461
+ vttTimestampToSeconds,
1462
+ waitForShotsForAsset
1324
1463
  };
1325
1464
  //# sourceMappingURL=index.js.map