sanity-plugin-mux-input 4.0.3 → 4.1.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 +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +248 -44
- package/dist/index.js.map +1 -1
- package/package.json +9 -10
package/dist/index.d.ts
CHANGED
|
@@ -214,6 +214,7 @@ interface MuxAsset {
|
|
|
214
214
|
status: 'preparing' | 'ready' | 'errored';
|
|
215
215
|
duration: number;
|
|
216
216
|
max_stored_resolution: 'Audio only' | 'SD' | 'HD' | 'FHD' | 'UHD';
|
|
217
|
+
max_resolution_tier?: '2160p' | '1440p' | '1080p';
|
|
217
218
|
max_stored_frame_rate: -1 | number;
|
|
218
219
|
aspect_ratio: `${number}:${number}`;
|
|
219
220
|
playback_ids: MuxPlaybackId[];
|
|
@@ -225,7 +226,7 @@ interface MuxAsset {
|
|
|
225
226
|
live_stream_id?: string;
|
|
226
227
|
master?: {
|
|
227
228
|
status: 'ready' | 'preparing' | 'errored';
|
|
228
|
-
url
|
|
229
|
+
url?: string;
|
|
229
230
|
};
|
|
230
231
|
master_access: 'temporary' | 'none';
|
|
231
232
|
mp4_support: 'standard' | 'none';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/util/types.ts","../src/_exports/index.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/util/types.ts","../src/_exports/index.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useClient as useClient$1, createHookFromObservableFactory, useDocumentStore, collate, useDocumentValues, truncateString, useFormattedDuration, SanityDefaultPreview, useTimeAgo, TextWithTone, isRecord, getPreviewStateObservable,
|
|
1
|
+
import { useClient as useClient$1, createHookFromObservableFactory, useDocumentStore, collate, useDocumentValues, truncateString, useFormattedDuration, SanityDefaultPreview, useTimeAgo, TextWithTone, isRecord, getPreviewStateObservable, DocumentPreviewPresence, getPreviewValueWithFallback, useDocumentPreviewStore, useSchema, useDocumentPresence, PreviewCard, useCurrentUser, isReference, useProjectId, useDataset, PatchEvent, unset, setIfMissing, set, LinearProgress, FormField as FormField$2, definePlugin } from "sanity";
|
|
2
2
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { ErrorOutlineIcon, InfoOutlineIcon, RetryIcon, CheckmarkCircleIcon, RetrieveIcon, ChevronLeftIcon, ChevronRightIcon, SyncIcon, SortIcon, UploadIcon, TranslateIcon,
|
|
3
|
+
import { ErrorOutlineIcon, InfoOutlineIcon, RetryIcon, CheckmarkCircleIcon, RetrieveIcon, ChevronLeftIcon, ChevronRightIcon, SyncIcon, SortIcon, DownloadIcon, UploadIcon, TranslateIcon, AddIcon, ChevronUpIcon, ChevronDownIcon, TrashIcon, EditIcon, WarningOutlineIcon, PublishIcon, DocumentIcon, RevertIcon, SearchIcon, ClockIcon, CropIcon, CalendarIcon, TagIcon, CheckmarkIcon, LockIcon, PlayIcon, PlugIcon, EllipsisHorizontalIcon, ImageIcon, ResetIcon, WarningFilledIcon, DocumentVideoIcon } from "@sanity/icons";
|
|
4
4
|
import { Dialog, Stack, Card, Text, Button, useTheme_v2, Flex, Box, TextInput, Checkbox, Code, Inline, Spinner, Heading, Label as Label$1, Radio, MenuButton, Menu, MenuItem, useToast, Autocomplete, Tooltip, TabList, Tab, TabPanel, Grid, useClickOutsideEvent, Popover, MenuDivider, rem } from "@sanity/ui";
|
|
5
|
-
import { createContext, useState, useCallback, useMemo, useContext, useReducer, useId, memo, useRef, useEffect, Suspense, isValidElement
|
|
5
|
+
import { createContext, useState, useCallback, useMemo, useContext, useReducer, useId, memo, useRef, useEffect, Suspense, isValidElement } from "react";
|
|
6
6
|
import compact from "lodash/compact.js";
|
|
7
7
|
import toLower from "lodash/toLower.js";
|
|
8
8
|
import trim from "lodash/trim.js";
|
|
@@ -142,7 +142,7 @@ function useDialogState() {
|
|
|
142
142
|
const PLUGIN_VERSION_QUERY = {
|
|
143
143
|
sanityVersion: (
|
|
144
144
|
// @ts-expect-error - this constant is search/replaced so must be exact, not accessed with an index signature
|
|
145
|
-
"4.
|
|
145
|
+
"4.1.1"
|
|
146
146
|
)
|
|
147
147
|
};
|
|
148
148
|
function saveSecrets(client, token, secretKey, enableSignedUrls, signingKeyId, signingKeyPrivate, drmConfigId) {
|
|
@@ -250,7 +250,7 @@ const useSaveSecrets = (client, secrets) => useCallback(async ({
|
|
|
250
250
|
signingKeyPrivate,
|
|
251
251
|
drmConfigId
|
|
252
252
|
};
|
|
253
|
-
}, [client, secrets]), name = "mux-input", cacheNs = "sanity-plugin-mux-input", muxSecretsDocumentId = "secrets.mux", DIALOGS_Z_INDEX = 6e4, THUMBNAIL_ASPECT_RATIO = 1.7777777777777777, MIN_ASPECT_RATIO = 5 / 4, AUDIO_ASPECT_RATIO = 5 / 1, path$1 = ["token", "secretKey", "enableSignedUrls", "signingKeyId", "signingKeyPrivate", "drmConfigId"], useSecretsDocumentValues = () => {
|
|
253
|
+
}, [client, secrets]), name = "mux-input", cacheNs = "sanity-plugin-mux-input", muxSecretsDocumentId = "secrets.mux", DIALOGS_Z_INDEX = 6e4, MEZZANINE_LEARN_MORE_URL = "https://www.mux.com/docs/guides/download-for-offline-editing#enable-master-access", THUMBNAIL_ASPECT_RATIO = 1.7777777777777777, MIN_ASPECT_RATIO = 5 / 4, AUDIO_ASPECT_RATIO = 5 / 1, path$1 = ["token", "secretKey", "enableSignedUrls", "signingKeyId", "signingKeyPrivate", "drmConfigId"], useSecretsDocumentValues = () => {
|
|
254
254
|
const {
|
|
255
255
|
error,
|
|
256
256
|
isLoading,
|
|
@@ -638,6 +638,23 @@ function deleteTextTrack(client, assetId, trackId) {
|
|
|
638
638
|
query: PLUGIN_VERSION_QUERY
|
|
639
639
|
});
|
|
640
640
|
}
|
|
641
|
+
function updateMasterAccess(client, assetId, masterAccess) {
|
|
642
|
+
const {
|
|
643
|
+
dataset
|
|
644
|
+
} = client.config();
|
|
645
|
+
return client.request({
|
|
646
|
+
url: `/addons/mux/assets/${dataset}/${assetId}/master-access`,
|
|
647
|
+
withCredentials: !0,
|
|
648
|
+
method: "PUT",
|
|
649
|
+
body: {
|
|
650
|
+
master_access: masterAccess
|
|
651
|
+
},
|
|
652
|
+
headers: {
|
|
653
|
+
"Content-Type": "application/json"
|
|
654
|
+
},
|
|
655
|
+
query: PLUGIN_VERSION_QUERY
|
|
656
|
+
});
|
|
657
|
+
}
|
|
641
658
|
const ASSETS_PER_PAGE = 100;
|
|
642
659
|
async function fetchMuxAssetsPage(client, cursor) {
|
|
643
660
|
try {
|
|
@@ -1135,19 +1152,19 @@ const PageSelector = (props) => {
|
|
|
1135
1152
|
function addKeysToMuxData(data) {
|
|
1136
1153
|
return {
|
|
1137
1154
|
...data,
|
|
1138
|
-
tracks: data.tracks?.map((track) => ({
|
|
1155
|
+
tracks: data.tracks?.map((track, index) => ({
|
|
1139
1156
|
...track,
|
|
1140
|
-
_key:
|
|
1157
|
+
_key: track.id || `track-${index}`
|
|
1141
1158
|
})),
|
|
1142
|
-
playback_ids: data.playback_ids?.map((playbackId) => ({
|
|
1159
|
+
playback_ids: data.playback_ids?.map((playbackId, index) => ({
|
|
1143
1160
|
...playbackId,
|
|
1144
|
-
_key:
|
|
1161
|
+
_key: playbackId.id || `playback-${index}`
|
|
1145
1162
|
})),
|
|
1146
1163
|
static_renditions: data.static_renditions ? {
|
|
1147
1164
|
...data.static_renditions,
|
|
1148
|
-
files: data.static_renditions.files?.map((file) => ({
|
|
1165
|
+
files: data.static_renditions.files?.map((file, index) => ({
|
|
1149
1166
|
...file,
|
|
1150
|
-
_key:
|
|
1167
|
+
_key: file.id || `rendition-${index}`
|
|
1151
1168
|
}))
|
|
1152
1169
|
} : void 0
|
|
1153
1170
|
};
|
|
@@ -1393,6 +1410,144 @@ function StopWatchIcon(props) {
|
|
|
1393
1410
|
/* @__PURE__ */ jsx("path", { d: "M192 32h128v48H192z", fill: "currentColor" })
|
|
1394
1411
|
] });
|
|
1395
1412
|
}
|
|
1413
|
+
const POLL_INTERVAL_MS = 3e3;
|
|
1414
|
+
function getMezzanineStatus(asset) {
|
|
1415
|
+
const master = asset.data?.master;
|
|
1416
|
+
return master?.status === "preparing" ? "preparing" : master?.status === "ready" && master.url ? "ready" : master?.status === "errored" ? "errored" : "disabled";
|
|
1417
|
+
}
|
|
1418
|
+
function useMezzanine(asset) {
|
|
1419
|
+
const client = useClient(), toast = useToast(), master = asset.data?.master, [busy, setBusy] = useState(!1), [expired, setExpired] = useState(!1), [prevAssetId, setPrevAssetId] = useState(asset.assetId);
|
|
1420
|
+
prevAssetId !== asset.assetId && (setPrevAssetId(asset.assetId), setExpired(!1));
|
|
1421
|
+
const resolution = useMemo(() => asset.data?.max_resolution_tier || asset.data?.max_stored_resolution || void 0, [asset.data?.max_resolution_tier, asset.data?.max_stored_resolution]), status = getMezzanineStatus(asset), persist = useCallback(async (data) => {
|
|
1422
|
+
asset._id && await client.patch(asset._id).set({
|
|
1423
|
+
status: data.status,
|
|
1424
|
+
data: addKeysToMuxData(data)
|
|
1425
|
+
}).commit({
|
|
1426
|
+
returnDocuments: !1
|
|
1427
|
+
});
|
|
1428
|
+
}, [asset._id, client]), refresh = useCallback(async () => {
|
|
1429
|
+
if (!asset.assetId || !asset._id) return;
|
|
1430
|
+
const {
|
|
1431
|
+
data
|
|
1432
|
+
} = await getAsset(client, asset.assetId);
|
|
1433
|
+
return await persist(data), data;
|
|
1434
|
+
}, [asset.assetId, asset._id, client, persist]);
|
|
1435
|
+
useEffect(() => {
|
|
1436
|
+
if (master?.status !== "preparing" || !asset.assetId || !asset._id) return;
|
|
1437
|
+
let cancelled = !1, running = !1;
|
|
1438
|
+
const interval = setInterval(async () => {
|
|
1439
|
+
if (!running) {
|
|
1440
|
+
running = !0;
|
|
1441
|
+
try {
|
|
1442
|
+
const data = await refresh();
|
|
1443
|
+
if (cancelled) return;
|
|
1444
|
+
(!data || data.master?.status !== "preparing") && clearInterval(interval);
|
|
1445
|
+
} catch (error) {
|
|
1446
|
+
console.error("Failed to poll mezzanine status:", error);
|
|
1447
|
+
} finally {
|
|
1448
|
+
running = !1;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}, POLL_INTERVAL_MS);
|
|
1452
|
+
return () => {
|
|
1453
|
+
cancelled = !0, clearInterval(interval);
|
|
1454
|
+
};
|
|
1455
|
+
}, [master?.status, asset.assetId, asset._id, refresh]);
|
|
1456
|
+
const enable = useCallback(async () => {
|
|
1457
|
+
if (!(!asset.assetId || !asset._id)) {
|
|
1458
|
+
setBusy(!0), setExpired(!1);
|
|
1459
|
+
try {
|
|
1460
|
+
const {
|
|
1461
|
+
data
|
|
1462
|
+
} = await updateMasterAccess(client, asset.assetId, "temporary");
|
|
1463
|
+
await persist(data);
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
toast.push({
|
|
1466
|
+
status: "error",
|
|
1467
|
+
title: "Could not enable the mezzanine file",
|
|
1468
|
+
description: error instanceof Error ? error.message : "Please try again"
|
|
1469
|
+
});
|
|
1470
|
+
} finally {
|
|
1471
|
+
setBusy(!1);
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
}, [asset.assetId, asset._id, client, persist, toast]), download = useCallback(async () => {
|
|
1475
|
+
if (asset.assetId) {
|
|
1476
|
+
setBusy(!0);
|
|
1477
|
+
try {
|
|
1478
|
+
const data = await refresh(), url = data?.master?.status === "ready" ? data.master.url : void 0;
|
|
1479
|
+
url ? (setExpired(!1), triggerMezzanineDownload(url)) : setExpired(!0);
|
|
1480
|
+
} catch (error) {
|
|
1481
|
+
toast.push({
|
|
1482
|
+
status: "error",
|
|
1483
|
+
title: "Could not download the mezzanine file",
|
|
1484
|
+
description: error instanceof Error ? error.message : "Please try again"
|
|
1485
|
+
});
|
|
1486
|
+
} finally {
|
|
1487
|
+
setBusy(!1);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
}, [asset.assetId, refresh, toast]);
|
|
1491
|
+
return {
|
|
1492
|
+
status,
|
|
1493
|
+
busy,
|
|
1494
|
+
expired,
|
|
1495
|
+
resolution,
|
|
1496
|
+
enable,
|
|
1497
|
+
download
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
function triggerMezzanineDownload(masterUrl) {
|
|
1501
|
+
if (typeof window > "u") return;
|
|
1502
|
+
const anchor = document.createElement("a");
|
|
1503
|
+
anchor.href = masterUrl, anchor.target = "_blank", anchor.rel = "noopener noreferrer", document.body.appendChild(anchor), anchor.click(), document.body.removeChild(anchor);
|
|
1504
|
+
}
|
|
1505
|
+
function MezzanineExplanation() {
|
|
1506
|
+
return /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
1507
|
+
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "When you enable the mezzanine file, Mux creates a copy equivalent in quality to your original video \u2014 ideal for offline editing or archiving. Unlike the streamable MP4 (static) renditions, it is not meant for streaming." }),
|
|
1508
|
+
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "The file is prepared in the background and may take a few minutes depending on the asset's duration and resolution. Enabling is free and the download stays available for 24 hours." })
|
|
1509
|
+
] });
|
|
1510
|
+
}
|
|
1511
|
+
function Mezzanine({
|
|
1512
|
+
asset,
|
|
1513
|
+
withExplanation = !0
|
|
1514
|
+
}) {
|
|
1515
|
+
const {
|
|
1516
|
+
status,
|
|
1517
|
+
busy,
|
|
1518
|
+
expired,
|
|
1519
|
+
resolution,
|
|
1520
|
+
enable,
|
|
1521
|
+
download
|
|
1522
|
+
} = useMezzanine(asset), assetReady = asset.status === "ready" || asset.data?.status === "ready", isReady = status === "ready" && !expired, isPreparing = status === "preparing", showExplanation = !isReady && !isPreparing;
|
|
1523
|
+
return /* @__PURE__ */ jsx(Card, { padding: 3, radius: 2, tone: "transparent", border: !0, children: /* @__PURE__ */ jsxs(Stack, { space: 4, children: [
|
|
1524
|
+
/* @__PURE__ */ jsxs(Flex, { align: "center", justify: "space-between", gap: 3, children: [
|
|
1525
|
+
/* @__PURE__ */ jsx(Label$1, { muted: !0, size: 1, children: "Mezzanine" }),
|
|
1526
|
+
/* @__PURE__ */ jsx(Text, { size: 1, children: /* @__PURE__ */ jsx("a", { href: MEZZANINE_LEARN_MORE_URL, target: "_blank", rel: "noopener noreferrer", children: "Learn more" }) })
|
|
1527
|
+
] }),
|
|
1528
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
1529
|
+
/* @__PURE__ */ jsx(Text, { size: 1, muted: !isReady, children: "mezzanine.mp4" }),
|
|
1530
|
+
resolution && /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: resolution })
|
|
1531
|
+
] }),
|
|
1532
|
+
withExplanation && showExplanation && /* @__PURE__ */ jsx(MezzanineExplanation, {}),
|
|
1533
|
+
showExplanation && (expired || status === "errored") && /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
1534
|
+
expired && /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "The previous mezzanine file expired. Enable it again to download." }),
|
|
1535
|
+
status === "errored" && /* @__PURE__ */ jsx(Text, { size: 1, style: {
|
|
1536
|
+
color: "var(--card-critical-color)"
|
|
1537
|
+
}, children: "Mux could not prepare the mezzanine file. Please try again." })
|
|
1538
|
+
] }),
|
|
1539
|
+
isPreparing && /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "Preparing the mezzanine file\u2026 this can take a few minutes. You can close this and come back later." }),
|
|
1540
|
+
isReady && /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "Ready to download. The link stays available for about 24 hours." }),
|
|
1541
|
+
/* @__PURE__ */ jsx(Flex, { justify: "flex-end", gap: 2, children: isPreparing ? /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
1542
|
+
/* @__PURE__ */ jsx(Spinner, { muted: !0, size: 1 }),
|
|
1543
|
+
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "Preparing\u2026" })
|
|
1544
|
+
] }) : isReady ? /* @__PURE__ */ jsx(Button, { icon: DownloadIcon, text: "Download", tone: "positive", fontSize: 1, padding: 3, loading: busy, disabled: busy, onClick: () => {
|
|
1545
|
+
download();
|
|
1546
|
+
} }) : /* @__PURE__ */ jsx(Button, { text: status === "errored" ? "Try again" : "Enable", tone: "primary", fontSize: 1, padding: 3, loading: busy, disabled: busy || !assetReady, onClick: () => {
|
|
1547
|
+
enable();
|
|
1548
|
+
} }) })
|
|
1549
|
+
] }) });
|
|
1550
|
+
}
|
|
1396
1551
|
function useResyncAsset(options) {
|
|
1397
1552
|
const client = useClient(), toast = useToast(), [resyncState, setResyncState] = useState("idle"), [resyncError, setResyncError] = useState(null), showToast = options?.showToast ?? !1, resyncAsset = useCallback(async (asset) => {
|
|
1398
1553
|
if (!asset.assetId) {
|
|
@@ -1625,6 +1780,7 @@ const SUPPORTED_MUX_LANGUAGES = [{
|
|
|
1625
1780
|
code: "bg",
|
|
1626
1781
|
state: "Beta"
|
|
1627
1782
|
}];
|
|
1783
|
+
SUPPORTED_MUX_LANGUAGES.map((l) => l.code);
|
|
1628
1784
|
function isCustomTextTrack(track) {
|
|
1629
1785
|
return track.type !== "autogenerated";
|
|
1630
1786
|
}
|
|
@@ -1820,7 +1976,7 @@ function AddCaptionDialog({
|
|
|
1820
1976
|
textAlign: "center"
|
|
1821
1977
|
}, children: "Or enter the caption file URL" }),
|
|
1822
1978
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
1823
|
-
/* @__PURE__ */ jsx(Label$1, { htmlFor: "vtt-url", children: "Caption File URL (.vtt or .srt)" }),
|
|
1979
|
+
/* @__PURE__ */ jsx(Label$1, { as: "label", htmlFor: "vtt-url", children: "Caption File URL (.vtt or .srt)" }),
|
|
1824
1980
|
/* @__PURE__ */ jsx(TextInput, { id: "vtt-url", placeholder: "https://example.com/subtitles.vtt", value: vttUrl, onChange: (e) => {
|
|
1825
1981
|
setVttUrl(e.currentTarget.value), setSelectedFile(null);
|
|
1826
1982
|
}, disabled: isSubmitting })
|
|
@@ -1828,7 +1984,7 @@ function AddCaptionDialog({
|
|
|
1828
1984
|
] })
|
|
1829
1985
|
] }),
|
|
1830
1986
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
1831
|
-
/* @__PURE__ */ jsx(Label$1, { htmlFor: "caption-name", children: "Audio name" }),
|
|
1987
|
+
/* @__PURE__ */ jsx(Label$1, { as: "label", htmlFor: "caption-name", children: "Audio name" }),
|
|
1832
1988
|
/* @__PURE__ */ jsx(Autocomplete, { id: "caption-name", value: selectedLanguage?.value || "", onChange: (newValue) => {
|
|
1833
1989
|
const selected = (isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS$1).find((opt) => opt.value === newValue);
|
|
1834
1990
|
selected && (setSelectedLanguage(selected), setLanguageCode(selected.value), setName(selected.label));
|
|
@@ -1840,7 +1996,7 @@ function AddCaptionDialog({
|
|
|
1840
1996
|
] }) }), disabled: isSubmitting })
|
|
1841
1997
|
] }),
|
|
1842
1998
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
1843
|
-
/* @__PURE__ */ jsx(Label$1, { htmlFor: "caption-language", children: "Language Code" }),
|
|
1999
|
+
/* @__PURE__ */ jsx(Label$1, { as: "label", htmlFor: "caption-language", children: "Language Code" }),
|
|
1844
2000
|
/* @__PURE__ */ jsx(TextInput, { id: "caption-language", placeholder: "en-US", value: languageCode, onChange: (e) => {
|
|
1845
2001
|
setLanguageCode(e.currentTarget.value), selectedLanguage && selectedLanguage.value !== e.currentTarget.value && (setSelectedLanguage(null), (!name2 || name2 === selectedLanguage.label) && setName(""));
|
|
1846
2002
|
}, disabled: isSubmitting })
|
|
@@ -2081,7 +2237,7 @@ function EditCaptionDialog({
|
|
|
2081
2237
|
] })
|
|
2082
2238
|
] }),
|
|
2083
2239
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
2084
|
-
/* @__PURE__ */ jsx(Label$1, { htmlFor: "vtt-url", children: "VTT File URL" }),
|
|
2240
|
+
/* @__PURE__ */ jsx(Label$1, { as: "label", htmlFor: "vtt-url", children: "VTT File URL" }),
|
|
2085
2241
|
/* @__PURE__ */ jsx(TextInput, { id: "vtt-url", placeholder: "https://example.com/subtitles.vtt", value: vttUrl, onChange: (e) => {
|
|
2086
2242
|
setVttUrl(e.currentTarget.value), setSelectedFile(null);
|
|
2087
2243
|
}, disabled: isSubmitting }),
|
|
@@ -2089,7 +2245,7 @@ function EditCaptionDialog({
|
|
|
2089
2245
|
] })
|
|
2090
2246
|
] }),
|
|
2091
2247
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
2092
|
-
/* @__PURE__ */ jsx(Label$1, { htmlFor: "caption-name", children: "Audio name" }),
|
|
2248
|
+
/* @__PURE__ */ jsx(Label$1, { as: "label", htmlFor: "caption-name", children: "Audio name" }),
|
|
2093
2249
|
/* @__PURE__ */ jsx(Autocomplete, { id: "caption-name", value: selectedLanguage?.value || "", onChange: (newValue) => {
|
|
2094
2250
|
const selected = LANGUAGE_OPTIONS.find((opt) => opt.value === newValue);
|
|
2095
2251
|
selected && (setSelectedLanguage(selected), setLanguageCode(selected.value), setName(selected.label));
|
|
@@ -2101,7 +2257,7 @@ function EditCaptionDialog({
|
|
|
2101
2257
|
] }) }), disabled: isSubmitting })
|
|
2102
2258
|
] }),
|
|
2103
2259
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
2104
|
-
/* @__PURE__ */ jsx(Label$1, { htmlFor: "caption-language", children: "Language Code" }),
|
|
2260
|
+
/* @__PURE__ */ jsx(Label$1, { as: "label", htmlFor: "caption-language", children: "Language Code" }),
|
|
2105
2261
|
/* @__PURE__ */ jsx(TextInput, { id: "caption-language", placeholder: "en-US", value: languageCode, onChange: (e) => {
|
|
2106
2262
|
setLanguageCode(e.currentTarget.value), selectedLanguage && selectedLanguage.value !== e.currentTarget.value && (setSelectedLanguage(null), (!name2 || name2 === selectedLanguage.label) && setName(""));
|
|
2107
2263
|
}, disabled: isSubmitting })
|
|
@@ -2472,6 +2628,20 @@ function AudioIcon(props) {
|
|
|
2472
2628
|
opacity: "0.65"
|
|
2473
2629
|
}, d: "M10.75 19q.95 0 1.6-.65t.65-1.6V13h3v-2h-4v3.875q-.275-.2-.587-.288t-.663-.087q-.95 0-1.6.65t-.65 1.6t.65 1.6t1.6.65M6 22q-.825 0-1.412-.587T4 20V4q0-.825.588-1.412T6 2h8l6 6v12q0 .825-.587 1.413T18 22zm7-13V4H6v16h12V9zM6 4v5zv16z" }) });
|
|
2474
2630
|
}
|
|
2631
|
+
function MezzanineDialog({
|
|
2632
|
+
asset,
|
|
2633
|
+
onClose
|
|
2634
|
+
}) {
|
|
2635
|
+
const {
|
|
2636
|
+
setDialogState
|
|
2637
|
+
} = useDialogStateContext(), dialogId = `MezzanineDialog${useId()}`, closing = () => {
|
|
2638
|
+
onClose?.(), setDialogState(!1);
|
|
2639
|
+
}, status = getMezzanineStatus(asset);
|
|
2640
|
+
return /* @__PURE__ */ jsx(Dialog, { id: dialogId, header: "Mezzanine file", onClose: closing, zOffset: DIALOGS_Z_INDEX, width: 1, children: /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsxs(Stack, { space: 4, children: [
|
|
2641
|
+
status !== "preparing" && status !== "ready" && /* @__PURE__ */ jsx(MezzanineExplanation, {}),
|
|
2642
|
+
/* @__PURE__ */ jsx(Mezzanine, { asset, withExplanation: !1 })
|
|
2643
|
+
] }) }) });
|
|
2644
|
+
}
|
|
2475
2645
|
function VideoPlayer({
|
|
2476
2646
|
asset,
|
|
2477
2647
|
thumbnailWidth = 250,
|
|
@@ -2560,7 +2730,7 @@ function VideoPlayer({
|
|
|
2560
2730
|
/* @__PURE__ */ jsx(MuxPlayer, { poster: isAudio ? void 0 : poster, ref: muxPlayer, ...props, playsInline: !0, playbackId, tokens, preload: "metadata", crossOrigin: "anonymous", metadata: {
|
|
2561
2731
|
player_name: "Sanity Admin Dashboard",
|
|
2562
2732
|
// @ts-expect-error - this constant is search/replaced so must be exact, not accessed with an index signature
|
|
2563
|
-
player_version: "4.
|
|
2733
|
+
player_version: "4.1.1",
|
|
2564
2734
|
page_type: "Preview Player"
|
|
2565
2735
|
}, audio: isAudio, _hlsConfig: hlsConfig, style: {
|
|
2566
2736
|
...!isAudio && {
|
|
@@ -2596,7 +2766,8 @@ function VideoPlayer({
|
|
|
2596
2766
|
currentTime: muxPlayer?.current?.currentTime
|
|
2597
2767
|
}
|
|
2598
2768
|
),
|
|
2599
|
-
dialogState === "edit-captions" && /* @__PURE__ */ jsx(CaptionsDialog, { asset })
|
|
2769
|
+
dialogState === "edit-captions" && /* @__PURE__ */ jsx(CaptionsDialog, { asset }),
|
|
2770
|
+
dialogState === "mezzanine" && /* @__PURE__ */ jsx(MezzanineDialog, { asset })
|
|
2600
2771
|
] });
|
|
2601
2772
|
}
|
|
2602
2773
|
function assetIsAudio(asset) {
|
|
@@ -2943,7 +3114,10 @@ const AssetInput = (props) => /* @__PURE__ */ jsx(FormField, { title: props.labe
|
|
|
2943
3114
|
} : void 0, children: [
|
|
2944
3115
|
/* @__PURE__ */ jsxs(Stack, { space: 4, flex: 1, sizing: "border", children: [
|
|
2945
3116
|
/* @__PURE__ */ jsx(VideoPlayer, { asset: props.asset, autoPlay: props.asset.autoPlay || !1 }),
|
|
2946
|
-
tab === "details" && /* @__PURE__ */
|
|
3117
|
+
tab === "details" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3118
|
+
/* @__PURE__ */ jsx(TextTracksManager, { asset: props.asset, iconOnly: !0, collapseTracks: !0, tracks: displayInfo?.text_tracks || props.asset.data?.tracks?.filter((track) => track.type === "text") || [] }),
|
|
3119
|
+
/* @__PURE__ */ jsx(Mezzanine, { asset: props.asset })
|
|
3120
|
+
] })
|
|
2947
3121
|
] }),
|
|
2948
3122
|
/* @__PURE__ */ jsxs(Stack, { space: 4, flex: 1, sizing: "border", children: [
|
|
2949
3123
|
/* @__PURE__ */ jsxs(TabList, { space: 2, children: [
|
|
@@ -3142,22 +3316,31 @@ const useAccessControl = (config) => {
|
|
|
3142
3316
|
return !1;
|
|
3143
3317
|
const files = asset?.data?.static_renditions?.files;
|
|
3144
3318
|
return !files || files.length === 0 ? !1 : files.some((file) => file.status === "preparing");
|
|
3145
|
-
}, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files]), shouldFetch = useMemo(() => !!asset?.assetId && (asset?.status === "preparing" || isPreparingStaticRenditions), [asset?.assetId, asset?.status, isPreparingStaticRenditions]);
|
|
3319
|
+
}, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files]), shouldFetch = useMemo(() => !!asset?.assetId && (asset?.status === "preparing" || isPreparingStaticRenditions), [asset?.assetId, asset?.status, isPreparingStaticRenditions]), errorLoggedRef = useRef(!1);
|
|
3146
3320
|
return useSWR(shouldFetch ? `/${projectId}/addons/mux/assets/${dataset}/data/${asset?.assetId}` : null, async () => {
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3321
|
+
try {
|
|
3322
|
+
const {
|
|
3323
|
+
data
|
|
3324
|
+
} = await client.request({
|
|
3325
|
+
url: `/addons/mux/assets/${dataset}/data/${asset.assetId}`,
|
|
3326
|
+
withCredentials: !0,
|
|
3327
|
+
method: "GET",
|
|
3328
|
+
query: PLUGIN_VERSION_QUERY
|
|
3329
|
+
});
|
|
3330
|
+
if (!asset?._id || !data) return;
|
|
3331
|
+
await client.patch(asset._id).set({
|
|
3332
|
+
status: data.status,
|
|
3333
|
+
data: addKeysToMuxData(data)
|
|
3334
|
+
}).commit({
|
|
3335
|
+
returnDocuments: !1
|
|
3336
|
+
}), errorLoggedRef.current = !1;
|
|
3337
|
+
} catch (error) {
|
|
3338
|
+
errorLoggedRef.current || (errorLoggedRef.current = !0, console.error("[sanity-plugin-mux-input] Mux polling failed", {
|
|
3339
|
+
assetId: asset?.assetId,
|
|
3340
|
+
documentId: asset?._id,
|
|
3341
|
+
error
|
|
3342
|
+
}));
|
|
3343
|
+
}
|
|
3161
3344
|
}, {
|
|
3162
3345
|
refreshInterval: 2e3,
|
|
3163
3346
|
refreshWhenHidden: !0,
|
|
@@ -3681,7 +3864,8 @@ const FileButton = /* @__PURE__ */ styled(MenuItem).withConfig({
|
|
|
3681
3864
|
opacity: 0;
|
|
3682
3865
|
}
|
|
3683
3866
|
`;
|
|
3684
|
-
})
|
|
3867
|
+
});
|
|
3868
|
+
function FileInputMenuItem(props) {
|
|
3685
3869
|
const {
|
|
3686
3870
|
icon: Icon,
|
|
3687
3871
|
id: idProp,
|
|
@@ -3694,6 +3878,7 @@ const FileButton = /* @__PURE__ */ styled(MenuItem).withConfig({
|
|
|
3694
3878
|
textAlign,
|
|
3695
3879
|
text,
|
|
3696
3880
|
disabled,
|
|
3881
|
+
ref,
|
|
3697
3882
|
...rest
|
|
3698
3883
|
} = props, idHook = useId(), id = idProp || idHook, handleChange = useCallback((event) => {
|
|
3699
3884
|
onSelect && event.target.files && onSelect(Array.from(event.target.files));
|
|
@@ -3704,11 +3889,12 @@ const FileButton = /* @__PURE__ */ styled(MenuItem).withConfig({
|
|
|
3704
3889
|
] }) }),
|
|
3705
3890
|
text && /* @__PURE__ */ jsx(Text, { align: textAlign, size: fontSize, textOverflow: "ellipsis", children: text })
|
|
3706
3891
|
] });
|
|
3707
|
-
return /* @__PURE__ */ jsxs(FileButton, { ...rest, htmlFor: id, disabled, ref
|
|
3892
|
+
return /* @__PURE__ */ jsxs(FileButton, { ...rest, htmlFor: id, disabled, ref, children: [
|
|
3708
3893
|
content,
|
|
3709
3894
|
/* @__PURE__ */ jsx("input", { "data-testid": "file-button-input", accept, capture, id, multiple, onChange: handleChange, type: "file", value: "", disabled })
|
|
3710
3895
|
] });
|
|
3711
|
-
}
|
|
3896
|
+
}
|
|
3897
|
+
const LockCard = styled(Card).withConfig({
|
|
3712
3898
|
displayName: "LockCard",
|
|
3713
3899
|
componentId: "sc-aimiq6-0"
|
|
3714
3900
|
})`position:absolute;top:0;left:0;opacity:0.6;mix-blend-mode:screen;background:transparent;`, LockButton = styled(Button).withConfig({
|
|
@@ -3748,6 +3934,8 @@ function PlayerActionsMenu$1(props) {
|
|
|
3748
3934
|
/* @__PURE__ */ jsx(MenuItem, { icon: SyncIcon, text: "Resync from Mux", onClick: handleResync, disabled: readOnly || isResyncing })
|
|
3749
3935
|
] }),
|
|
3750
3936
|
/* @__PURE__ */ jsx(MenuDivider, {}),
|
|
3937
|
+
/* @__PURE__ */ jsx(MenuItem, { icon: DownloadIcon, text: "Mezzanine", onClick: () => setDialogState("mezzanine") }),
|
|
3938
|
+
/* @__PURE__ */ jsx(MenuDivider, {}),
|
|
3751
3939
|
hasConfigAccess && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3752
3940
|
/* @__PURE__ */ jsx(MenuItem, { icon: PlugIcon, text: "Configure API", onClick: () => setDialogState("secrets") }),
|
|
3753
3941
|
/* @__PURE__ */ jsx(MenuDivider, {})
|
|
@@ -5050,23 +5238,26 @@ function withFocusRing(component) {
|
|
|
5050
5238
|
`;
|
|
5051
5239
|
});
|
|
5052
5240
|
}
|
|
5053
|
-
const UploadCardWithFocusRing = withFocusRing(Card)
|
|
5241
|
+
const UploadCardWithFocusRing = withFocusRing(Card);
|
|
5242
|
+
function UploadCard({
|
|
5054
5243
|
children,
|
|
5055
5244
|
tone,
|
|
5056
5245
|
onPaste,
|
|
5057
5246
|
onDrop,
|
|
5058
5247
|
onDragEnter,
|
|
5059
5248
|
onDragLeave,
|
|
5060
|
-
onDragOver
|
|
5061
|
-
|
|
5249
|
+
onDragOver,
|
|
5250
|
+
ref
|
|
5251
|
+
}) {
|
|
5062
5252
|
const inputRef = useRef(null), handleKeyDown = useCallback((event) => {
|
|
5063
5253
|
event.target.closest("#vtt-url") || (event.ctrlKey || event.metaKey) && event.key === "v" && inputRef.current.focus();
|
|
5064
5254
|
}, []);
|
|
5065
|
-
return /* @__PURE__ */ jsxs(UploadCardWithFocusRing, { tone, ref
|
|
5255
|
+
return /* @__PURE__ */ jsxs(UploadCardWithFocusRing, { tone, ref, padding: 0, radius: 2, shadow: 0, tabIndex: 0, onKeyDown: handleKeyDown, onPaste, onDrop, onDragEnter, onDragLeave, onDragOver, children: [
|
|
5066
5256
|
/* @__PURE__ */ jsx(HiddenInput$1, { ref: inputRef }),
|
|
5067
5257
|
children
|
|
5068
5258
|
] });
|
|
5069
|
-
}
|
|
5259
|
+
}
|
|
5260
|
+
const HiddenInput$1 = styled.input.attrs({
|
|
5070
5261
|
type: "text"
|
|
5071
5262
|
}).withConfig({
|
|
5072
5263
|
displayName: "HiddenInput",
|
|
@@ -5538,6 +5729,16 @@ const muxVideoSchema = {
|
|
|
5538
5729
|
type: "mux.staticRenditionFile"
|
|
5539
5730
|
}]
|
|
5540
5731
|
}]
|
|
5732
|
+
}, muxMasterFile = {
|
|
5733
|
+
name: "mux.masterFile",
|
|
5734
|
+
type: "object",
|
|
5735
|
+
fields: [{
|
|
5736
|
+
type: "string",
|
|
5737
|
+
name: "status"
|
|
5738
|
+
}, {
|
|
5739
|
+
type: "string",
|
|
5740
|
+
name: "url"
|
|
5741
|
+
}]
|
|
5541
5742
|
}, muxAssetData = {
|
|
5542
5743
|
name: "mux.assetData",
|
|
5543
5744
|
title: "Mux asset data",
|
|
@@ -5602,6 +5803,9 @@ const muxVideoSchema = {
|
|
|
5602
5803
|
}, {
|
|
5603
5804
|
name: "static_renditions",
|
|
5604
5805
|
type: "mux.staticRenditions"
|
|
5806
|
+
}, {
|
|
5807
|
+
name: "master",
|
|
5808
|
+
type: "mux.masterFile"
|
|
5605
5809
|
}]
|
|
5606
5810
|
}, muxVideoAsset = {
|
|
5607
5811
|
name: "mux.videoAsset",
|
|
@@ -5626,7 +5830,7 @@ const muxVideoSchema = {
|
|
|
5626
5830
|
type: "mux.assetData",
|
|
5627
5831
|
name: "data"
|
|
5628
5832
|
}]
|
|
5629
|
-
}, schemaTypes = [muxTrack, muxPlaybackId, muxStaticRenditionFile, muxStaticRenditions, muxAssetData, muxVideoAsset], defaultConfig = {
|
|
5833
|
+
}, schemaTypes = [muxTrack, muxPlaybackId, muxStaticRenditionFile, muxStaticRenditions, muxMasterFile, muxAssetData, muxVideoAsset], defaultConfig = {
|
|
5630
5834
|
static_renditions: [],
|
|
5631
5835
|
mp4_support: "none",
|
|
5632
5836
|
video_quality: "plus",
|