@remotion/media 4.0.490 → 4.0.492

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.
@@ -1122,6 +1122,7 @@ var makeStableFramePool = () => {
1122
1122
  if (!context) {
1123
1123
  throw new Error("Could not create canvas context");
1124
1124
  }
1125
+ context.clearRect(0, 0, stableCanvas.width, stableCanvas.height);
1125
1126
  context.drawImage(canvas, 0, 0);
1126
1127
  let released = false;
1127
1128
  const stableFrame = {
@@ -1815,6 +1816,9 @@ class MediaPlayer {
1815
1816
  }
1816
1817
  const canDecode = await videoTrack.canDecode();
1817
1818
  if (!canDecode) {
1819
+ if (videoTrack.codec === "prores") {
1820
+ return { type: "cannot-decode-prores" };
1821
+ }
1818
1822
  return { type: "cannot-decode" };
1819
1823
  }
1820
1824
  if (this.isDisposalError()) {
@@ -2533,6 +2537,9 @@ var AudioForPreviewAssertedShowing = ({
2533
2537
  handleError(new Error(`No video or audio tracks found for ${preloadedSrc}.`), `No video or audio tracks found for ${preloadedSrc}, falling back to <Html5Audio>`);
2534
2538
  return;
2535
2539
  }
2540
+ if (result.type === "cannot-decode-prores") {
2541
+ throw new Error(`Encountered ProRes media for ${preloadedSrc}. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
2542
+ }
2536
2543
  if (result.type === "success") {
2537
2544
  setMediaPlayerReady(true);
2538
2545
  setMediaDurationInSeconds(result.durationInSeconds);
@@ -3916,6 +3923,9 @@ var getSinks = async (src, logLevel, credentials, requestInit) => {
3916
3923
  }
3917
3924
  const canDecode = await videoTrack.canDecode();
3918
3925
  if (!canDecode) {
3926
+ if (videoTrack.codec === "prores") {
3927
+ return "cannot-decode-prores";
3928
+ }
3919
3929
  return "cannot-decode";
3920
3930
  }
3921
3931
  const sampleSink = new VideoSampleSink(videoTrack);
@@ -4174,6 +4184,12 @@ var extractFrameInternal = async ({
4174
4184
  if (video === "cannot-decode") {
4175
4185
  return { type: "cannot-decode", durationInSeconds: mediaDurationInSeconds };
4176
4186
  }
4187
+ if (video === "cannot-decode-prores") {
4188
+ return {
4189
+ type: "cannot-decode-prores",
4190
+ durationInSeconds: mediaDurationInSeconds
4191
+ };
4192
+ }
4177
4193
  if (video === "unknown-container-format") {
4178
4194
  return { type: "unknown-container-format" };
4179
4195
  }
@@ -4329,6 +4345,12 @@ var extractFrameAndAudio = async ({
4329
4345
  durationInSeconds: video.durationInSeconds
4330
4346
  };
4331
4347
  }
4348
+ if (video?.type === "cannot-decode-prores") {
4349
+ return {
4350
+ type: "cannot-decode-prores",
4351
+ durationInSeconds: video.durationInSeconds
4352
+ };
4353
+ }
4332
4354
  if (video?.type === "unknown-container-format") {
4333
4355
  return { type: "unknown-container-format" };
4334
4356
  }
@@ -4416,6 +4438,15 @@ var addBroadcastChannelListener = () => {
4416
4438
  window.remotion_broadcastChannel.postMessage(cannotDecodeResponse);
4417
4439
  return;
4418
4440
  }
4441
+ if (result.type === "cannot-decode-prores") {
4442
+ const cannotDecodeProresResponse = {
4443
+ type: "response-cannot-decode-prores",
4444
+ id: data.id,
4445
+ durationInSeconds: result.durationInSeconds
4446
+ };
4447
+ window.remotion_broadcastChannel.postMessage(cannotDecodeProresResponse);
4448
+ return;
4449
+ }
4419
4450
  if (result.type === "cannot-decode-alpha") {
4420
4451
  const cannotDecodeAlphaResponse = {
4421
4452
  type: "response-cannot-decode-alpha",
@@ -4562,6 +4593,14 @@ var extractFrameViaBroadcastChannel = async ({
4562
4593
  window.remotion_broadcastChannel.removeEventListener("message", onMessage);
4563
4594
  return;
4564
4595
  }
4596
+ if (data.type === "response-cannot-decode-prores") {
4597
+ resolve({
4598
+ type: "cannot-decode-prores",
4599
+ durationInSeconds: data.durationInSeconds
4600
+ });
4601
+ window.remotion_broadcastChannel.removeEventListener("message", onMessage);
4602
+ return;
4603
+ }
4565
4604
  if (data.type === "response-network-error") {
4566
4605
  resolve({ type: "network-error" });
4567
4606
  window.remotion_broadcastChannel.removeEventListener("message", onMessage);
@@ -4735,6 +4774,9 @@ var AudioForRendering = ({
4735
4774
  if (result.type === "cannot-decode-alpha") {
4736
4775
  throw new Error(`Cannot decode alpha component for ${src}, and 'disallowFallbackToHtml5Audio' was set. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
4737
4776
  }
4777
+ if (result.type === "cannot-decode-prores") {
4778
+ throw new Error(`Encountered ProRes media for ${src}. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
4779
+ }
4738
4780
  if (result.type === "network-error") {
4739
4781
  handleError(new Error(`Network error fetching ${src}.`), new Error(`Cannot render audio "${src}": Network error while fetching the audio (possibly CORS).`), `Network error fetching ${src}, falling back to <Html5Audio>`);
4740
4782
  return;
@@ -4834,6 +4876,12 @@ var AudioForRendering = ({
4834
4876
  import { jsx as jsx3 } from "react/jsx-runtime";
4835
4877
  var { validateMediaProps } = Internals17;
4836
4878
  var audioSchema = {
4879
+ src: {
4880
+ type: "asset",
4881
+ default: undefined,
4882
+ description: "Source",
4883
+ keyframable: false
4884
+ },
4837
4885
  ...Internals17.baseSchema,
4838
4886
  volume: {
4839
4887
  type: "number",
@@ -4948,13 +4996,34 @@ var Audio = Interactive.withSchema({
4948
4996
  // src/video/video.tsx
4949
4997
  import React6, { useMemo as useMemo6, useState as useState6 } from "react";
4950
4998
  import {
4951
- Internals as Internals21,
4999
+ Internals as Internals22,
4952
5000
  Interactive as Interactive2,
4953
5001
  Sequence as Sequence2,
4954
5002
  useRemotionEnvironment as useRemotionEnvironment4,
4955
5003
  useVideoConfig as useVideoConfig5
4956
5004
  } from "remotion";
4957
5005
 
5006
+ // src/video/get-video-sequence-duration.ts
5007
+ import { Internals as Internals18 } from "remotion";
5008
+ var getVideoSequenceDuration = ({
5009
+ durationInFrames,
5010
+ loop,
5011
+ playbackRate,
5012
+ trimAfter,
5013
+ trimBefore
5014
+ }) => {
5015
+ if (loop || trimAfter === undefined) {
5016
+ return durationInFrames;
5017
+ }
5018
+ const trimmedDuration = Internals18.calculateMediaDuration({
5019
+ trimAfter,
5020
+ trimBefore,
5021
+ playbackRate,
5022
+ mediaDurationInFrames: Infinity
5023
+ });
5024
+ return Math.min(durationInFrames ?? Infinity, trimmedDuration);
5025
+ };
5026
+
4958
5027
  // src/video/video-for-preview.tsx
4959
5028
  import {
4960
5029
  useCallback,
@@ -4967,12 +5036,25 @@ import {
4967
5036
  } from "react";
4968
5037
  import {
4969
5038
  Html5Video,
4970
- Internals as Internals19,
5039
+ Internals as Internals20,
4971
5040
  useBufferState as useBufferState2,
4972
5041
  useCurrentFrame as useCurrentFrame3,
4973
5042
  useVideoConfig as useVideoConfig3
4974
5043
  } from "remotion";
4975
5044
 
5045
+ // src/prores-error.ts
5046
+ var PRORES_DOCS_URL = "https://www.remotion.dev/docs/videos/prores";
5047
+ var proresDecoderNotEnabledMessage = (src) => {
5048
+ return `Cannot decode "${src}": it is encoded with Apple ProRes, which WebCodecs does not support natively. ` + `ProRes decoding is not enabled by default. Register the ProRes decoder by calling ` + `registerProresDecoder() from "@mediabunny/prores" in your entry point, before registerRoot(). ` + `See ${PRORES_DOCS_URL}. ` + `(This is required to decode a ProRes source for both preview and rendering — it is unrelated to exporting a video as ProRes.)`;
5049
+ };
5050
+
5051
+ class ProResDecoderNotEnabledError extends Error {
5052
+ constructor(src) {
5053
+ super(proresDecoderNotEnabledMessage(src));
5054
+ this.name = "ProResDecoderNotEnabledError";
5055
+ }
5056
+ }
5057
+
4976
5058
  // src/video/video-frame-cache.ts
4977
5059
  var cache = new Map;
4978
5060
  var cacheVideoFrame = (src, sourceCanvas) => {
@@ -4997,7 +5079,7 @@ var getCachedVideoFrame = (src) => {
4997
5079
  };
4998
5080
 
4999
5081
  // src/video/warn-object-fit-css.ts
5000
- import { Internals as Internals18 } from "remotion";
5082
+ import { Internals as Internals19 } from "remotion";
5001
5083
  var OBJECT_FIT_CLASS_PATTERN = /\bobject-(contain|cover|fill|none|scale-down)\b/;
5002
5084
  var warnedStyle = false;
5003
5085
  var warnedClassName = false;
@@ -5008,11 +5090,11 @@ var warnAboutObjectFitInStyleOrClassName = ({
5008
5090
  }) => {
5009
5091
  if (!warnedStyle && style?.objectFit) {
5010
5092
  warnedStyle = true;
5011
- Internals18.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of the `style` prop.");
5093
+ Internals19.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of the `style` prop.");
5012
5094
  }
5013
5095
  if (!warnedClassName && className && OBJECT_FIT_CLASS_PATTERN.test(className)) {
5014
5096
  warnedClassName = true;
5015
- Internals18.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of `object-*` CSS class names.");
5097
+ Internals19.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of `object-*` CSS class names.");
5016
5098
  }
5017
5099
  };
5018
5100
 
@@ -5030,7 +5112,7 @@ var {
5030
5112
  usePreload: usePreload2,
5031
5113
  SequenceContext: SequenceContext2,
5032
5114
  useEffectChainState
5033
- } = Internals19;
5115
+ } = Internals20;
5034
5116
  var VideoForPreviewAssertedShowing = ({
5035
5117
  src: unpreloadedSrc,
5036
5118
  style,
@@ -5073,7 +5155,7 @@ var VideoForPreviewAssertedShowing = ({
5073
5155
  const [mediaPlayerReady, setMediaPlayerReady] = useState4(false);
5074
5156
  const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState4(false);
5075
5157
  const [playing] = Timeline2.usePlayingState();
5076
- const { playbackRate: globalPlaybackRate } = Internals19.usePlaybackRate();
5158
+ const { playbackRate: globalPlaybackRate } = Internals20.usePlaybackRate();
5077
5159
  const sharedAudioContext = useContext4(SharedAudioContext2);
5078
5160
  const buffer = useBufferState2();
5079
5161
  const canvasRefCallback = useCallback((canvas) => {
@@ -5110,12 +5192,12 @@ var VideoForPreviewAssertedShowing = ({
5110
5192
  const currentTimeRef = useRef2(currentTime);
5111
5193
  currentTimeRef.current = currentTime;
5112
5194
  const preloadedSrc = usePreload2(src);
5113
- const buffering = useContext4(Internals19.BufferingContextReact);
5195
+ const buffering = useContext4(Internals20.BufferingContextReact);
5114
5196
  if (!buffering) {
5115
5197
  throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
5116
5198
  }
5117
5199
  const effectiveMuted = muted || playerMuted || userPreferredVolume <= 0;
5118
- const isPlayerBuffering = Internals19.useIsPlayerBuffering(buffering);
5200
+ const isPlayerBuffering = Internals20.useIsPlayerBuffering(buffering);
5119
5201
  const initialPlaying = useRef2(playing && !isPlayerBuffering);
5120
5202
  const initialIsPremounting = useRef2(isPremounting);
5121
5203
  const initialIsPostmounting = useRef2(isPostmounting);
@@ -5213,7 +5295,7 @@ var VideoForPreviewAssertedShowing = ({
5213
5295
  if (action === "fail") {
5214
5296
  throw errorToUse;
5215
5297
  }
5216
- Internals19.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5298
+ Internals20.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5217
5299
  setShouldFallbackToNativeVideo(true);
5218
5300
  };
5219
5301
  if (result.type === "unknown-container-format") {
@@ -5228,6 +5310,9 @@ var VideoForPreviewAssertedShowing = ({
5228
5310
  handleError(new Error(`Cannot decode ${preloadedSrc}.`), `Cannot decode ${preloadedSrc}, falling back to <OffthreadVideo>`);
5229
5311
  return;
5230
5312
  }
5313
+ if (result.type === "cannot-decode-prores") {
5314
+ throw new ProResDecoderNotEnabledError(preloadedSrc);
5315
+ }
5231
5316
  if (result.type === "no-tracks") {
5232
5317
  handleError(new Error(`No video or audio tracks found for ${preloadedSrc}.`), `No video or audio tracks found for ${preloadedSrc}, falling back to <OffthreadVideo>`);
5233
5318
  return;
@@ -5238,6 +5323,10 @@ var VideoForPreviewAssertedShowing = ({
5238
5323
  hasDrawnRealFrameRef.current = true;
5239
5324
  }
5240
5325
  }).catch((error) => {
5326
+ if (error instanceof ProResDecoderNotEnabledError) {
5327
+ onErrorRef.current?.(error);
5328
+ throw error;
5329
+ }
5241
5330
  const [action, errorToUse] = callOnErrorAndResolve({
5242
5331
  onError: onErrorRef.current,
5243
5332
  error,
@@ -5248,7 +5337,7 @@ var VideoForPreviewAssertedShowing = ({
5248
5337
  if (action === "fail") {
5249
5338
  throw errorToUse;
5250
5339
  }
5251
- Internals19.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", errorToUse);
5340
+ Internals20.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", errorToUse);
5252
5341
  setShouldFallbackToNativeVideo(true);
5253
5342
  });
5254
5343
  } catch (error) {
@@ -5262,12 +5351,12 @@ var VideoForPreviewAssertedShowing = ({
5262
5351
  if (action === "fail") {
5263
5352
  throw errorToUse;
5264
5353
  }
5265
- Internals19.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", errorToUse);
5354
+ Internals20.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", errorToUse);
5266
5355
  setShouldFallbackToNativeVideo(true);
5267
5356
  }
5268
5357
  return () => {
5269
5358
  if (mediaPlayerRef.current) {
5270
- Internals19.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
5359
+ Internals20.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
5271
5360
  mediaPlayerRef.current.dispose();
5272
5361
  mediaPlayerRef.current = null;
5273
5362
  }
@@ -5291,7 +5380,7 @@ var VideoForPreviewAssertedShowing = ({
5291
5380
  ]);
5292
5381
  warnAboutObjectFitInStyleOrClassName({ style, className, logLevel });
5293
5382
  const classNameValue = useMemo4(() => {
5294
- return [Internals19.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals19.truthy).join(" ");
5383
+ return [Internals20.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals20.truthy).join(" ");
5295
5384
  }, [className]);
5296
5385
  useCommonEffects({
5297
5386
  mediaPlayerRef,
@@ -5415,7 +5504,7 @@ import {
5415
5504
  useState as useState5
5416
5505
  } from "react";
5417
5506
  import {
5418
- Internals as Internals20,
5507
+ Internals as Internals21,
5419
5508
  Loop,
5420
5509
  random as random2,
5421
5510
  useCurrentFrame as useCurrentFrame4,
@@ -5456,11 +5545,11 @@ var VideoForRendering = ({
5456
5545
  throw new TypeError("No `src` was passed to <Video>.");
5457
5546
  }
5458
5547
  const frame = useCurrentFrame4();
5459
- const absoluteFrame = Internals20.useTimelinePosition();
5548
+ const absoluteFrame = Internals21.useTimelinePosition();
5460
5549
  const { fps } = useVideoConfig4();
5461
- const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals20.RenderAssetManager);
5462
- const startsAt = Internals20.useMediaStartsAt();
5463
- const sequenceContext = useContext5(Internals20.SequenceContext);
5550
+ const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals21.RenderAssetManager);
5551
+ const startsAt = Internals21.useMediaStartsAt();
5552
+ const sequenceContext = useContext5(Internals21.SequenceContext);
5464
5553
  const id = useMemo5(() => `media-video-${random2(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
5465
5554
  src,
5466
5555
  sequenceContext?.cumulatedFrom,
@@ -5472,10 +5561,10 @@ var VideoForRendering = ({
5472
5561
  const canvasRef = useRef3(null);
5473
5562
  const [replaceWithOffthreadVideo, setReplaceWithOffthreadVideo] = useState5(false);
5474
5563
  const [initialRequestInit] = useState5(requestInit);
5475
- const audioEnabled = Internals20.useAudioEnabled();
5476
- const videoEnabled = Internals20.useVideoEnabled();
5564
+ const audioEnabled = Internals21.useAudioEnabled();
5565
+ const videoEnabled = Internals21.useVideoEnabled();
5477
5566
  const maxCacheSize = useMaxMediaCacheSize(logLevel);
5478
- const effectChainState = Internals20.useEffectChainState();
5567
+ const effectChainState = Internals21.useEffectChainState();
5479
5568
  const [error, setError] = useState5(null);
5480
5569
  if (error) {
5481
5570
  throw error;
@@ -5540,7 +5629,7 @@ var VideoForRendering = ({
5540
5629
  return;
5541
5630
  }
5542
5631
  if (window.remotion_isMainTab) {
5543
- Internals20.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5632
+ Internals21.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5544
5633
  }
5545
5634
  setReplaceWithOffthreadVideo({
5546
5635
  durationInSeconds: mediaDurationInSeconds
@@ -5554,6 +5643,12 @@ var VideoForRendering = ({
5554
5643
  handleError(new Error(`Cannot decode ${src}.`), new Error(`Cannot render video "${src}": The video could not be decoded by the browser.`), `Cannot decode ${src}, falling back to <OffthreadVideo>`, result.durationInSeconds);
5555
5644
  return;
5556
5645
  }
5646
+ if (result.type === "cannot-decode-prores") {
5647
+ const proresError = new ProResDecoderNotEnabledError(src);
5648
+ onError?.(proresError);
5649
+ cancelRender3(proresError);
5650
+ return;
5651
+ }
5557
5652
  if (result.type === "cannot-decode-alpha") {
5558
5653
  handleError(new Error(`Cannot decode alpha component for ${src}.`), new Error(`Cannot render video "${src}": The alpha channel could not be decoded by the browser.`), `Cannot decode alpha component for ${src}, falling back to <OffthreadVideo>`, result.durationInSeconds);
5559
5654
  return;
@@ -5578,7 +5673,7 @@ var VideoForRendering = ({
5578
5673
  context.canvas.style.aspectRatio = `${context.canvas.width} / ${context.canvas.height}`;
5579
5674
  context.drawImage(imageBitmap, 0, 0);
5580
5675
  if (effects.length > 0) {
5581
- const completed = await Internals20.runEffectChain({
5676
+ const completed = await Internals21.runEffectChain({
5582
5677
  state: effectChainState.get(imageBitmap.width, imageBitmap.height),
5583
5678
  source: context.canvas,
5584
5679
  effects,
@@ -5609,12 +5704,12 @@ var VideoForRendering = ({
5609
5704
  frame,
5610
5705
  startsAt
5611
5706
  });
5612
- const volume = Internals20.evaluateVolume({
5707
+ const volume = Internals21.evaluateVolume({
5613
5708
  volume: volumeProp,
5614
5709
  frame: volumePropsFrame,
5615
5710
  mediaVolume: 1
5616
5711
  });
5617
- Internals20.warnAboutTooHighVolume(volume);
5712
+ Internals21.warnAboutTooHighVolume(volume);
5618
5713
  if (audio && volume > 0) {
5619
5714
  applyVolume(audio.data, volume);
5620
5715
  registerRenderAsset({
@@ -5675,7 +5770,7 @@ var VideoForRendering = ({
5675
5770
  ]);
5676
5771
  warnAboutObjectFitInStyleOrClassName({ style, className, logLevel });
5677
5772
  const classNameValue = useMemo5(() => {
5678
- return [Internals20.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals20.truthy).join(" ");
5773
+ return [Internals21.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals21.truthy).join(" ");
5679
5774
  }, [className]);
5680
5775
  const styleWithObjectFit = useMemo5(() => {
5681
5776
  return {
@@ -5684,7 +5779,7 @@ var VideoForRendering = ({
5684
5779
  };
5685
5780
  }, [objectFitProp, style]);
5686
5781
  if (replaceWithOffthreadVideo) {
5687
- const fallback = /* @__PURE__ */ jsx5(Internals20.InnerOffthreadVideo, {
5782
+ const fallback = /* @__PURE__ */ jsx5(Internals21.InnerOffthreadVideo, {
5688
5783
  ...props,
5689
5784
  src,
5690
5785
  playbackRate: playbackRate ?? 1,
@@ -5726,7 +5821,7 @@ var VideoForRendering = ({
5726
5821
  }
5727
5822
  return /* @__PURE__ */ jsx5(Loop, {
5728
5823
  layout: "none",
5729
- durationInFrames: Internals20.calculateMediaDuration({
5824
+ durationInFrames: Internals21.calculateMediaDuration({
5730
5825
  trimAfter: trimAfterValue,
5731
5826
  mediaDurationInFrames: replaceWithOffthreadVideo.durationInSeconds * fps,
5732
5827
  playbackRate,
@@ -5750,9 +5845,15 @@ var VideoForRendering = ({
5750
5845
 
5751
5846
  // src/video/video.tsx
5752
5847
  import { jsx as jsx6 } from "react/jsx-runtime";
5753
- var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } = Internals21;
5848
+ var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } = Internals22;
5754
5849
  var videoSchema = {
5755
- ...Internals21.baseSchema,
5850
+ src: {
5851
+ type: "asset",
5852
+ default: undefined,
5853
+ description: "Source",
5854
+ keyframable: false
5855
+ },
5856
+ ...Internals22.baseSchema,
5756
5857
  volume: {
5757
5858
  type: "number",
5758
5859
  min: 0,
@@ -5771,8 +5872,9 @@ var videoSchema = {
5771
5872
  hiddenFromList: false,
5772
5873
  keyframable: false
5773
5874
  },
5875
+ muted: { type: "boolean", default: false, description: "Muted" },
5774
5876
  loop: { type: "boolean", default: false, description: "Loop" },
5775
- ...Internals21.transformSchema
5877
+ ...Internals22.transformSchema
5776
5878
  };
5777
5879
  var InnerVideo = ({
5778
5880
  src,
@@ -5924,12 +6026,19 @@ var VideoInner = ({
5924
6026
  hidden,
5925
6027
  ...props
5926
6028
  }) => {
5927
- const fallbackLogLevel = Internals21.useLogLevel();
5928
- const [mediaVolume] = Internals21.useMediaVolumeState();
5929
- const mediaStartsAt = Internals21.useMediaStartsAt();
6029
+ const fallbackLogLevel = Internals22.useLogLevel();
6030
+ const [mediaVolume] = Internals22.useMediaVolumeState();
6031
+ const mediaStartsAt = Internals22.useMediaStartsAt();
5930
6032
  const videoConfig = useVideoConfig5();
5931
6033
  const sequenceDurationInFrames = Math.min(durationInFrames ?? Infinity, Math.max(0, videoConfig.durationInFrames - (from ?? 0)));
5932
- const basicInfo = Internals21.useBasicMediaInTimeline({
6034
+ const videoSequenceDuration = getVideoSequenceDuration({
6035
+ durationInFrames,
6036
+ loop: loop ?? false,
6037
+ playbackRate: playbackRate ?? 1,
6038
+ trimAfter,
6039
+ trimBefore
6040
+ });
6041
+ const basicInfo = Internals22.useBasicMediaInTimeline({
5933
6042
  src,
5934
6043
  volume,
5935
6044
  playbackRate: playbackRate ?? 1,
@@ -5964,11 +6073,11 @@ var VideoInner = ({
5964
6073
  type: "video",
5965
6074
  data: basicInfo
5966
6075
  }), [basicInfo]);
5967
- const memoizedEffects = Internals21.useMemoizedEffects({
6076
+ const memoizedEffects = Internals22.useMemoizedEffects({
5968
6077
  effects: effects ?? [],
5969
6078
  overrideId: controls?.overrideId ?? null
5970
6079
  });
5971
- const memoizedEffectDefinitions = Internals21.useMemoizedEffectDefinitions(effects ?? []);
6080
+ const memoizedEffectDefinitions = Internals22.useMemoizedEffectDefinitions(effects ?? []);
5972
6081
  const refForOutline = React6.useRef(null);
5973
6082
  if (sequenceDurationInFrames === 0) {
5974
6083
  return null;
@@ -5976,7 +6085,7 @@ var VideoInner = ({
5976
6085
  return /* @__PURE__ */ jsx6(Sequence2, {
5977
6086
  layout: "none",
5978
6087
  from: from ?? 0,
5979
- durationInFrames: basicInfo.duration,
6088
+ durationInFrames: videoSequenceDuration,
5980
6089
  freeze,
5981
6090
  _remotionInternalStack: stack,
5982
6091
  _remotionInternalIsMedia: isMedia,
@@ -10,6 +10,8 @@ export type MediaPlayerInitResult = {
10
10
  type: 'unknown-container-format';
11
11
  } | {
12
12
  type: 'cannot-decode';
13
+ } | {
14
+ type: 'cannot-decode-prores';
13
15
  } | {
14
16
  type: 'network-error';
15
17
  } | {
@@ -0,0 +1,4 @@
1
+ export declare const proresDecoderNotEnabledMessage: (src: string) => string;
2
+ export declare class ProResDecoderNotEnabledError extends Error {
3
+ constructor(src: string);
4
+ }
@@ -0,0 +1,7 @@
1
+ export declare const getVideoSequenceDuration: ({ durationInFrames, loop, playbackRate, trimAfter, trimBefore, }: {
2
+ readonly durationInFrames: number | undefined;
3
+ readonly loop: boolean;
4
+ readonly playbackRate: number;
5
+ readonly trimAfter: number | undefined;
6
+ readonly trimBefore: number | undefined;
7
+ }) => number | undefined;
@@ -15,6 +15,10 @@ export type MessageFromMainTab = {
15
15
  type: 'response-cannot-decode';
16
16
  id: string;
17
17
  durationInSeconds: number | null;
18
+ } | {
19
+ type: 'response-cannot-decode-prores';
20
+ id: string;
21
+ durationInSeconds: number | null;
18
22
  } | {
19
23
  type: 'response-cannot-decode-alpha';
20
24
  id: string;
@@ -8,6 +8,9 @@ export type ExtractFrameViaBroadcastChannelResult = {
8
8
  } | {
9
9
  type: 'cannot-decode';
10
10
  durationInSeconds: number | null;
11
+ } | {
12
+ type: 'cannot-decode-prores';
13
+ durationInSeconds: number | null;
11
14
  } | {
12
15
  type: 'cannot-decode-alpha';
13
16
  durationInSeconds: number | null;
@@ -8,6 +8,9 @@ type ExtractFrameResult = {
8
8
  } | {
9
9
  type: 'cannot-decode';
10
10
  durationInSeconds: number | null;
11
+ } | {
12
+ type: 'cannot-decode-prores';
13
+ durationInSeconds: number | null;
11
14
  } | {
12
15
  type: 'cannot-decode-alpha';
13
16
  durationInSeconds: number | null;
@@ -7,7 +7,7 @@ type AudioSinks = {
7
7
  sampleSink: AudioSampleSink;
8
8
  };
9
9
  export type AudioSinkResult = AudioSinks | 'no-audio-track' | 'cannot-decode-audio' | 'unknown-container-format' | 'network-error';
10
- export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'cannot-decode-alpha' | 'unknown-container-format' | 'network-error';
10
+ export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'cannot-decode-prores' | 'cannot-decode-alpha' | 'unknown-container-format' | 'network-error';
11
11
  export declare const getSinks: (src: string, logLevel: "error" | "info" | "trace" | "verbose" | "warn", credentials: RequestCredentials | undefined, requestInit?: MediaRequestInit | undefined) => Promise<{
12
12
  getVideo: () => Promise<VideoSinkResult>;
13
13
  getAudio: (index: number | null) => Promise<AudioSinkResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/media",
3
- "version": "4.0.490",
3
+ "version": "4.0.492",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/esm/index.mjs",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "mediabunny": "1.50.8",
26
- "remotion": "4.0.490",
26
+ "remotion": "4.0.492",
27
27
  "zod": "4.3.6"
28
28
  },
29
29
  "peerDependencies": {
@@ -31,8 +31,8 @@
31
31
  "react-dom": ">=16.8.0"
32
32
  },
33
33
  "devDependencies": {
34
- "@remotion/eslint-config-internal": "4.0.490",
35
- "@remotion/player": "4.0.490",
34
+ "@remotion/eslint-config-internal": "4.0.492",
35
+ "@remotion/player": "4.0.492",
36
36
  "@vitest/browser-webdriverio": "4.0.9",
37
37
  "eslint": "9.19.0",
38
38
  "react": "19.2.3",