@mux/ai 0.28.1 → 0.29.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.
- package/dist/{index-bjQi1ZCj.d.ts → index-CXwsu679.d.ts} +18 -4
- package/dist/{index-DUVBpnj5.d.ts → index-DJirK4fh.d.ts} +13 -13
- package/dist/index.d.ts +5 -5
- package/dist/index.js +232 -45
- package/dist/index.js.map +1 -1
- package/dist/primitives/index.d.ts +2 -2
- package/dist/primitives/index.js +96 -15
- package/dist/primitives/index.js.map +1 -1
- package/dist/{shots-mGJfYGiO.d.ts → shots-BKd7TMFN.d.ts} +19 -1
- package/dist/workflows/index.d.ts +2 -2
- package/dist/workflows/index.js +230 -44
- package/dist/workflows/index.js.map +1 -1
- package/package.json +7 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { D as DEFAULT_STORYBOARD_WIDTH, H as HeatmapOptions, a as HeatmapResponse, L as LOW_CONFIDENCE_THRESHOLD, M as MAX_CUE_TEXT_CHARS, T as ThumbnailOptions, b as TranscriptFetchOptions, c as TranscriptResult, V as VTTCue, d as VTTCueBudgetChunkingOptions, e as VTTDurationChunk, f as VTTDurationChunkingOptions, g as buildTranscriptUrl, h as buildVttFromCueBlocks, j as buildVttFromTranslatedCueBlocks, k as chunkByTokens, l as chunkText, m as chunkVTTCues, n as chunkVTTCuesByBudget, o as chunkVTTCuesByDuration, p as concatenateVttSegments, q as estimateTokenCount, r as extractTextFromVTT, s as extractTimestampedTranscript, t as fetchTranscriptForAsset, u as
|
|
2
|
-
export {
|
|
1
|
+
export { D as DEFAULT_STORYBOARD_WIDTH, H as HeatmapOptions, a as HeatmapResponse, L as LOW_CONFIDENCE_THRESHOLD, M as MAX_CUE_TEXT_CHARS, T as ThumbnailOptions, b as TranscriptFetchOptions, c as TranscriptResult, V as VTTCue, d as VTTCueBudgetChunkingOptions, e as VTTDurationChunk, f as VTTDurationChunkingOptions, g as buildTranscriptUrl, h as buildVttFromCueBlocks, j as buildVttFromTranslatedCueBlocks, k as chunkByTokens, l as chunkText, m as chunkVTTCues, n as chunkVTTCuesByBudget, o as chunkVTTCuesByDuration, p as concatenateVttSegments, q as estimateTokenCount, r as extractTextFromVTT, s as extractTimestampedTranscript, t as fetchTranscriptForAsset, u as filterVttByScope, v as findCaptionTrack, w as getHeatmapForAsset, x as getHeatmapForPlaybackId, y as getHeatmapForVideo, z as getReadyTextTracks, A as getReliableLanguageCode, B as getStoryboardUrl, C as getThumbnailUrls, E as parseVTTCues, F as replaceCueText, G as sanitizeUntrustedText, I as secondsToTimestamp, J as splitVttPreambleAndCueBlocks, K as stripVttMetadataBlocks, N as vttTimestampToSeconds } from '../index-CXwsu679.js';
|
|
2
|
+
export { q as CompletedShotsResult, r as ErroredShotsResult, H as Hotspot, s as HotspotOptions, t as HotspotResponse, u as PendingShotsResult, v as Shot, w as ShotRequestOptions, x as ShotsResult, y as WaitForShotsOptions, z as getHotspotsForAsset, B as getHotspotsForPlaybackId, D as getHotspotsForVideo, F as getShotsForAsset, G as requestShotsForAsset, J as waitForShotsForAsset } from '../shots-BKd7TMFN.js';
|
|
3
3
|
import '@mux/mux-node';
|
package/dist/primitives/index.js
CHANGED
|
@@ -1111,13 +1111,22 @@ async function signUrl(url, playbackId, type = "video", params, credentials) {
|
|
|
1111
1111
|
|
|
1112
1112
|
// src/primitives/storyboards.ts
|
|
1113
1113
|
var DEFAULT_STORYBOARD_WIDTH = 640;
|
|
1114
|
-
async function getStoryboardUrl(playbackId, width = DEFAULT_STORYBOARD_WIDTH, shouldSign = false, credentials) {
|
|
1114
|
+
async function getStoryboardUrl(playbackId, width = DEFAULT_STORYBOARD_WIDTH, shouldSign = false, credentials, scope) {
|
|
1115
1115
|
"use step";
|
|
1116
1116
|
const baseUrl = getMuxStoryboardBaseUrl(playbackId);
|
|
1117
|
+
const params = { width };
|
|
1118
|
+
if (scope?.startTime !== void 0) {
|
|
1119
|
+
params.asset_start_time = scope.startTime;
|
|
1120
|
+
}
|
|
1121
|
+
if (scope?.endTime !== void 0) {
|
|
1122
|
+
params.asset_end_time = scope.endTime;
|
|
1123
|
+
}
|
|
1117
1124
|
if (shouldSign) {
|
|
1118
|
-
return signUrl(baseUrl, playbackId, "storyboard",
|
|
1125
|
+
return signUrl(baseUrl, playbackId, "storyboard", params, credentials);
|
|
1119
1126
|
}
|
|
1120
|
-
return `${baseUrl}
|
|
1127
|
+
return `${baseUrl}?${new URLSearchParams(
|
|
1128
|
+
Object.entries(params).map(([key, value]) => [key, String(value)])
|
|
1129
|
+
).toString()}`;
|
|
1121
1130
|
}
|
|
1122
1131
|
|
|
1123
1132
|
// src/primitives/text-chunking.ts
|
|
@@ -1358,30 +1367,77 @@ function chunkText(text, strategy) {
|
|
|
1358
1367
|
}
|
|
1359
1368
|
}
|
|
1360
1369
|
|
|
1370
|
+
// src/lib/workflow-scope.ts
|
|
1371
|
+
function hasWorkflowScopeBoundaries(scope) {
|
|
1372
|
+
return scope?.startTime !== void 0 || scope?.endTime !== void 0;
|
|
1373
|
+
}
|
|
1374
|
+
function resolveWorkflowScope(scope, assetDurationSeconds) {
|
|
1375
|
+
if (assetDurationSeconds === void 0 || !Number.isFinite(assetDurationSeconds) || assetDurationSeconds <= 0) {
|
|
1376
|
+
throw new MuxAiError("Asset has no valid duration.", { type: "validation_error" });
|
|
1377
|
+
}
|
|
1378
|
+
const startTime = scope?.startTime ?? 0;
|
|
1379
|
+
const endTime = scope?.endTime ?? assetDurationSeconds;
|
|
1380
|
+
if (!Number.isFinite(startTime) || startTime < 0) {
|
|
1381
|
+
throw new MuxAiError(
|
|
1382
|
+
`scope.startTime must be a finite, non-negative number (received ${startTime}).`,
|
|
1383
|
+
{ type: "validation_error" }
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
if (!Number.isFinite(endTime) || endTime < 0) {
|
|
1387
|
+
throw new MuxAiError(
|
|
1388
|
+
`scope.endTime must be a finite, non-negative number (received ${endTime}).`,
|
|
1389
|
+
{ type: "validation_error" }
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
if (endTime > assetDurationSeconds) {
|
|
1393
|
+
throw new MuxAiError(
|
|
1394
|
+
`scope.endTime (${endTime}) cannot exceed the asset duration (${assetDurationSeconds}).`,
|
|
1395
|
+
{ type: "validation_error" }
|
|
1396
|
+
);
|
|
1397
|
+
}
|
|
1398
|
+
if (startTime >= endTime) {
|
|
1399
|
+
throw new MuxAiError(
|
|
1400
|
+
`scope.startTime (${startTime}) must be less than scope.endTime (${endTime}).`,
|
|
1401
|
+
{ type: "validation_error" }
|
|
1402
|
+
);
|
|
1403
|
+
}
|
|
1404
|
+
return { startTime, endTime };
|
|
1405
|
+
}
|
|
1406
|
+
function timeRangesOverlap(firstStart, firstEnd, second) {
|
|
1407
|
+
const secondStart = second.startTime ?? 0;
|
|
1408
|
+
const secondEnd = second.endTime ?? Number.POSITIVE_INFINITY;
|
|
1409
|
+
return firstStart < secondEnd && firstEnd > secondStart;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1361
1412
|
// src/primitives/thumbnails.ts
|
|
1362
1413
|
async function getThumbnailUrls(playbackId, duration, options = {}) {
|
|
1363
1414
|
"use step";
|
|
1364
|
-
const { interval = 10, width = 640, shouldSign = false, maxSamples, credentials } = options;
|
|
1415
|
+
const { interval = 10, width = 640, shouldSign = false, maxSamples, credentials, scope } = options;
|
|
1416
|
+
const effectiveScope = hasWorkflowScopeBoundaries(scope) ? scope : void 0;
|
|
1417
|
+
const resolvedScope = effectiveScope ? resolveWorkflowScope(effectiveScope, duration) : { startTime: 0, endTime: duration };
|
|
1418
|
+
const rangeDuration = resolvedScope.endTime - resolvedScope.startTime;
|
|
1365
1419
|
let timestamps = [];
|
|
1366
|
-
if (
|
|
1367
|
-
const spacing =
|
|
1420
|
+
if (rangeDuration <= 50) {
|
|
1421
|
+
const spacing = rangeDuration / 6;
|
|
1368
1422
|
for (let i = 1; i <= 5; i++) {
|
|
1369
|
-
|
|
1423
|
+
const time = resolvedScope.startTime + i * spacing;
|
|
1424
|
+
timestamps.push(effectiveScope ? Number(time.toFixed(3)) : Math.round(time));
|
|
1370
1425
|
}
|
|
1371
1426
|
} else {
|
|
1372
|
-
for (let time =
|
|
1427
|
+
for (let time = resolvedScope.startTime; time < resolvedScope.endTime; time += interval) {
|
|
1373
1428
|
timestamps.push(time);
|
|
1374
1429
|
}
|
|
1375
1430
|
}
|
|
1376
1431
|
if (maxSamples !== void 0 && timestamps.length > maxSamples) {
|
|
1377
1432
|
const newTimestamps = [];
|
|
1378
|
-
newTimestamps.push(
|
|
1433
|
+
newTimestamps.push(resolvedScope.startTime);
|
|
1379
1434
|
if (maxSamples >= 2) {
|
|
1380
|
-
const
|
|
1435
|
+
const lastTime = effectiveScope ? Math.max(resolvedScope.startTime, resolvedScope.endTime - 1e-3) : resolvedScope.endTime;
|
|
1436
|
+
const spacing = (lastTime - resolvedScope.startTime) / (maxSamples - 1);
|
|
1381
1437
|
for (let i = 1; i < maxSamples - 1; i++) {
|
|
1382
|
-
newTimestamps.push(spacing * i);
|
|
1438
|
+
newTimestamps.push(resolvedScope.startTime + spacing * i);
|
|
1383
1439
|
}
|
|
1384
|
-
newTimestamps.push(
|
|
1440
|
+
newTimestamps.push(lastTime);
|
|
1385
1441
|
}
|
|
1386
1442
|
timestamps = newTimestamps;
|
|
1387
1443
|
}
|
|
@@ -1792,6 +1848,23 @@ function parseVTTCues(vttContent) {
|
|
|
1792
1848
|
}
|
|
1793
1849
|
return cues;
|
|
1794
1850
|
}
|
|
1851
|
+
function filterVttByScope(vttContent, scope) {
|
|
1852
|
+
if (!scope || scope.startTime === void 0 && scope.endTime === void 0) {
|
|
1853
|
+
return vttContent;
|
|
1854
|
+
}
|
|
1855
|
+
const { preamble, cueBlocks } = splitVttPreambleAndCueBlocks(vttContent);
|
|
1856
|
+
const scopedCueBlocks = cueBlocks.filter((cueBlock) => {
|
|
1857
|
+
const cue = parseVTTCues(cueBlock)[0];
|
|
1858
|
+
return cue ? timeRangesOverlap(cue.startTime, cue.endTime, scope) : false;
|
|
1859
|
+
}).map((cueBlock, index) => {
|
|
1860
|
+
const lines = cueBlock.split("\n");
|
|
1861
|
+
if (/^\d+$/.test(lines[0]?.trim()) && lines[1]?.includes("-->")) {
|
|
1862
|
+
lines[0] = String(index + 1);
|
|
1863
|
+
}
|
|
1864
|
+
return lines.join("\n");
|
|
1865
|
+
});
|
|
1866
|
+
return buildVttFromCueBlocks(scopedCueBlocks, preamble);
|
|
1867
|
+
}
|
|
1795
1868
|
function splitVttPreambleAndCueBlocks(vttContent) {
|
|
1796
1869
|
const normalizedContent = normalizeLineEndings(vttContent).trim();
|
|
1797
1870
|
if (!normalizedContent) {
|
|
@@ -1896,6 +1969,7 @@ async function fetchTranscriptForAsset(asset, playbackId, options = {}) {
|
|
|
1896
1969
|
const {
|
|
1897
1970
|
languageCode,
|
|
1898
1971
|
cleanTranscript = true,
|
|
1972
|
+
scope,
|
|
1899
1973
|
shouldSign,
|
|
1900
1974
|
credentials,
|
|
1901
1975
|
required = false
|
|
@@ -1927,9 +2001,15 @@ async function fetchTranscriptForAsset(asset, playbackId, options = {}) {
|
|
|
1927
2001
|
return { transcriptText: "", transcriptUrl, track };
|
|
1928
2002
|
}
|
|
1929
2003
|
const rawVtt = await response.text();
|
|
1930
|
-
const
|
|
1931
|
-
|
|
1932
|
-
|
|
2004
|
+
const effectiveScope = hasWorkflowScopeBoundaries(scope) ? scope : void 0;
|
|
2005
|
+
const scopedVtt = filterVttByScope(rawVtt, effectiveScope);
|
|
2006
|
+
const transcriptText = cleanTranscript ? extractTextFromVTT(scopedVtt) : scopedVtt;
|
|
2007
|
+
const hasScopedCues = !effectiveScope || parseVTTCues(scopedVtt).length > 0;
|
|
2008
|
+
if (required && (!transcriptText.trim() || !hasScopedCues)) {
|
|
2009
|
+
throw new MuxAiError(
|
|
2010
|
+
effectiveScope ? "Transcript has no cues in the requested scope." : "Transcript is empty.",
|
|
2011
|
+
{ type: "validation_error" }
|
|
2012
|
+
);
|
|
1933
2013
|
}
|
|
1934
2014
|
return { transcriptText, transcriptUrl, track };
|
|
1935
2015
|
} catch (error) {
|
|
@@ -1957,6 +2037,7 @@ export {
|
|
|
1957
2037
|
extractTextFromVTT,
|
|
1958
2038
|
extractTimestampedTranscript,
|
|
1959
2039
|
fetchTranscriptForAsset,
|
|
2040
|
+
filterVttByScope,
|
|
1960
2041
|
findCaptionTrack,
|
|
1961
2042
|
getHeatmapForAsset,
|
|
1962
2043
|
getHeatmapForPlaybackId,
|