sanity-plugin-mux-input 2.10.0 → 2.11.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/README.md +8 -8
- package/dist/index.d.mts +18 -5
- package/dist/index.d.ts +18 -5
- package/dist/index.js +88 -56
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +88 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_exports/index.ts +14 -1
- package/src/components/UploadConfiguration.tsx +29 -29
- package/src/components/UploadProgress.tsx +5 -0
- package/src/components/Uploader.tsx +38 -4
- package/src/components/VideoPlayer.tsx +9 -5
- package/src/schema.ts +4 -0
- package/src/util/types.ts +26 -10
package/README.md
CHANGED
|
@@ -122,7 +122,7 @@ For reference, here's an example `mux.videoAsset` document:
|
|
|
122
122
|
thumbTime: 65.82,
|
|
123
123
|
// Full Mux asset data:
|
|
124
124
|
data: {
|
|
125
|
-
|
|
125
|
+
video_quality: 'plus',
|
|
126
126
|
max_resolution_tier: '1080p',
|
|
127
127
|
aspect_ratio: '16:9',
|
|
128
128
|
created_at: '1706645034',
|
|
@@ -228,25 +228,25 @@ export default defineConfig({
|
|
|
228
228
|
|
|
229
229
|
When uploading new assets, editors can still choose a lower resolution for each video than configured globally. This option controls the maximum resolution encoded or processed for the uploaded video. The option is particularly important to manage costs when uploaded videos are higher than `1080p` resolution. More information on the feature is available on Mux's [docs](https://docs.mux.com/guides/stream-videos-in-4k). Also, read more on this feature announcement on Mux's [blog](https://www.mux.com/blog/more-pixels-fewer-problems-introducing-4k-support-for-mux-video).
|
|
230
230
|
|
|
231
|
-
###
|
|
231
|
+
### Video Quality Level (plus or basic)
|
|
232
232
|
|
|
233
|
-
The [
|
|
233
|
+
The [video quality level](https://docs.mux.com/guides/use-video-quality-levels) informs the cost, quality, and available platform features for the asset. You can choose between `plus` and `basic` at the plugin configuration. Defaults to `plus`.
|
|
234
234
|
|
|
235
235
|
```js
|
|
236
236
|
import {muxInput} from 'sanity-plugin-mux-input'
|
|
237
237
|
|
|
238
238
|
export default defineConfig({
|
|
239
|
-
plugins: [muxInput({
|
|
239
|
+
plugins: [muxInput({video_quality: 'basic'})],
|
|
240
240
|
})
|
|
241
241
|
```
|
|
242
242
|
|
|
243
|
-
If `
|
|
243
|
+
If `video_quality: 'plus'`, editors can still choose to use the `basic` video quality level on a per-video basis when uploading new assets.
|
|
244
244
|
|
|
245
|
-
More information on the feature is available on Mux's [documentation](https://
|
|
245
|
+
More information on the feature is available on Mux's [documentation](https://www.mux.com/docs/guides/use-video-quality-levels). Also, read more on the feature announcement on Mux's [blog](https://www.mux.com/blog/our-next-pricing-lever-baseline-on-demand-assets-with-free-video-encoding)
|
|
246
246
|
|
|
247
247
|
### Auto-generated subtitles and captions
|
|
248
248
|
|
|
249
|
-
If you'
|
|
249
|
+
If you are using 'plus' video quality level, you can use Mux's [auto-generated subtitles](https://docs.mux.com/guides/video/auto-generated-subtitles) feature. Unless you pass `disableTextTrackConfig: true` to the configuration, users will be able to choose a language to auto-generate subtitles for uploaded videos. Refer to Mux's documentation for the list of supported languages.
|
|
250
250
|
|
|
251
251
|
You can also define a default language for the upload configuration form:
|
|
252
252
|
|
|
@@ -256,7 +256,7 @@ import {muxInput} from 'sanity-plugin-mux-input'
|
|
|
256
256
|
export default defineConfig({
|
|
257
257
|
plugins: [
|
|
258
258
|
muxInput({
|
|
259
|
-
|
|
259
|
+
video_quality: 'plus',
|
|
260
260
|
defaultAutogeneratedSubtitleLang: 'en', // choose from one of the supported languages
|
|
261
261
|
}),
|
|
262
262
|
],
|
package/dist/index.d.mts
CHANGED
|
@@ -79,24 +79,32 @@ export declare const muxInput: Plugin_2<void | Partial<PluginConfig>>
|
|
|
79
79
|
declare interface MuxInputConfig {
|
|
80
80
|
/**
|
|
81
81
|
* Enable static renditions by setting this to 'standard'. Can be overwritten on a per-asset basis.
|
|
82
|
-
* Requires `"
|
|
82
|
+
* Requires `"video_quality": "plus"`
|
|
83
83
|
* @see {@link https://docs.mux.com/guides/video/enable-static-mp4-renditions#why-enable-mp4-support}
|
|
84
84
|
* @defaultValue 'none'
|
|
85
85
|
*/
|
|
86
86
|
mp4_support: 'none' | 'standard'
|
|
87
87
|
/**
|
|
88
88
|
* Max resolution tier can be used to control the maximum resolution_tier your asset is encoded, stored, and streamed at.
|
|
89
|
-
* Requires `"
|
|
89
|
+
* Requires `"video_quality": "plus"`
|
|
90
90
|
* @see {@link https://docs.mux.com/guides/stream-videos-in-4k}
|
|
91
91
|
* @defaultValue '1080p'
|
|
92
92
|
*/
|
|
93
93
|
max_resolution_tier: '2160p' | '1440p' | '1080p'
|
|
94
94
|
/**
|
|
95
|
+
* @deprecated Use {@link video_quality}
|
|
96
|
+
* <br>
|
|
95
97
|
* The encoding tier informs the cost, quality, and available platform features for the asset.
|
|
96
98
|
* @see {@link https://docs.mux.com/guides/use-encoding-tiers}
|
|
97
99
|
* @defaultValue 'smart'
|
|
98
100
|
*/
|
|
99
|
-
encoding_tier
|
|
101
|
+
encoding_tier?: 'baseline' | 'smart'
|
|
102
|
+
/**
|
|
103
|
+
* The video quality level informs the cost, quality, and available platform features for the asset.
|
|
104
|
+
* @see {@link https://www.mux.com/docs/guides/use-video-quality-levels}
|
|
105
|
+
* @defaultValue 'plus'
|
|
106
|
+
*/
|
|
107
|
+
video_quality: 'basic' | 'plus' | 'premium'
|
|
100
108
|
/**
|
|
101
109
|
* Normalize the audio track loudness level.
|
|
102
110
|
* @see {@link https://docs.mux.com/guides/adjust-audio-levels#how-to-turn-on-audio-normalization}
|
|
@@ -109,9 +117,14 @@ declare interface MuxInputConfig {
|
|
|
109
117
|
* @defaultValue false
|
|
110
118
|
*/
|
|
111
119
|
defaultSigned?: boolean
|
|
120
|
+
/**
|
|
121
|
+
* Enables public URLs by default.
|
|
122
|
+
* @defaultValue true
|
|
123
|
+
*/
|
|
124
|
+
defaultPublic?: boolean
|
|
112
125
|
/**
|
|
113
126
|
* Auto-generate captions for these languages by default.
|
|
114
|
-
* Requires `"
|
|
127
|
+
* Requires `"video_quality": "plus"`
|
|
115
128
|
*
|
|
116
129
|
* @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}
|
|
117
130
|
* @deprecated use `defaultAutogeneratedSubtitleLang` instead. Only a single autogenerated
|
|
@@ -119,7 +132,7 @@ declare interface MuxInputConfig {
|
|
|
119
132
|
defaultAutogeneratedSubtitleLangs?: SupportedMuxLanguage[]
|
|
120
133
|
/**
|
|
121
134
|
* Auto-generate captions for this language by default. Users can still
|
|
122
|
-
* Requires `"
|
|
135
|
+
* Requires `"video_quality": "plus"`
|
|
123
136
|
*
|
|
124
137
|
* @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}
|
|
125
138
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -79,24 +79,32 @@ export declare const muxInput: Plugin_2<void | Partial<PluginConfig>>
|
|
|
79
79
|
declare interface MuxInputConfig {
|
|
80
80
|
/**
|
|
81
81
|
* Enable static renditions by setting this to 'standard'. Can be overwritten on a per-asset basis.
|
|
82
|
-
* Requires `"
|
|
82
|
+
* Requires `"video_quality": "plus"`
|
|
83
83
|
* @see {@link https://docs.mux.com/guides/video/enable-static-mp4-renditions#why-enable-mp4-support}
|
|
84
84
|
* @defaultValue 'none'
|
|
85
85
|
*/
|
|
86
86
|
mp4_support: 'none' | 'standard'
|
|
87
87
|
/**
|
|
88
88
|
* Max resolution tier can be used to control the maximum resolution_tier your asset is encoded, stored, and streamed at.
|
|
89
|
-
* Requires `"
|
|
89
|
+
* Requires `"video_quality": "plus"`
|
|
90
90
|
* @see {@link https://docs.mux.com/guides/stream-videos-in-4k}
|
|
91
91
|
* @defaultValue '1080p'
|
|
92
92
|
*/
|
|
93
93
|
max_resolution_tier: '2160p' | '1440p' | '1080p'
|
|
94
94
|
/**
|
|
95
|
+
* @deprecated Use {@link video_quality}
|
|
96
|
+
* <br>
|
|
95
97
|
* The encoding tier informs the cost, quality, and available platform features for the asset.
|
|
96
98
|
* @see {@link https://docs.mux.com/guides/use-encoding-tiers}
|
|
97
99
|
* @defaultValue 'smart'
|
|
98
100
|
*/
|
|
99
|
-
encoding_tier
|
|
101
|
+
encoding_tier?: 'baseline' | 'smart'
|
|
102
|
+
/**
|
|
103
|
+
* The video quality level informs the cost, quality, and available platform features for the asset.
|
|
104
|
+
* @see {@link https://www.mux.com/docs/guides/use-video-quality-levels}
|
|
105
|
+
* @defaultValue 'plus'
|
|
106
|
+
*/
|
|
107
|
+
video_quality: 'basic' | 'plus' | 'premium'
|
|
100
108
|
/**
|
|
101
109
|
* Normalize the audio track loudness level.
|
|
102
110
|
* @see {@link https://docs.mux.com/guides/adjust-audio-levels#how-to-turn-on-audio-normalization}
|
|
@@ -109,9 +117,14 @@ declare interface MuxInputConfig {
|
|
|
109
117
|
* @defaultValue false
|
|
110
118
|
*/
|
|
111
119
|
defaultSigned?: boolean
|
|
120
|
+
/**
|
|
121
|
+
* Enables public URLs by default.
|
|
122
|
+
* @defaultValue true
|
|
123
|
+
*/
|
|
124
|
+
defaultPublic?: boolean
|
|
112
125
|
/**
|
|
113
126
|
* Auto-generate captions for these languages by default.
|
|
114
|
-
* Requires `"
|
|
127
|
+
* Requires `"video_quality": "plus"`
|
|
115
128
|
*
|
|
116
129
|
* @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}
|
|
117
130
|
* @deprecated use `defaultAutogeneratedSubtitleLang` instead. Only a single autogenerated
|
|
@@ -119,7 +132,7 @@ declare interface MuxInputConfig {
|
|
|
119
132
|
defaultAutogeneratedSubtitleLangs?: SupportedMuxLanguage[]
|
|
120
133
|
/**
|
|
121
134
|
* Auto-generate captions for this language by default. Users can still
|
|
122
|
-
* Requires `"
|
|
135
|
+
* Requires `"video_quality": "plus"`
|
|
123
136
|
*
|
|
124
137
|
* @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}
|
|
125
138
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1489,14 +1489,18 @@ function VideoPlayer({
|
|
|
1489
1489
|
children,
|
|
1490
1490
|
...props
|
|
1491
1491
|
}) {
|
|
1492
|
-
const client = useClient(), { dialogState } = useDialogStateContext(), isAudio = assetIsAudio(asset), muxPlayer = React.useRef(null),
|
|
1492
|
+
const client = useClient(), { dialogState } = useDialogStateContext(), isAudio = assetIsAudio(asset), muxPlayer = React.useRef(null), {
|
|
1493
|
+
src: videoSrc,
|
|
1494
|
+
thumbnail: thumbnailSrc,
|
|
1495
|
+
error
|
|
1496
|
+
} = React.useMemo(() => {
|
|
1493
1497
|
try {
|
|
1494
|
-
const src = asset?.playbackId && getVideoSrc({ client, asset });
|
|
1495
|
-
return src ? { src } : { error: new TypeError("Asset has no playback ID") };
|
|
1498
|
+
const thumbnail = getPosterSrc({ asset, client, width: thumbnailWidth }), src = asset?.playbackId && getVideoSrc({ client, asset });
|
|
1499
|
+
return src ? { src, thumbnail } : { error: new TypeError("Asset has no playback ID") };
|
|
1496
1500
|
} catch (error2) {
|
|
1497
1501
|
return { error: error2 };
|
|
1498
1502
|
}
|
|
1499
|
-
}, [asset, client]), signedToken = React.useMemo(() => {
|
|
1503
|
+
}, [asset, client, thumbnailWidth]), signedToken = React.useMemo(() => {
|
|
1500
1504
|
try {
|
|
1501
1505
|
return new URL(videoSrc).searchParams.get("token");
|
|
1502
1506
|
} catch {
|
|
@@ -1513,7 +1517,7 @@ function VideoPlayer({
|
|
|
1513
1517
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1514
1518
|
MuxPlayer__default.default,
|
|
1515
1519
|
{
|
|
1516
|
-
poster:
|
|
1520
|
+
poster: thumbnailSrc,
|
|
1517
1521
|
ref: muxPlayer,
|
|
1518
1522
|
...props,
|
|
1519
1523
|
playsInline: !0,
|
|
@@ -1523,7 +1527,7 @@ function VideoPlayer({
|
|
|
1523
1527
|
crossOrigin: "anonymous",
|
|
1524
1528
|
metadata: {
|
|
1525
1529
|
player_name: "Sanity Admin Dashboard",
|
|
1526
|
-
player_version: "2.
|
|
1530
|
+
player_version: "2.11.0",
|
|
1527
1531
|
page_type: "Preview Player"
|
|
1528
1532
|
},
|
|
1529
1533
|
audio: isAudio,
|
|
@@ -2900,25 +2904,29 @@ const TopControls = styledComponents.styled.div`
|
|
|
2900
2904
|
onCancel,
|
|
2901
2905
|
filename,
|
|
2902
2906
|
text = "Uploading"
|
|
2903
|
-
}) =>
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2907
|
+
}) => {
|
|
2908
|
+
const isCancelDisabled = progress >= 90;
|
|
2909
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CardWrapper, { tone: "primary", padding: 4, border: !0, height: "fill", children: /* @__PURE__ */ jsxRuntime.jsxs(FlexWrapper, { align: "center", justify: "space-between", height: "fill", direction: "row", gap: 2, children: [
|
|
2910
|
+
/* @__PURE__ */ jsxRuntime.jsxs(LeftSection, { children: [
|
|
2911
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { justify: "center", gap: [3, 3, 2, 2], direction: ["column", "column", "row"], children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Inline, { space: 2, children: [
|
|
2912
|
+
text,
|
|
2913
|
+
/* @__PURE__ */ jsxRuntime.jsx(CodeWrapper, { size: 1, children: filename || "..." })
|
|
2914
|
+
] }) }) }),
|
|
2915
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Card, { marginTop: 3, radius: 5, shadow: 1, children: /* @__PURE__ */ jsxRuntime.jsx(sanity.LinearProgress, { value: progress }) })
|
|
2916
|
+
] }),
|
|
2917
|
+
onCancel ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2918
|
+
ui.Button,
|
|
2919
|
+
{
|
|
2920
|
+
fontSize: 2,
|
|
2921
|
+
text: "Cancel upload",
|
|
2922
|
+
mode: "ghost",
|
|
2923
|
+
tone: "critical",
|
|
2924
|
+
onClick: onCancel,
|
|
2925
|
+
disabled: isCancelDisabled
|
|
2926
|
+
}
|
|
2927
|
+
) : null
|
|
2928
|
+
] }) });
|
|
2929
|
+
}, Player = ({ asset, buttons, readOnly, onChange }) => {
|
|
2922
2930
|
const isLoading = React.useMemo(() => asset?.status === "preparing" ? "Preparing the video" : asset?.status === "waiting_for_upload" ? "Waiting for upload to start" : asset?.status === "waiting" ? "Processing upload" : !(asset?.status === "ready" || typeof asset?.status > "u"), [asset]), isPreparingStaticRenditions = React.useMemo(() => asset?.data?.static_renditions?.status === "preparing", [asset?.data?.static_renditions?.status]), playRef = React.useRef(null), muteRef = React.useRef(null), handleCancelUpload = useCancelUpload(asset, onChange);
|
|
2923
2931
|
return React.useEffect(() => {
|
|
2924
2932
|
const style = document.createElement("style");
|
|
@@ -3332,9 +3340,10 @@ function PlaybackPolicy({
|
|
|
3332
3340
|
noPolicySelected && /* @__PURE__ */ jsxRuntime.jsx(PlaybackPolicyWarning, {})
|
|
3333
3341
|
] });
|
|
3334
3342
|
}
|
|
3335
|
-
const
|
|
3336
|
-
{ value: "
|
|
3337
|
-
{ value: "
|
|
3343
|
+
const VIDEO_QUALITY_LEVELS = [
|
|
3344
|
+
{ value: "basic", label: "Basic" },
|
|
3345
|
+
{ value: "plus", label: "Plus" },
|
|
3346
|
+
{ value: "premium", label: "Premium" }
|
|
3338
3347
|
], RESOLUTION_TIERS = [
|
|
3339
3348
|
{ value: "1080p", label: "1080p" },
|
|
3340
3349
|
{ value: "1440p", label: "1440p (2k)" },
|
|
@@ -3348,7 +3357,7 @@ function UploadConfiguration({
|
|
|
3348
3357
|
onClose
|
|
3349
3358
|
}) {
|
|
3350
3359
|
const id = React.useId(), autoTextTracks = React.useRef(
|
|
3351
|
-
pluginConfig.
|
|
3360
|
+
pluginConfig.video_quality === "plus" && pluginConfig.defaultAutogeneratedSubtitleLang ? [
|
|
3352
3361
|
{
|
|
3353
3362
|
_id: uuid.uuid(),
|
|
3354
3363
|
type: "autogenerated",
|
|
@@ -3359,16 +3368,16 @@ function UploadConfiguration({
|
|
|
3359
3368
|
).current, [config, dispatch] = React.useReducer(
|
|
3360
3369
|
(prev, action) => {
|
|
3361
3370
|
switch (action.action) {
|
|
3362
|
-
case "
|
|
3363
|
-
return action.value === "
|
|
3364
|
-
|
|
3371
|
+
case "video_quality":
|
|
3372
|
+
return action.value === "basic" ? Object.assign({}, prev, {
|
|
3373
|
+
video_quality: action.value,
|
|
3365
3374
|
mp4_support: "none",
|
|
3366
3375
|
max_resolution_tier: "1080p",
|
|
3367
3376
|
text_tracks: prev.text_tracks?.filter(({ type }) => type !== "autogenerated"),
|
|
3368
3377
|
public_policy: !0,
|
|
3369
3378
|
signed_policy: !1
|
|
3370
3379
|
}) : Object.assign({}, prev, {
|
|
3371
|
-
|
|
3380
|
+
video_quality: action.value,
|
|
3372
3381
|
mp4_support: pluginConfig.mp4_support,
|
|
3373
3382
|
max_resolution_tier: pluginConfig.max_resolution_tier,
|
|
3374
3383
|
text_tracks: [...autoTextTracks, ...prev.text_tracks || []]
|
|
@@ -3410,11 +3419,11 @@ function UploadConfiguration({
|
|
|
3410
3419
|
}
|
|
3411
3420
|
},
|
|
3412
3421
|
{
|
|
3413
|
-
|
|
3422
|
+
video_quality: pluginConfig.video_quality,
|
|
3414
3423
|
max_resolution_tier: pluginConfig.max_resolution_tier,
|
|
3415
3424
|
mp4_support: pluginConfig.mp4_support,
|
|
3416
3425
|
signed_policy: secrets.enableSignedUrls && pluginConfig.defaultSigned,
|
|
3417
|
-
public_policy:
|
|
3426
|
+
public_policy: pluginConfig.defaultPublic,
|
|
3418
3427
|
normalize_audio: pluginConfig.normalize_audio,
|
|
3419
3428
|
text_tracks: autoTextTracks
|
|
3420
3429
|
}
|
|
@@ -3422,7 +3431,7 @@ function UploadConfiguration({
|
|
|
3422
3431
|
if (React.useEffect(() => {
|
|
3423
3432
|
skipConfig && startUpload(formatUploadConfig(config));
|
|
3424
3433
|
}, []), skipConfig) return null;
|
|
3425
|
-
const maxSupportedResolution = RESOLUTION_TIERS.findIndex(
|
|
3434
|
+
const basicConfig = config.video_quality !== "plus" && config.video_quality !== "premium", maxSupportedResolution = RESOLUTION_TIERS.findIndex(
|
|
3426
3435
|
(rt) => rt.value === pluginConfig.max_resolution_tier
|
|
3427
3436
|
);
|
|
3428
3437
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3458,9 +3467,9 @@ function UploadConfiguration({
|
|
|
3458
3467
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3459
3468
|
sanity.FormField,
|
|
3460
3469
|
{
|
|
3461
|
-
title: "
|
|
3470
|
+
title: "Video Quality Level",
|
|
3462
3471
|
description: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3463
|
-
"The
|
|
3472
|
+
"The video quality level informs the cost, quality, and available platform features for the asset.",
|
|
3464
3473
|
" ",
|
|
3465
3474
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3466
3475
|
"a",
|
|
@@ -3472,16 +3481,16 @@ function UploadConfiguration({
|
|
|
3472
3481
|
}
|
|
3473
3482
|
)
|
|
3474
3483
|
] }),
|
|
3475
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { gap: 3, children:
|
|
3484
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { gap: 3, children: VIDEO_QUALITY_LEVELS.map(({ value, label }) => {
|
|
3476
3485
|
const inputId = `${id}--encodingtier-${value}`;
|
|
3477
3486
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", gap: 2, children: [
|
|
3478
3487
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3479
3488
|
ui.Radio,
|
|
3480
3489
|
{
|
|
3481
|
-
checked: config.
|
|
3490
|
+
checked: config.video_quality === value,
|
|
3482
3491
|
name: "asset-encodingtier",
|
|
3483
3492
|
onChange: (e) => dispatch({
|
|
3484
|
-
action: "
|
|
3493
|
+
action: "video_quality",
|
|
3485
3494
|
value: e.currentTarget.value
|
|
3486
3495
|
}),
|
|
3487
3496
|
value,
|
|
@@ -3493,7 +3502,7 @@ function UploadConfiguration({
|
|
|
3493
3502
|
}) })
|
|
3494
3503
|
}
|
|
3495
3504
|
),
|
|
3496
|
-
|
|
3505
|
+
!basicConfig && maxSupportedResolution > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3497
3506
|
sanity.FormField,
|
|
3498
3507
|
{
|
|
3499
3508
|
title: "Resolution Tier",
|
|
@@ -3533,9 +3542,9 @@ function UploadConfiguration({
|
|
|
3533
3542
|
}) })
|
|
3534
3543
|
}
|
|
3535
3544
|
),
|
|
3536
|
-
|
|
3545
|
+
!basicConfig && /* @__PURE__ */ jsxRuntime.jsx(sanity.FormField, { title: "Additional Configuration", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
|
|
3537
3546
|
/* @__PURE__ */ jsxRuntime.jsx(PlaybackPolicy, { id, config, secrets, dispatch }),
|
|
3538
|
-
|
|
3547
|
+
!basicConfig && /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", gap: 2, padding: [0, 2], children: [
|
|
3539
3548
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3540
3549
|
ui.Checkbox,
|
|
3541
3550
|
{
|
|
@@ -3554,7 +3563,7 @@ function UploadConfiguration({
|
|
|
3554
3563
|
] })
|
|
3555
3564
|
] }) })
|
|
3556
3565
|
] }),
|
|
3557
|
-
!disableTextTrackConfig &&
|
|
3566
|
+
!disableTextTrackConfig && !basicConfig && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3558
3567
|
TextTracksEditor,
|
|
3559
3568
|
{
|
|
3560
3569
|
tracks: config.text_tracks,
|
|
@@ -3565,7 +3574,7 @@ function UploadConfiguration({
|
|
|
3565
3574
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3566
3575
|
ui.Button,
|
|
3567
3576
|
{
|
|
3568
|
-
disabled:
|
|
3577
|
+
disabled: !basicConfig && !config.public_policy && !config.signed_policy,
|
|
3569
3578
|
icon: icons.UploadIcon,
|
|
3570
3579
|
text: "Upload",
|
|
3571
3580
|
tone: "positive",
|
|
@@ -3606,7 +3615,7 @@ function formatUploadConfig(config) {
|
|
|
3606
3615
|
mp4_support: config.mp4_support,
|
|
3607
3616
|
playback_policy: setPlaybackPolicy(config),
|
|
3608
3617
|
max_resolution_tier: config.max_resolution_tier,
|
|
3609
|
-
|
|
3618
|
+
video_quality: config.video_quality,
|
|
3610
3619
|
normalize_audio: config.normalize_audio
|
|
3611
3620
|
};
|
|
3612
3621
|
}
|
|
@@ -3784,7 +3793,7 @@ function Uploader(props) {
|
|
|
3784
3793
|
handleClick: (event) => events$.next(event)
|
|
3785
3794
|
};
|
|
3786
3795
|
})()
|
|
3787
|
-
).current, uploadRef = React.useRef(null), [state, dispatch] = React.useReducer(
|
|
3796
|
+
).current, uploadRef = React.useRef(null), uploadingDocumentId = React.useRef(null), [state, dispatch] = React.useReducer(
|
|
3788
3797
|
(prev, action) => {
|
|
3789
3798
|
switch (action.action) {
|
|
3790
3799
|
case "stageUpload":
|
|
@@ -3810,9 +3819,9 @@ function Uploader(props) {
|
|
|
3810
3819
|
});
|
|
3811
3820
|
case "reset":
|
|
3812
3821
|
case "complete":
|
|
3813
|
-
return uploadRef.current?.unsubscribe(), uploadRef.current = null, INITIAL_STATE;
|
|
3822
|
+
return uploadRef.current?.unsubscribe(), uploadRef.current = null, uploadingDocumentId.current = null, INITIAL_STATE;
|
|
3814
3823
|
case "error":
|
|
3815
|
-
return uploadRef.current?.unsubscribe(), uploadRef.current = null, Object.assign({}, INITIAL_STATE, { error: action.error });
|
|
3824
|
+
return uploadRef.current?.unsubscribe(), uploadRef.current = null, uploadingDocumentId.current = null, Object.assign({}, INITIAL_STATE, { error: action.error });
|
|
3816
3825
|
default:
|
|
3817
3826
|
return prev;
|
|
3818
3827
|
}
|
|
@@ -3823,9 +3832,21 @@ function Uploader(props) {
|
|
|
3823
3832
|
error: null
|
|
3824
3833
|
}
|
|
3825
3834
|
);
|
|
3826
|
-
React.useEffect(() =>
|
|
3827
|
-
|
|
3828
|
-
|
|
3835
|
+
React.useEffect(() => {
|
|
3836
|
+
const cleanup = () => {
|
|
3837
|
+
if (uploadRef.current && !uploadRef.current.closed && uploadRef.current.unsubscribe(), uploadingDocumentId.current && props.asset?._id !== uploadingDocumentId.current) {
|
|
3838
|
+
const docId = uploadingDocumentId.current;
|
|
3839
|
+
uploadingDocumentId.current = null, props.client.delete(docId).catch((err) => {
|
|
3840
|
+
console.warn("Failed to cleanup orphaned upload document:", err);
|
|
3841
|
+
});
|
|
3842
|
+
}
|
|
3843
|
+
}, handleBeforeUnload = () => {
|
|
3844
|
+
cleanup();
|
|
3845
|
+
};
|
|
3846
|
+
return window.addEventListener("beforeunload", handleBeforeUnload), window.addEventListener("pagehide", handleBeforeUnload), () => {
|
|
3847
|
+
window.removeEventListener("beforeunload", handleBeforeUnload), window.removeEventListener("pagehide", handleBeforeUnload), cleanup();
|
|
3848
|
+
};
|
|
3849
|
+
}, [props.client, props.asset?._id]);
|
|
3829
3850
|
const startUpload = (settings) => {
|
|
3830
3851
|
const { stagedUpload } = state;
|
|
3831
3852
|
if (!stagedUpload || uploadRef.current) return;
|
|
@@ -3848,7 +3869,7 @@ function Uploader(props) {
|
|
|
3848
3869
|
operators.takeUntil(
|
|
3849
3870
|
cancelUploadButton.observable.pipe(
|
|
3850
3871
|
operators.tap(() => {
|
|
3851
|
-
|
|
3872
|
+
uploadingDocumentId.current && (props.client.delete(uploadingDocumentId.current), uploadingDocumentId.current = null);
|
|
3852
3873
|
})
|
|
3853
3874
|
)
|
|
3854
3875
|
)
|
|
@@ -3859,6 +3880,8 @@ function Uploader(props) {
|
|
|
3859
3880
|
next: (event) => {
|
|
3860
3881
|
switch (event.type) {
|
|
3861
3882
|
case "uuid":
|
|
3883
|
+
uploadingDocumentId.current = event.uuid, dispatch({ action: "progressInfo", ...event });
|
|
3884
|
+
break;
|
|
3862
3885
|
case "file":
|
|
3863
3886
|
case "url":
|
|
3864
3887
|
dispatch({ action: "progressInfo", ...event });
|
|
@@ -3867,7 +3890,7 @@ function Uploader(props) {
|
|
|
3867
3890
|
dispatch({ action: "progress", percent: event.percent });
|
|
3868
3891
|
break;
|
|
3869
3892
|
case "success":
|
|
3870
|
-
dispatch({ action: "progress", percent: 100 }), props.onChange(
|
|
3893
|
+
dispatch({ action: "progress", percent: 100 }), uploadingDocumentId.current = null, props.onChange(
|
|
3871
3894
|
sanity.PatchEvent.from([
|
|
3872
3895
|
sanity.setIfMissing({ asset: {} }),
|
|
3873
3896
|
sanity.set({ _type: "reference", _weak: !0, _ref: event.asset._id }, ["asset"])
|
|
@@ -4147,6 +4170,10 @@ const muxVideoSchema = {
|
|
|
4147
4170
|
type: "string",
|
|
4148
4171
|
name: "encoding_tier"
|
|
4149
4172
|
},
|
|
4173
|
+
{
|
|
4174
|
+
type: "string",
|
|
4175
|
+
name: "video_quality"
|
|
4176
|
+
},
|
|
4150
4177
|
{
|
|
4151
4178
|
type: "string",
|
|
4152
4179
|
name: "master_access"
|
|
@@ -4225,13 +4252,18 @@ const muxVideoSchema = {
|
|
|
4225
4252
|
muxVideoAsset
|
|
4226
4253
|
], defaultConfig = {
|
|
4227
4254
|
mp4_support: "none",
|
|
4228
|
-
|
|
4255
|
+
video_quality: "plus",
|
|
4229
4256
|
max_resolution_tier: "1080p",
|
|
4230
4257
|
normalize_audio: !1,
|
|
4258
|
+
defaultPublic: !0,
|
|
4231
4259
|
defaultSigned: !1,
|
|
4232
4260
|
tool: DEFAULT_TOOL_CONFIG,
|
|
4233
4261
|
allowedRolesForConfiguration: []
|
|
4234
4262
|
}, muxInput = sanity.definePlugin((userConfig) => {
|
|
4263
|
+
if (typeof userConfig == "object" && "encoding_tier" in userConfig) {
|
|
4264
|
+
const deprecated_encoding_tier = userConfig.encoding_tier;
|
|
4265
|
+
userConfig.video_quality || (deprecated_encoding_tier === "baseline" && (userConfig.video_quality = "basic"), deprecated_encoding_tier === "smart" && (userConfig.video_quality = "plus"));
|
|
4266
|
+
}
|
|
4235
4267
|
const config = { ...defaultConfig, ...userConfig || {} };
|
|
4236
4268
|
return {
|
|
4237
4269
|
name: "mux-input",
|