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 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
- encoding_tier: 'smart',
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
- ### Encoding tier (smart or baseline)
231
+ ### Video Quality Level (plus or basic)
232
232
 
233
- The [encoding tier](https://docs.mux.com/guides/use-encoding-tiers) informs the cost, quality, and available platform features for the asset. You can choose between `smart` and `baseline` at the plugin configuration. Defaults to `smart`.
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({encoding_tier: 'baseline'})],
239
+ plugins: [muxInput({video_quality: 'basic'})],
240
240
  })
241
241
  ```
242
242
 
243
- If `encoding_tier: 'smart'`, editors can still choose to use the `baseline` encoding tier on a per-video basis when uploading new assets.
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://docs.mux.com/guides/use-encoding-tiers). 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)
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've enabled smart encoding, 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.
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
- encoding_tier: 'smart',
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 `"encoding_tier": "smart"`
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 `"encoding_tier": "smart"`
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: 'baseline' | 'smart'
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 `"encoding_tier": "smart"`
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 `"encoding_tier": "smart"`
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 `"encoding_tier": "smart"`
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 `"encoding_tier": "smart"`
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: 'baseline' | 'smart'
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 `"encoding_tier": "smart"`
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 `"encoding_tier": "smart"`
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), thumbnail = getPosterSrc({ asset, client, width: thumbnailWidth }), { src: videoSrc, error } = React.useMemo(() => {
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: thumbnail,
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.10.0",
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
- }) => /* @__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: [
2904
- /* @__PURE__ */ jsxRuntime.jsxs(LeftSection, { children: [
2905
- /* @__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: [
2906
- text,
2907
- /* @__PURE__ */ jsxRuntime.jsx(CodeWrapper, { size: 1, children: filename || "..." })
2908
- ] }) }) }),
2909
- /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { marginTop: 3, radius: 5, shadow: 1, children: /* @__PURE__ */ jsxRuntime.jsx(sanity.LinearProgress, { value: progress }) })
2910
- ] }),
2911
- onCancel ? /* @__PURE__ */ jsxRuntime.jsx(
2912
- ui.Button,
2913
- {
2914
- fontSize: 2,
2915
- text: "Cancel upload",
2916
- mode: "ghost",
2917
- tone: "critical",
2918
- onClick: onCancel
2919
- }
2920
- ) : null
2921
- ] }) }), Player = ({ asset, buttons, readOnly, onChange }) => {
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 ENCODING_OPTIONS = [
3336
- { value: "smart", label: "Smart" },
3337
- { value: "baseline", label: "Baseline" }
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.encoding_tier === "smart" && pluginConfig.defaultAutogeneratedSubtitleLang ? [
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 "encoding_tier":
3363
- return action.value === "baseline" ? Object.assign({}, prev, {
3364
- encoding_tier: action.value,
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
- encoding_tier: action.value,
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
- encoding_tier: pluginConfig.encoding_tier,
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: !0,
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: "Encoding Tier",
3470
+ title: "Video Quality Level",
3462
3471
  description: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3463
- "The encoding tier informs the cost, quality, and available platform features for the asset.",
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: ENCODING_OPTIONS.map(({ value, label }) => {
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.encoding_tier === value,
3490
+ checked: config.video_quality === value,
3482
3491
  name: "asset-encodingtier",
3483
3492
  onChange: (e) => dispatch({
3484
- action: "encoding_tier",
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
- config.encoding_tier === "smart" && maxSupportedResolution > 0 && /* @__PURE__ */ jsxRuntime.jsx(
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
- config.encoding_tier === "smart" && /* @__PURE__ */ jsxRuntime.jsx(sanity.FormField, { title: "Additional Configuration", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
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
- config.encoding_tier === "smart" && /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", gap: 2, padding: [0, 2], children: [
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 && config.encoding_tier === "smart" && /* @__PURE__ */ jsxRuntime.jsx(
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: config.encoding_tier === "smart" && !config.public_policy && !config.signed_policy,
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
- encoding_tier: config.encoding_tier,
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
- uploadRef.current && !uploadRef.current.closed && uploadRef.current.unsubscribe();
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
- state.uploadStatus?.uuid && props.client.delete(state.uploadStatus.uuid);
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
- encoding_tier: "smart",
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",