@remotion/media 4.0.514 → 4.0.516

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.
@@ -40,7 +40,7 @@ var __callDispose = (stack, error, hasError) => {
40
40
  import { useMemo as useMemo3, useState as useState3 } from "react";
41
41
  import {
42
42
  Freeze,
43
- Internals as Internals18,
43
+ Internals as Internals19,
44
44
  Interactive,
45
45
  Sequence,
46
46
  useRemotionEnvironment as useRemotionEnvironment2,
@@ -78,7 +78,7 @@ var getLoopDisplay = ({
78
78
  // src/audio/audio-for-preview.tsx
79
79
  import { useContext as useContext2, useEffect, useMemo, useRef, useState } from "react";
80
80
  import {
81
- Internals as Internals8,
81
+ Internals as Internals9,
82
82
  Audio as RemotionAudio,
83
83
  useBufferState,
84
84
  useCurrentFrame,
@@ -137,7 +137,7 @@ var calculateEndTime = ({
137
137
  };
138
138
 
139
139
  // src/media-player.ts
140
- import { Internals as Internals6 } from "remotion";
140
+ import { Internals as Internals7 } from "remotion";
141
141
 
142
142
  // src/audio-iterator-manager.ts
143
143
  import {
@@ -406,8 +406,8 @@ async function* makeLoopingIterator({
406
406
  return;
407
407
  }
408
408
  }
409
- if (!yieldedInPass) {
410
- throw new Error(`Audio loop pass from ${passStartInSeconds} to ${segmentEndInSeconds} yielded no buffers`);
409
+ if (!yieldedInPass && passStartInSeconds === loopStartInSeconds) {
410
+ return;
411
411
  }
412
412
  passBaseTimestamp += segmentEndInSeconds - passStartInSeconds;
413
413
  passStartInSeconds = loopStartInSeconds;
@@ -585,7 +585,7 @@ var audioIteratorManager = ({
585
585
  onDone();
586
586
  return;
587
587
  }
588
- onScheduled(result.value.sourceDurationInSeconds);
588
+ onScheduled(result.value.sourceDurationInSeconds, result.value.timelineTimestamp);
589
589
  notifyNodeScheduled();
590
590
  onAudioChunk({
591
591
  buffer: result.value,
@@ -667,7 +667,7 @@ var audioIteratorManager = ({
667
667
  });
668
668
  audioIteratorsCreated++;
669
669
  audioBufferIterator = iterator;
670
- let bufferedDuration = 0;
670
+ let bufferedUntil = startFromSecond;
671
671
  let hasUnblockedPlayback = false;
672
672
  const unblockPlayback = () => {
673
673
  if (hasUnblockedPlayback) {
@@ -682,8 +682,9 @@ var audioIteratorManager = ({
682
682
  getTargetTime,
683
683
  playbackRate,
684
684
  scheduleAudioNode,
685
- onScheduled: (sourceDurationInSeconds) => {
686
- bufferedDuration += sourceDurationInSeconds;
685
+ onScheduled: (sourceDurationInSeconds, timelineTimestamp) => {
686
+ bufferedUntil = Math.max(bufferedUntil, timelineTimestamp + sourceDurationInSeconds);
687
+ const bufferedDuration = bufferedUntil - startFromSecond;
687
688
  if (hasEnoughAudioToStartPlayback(bufferedDuration)) {
688
689
  unblockPlayback();
689
690
  }
@@ -752,7 +753,8 @@ var audioIteratorManager = ({
752
753
  return;
753
754
  }
754
755
  const currentIteratorTimestamp = audioBufferIterator.guessNextTimestamp();
755
- if (currentIteratorTimestamp < timeToCheck && Math.abs(currentIteratorTimestamp - timeToCheck) < 1) {
756
+ const iteratorHasAdvancedThroughSilence = loop && currentAnchor !== null && unloopedNewTime >= currentAnchor.unloopedStartInSeconds && currentIteratorTimestamp >= timeToCheck;
757
+ if (iteratorHasAdvancedThroughSilence || currentIteratorTimestamp < timeToCheck && Math.abs(currentIteratorTimestamp - timeToCheck) < 1) {
756
758
  processNext();
757
759
  return;
758
760
  }
@@ -843,6 +845,10 @@ var drawPreviewOverlay = ({
843
845
  }
844
846
  };
845
847
 
848
+ // src/get-shared-input.ts
849
+ import { ALL_FORMATS, Input, UrlSource } from "mediabunny";
850
+ import { Internals as Internals5 } from "remotion";
851
+
846
852
  // src/get-duration-or-compute.ts
847
853
  var getDurationOrCompute = async (input) => {
848
854
  return await input.getDurationFromMetadata(undefined, {
@@ -850,9 +856,6 @@ var getDurationOrCompute = async (input) => {
850
856
  }) ?? input.computeDuration(undefined, { skipLiveWait: true });
851
857
  };
852
858
 
853
- // src/get-shared-input.ts
854
- import { ALL_FORMATS, Input, UrlSource } from "mediabunny";
855
-
856
859
  // src/max-cache-size.ts
857
860
  import { cancelRender, Internals as Internals4 } from "remotion";
858
861
  var getUncachedMaxCacheSize = (logLevel) => {
@@ -967,16 +970,16 @@ var resolveRequestInit = ({
967
970
  };
968
971
 
969
972
  // src/get-shared-input.ts
970
- var sharedInputs = {};
971
973
  var getSharedInputCacheKey = ({
972
974
  src,
973
975
  credentials,
974
976
  requestInit
975
- }) => JSON.stringify([
977
+ }) => Internals5.getMediabunnyInputResourceKey({
976
978
  src,
977
- credentials ?? null,
978
- getMediaRequestInitFingerprint(requestInit)
979
- ]);
979
+ credentials: credentials ?? null,
980
+ requestInitFingerprint: getMediaRequestInitFingerprint(requestInit),
981
+ revision: null
982
+ });
980
983
  var acquireSharedInput = ({
981
984
  src,
982
985
  credentials,
@@ -989,35 +992,28 @@ var acquireSharedInput = ({
989
992
  credentials,
990
993
  requestInit: normalizedRequestInit
991
994
  });
992
- const existing = sharedInputs[cacheKey];
993
- if (existing) {
994
- existing.refCount++;
995
- return { input: existing.input, cacheKey };
996
- }
997
995
  const resolvedRequestInit = resolveRequestInit({
998
996
  credentials,
999
997
  requestInit: normalizedRequestInit
1000
998
  });
1001
- const input = new Input({
1002
- source: new UrlSource(src, {
1003
- maxCacheSize: getMaxSourceCacheSize(logLevel),
1004
- ...resolvedRequestInit ? { requestInit: resolvedRequestInit } : undefined
1005
- }),
1006
- formats: ALL_FORMATS
999
+ const lease = Internals5.globalMediaResourceManager.acquire({
1000
+ key: cacheKey,
1001
+ create: () => {
1002
+ const input = new Input({
1003
+ source: new UrlSource(src, {
1004
+ maxCacheSize: getMaxSourceCacheSize(logLevel),
1005
+ ...resolvedRequestInit ? { requestInit: resolvedRequestInit } : undefined
1006
+ }),
1007
+ formats: ALL_FORMATS
1008
+ });
1009
+ return { resource: input, dispose: () => input.dispose() };
1010
+ }
1007
1011
  });
1008
- sharedInputs[cacheKey] = { input, refCount: 1 };
1009
- return { input, cacheKey };
1010
- };
1011
- var releaseSharedInput = (cacheKey) => {
1012
- const entry = sharedInputs[cacheKey];
1013
- if (!entry) {
1014
- return;
1015
- }
1016
- entry.refCount--;
1017
- if (entry.refCount <= 0) {
1018
- delete sharedInputs[cacheKey];
1019
- entry.input.dispose();
1020
- }
1012
+ return {
1013
+ input: lease.resource,
1014
+ getDuration: () => lease.getOrCreateValue(Internals5.MEDIABUNNY_DURATION_VALUE_KEY, () => getDurationOrCompute(lease.resource)),
1015
+ release: lease.release
1016
+ };
1021
1017
  };
1022
1018
 
1023
1019
  // src/helpers/resolve-audio-track.ts
@@ -1141,7 +1137,7 @@ class PremountAwareDelayPlayback {
1141
1137
 
1142
1138
  // src/video-iterator-manager.ts
1143
1139
  import { CanvasSink } from "mediabunny";
1144
- import { Internals as Internals5 } from "remotion";
1140
+ import { Internals as Internals6 } from "remotion";
1145
1141
 
1146
1142
  // src/helpers/round-to-4-digits.ts
1147
1143
  var roundTo4Digits = (timestamp) => {
@@ -1551,7 +1547,7 @@ var createVideoIterator = async (timeToSeek, cache) => {
1551
1547
  };
1552
1548
 
1553
1549
  // src/video-iterator-manager.ts
1554
- var { runEffectChain } = Internals5;
1550
+ var { runEffectChain } = Internals6;
1555
1551
  var isSequentialMediaTimeAdvance = ({
1556
1552
  previousTime,
1557
1553
  newTime,
@@ -1630,7 +1626,7 @@ var videoIteratorManager = async ({
1630
1626
  if (callback) {
1631
1627
  callback(frame.canvas);
1632
1628
  }
1633
- Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, `[MediaPlayer] Drew frame ${frame.timestamp.toFixed(3)}s`);
1629
+ Internals6.Log.trace({ logLevel, tag: "@remotion/media" }, `[MediaPlayer] Drew frame ${frame.timestamp.toFixed(3)}s`);
1634
1630
  };
1635
1631
  const redrawCurrentFrame = async () => {
1636
1632
  if (!lastDrawnFrame) {
@@ -1642,7 +1638,7 @@ var videoIteratorManager = async ({
1642
1638
  if (callback) {
1643
1639
  callback(lastDrawnFrame.canvas);
1644
1640
  }
1645
- Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, `[MediaPlayer] Redrew frame ${lastDrawnFrame.timestamp.toFixed(3)}s with updated effects`);
1641
+ Internals6.Log.trace({ logLevel, tag: "@remotion/media" }, `[MediaPlayer] Redrew frame ${lastDrawnFrame.timestamp.toFixed(3)}s with updated effects`);
1646
1642
  };
1647
1643
  const startVideoIterator = async (timeToSeek, nonce) => {
1648
1644
  let __stack = [];
@@ -1659,6 +1655,9 @@ var videoIteratorManager = async ({
1659
1655
  return;
1660
1656
  }
1661
1657
  if (nonce.isStale()) {
1658
+ if (!videoFrameIterator.isDestroyed() && iterator.initialFrame) {
1659
+ await drawFrame(iterator.initialFrame);
1660
+ }
1662
1661
  return;
1663
1662
  }
1664
1663
  if (videoFrameIterator.isDestroyed()) {
@@ -1817,14 +1816,15 @@ class MediaPlayer {
1817
1816
  this.onVideoFrameCallback = onVideoFrameCallback;
1818
1817
  this.playing = playing;
1819
1818
  this.sequenceOffset = sequenceOffset;
1820
- const { input, cacheKey } = acquireSharedInput({
1819
+ const { input, getDuration, release } = acquireSharedInput({
1821
1820
  src: this.src,
1822
1821
  credentials,
1823
1822
  requestInit,
1824
1823
  logLevel
1825
1824
  });
1826
1825
  this.input = input;
1827
- this.inputCacheKey = cacheKey;
1826
+ this.getDuration = getDuration;
1827
+ this.releaseInput = release;
1828
1828
  this.tagType = tagType;
1829
1829
  this.getEffects = getEffects;
1830
1830
  this.getEffectChainState = getEffectChainState;
@@ -1841,7 +1841,8 @@ class MediaPlayer {
1841
1841
  }
1842
1842
  }
1843
1843
  input;
1844
- inputCacheKey;
1844
+ getDuration;
1845
+ releaseInput;
1845
1846
  disposed = false;
1846
1847
  isDisposalError() {
1847
1848
  return this.disposed || this.input.disposed === true;
@@ -1892,11 +1893,11 @@ class MediaPlayer {
1892
1893
  if (isNetworkError(err)) {
1893
1894
  throw error;
1894
1895
  }
1895
- Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Failed to recognize format for ${this.src}`, error);
1896
+ Internals7.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Failed to recognize format for ${this.src}`, error);
1896
1897
  return { type: "unknown-container-format" };
1897
1898
  }
1898
1899
  const [durationInSeconds, videoTrack, audioTracks] = await Promise.all([
1899
- getDurationOrCompute(this.input),
1900
+ this.getDuration(),
1900
1901
  this.input.getPrimaryVideoTrack(),
1901
1902
  this.input.getAudioTracks()
1902
1903
  ]);
@@ -1995,16 +1996,16 @@ class MediaPlayer {
1995
1996
  if (this.isDisposalError()) {
1996
1997
  return { type: "disposed" };
1997
1998
  }
1998
- Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to start audio and video iterators", error);
1999
+ Internals7.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to start audio and video iterators", error);
1999
2000
  }
2000
2001
  return { type: "success", durationInSeconds };
2001
2002
  } catch (error) {
2002
2003
  const err = error;
2003
2004
  if (isNetworkError(err)) {
2004
- Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Network/CORS error for ${this.src}`, err);
2005
+ Internals7.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Network/CORS error for ${this.src}`, err);
2005
2006
  return { type: "network-error" };
2006
2007
  }
2007
- Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to initialize", error);
2008
+ Internals7.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to initialize", error);
2008
2009
  throw error;
2009
2010
  }
2010
2011
  } catch (_catch) {
@@ -2188,7 +2189,7 @@ class MediaPlayer {
2188
2189
  this.nonceManager.createAsyncOperation();
2189
2190
  this.videoIteratorManager?.destroy();
2190
2191
  this.audioIteratorManager?.destroyIterator();
2191
- releaseSharedInput(this.inputCacheKey);
2192
+ this.releaseInput();
2192
2193
  }
2193
2194
  getTargetTime = (mediaTimestamp, currentTime) => {
2194
2195
  if (!this.sharedAudioContext) {
@@ -2302,7 +2303,7 @@ var callOnErrorAndResolve = ({
2302
2303
 
2303
2304
  // src/use-common-effects.ts
2304
2305
  import { useContext, useLayoutEffect } from "react";
2305
- import { Internals as Internals7 } from "remotion";
2306
+ import { Internals as Internals8 } from "remotion";
2306
2307
  var useCommonEffects = ({
2307
2308
  mediaPlayerRef,
2308
2309
  mediaPlayerReady,
@@ -2326,7 +2327,7 @@ var useCommonEffects = ({
2326
2327
  logLevel,
2327
2328
  label
2328
2329
  }) => {
2329
- const sharedAudioContext = useContext(Internals7.SharedAudioContext);
2330
+ const sharedAudioContext = useContext(Internals8.SharedAudioContext);
2330
2331
  useLayoutEffect(() => {
2331
2332
  const mediaPlayer = mediaPlayerRef.current;
2332
2333
  if (!mediaPlayer)
@@ -2444,7 +2445,7 @@ var useCommonEffects = ({
2444
2445
  if (!mediaPlayer || !mediaPlayerReady)
2445
2446
  return;
2446
2447
  mediaPlayer.seekTo(currentTime).catch(() => {});
2447
- Internals7.Log.trace({ logLevel, tag: "@remotion/media" }, `[${label}] Updating target time to ${currentTime.toFixed(3)}s`);
2448
+ Internals8.Log.trace({ logLevel, tag: "@remotion/media" }, `[${label}] Updating target time to ${currentTime.toFixed(3)}s`);
2448
2449
  }, [currentTime, logLevel, mediaPlayerReady, label, mediaPlayerRef]);
2449
2450
  };
2450
2451
 
@@ -2461,7 +2462,7 @@ var {
2461
2462
  warnAboutTooHighVolume,
2462
2463
  usePreload,
2463
2464
  SequenceContext
2464
- } = Internals8;
2465
+ } = Internals9;
2465
2466
  var AudioForPreviewAssertedShowing = ({
2466
2467
  src,
2467
2468
  playbackRate,
@@ -2494,7 +2495,7 @@ var AudioForPreviewAssertedShowing = ({
2494
2495
  const [mediaPlayerReady, setMediaPlayerReady] = useState(false);
2495
2496
  const [shouldFallbackToNativeAudio, setShouldFallbackToNativeAudio] = useState(false);
2496
2497
  const [playing] = Timeline.usePlayingState();
2497
- const { playbackRate: globalPlaybackRate } = Internals8.usePlaybackRate();
2498
+ const { playbackRate: globalPlaybackRate } = Internals9.usePlaybackRate();
2498
2499
  const sharedAudioContext = useContext2(SharedAudioContext);
2499
2500
  const buffer = useBufferState();
2500
2501
  const [playerMuted] = usePlayerMutedState();
@@ -2520,12 +2521,12 @@ var AudioForPreviewAssertedShowing = ({
2520
2521
  const isPremounting = Boolean(parentSequence?.premounting);
2521
2522
  const isPostmounting = Boolean(parentSequence?.postmounting);
2522
2523
  const sequenceOffset = (parentSequence?.absoluteFrom ?? 0) / videoConfig.fps;
2523
- const bufferingContext = useContext2(Internals8.BufferingContextReact);
2524
+ const bufferingContext = useContext2(Internals9.BufferingContextReact);
2524
2525
  if (!bufferingContext) {
2525
2526
  throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
2526
2527
  }
2527
2528
  const effectiveMuted = muted || playerMuted || userPreferredVolume <= 0;
2528
- const isPlayerBuffering = Internals8.useIsPlayerBuffering(bufferingContext);
2529
+ const isPlayerBuffering = Internals9.useIsPlayerBuffering(bufferingContext);
2529
2530
  const initialPlaying = useRef(playing && !isPlayerBuffering);
2530
2531
  const initialIsPremounting = useRef(isPremounting);
2531
2532
  const initialIsPostmounting = useRef(isPostmounting);
@@ -2621,7 +2622,7 @@ var AudioForPreviewAssertedShowing = ({
2621
2622
  if (action === "fail") {
2622
2623
  throw errorToUse;
2623
2624
  } else {
2624
- Internals8.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
2625
+ Internals9.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
2625
2626
  setShouldFallbackToNativeAudio(true);
2626
2627
  }
2627
2628
  };
@@ -2647,7 +2648,7 @@ var AudioForPreviewAssertedShowing = ({
2647
2648
  if (result.type === "success") {
2648
2649
  setMediaPlayerReady(true);
2649
2650
  setMediaDurationInSeconds(result.durationInSeconds);
2650
- Internals8.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] MediaPlayer initialized successfully`);
2651
+ Internals9.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] MediaPlayer initialized successfully`);
2651
2652
  }
2652
2653
  }).catch((error) => {
2653
2654
  const [action, errorToUse] = callOnErrorAndResolve({
@@ -2660,7 +2661,7 @@ var AudioForPreviewAssertedShowing = ({
2660
2661
  if (action === "fail") {
2661
2662
  throw errorToUse;
2662
2663
  } else {
2663
- Internals8.Log.error({ logLevel, tag: "@remotion/media" }, "[AudioForPreview] Failed to initialize MediaPlayer", error);
2664
+ Internals9.Log.error({ logLevel, tag: "@remotion/media" }, "[AudioForPreview] Failed to initialize MediaPlayer", error);
2664
2665
  setShouldFallbackToNativeAudio(true);
2665
2666
  }
2666
2667
  });
@@ -2675,12 +2676,12 @@ var AudioForPreviewAssertedShowing = ({
2675
2676
  if (action === "fail") {
2676
2677
  throw errorToUse;
2677
2678
  }
2678
- Internals8.Log.error({ logLevel, tag: "@remotion/media" }, "[AudioForPreview] MediaPlayer initialization failed", errorToUse);
2679
+ Internals9.Log.error({ logLevel, tag: "@remotion/media" }, "[AudioForPreview] MediaPlayer initialization failed", errorToUse);
2679
2680
  setShouldFallbackToNativeAudio(true);
2680
2681
  }
2681
2682
  return () => {
2682
2683
  if (mediaPlayerRef.current) {
2683
- Internals8.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] Disposing MediaPlayer`);
2684
+ Internals9.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] Disposing MediaPlayer`);
2684
2685
  mediaPlayerRef.current.dispose();
2685
2686
  mediaPlayerRef.current = null;
2686
2687
  }
@@ -2748,7 +2749,7 @@ var AudioForPreview = ({
2748
2749
  style
2749
2750
  }) => {
2750
2751
  const preloadedSrc = usePreload(src);
2751
- const defaultLogLevel = Internals8.useLogLevel();
2752
+ const defaultLogLevel = Internals9.useLogLevel();
2752
2753
  const frame = useCurrentFrame();
2753
2754
  const videoConfig = useVideoConfig();
2754
2755
  const currentTime = frame / videoConfig.fps;
@@ -2809,7 +2810,7 @@ import { useContext as useContext3, useLayoutEffect as useLayoutEffect2, useMemo
2809
2810
  import {
2810
2811
  cancelRender as cancelRender2,
2811
2812
  Html5Audio,
2812
- Internals as Internals17,
2813
+ Internals as Internals18,
2813
2814
  random,
2814
2815
  useCurrentFrame as useCurrentFrame2,
2815
2816
  useDelayRender,
@@ -2818,10 +2819,10 @@ import {
2818
2819
 
2819
2820
  // src/caches.ts
2820
2821
  import React2 from "react";
2821
- import { Internals as Internals15 } from "remotion";
2822
+ import { Internals as Internals16 } from "remotion";
2822
2823
 
2823
2824
  // src/audio-extraction/audio-manager.ts
2824
- import { Internals as Internals10 } from "remotion";
2825
+ import { Internals as Internals11 } from "remotion";
2825
2826
 
2826
2827
  // src/serialized-queue.ts
2827
2828
  var makeSerializedQueue = () => {
@@ -2838,7 +2839,7 @@ var makeSerializedQueue = () => {
2838
2839
  };
2839
2840
 
2840
2841
  // src/audio-extraction/audio-iterator.ts
2841
- import { Internals as Internals9 } from "remotion";
2842
+ import { Internals as Internals10 } from "remotion";
2842
2843
 
2843
2844
  // src/audio-extraction/audio-cache.ts
2844
2845
  var BYTES_PER_SAMPLE = {
@@ -2938,7 +2939,7 @@ var warnAboutMatroskaOnce = (src, logLevel) => {
2938
2939
  return;
2939
2940
  }
2940
2941
  warned[src] = true;
2941
- Internals9.Log.warn({ logLevel, tag: "@remotion/media" }, `Audio from ${src} will need to be read from the beginning. https://www.remotion.dev/docs/media/support#matroska-limitation`);
2942
+ Internals10.Log.warn({ logLevel, tag: "@remotion/media" }, `Audio from ${src} will need to be read from the beginning. https://www.remotion.dev/docs/media/support#matroska-limitation`);
2942
2943
  };
2943
2944
  var makeAudioIterator2 = ({
2944
2945
  audioSampleSink,
@@ -3006,7 +3007,7 @@ var makeAudioIterator2 = ({
3006
3007
  if (openTimestamps.length > 0) {
3007
3008
  const first = openTimestamps[0];
3008
3009
  const last = openTimestamps[openTimestamps.length - 1];
3009
- Internals9.Log.verbose({ logLevel, tag: "@remotion/media" }, "Open audio samples for src", src, `${first.toFixed(3)}...${last.toFixed(3)}`);
3010
+ Internals10.Log.verbose({ logLevel, tag: "@remotion/media" }, "Open audio samples for src", src, `${first.toFixed(3)}...${last.toFixed(3)}`);
3010
3011
  }
3011
3012
  };
3012
3013
  const getCacheStats = () => {
@@ -3106,7 +3107,7 @@ var makeAudioManager = ({
3106
3107
  if (seenKeys.has(key)) {
3107
3108
  iterator.prepareForDeletion();
3108
3109
  iterators.splice(iterators.indexOf(iterator), 1);
3109
- Internals10.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted duplicate iterator for ${iterator.src}`);
3110
+ Internals11.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted duplicate iterator for ${iterator.src}`);
3110
3111
  }
3111
3112
  seenKeys.add(key);
3112
3113
  }
@@ -3130,7 +3131,7 @@ var makeAudioManager = ({
3130
3131
  attempts++;
3131
3132
  }
3132
3133
  if ((await getTotalCacheStats()).totalSize > maxCacheSize && attempts >= maxAttempts) {
3133
- Internals10.Log.warn({ logLevel, tag: "@remotion/media" }, `Audio cache: Exceeded max cache size after ${maxAttempts} attempts. Still ${(await getTotalCacheStats()).totalSize} bytes used, target was ${maxCacheSize} bytes.`);
3134
+ Internals11.Log.warn({ logLevel, tag: "@remotion/media" }, `Audio cache: Exceeded max cache size after ${maxAttempts} attempts. Still ${(await getTotalCacheStats()).totalSize} bytes used, target was ${maxCacheSize} bytes.`);
3134
3135
  }
3135
3136
  for (const iterator of iterators) {
3136
3137
  if (iterator.src === src && await iterator.waitForCompletion() && iterator.canSatisfyRequestedTime(timeInSeconds)) {
@@ -3216,7 +3217,7 @@ var makeAudioManager = ({
3216
3217
  };
3217
3218
 
3218
3219
  // src/get-sink.ts
3219
- import { Internals as Internals12 } from "remotion";
3220
+ import { Internals as Internals13 } from "remotion";
3220
3221
 
3221
3222
  // src/video-extraction/get-frames-since-keyframe.ts
3222
3223
  import {
@@ -3229,7 +3230,7 @@ import {
3229
3230
  VideoSampleSink,
3230
3231
  WEBM
3231
3232
  } from "mediabunny";
3232
- import { Internals as Internals11 } from "remotion";
3233
+ import { Internals as Internals12 } from "remotion";
3233
3234
 
3234
3235
  // src/browser-can-use-webgl2.ts
3235
3236
  var browserCanUseWebGl2 = null;
@@ -3325,7 +3326,7 @@ var makeSinks = (src, logLevel, credentials, requestInit) => {
3325
3326
  });
3326
3327
  const hasAlpha = startPacket?.sideData.alpha;
3327
3328
  if (hasAlpha && !canBrowserUseWebGl2()) {
3328
- Internals11.Log.warn({ logLevel, tag: "@remotion/media" }, `WebGL2 is not available, using the non-fast CPU path to decode alpha for ${src}.`);
3329
+ Internals12.Log.warn({ logLevel, tag: "@remotion/media" }, `WebGL2 is not available, using the non-fast CPU path to decode alpha for ${src}.`);
3329
3330
  }
3330
3331
  return {
3331
3332
  sampleSink
@@ -3418,7 +3419,7 @@ var makeSinkManager = () => {
3418
3419
  });
3419
3420
  let promise = sinkPromises[cacheKey];
3420
3421
  if (!promise) {
3421
- Internals12.Log.verbose({
3422
+ Internals13.Log.verbose({
3422
3423
  logLevel,
3423
3424
  tag: "@remotion/media"
3424
3425
  }, `Sink for ${src} was not found, creating new sink`);
@@ -3453,7 +3454,7 @@ var makeSinkManager = () => {
3453
3454
  };
3454
3455
 
3455
3456
  // src/video-extraction/keyframe-manager.ts
3456
- import { Internals as Internals14 } from "remotion";
3457
+ import { Internals as Internals15 } from "remotion";
3457
3458
 
3458
3459
  // src/render-timestamp-range.ts
3459
3460
  var renderTimestampRange = (timestamps) => {
@@ -3467,7 +3468,7 @@ var renderTimestampRange = (timestamps) => {
3467
3468
  };
3468
3469
 
3469
3470
  // src/video-extraction/keyframe-bank.ts
3470
- import { Internals as Internals13 } from "remotion";
3471
+ import { Internals as Internals14 } from "remotion";
3471
3472
 
3472
3473
  // src/video-extraction/get-allocation-size.ts
3473
3474
  var BYTES_PER_PIXEL_FOR_OPAQUE_FRAME = 3;
@@ -3548,7 +3549,7 @@ var makeKeyframeBank = async ({
3548
3549
  }
3549
3550
  }
3550
3551
  if (deletedTimestamps.length > 0) {
3551
- Internals13.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted ${deletedTimestamps.length} frame${deletedTimestamps.length === 1 ? "" : "s"} ${renderTimestampRange(deletedTimestamps)} for src ${src} because it is lower than ${timestampInSeconds}. Remaining: ${renderTimestampRange(frameTimestamps)}`);
3552
+ Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted ${deletedTimestamps.length} frame${deletedTimestamps.length === 1 ? "" : "s"} ${renderTimestampRange(deletedTimestamps)} for src ${src} because it is lower than ${timestampInSeconds}. Remaining: ${renderTimestampRange(frameTimestamps)}`);
3552
3553
  }
3553
3554
  };
3554
3555
  const hasDecodedEnoughForTimestamp = (timestamp) => {
@@ -3577,7 +3578,7 @@ var makeKeyframeBank = async ({
3577
3578
  frameTimestamps.push(frame.timestamp);
3578
3579
  allocationSize += getAllocationSize(frame);
3579
3580
  lastUsed = Date.now();
3580
- Internals13.Log.trace({ logLevel, tag: "@remotion/media" }, `Added frame at ${frame.timestamp}sec to bank`);
3581
+ Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, `Added frame at ${frame.timestamp}sec to bank`);
3581
3582
  };
3582
3583
  const ensureEnoughFramesForTimestamp = async (timestampInSeconds, logLevel, fps) => {
3583
3584
  while (!hasDecodedEnoughForTimestamp(timestampInSeconds)) {
@@ -3632,7 +3633,7 @@ var makeKeyframeBank = async ({
3632
3633
  throw new Error("No first frame found");
3633
3634
  }
3634
3635
  const startTimestampInSeconds = firstFrame.value.timestamp;
3635
- Internals13.Log.verbose({ logLevel: parentLogLevel, tag: "@remotion/media" }, `Creating keyframe bank from ${startTimestampInSeconds}sec`);
3636
+ Internals14.Log.verbose({ logLevel: parentLogLevel, tag: "@remotion/media" }, `Creating keyframe bank from ${startTimestampInSeconds}sec`);
3636
3637
  addFrame(firstFrame.value, parentLogLevel);
3637
3638
  const getRangeOfTimestamps = () => {
3638
3639
  if (frameTimestamps.length === 0) {
@@ -3649,7 +3650,7 @@ var makeKeyframeBank = async ({
3649
3650
  const prepareForDeletion = (logLevel, reason) => {
3650
3651
  const range = getRangeOfTimestamps();
3651
3652
  if (range) {
3652
- Internals13.Log.verbose({ logLevel, tag: "@remotion/media" }, `Preparing for deletion (${reason}) of keyframe bank from ${range?.firstTimestamp}sec to ${range?.lastTimestamp}sec`);
3653
+ Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Preparing for deletion (${reason}) of keyframe bank from ${range?.firstTimestamp}sec to ${range?.lastTimestamp}sec`);
3653
3654
  }
3654
3655
  let framesDeleted = 0;
3655
3656
  for (const frameTimestamp of frameTimestamps.slice()) {
@@ -3747,10 +3748,10 @@ var makeKeyframeManager = ({
3747
3748
  if (size === 0) {
3748
3749
  continue;
3749
3750
  }
3750
- Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Open frames for src ${src}: ${renderTimestampRange(timestamps)}`);
3751
+ Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Open frames for src ${src}: ${renderTimestampRange(timestamps)}`);
3751
3752
  }
3752
3753
  }
3753
- Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Video cache stats: ${count} open frames, ${totalSize} bytes`);
3754
+ Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Video cache stats: ${count} open frames, ${totalSize} bytes`);
3754
3755
  };
3755
3756
  const getCacheStats = () => {
3756
3757
  let count = 0;
@@ -3800,7 +3801,7 @@ var makeKeyframeManager = ({
3800
3801
  const { framesDeleted } = bank.prepareForDeletion(logLevel, "deleted oldest keyframe bank to stay under max cache size");
3801
3802
  sources[src].splice(index, 1);
3802
3803
  if (range) {
3803
- Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted ${framesDeleted} frames for src ${src} from ${range?.firstTimestamp}sec to ${range?.lastTimestamp}sec to free up memory.`);
3804
+ Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted ${framesDeleted} frames for src ${src} from ${range?.firstTimestamp}sec to ${range?.lastTimestamp}sec to free up memory.`);
3804
3805
  }
3805
3806
  return { finish: false };
3806
3807
  };
@@ -3813,12 +3814,12 @@ var makeKeyframeManager = ({
3813
3814
  if (finish) {
3814
3815
  break;
3815
3816
  }
3816
- Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, "Deleted oldest keyframe bank to stay under max cache size", (cacheStats.totalSize / 1024 / 1024).toFixed(1), "out of", (maxCacheSize / 1024 / 1024).toFixed(1));
3817
+ Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, "Deleted oldest keyframe bank to stay under max cache size", (cacheStats.totalSize / 1024 / 1024).toFixed(1), "out of", (maxCacheSize / 1024 / 1024).toFixed(1));
3817
3818
  cacheStats = getTotalCacheStats();
3818
3819
  attempts++;
3819
3820
  }
3820
3821
  if (cacheStats.totalSize > maxCacheSize && attempts >= maxAttempts) {
3821
- Internals14.Log.warn({ logLevel, tag: "@remotion/media" }, `Exceeded max cache size after ${maxAttempts} attempts. Remaining cache size: ${(cacheStats.totalSize / 1024 / 1024).toFixed(1)} MB, target was ${(maxCacheSize / 1024 / 1024).toFixed(1)} MB.`);
3822
+ Internals15.Log.warn({ logLevel, tag: "@remotion/media" }, `Exceeded max cache size after ${maxAttempts} attempts. Remaining cache size: ${(cacheStats.totalSize / 1024 / 1024).toFixed(1)} MB, target was ${(maxCacheSize / 1024 / 1024).toFixed(1)} MB.`);
3822
3823
  }
3823
3824
  };
3824
3825
  const clearKeyframeBanksBeforeTime = ({
@@ -3847,7 +3848,7 @@ var makeKeyframeManager = ({
3847
3848
  }
3848
3849
  if (range.lastTimestamp < threshold) {
3849
3850
  bank.prepareForDeletion(logLevel, "cleared before threshold " + threshold);
3850
- Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `[Video] Cleared frames for src ${src} from ${range.firstTimestamp}sec to ${range.lastTimestamp}sec`);
3851
+ Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `[Video] Cleared frames for src ${src} from ${range.firstTimestamp}sec to ${range.lastTimestamp}sec`);
3851
3852
  const bankIndex = banks.indexOf(bank);
3852
3853
  delete sources[src][bankIndex];
3853
3854
  } else {
@@ -3869,7 +3870,7 @@ var makeKeyframeManager = ({
3869
3870
  const existingBanks = sources[src] ?? [];
3870
3871
  const existingBank = existingBanks?.find((bank) => bank.canSatisfyTimestamp(timestamp));
3871
3872
  if (!existingBank) {
3872
- Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, `Creating new keyframe bank for src ${src} at timestamp ${timestamp}`);
3873
+ Internals15.Log.trace({ logLevel, tag: "@remotion/media" }, `Creating new keyframe bank for src ${src} at timestamp ${timestamp}`);
3873
3874
  const newKeyframeBank = await makeKeyframeBank({
3874
3875
  videoSampleSink,
3875
3876
  logLevel,
@@ -3882,10 +3883,10 @@ var makeKeyframeManager = ({
3882
3883
  return newKeyframeBank;
3883
3884
  }
3884
3885
  if (existingBank.canSatisfyTimestamp(timestamp)) {
3885
- Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, `Keyframe bank exists and satisfies timestamp ${timestamp}`);
3886
+ Internals15.Log.trace({ logLevel, tag: "@remotion/media" }, `Keyframe bank exists and satisfies timestamp ${timestamp}`);
3886
3887
  return existingBank;
3887
3888
  }
3888
- Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Keyframe bank exists but frame at time ${timestamp} does not exist anymore.`);
3889
+ Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Keyframe bank exists but frame at time ${timestamp} does not exist anymore.`);
3889
3890
  existingBank.prepareForDeletion(logLevel, "already existed but evicted");
3890
3891
  sources[src] = sources[src].filter((bank) => bank !== existingBank);
3891
3892
  const replacementKeybank = await makeKeyframeBank({
@@ -4031,7 +4032,7 @@ var makeMediaCache = () => {
4031
4032
  };
4032
4033
  var globalMediaCache = makeMediaCache();
4033
4034
  var useRenderMediaCache = (logLevel) => {
4034
- const renderResourceManager = React2.useContext(Internals15.RenderResourceManagerContext);
4035
+ const renderResourceManager = React2.useContext(Internals16.RenderResourceManagerContext);
4035
4036
  if (renderResourceManager === null) {
4036
4037
  return globalMediaCache;
4037
4038
  }
@@ -4047,7 +4048,7 @@ var useRenderMediaCache = (logLevel) => {
4047
4048
  });
4048
4049
  };
4049
4050
  var useMaxMediaCacheSize = (logLevel) => {
4050
- const context = React2.useContext(Internals15.MaxMediaCacheSizeContext);
4051
+ const context = React2.useContext(Internals16.MaxMediaCacheSizeContext);
4051
4052
  if (context === null) {
4052
4053
  return getMaxVideoCacheSize(logLevel);
4053
4054
  }
@@ -4088,6 +4089,9 @@ var fixFloatingPoint = (value) => {
4088
4089
  }
4089
4090
  return value;
4090
4091
  };
4092
+ var clampToS16 = (value) => {
4093
+ return Math.max(-32768, Math.min(32767, value));
4094
+ };
4091
4095
  var resampleAudioData = ({
4092
4096
  srcNumberOfChannels,
4093
4097
  sourceChannels,
@@ -4148,13 +4152,14 @@ var resampleAudioData = ({
4148
4152
  const l = getSourceValues(start, end, 0);
4149
4153
  const r = getSourceValues(start, end, 1);
4150
4154
  const c = getSourceValues(start, end, 2);
4151
- const sl = getSourceValues(start, end, 3);
4152
- const sr = getSourceValues(start, end, 4);
4155
+ const sl = getSourceValues(start, end, 4);
4156
+ const sr = getSourceValues(start, end, 5);
4153
4157
  const sq = Math.sqrt(1 / 2);
4154
- const l2 = l + sq * (c + sl);
4155
- const r2 = r + sq * (c + sr);
4156
- destination[newFrameIndex * 2 + 0] = l2;
4157
- destination[newFrameIndex * 2 + 1] = r2;
4158
+ const norm = 1 / (1 + sq + sq);
4159
+ const l2 = (l + sq * (c + sl)) * norm;
4160
+ const r2 = (r + sq * (c + sr)) * norm;
4161
+ destination[newFrameIndex * 2 + 0] = clampToS16(l2);
4162
+ destination[newFrameIndex * 2 + 1] = clampToS16(r2);
4158
4163
  } else {
4159
4164
  for (let i = 0;i < srcNumberOfChannels; i++) {
4160
4165
  destination[newFrameIndex * TARGET_NUMBER_OF_CHANNELS + i] = getSourceValues(start, end, i);
@@ -4455,7 +4460,7 @@ var extractAudio = (params) => {
4455
4460
  };
4456
4461
 
4457
4462
  // src/video-extraction/extract-frame.ts
4458
- import { Internals as Internals16 } from "remotion";
4463
+ import { Internals as Internals17 } from "remotion";
4459
4464
  var extractFrameInternal = async ({
4460
4465
  src,
4461
4466
  timeInSeconds: unloopedTimeInSeconds,
@@ -4545,7 +4550,7 @@ var extractFrameInternal = async ({
4545
4550
  durationInSeconds: await sink.getDuration()
4546
4551
  };
4547
4552
  } catch (err) {
4548
- Internals16.Log.info({ logLevel, tag: "@remotion/media" }, `Error decoding ${src} at time ${timeInSeconds}: ${err}`, err);
4553
+ Internals17.Log.info({ logLevel, tag: "@remotion/media" }, `Error decoding ${src} at time ${timeInSeconds}: ${err}`, err);
4549
4554
  return { type: "cannot-decode", durationInSeconds: mediaDurationInSeconds };
4550
4555
  }
4551
4556
  };
@@ -4784,7 +4789,11 @@ var addBroadcastChannelListener = () => {
4784
4789
  audio,
4785
4790
  durationInSeconds: durationInSeconds ?? null
4786
4791
  };
4787
- window.remotion_broadcastChannel.postMessage(response);
4792
+ try {
4793
+ window.remotion_broadcastChannel.postMessage(response);
4794
+ } finally {
4795
+ imageBitmap?.close();
4796
+ }
4788
4797
  } catch (error) {
4789
4798
  const response = {
4790
4799
  type: "response-error",
@@ -4984,13 +4993,13 @@ var AudioForRendering = ({
4984
4993
  credentials,
4985
4994
  requestInit
4986
4995
  }) => {
4987
- const defaultLogLevel = Internals17.useLogLevel();
4996
+ const defaultLogLevel = Internals18.useLogLevel();
4988
4997
  const logLevel = overriddenLogLevel ?? defaultLogLevel;
4989
4998
  const frame = useCurrentFrame2();
4990
- const absoluteFrame = Internals17.useTimelinePosition();
4991
- const videoConfig = Internals17.useUnsafeVideoConfig();
4992
- const { registerRenderAsset, unregisterRenderAsset } = useContext3(Internals17.RenderAssetManager);
4993
- const startsAt = Internals17.useMediaStartsAt();
4999
+ const absoluteFrame = Internals18.useTimelinePosition();
5000
+ const videoConfig = Internals18.useUnsafeVideoConfig();
5001
+ const { registerRenderAsset, unregisterRenderAsset } = useContext3(Internals18.RenderAssetManager);
5002
+ const startsAt = Internals18.useMediaStartsAt();
4994
5003
  const environment = useRemotionEnvironment();
4995
5004
  if (!videoConfig) {
4996
5005
  throw new Error("No video config found");
@@ -5002,7 +5011,7 @@ var AudioForRendering = ({
5002
5011
  const { delayRender, continueRender } = useDelayRender();
5003
5012
  const [replaceWithHtml5Audio, setReplaceWithHtml5Audio] = useState2(false);
5004
5013
  const [initialRequestInit] = useState2(requestInit);
5005
- const sequenceContext = useContext3(Internals17.SequenceContext);
5014
+ const sequenceContext = useContext3(Internals18.SequenceContext);
5006
5015
  const id = useMemo2(() => `media-audio-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
5007
5016
  src,
5008
5017
  sequenceContext?.cumulatedFrom,
@@ -5011,7 +5020,7 @@ var AudioForRendering = ({
5011
5020
  ]);
5012
5021
  const maxCacheSize = useMaxMediaCacheSize(logLevel);
5013
5022
  const mediaCache = useRenderMediaCache(logLevel);
5014
- const audioEnabled = Internals17.useAudioEnabled();
5023
+ const audioEnabled = Internals18.useAudioEnabled();
5015
5024
  useLayoutEffect2(() => {
5016
5025
  const timestamp = frame / fps;
5017
5026
  const durationInSeconds = 1 / fps;
@@ -5067,7 +5076,7 @@ var AudioForRendering = ({
5067
5076
  if (action === "fail") {
5068
5077
  cancelRender2(errorToUse);
5069
5078
  }
5070
- Internals17.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5079
+ Internals18.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5071
5080
  setReplaceWithHtml5Audio(true);
5072
5081
  };
5073
5082
  if (result.type === "unknown-container-format") {
@@ -5097,12 +5106,12 @@ var AudioForRendering = ({
5097
5106
  frame,
5098
5107
  startsAt
5099
5108
  });
5100
- const volume = Internals17.evaluateVolume({
5109
+ const volume = Internals18.evaluateVolume({
5101
5110
  volume: volumeProp,
5102
5111
  frame: volumePropsFrame,
5103
5112
  mediaVolume: 1
5104
5113
  });
5105
- Internals17.warnAboutTooHighVolume(volume);
5114
+ Internals18.warnAboutTooHighVolume(volume);
5106
5115
  if (audio && volume > 0) {
5107
5116
  applyVolume(audio.data, volume);
5108
5117
  registerRenderAsset({
@@ -5185,7 +5194,7 @@ var AudioForRendering = ({
5185
5194
 
5186
5195
  // src/audio/audio.tsx
5187
5196
  import { jsx as jsx3 } from "react/jsx-runtime";
5188
- var { validateMediaProps } = Internals18;
5197
+ var { validateMediaProps } = Internals19;
5189
5198
  var audioSchema = {
5190
5199
  src: {
5191
5200
  type: "asset",
@@ -5193,8 +5202,8 @@ var audioSchema = {
5193
5202
  description: "Source",
5194
5203
  keyframable: false
5195
5204
  },
5196
- ...Internals18.baseSchema,
5197
- ...Internals18.premountSchema,
5205
+ ...Internals19.baseSchema,
5206
+ ...Internals19.premountSchema,
5198
5207
  volume: {
5199
5208
  type: "number",
5200
5209
  min: 0,
@@ -5231,12 +5240,12 @@ var AudioInner = (props) => {
5231
5240
  ...otherProps
5232
5241
  } = props;
5233
5242
  const environment = useRemotionEnvironment2();
5234
- const sourceStack = controls ? Internals18.getStackForControls(controls) : null;
5235
- const [mediaVolume] = Internals18.useMediaVolumeState();
5236
- const mediaStartsAt = Internals18.useMediaStartsAt();
5243
+ const sourceStack = controls ? Internals19.getStackForControls(controls) : null;
5244
+ const [mediaVolume] = Internals19.useMediaVolumeState();
5245
+ const mediaStartsAt = Internals19.useMediaStartsAt();
5237
5246
  const videoConfig = useVideoConfig2();
5238
5247
  const sequenceDurationInFrames = Math.min(durationInFrames ?? Infinity, Math.max(0, videoConfig.durationInFrames - (from ?? 0)));
5239
- const basicInfo = Internals18.useBasicMediaInTimeline({
5248
+ const basicInfo = Internals19.useBasicMediaInTimeline({
5240
5249
  src: props.src,
5241
5250
  volume: props.volume,
5242
5251
  playbackRate: props.playbackRate ?? 1,
@@ -5280,7 +5289,7 @@ var AudioInner = (props) => {
5280
5289
  postmountingActive,
5281
5290
  premountingActive,
5282
5291
  premountingStyle
5283
- } = Internals18.usePremounting({
5292
+ } = Internals19.usePremounting({
5284
5293
  from: from ?? 0,
5285
5294
  durationInFrames: basicInfo.duration,
5286
5295
  premountFor: premountFor ?? null,
@@ -5341,7 +5350,7 @@ var Audio = Interactive.withSchema({
5341
5350
  import React6, { useMemo as useMemo6, useState as useState6 } from "react";
5342
5351
  import {
5343
5352
  Freeze as Freeze2,
5344
- Internals as Internals23,
5353
+ Internals as Internals24,
5345
5354
  Interactive as Interactive2,
5346
5355
  Sequence as Sequence2,
5347
5356
  useRemotionEnvironment as useRemotionEnvironment4,
@@ -5349,7 +5358,7 @@ import {
5349
5358
  } from "remotion";
5350
5359
 
5351
5360
  // src/video/get-video-sequence-duration.ts
5352
- import { Internals as Internals19 } from "remotion";
5361
+ import { Internals as Internals20 } from "remotion";
5353
5362
  var getVideoSequenceDuration = ({
5354
5363
  durationInFrames,
5355
5364
  loop,
@@ -5360,7 +5369,7 @@ var getVideoSequenceDuration = ({
5360
5369
  if (loop || trimAfter === undefined) {
5361
5370
  return durationInFrames;
5362
5371
  }
5363
- const trimmedDuration = Internals19.calculateMediaDuration({
5372
+ const trimmedDuration = Internals20.calculateMediaDuration({
5364
5373
  trimAfter,
5365
5374
  trimBefore,
5366
5375
  playbackRate,
@@ -5381,7 +5390,7 @@ import {
5381
5390
  } from "react";
5382
5391
  import {
5383
5392
  Html5Video,
5384
- Internals as Internals21,
5393
+ Internals as Internals22,
5385
5394
  useBufferState as useBufferState2,
5386
5395
  useCurrentFrame as useCurrentFrame3,
5387
5396
  useVideoConfig as useVideoConfig3
@@ -5424,7 +5433,7 @@ var getCachedVideoFrame = (src) => {
5424
5433
  };
5425
5434
 
5426
5435
  // src/video/warn-object-fit-css.ts
5427
- import { Internals as Internals20 } from "remotion";
5436
+ import { Internals as Internals21 } from "remotion";
5428
5437
  var OBJECT_FIT_CLASS_PATTERN = /\bobject-(contain|cover|fill|none|scale-down)\b/;
5429
5438
  var warnedStyle = false;
5430
5439
  var warnedClassName = false;
@@ -5435,11 +5444,11 @@ var warnAboutObjectFitInStyleOrClassName = ({
5435
5444
  }) => {
5436
5445
  if (!warnedStyle && style?.objectFit) {
5437
5446
  warnedStyle = true;
5438
- Internals20.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of the `style` prop.");
5447
+ Internals21.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of the `style` prop.");
5439
5448
  }
5440
5449
  if (!warnedClassName && className && OBJECT_FIT_CLASS_PATTERN.test(className)) {
5441
5450
  warnedClassName = true;
5442
- Internals20.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of `object-*` CSS class names.");
5451
+ Internals21.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of `object-*` CSS class names.");
5443
5452
  }
5444
5453
  };
5445
5454
 
@@ -5457,7 +5466,7 @@ var {
5457
5466
  usePreload: usePreload2,
5458
5467
  SequenceContext: SequenceContext2,
5459
5468
  useEffectChainState
5460
- } = Internals21;
5469
+ } = Internals22;
5461
5470
  var VideoForPreviewAssertedShowing = ({
5462
5471
  src: unpreloadedSrc,
5463
5472
  style,
@@ -5500,7 +5509,7 @@ var VideoForPreviewAssertedShowing = ({
5500
5509
  const [mediaPlayerReady, setMediaPlayerReady] = useState4(false);
5501
5510
  const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState4(false);
5502
5511
  const [playing] = Timeline2.usePlayingState();
5503
- const { playbackRate: globalPlaybackRate } = Internals21.usePlaybackRate();
5512
+ const { playbackRate: globalPlaybackRate } = Internals22.usePlaybackRate();
5504
5513
  const sharedAudioContext = useContext4(SharedAudioContext2);
5505
5514
  const buffer = useBufferState2();
5506
5515
  const canvasRefCallback = useCallback((canvas) => {
@@ -5537,12 +5546,12 @@ var VideoForPreviewAssertedShowing = ({
5537
5546
  const currentTimeRef = useRef2(currentTime);
5538
5547
  currentTimeRef.current = currentTime;
5539
5548
  const preloadedSrc = usePreload2(src);
5540
- const buffering = useContext4(Internals21.BufferingContextReact);
5549
+ const buffering = useContext4(Internals22.BufferingContextReact);
5541
5550
  if (!buffering) {
5542
5551
  throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
5543
5552
  }
5544
5553
  const effectiveMuted = muted || playerMuted || userPreferredVolume <= 0;
5545
- const isPlayerBuffering = Internals21.useIsPlayerBuffering(buffering);
5554
+ const isPlayerBuffering = Internals22.useIsPlayerBuffering(buffering);
5546
5555
  const initialPlaying = useRef2(playing && !isPlayerBuffering);
5547
5556
  const initialIsPremounting = useRef2(isPremounting);
5548
5557
  const initialIsPostmounting = useRef2(isPostmounting);
@@ -5639,7 +5648,7 @@ var VideoForPreviewAssertedShowing = ({
5639
5648
  if (action === "fail") {
5640
5649
  throw errorToUse;
5641
5650
  }
5642
- Internals21.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5651
+ Internals22.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5643
5652
  setShouldFallbackToNativeVideo(true);
5644
5653
  };
5645
5654
  if (result.type === "unknown-container-format") {
@@ -5681,7 +5690,7 @@ var VideoForPreviewAssertedShowing = ({
5681
5690
  if (action === "fail") {
5682
5691
  throw errorToUse;
5683
5692
  }
5684
- Internals21.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", errorToUse);
5693
+ Internals22.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", errorToUse);
5685
5694
  setShouldFallbackToNativeVideo(true);
5686
5695
  });
5687
5696
  } catch (error) {
@@ -5695,12 +5704,12 @@ var VideoForPreviewAssertedShowing = ({
5695
5704
  if (action === "fail") {
5696
5705
  throw errorToUse;
5697
5706
  }
5698
- Internals21.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", errorToUse);
5707
+ Internals22.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", errorToUse);
5699
5708
  setShouldFallbackToNativeVideo(true);
5700
5709
  }
5701
5710
  return () => {
5702
5711
  if (mediaPlayerRef.current) {
5703
- Internals21.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
5712
+ Internals22.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
5704
5713
  mediaPlayerRef.current.dispose();
5705
5714
  mediaPlayerRef.current = null;
5706
5715
  }
@@ -5724,7 +5733,7 @@ var VideoForPreviewAssertedShowing = ({
5724
5733
  ]);
5725
5734
  warnAboutObjectFitInStyleOrClassName({ style, className, logLevel });
5726
5735
  const classNameValue = useMemo4(() => {
5727
- return [Internals21.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals21.truthy).join(" ");
5736
+ return [Internals22.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals22.truthy).join(" ");
5728
5737
  }, [className]);
5729
5738
  useCommonEffects({
5730
5739
  mediaPlayerRef,
@@ -5848,7 +5857,7 @@ import {
5848
5857
  useState as useState5
5849
5858
  } from "react";
5850
5859
  import {
5851
- Internals as Internals22,
5860
+ Internals as Internals23,
5852
5861
  Loop,
5853
5862
  random as random2,
5854
5863
  useCurrentFrame as useCurrentFrame4,
@@ -5889,11 +5898,11 @@ var VideoForRendering = ({
5889
5898
  throw new TypeError("No `src` was passed to <Video>.");
5890
5899
  }
5891
5900
  const frame = useCurrentFrame4();
5892
- const absoluteFrame = Internals22.useTimelinePosition();
5901
+ const absoluteFrame = Internals23.useTimelinePosition();
5893
5902
  const { fps } = useVideoConfig4();
5894
- const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals22.RenderAssetManager);
5895
- const startsAt = Internals22.useMediaStartsAt();
5896
- const sequenceContext = useContext5(Internals22.SequenceContext);
5903
+ const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals23.RenderAssetManager);
5904
+ const startsAt = Internals23.useMediaStartsAt();
5905
+ const sequenceContext = useContext5(Internals23.SequenceContext);
5897
5906
  const id = useMemo5(() => `media-video-${random2(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
5898
5907
  src,
5899
5908
  sequenceContext?.cumulatedFrom,
@@ -5905,11 +5914,11 @@ var VideoForRendering = ({
5905
5914
  const canvasRef = useRef3(null);
5906
5915
  const [replaceWithOffthreadVideo, setReplaceWithOffthreadVideo] = useState5(false);
5907
5916
  const [initialRequestInit] = useState5(requestInit);
5908
- const audioEnabled = Internals22.useAudioEnabled();
5909
- const videoEnabled = Internals22.useVideoEnabled();
5917
+ const audioEnabled = Internals23.useAudioEnabled();
5918
+ const videoEnabled = Internals23.useVideoEnabled();
5910
5919
  const maxCacheSize = useMaxMediaCacheSize(logLevel);
5911
5920
  const mediaCache = useRenderMediaCache(logLevel);
5912
- const effectChainState = Internals22.useEffectChainState();
5921
+ const effectChainState = Internals23.useEffectChainState();
5913
5922
  const [error, setError] = useState5(null);
5914
5923
  if (error) {
5915
5924
  throw error;
@@ -5981,7 +5990,7 @@ var VideoForRendering = ({
5981
5990
  return;
5982
5991
  }
5983
5992
  if (window.remotion_isMainTab) {
5984
- Internals22.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5993
+ Internals23.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
5985
5994
  }
5986
5995
  setReplaceWithOffthreadVideo({
5987
5996
  durationInSeconds: mediaDurationInSeconds
@@ -6025,7 +6034,7 @@ var VideoForRendering = ({
6025
6034
  context.canvas.style.aspectRatio = `${context.canvas.width} / ${context.canvas.height}`;
6026
6035
  context.drawImage(imageBitmap, 0, 0);
6027
6036
  if (effects.length > 0) {
6028
- const completed = await Internals22.runEffectChain({
6037
+ const completed = await Internals23.runEffectChain({
6029
6038
  state: effectChainState.get(imageBitmap.width, imageBitmap.height),
6030
6039
  source: context.canvas,
6031
6040
  effects,
@@ -6056,12 +6065,12 @@ var VideoForRendering = ({
6056
6065
  frame,
6057
6066
  startsAt
6058
6067
  });
6059
- const volume = Internals22.evaluateVolume({
6068
+ const volume = Internals23.evaluateVolume({
6060
6069
  volume: volumeProp,
6061
6070
  frame: volumePropsFrame,
6062
6071
  mediaVolume: 1
6063
6072
  });
6064
- Internals22.warnAboutTooHighVolume(volume);
6073
+ Internals23.warnAboutTooHighVolume(volume);
6065
6074
  if (audio && volume > 0) {
6066
6075
  applyVolume(audio.data, volume);
6067
6076
  registerRenderAsset({
@@ -6126,7 +6135,7 @@ var VideoForRendering = ({
6126
6135
  ]);
6127
6136
  warnAboutObjectFitInStyleOrClassName({ style, className, logLevel });
6128
6137
  const classNameValue = useMemo5(() => {
6129
- return [Internals22.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals22.truthy).join(" ");
6138
+ return [Internals23.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals23.truthy).join(" ");
6130
6139
  }, [className]);
6131
6140
  const styleWithObjectFit = useMemo5(() => {
6132
6141
  return {
@@ -6135,7 +6144,7 @@ var VideoForRendering = ({
6135
6144
  };
6136
6145
  }, [objectFitProp, style]);
6137
6146
  if (replaceWithOffthreadVideo) {
6138
- const fallback = /* @__PURE__ */ jsx5(Internals22.InnerOffthreadVideo, {
6147
+ const fallback = /* @__PURE__ */ jsx5(Internals23.InnerOffthreadVideo, {
6139
6148
  ...props,
6140
6149
  src,
6141
6150
  playbackRate: playbackRate ?? 1,
@@ -6177,7 +6186,7 @@ var VideoForRendering = ({
6177
6186
  }
6178
6187
  return /* @__PURE__ */ jsx5(Loop, {
6179
6188
  layout: "none",
6180
- durationInFrames: Internals22.calculateMediaDuration({
6189
+ durationInFrames: Internals23.calculateMediaDuration({
6181
6190
  trimAfter: trimAfterValue,
6182
6191
  mediaDurationInFrames: replaceWithOffthreadVideo.durationInSeconds * fps,
6183
6192
  playbackRate,
@@ -6206,7 +6215,7 @@ var {
6206
6215
  resolveTrimProps,
6207
6216
  validateMediaProps: validateMediaProps2,
6208
6217
  useCropStyle
6209
- } = Internals23;
6218
+ } = Internals24;
6210
6219
  var videoSchema = {
6211
6220
  src: {
6212
6221
  type: "asset",
@@ -6214,8 +6223,8 @@ var videoSchema = {
6214
6223
  description: "Source",
6215
6224
  keyframable: false
6216
6225
  },
6217
- ...Internals23.baseSchema,
6218
- ...Internals23.premountSchema,
6226
+ ...Internals24.baseSchema,
6227
+ ...Internals24.premountSchema,
6219
6228
  volume: {
6220
6229
  type: "number",
6221
6230
  min: 0,
@@ -6236,7 +6245,7 @@ var videoSchema = {
6236
6245
  },
6237
6246
  muted: { type: "boolean", default: false, description: "Muted" },
6238
6247
  loop: { type: "boolean", default: false, description: "Loop" },
6239
- ...Internals23.transformSchema,
6248
+ ...Internals24.transformSchema,
6240
6249
  ...Interactive2.backgroundSchema,
6241
6250
  ...Interactive2.borderSchema,
6242
6251
  ...Interactive2.borderRadiusSchema,
@@ -6399,10 +6408,10 @@ var VideoInner = ({
6399
6408
  cropBottom,
6400
6409
  ...props
6401
6410
  }) => {
6402
- const sourceStack = controls ? Internals23.getStackForControls(controls) ?? undefined : undefined;
6403
- const fallbackLogLevel = Internals23.useLogLevel();
6404
- const [mediaVolume] = Internals23.useMediaVolumeState();
6405
- const mediaStartsAt = Internals23.useMediaStartsAt();
6411
+ const sourceStack = controls ? Internals24.getStackForControls(controls) ?? undefined : undefined;
6412
+ const fallbackLogLevel = Internals24.useLogLevel();
6413
+ const [mediaVolume] = Internals24.useMediaVolumeState();
6414
+ const mediaStartsAt = Internals24.useMediaStartsAt();
6406
6415
  const videoConfig = useVideoConfig5();
6407
6416
  const sequenceDurationInFrames = Math.min(durationInFrames ?? Infinity, Math.max(0, videoConfig.durationInFrames - (from ?? 0)));
6408
6417
  const videoSequenceDuration = getVideoSequenceDuration({
@@ -6412,7 +6421,7 @@ var VideoInner = ({
6412
6421
  trimAfter,
6413
6422
  trimBefore
6414
6423
  });
6415
- const basicInfo = Internals23.useBasicMediaInTimeline({
6424
+ const basicInfo = Internals24.useBasicMediaInTimeline({
6416
6425
  src,
6417
6426
  volume,
6418
6427
  playbackRate: playbackRate ?? 1,
@@ -6448,11 +6457,11 @@ var VideoInner = ({
6448
6457
  type: "video",
6449
6458
  data: basicInfo
6450
6459
  }), [basicInfo]);
6451
- const memoizedEffects = Internals23.useMemoizedEffects({
6460
+ const memoizedEffects = Internals24.useMemoizedEffects({
6452
6461
  effects: effects ?? [],
6453
6462
  overrideId: controls?.overrideId ?? null
6454
6463
  });
6455
- const memoizedEffectDefinitions = Internals23.useMemoizedEffectDefinitions(effects ?? []);
6464
+ const memoizedEffectDefinitions = Internals24.useMemoizedEffectDefinitions(effects ?? []);
6456
6465
  const refForOutline = React6.useRef(null);
6457
6466
  const {
6458
6467
  effectivePostmountFor,
@@ -6462,7 +6471,7 @@ var VideoInner = ({
6462
6471
  postmountingActive,
6463
6472
  premountingActive,
6464
6473
  premountingStyle
6465
- } = Internals23.usePremounting({
6474
+ } = Internals24.usePremounting({
6466
6475
  from: from ?? 0,
6467
6476
  durationInFrames: videoSequenceDuration ?? Infinity,
6468
6477
  premountFor: premountFor ?? null,
@@ -7,6 +7,6 @@ export declare const acquireSharedInput: ({ src, credentials, requestInit, logLe
7
7
  logLevel: "error" | "info" | "trace" | "verbose" | "warn";
8
8
  }) => {
9
9
  input: Input<import("mediabunny").Source>;
10
- cacheKey: string;
10
+ getDuration: () => Promise<number>;
11
+ release: () => void;
11
12
  };
12
- export declare const releaseSharedInput: (cacheKey: string) => void;
@@ -74,7 +74,8 @@ export declare class MediaPlayer {
74
74
  getEffectChainState: (width: number, height: number) => EffectChainState | null;
75
75
  });
76
76
  private input;
77
- private inputCacheKey;
77
+ private getDuration;
78
+ private releaseInput;
78
79
  private disposed;
79
80
  private isDisposalError;
80
81
  initialize(startTimeUnresolved: number, initialMuted: boolean): Promise<MediaPlayerInitResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/media",
3
- "version": "4.0.514",
3
+ "version": "4.0.516",
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.55.1",
26
- "remotion": "4.0.514",
26
+ "remotion": "4.0.516",
27
27
  "zod": "4.4.3"
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.514",
35
- "@remotion/player": "4.0.514",
34
+ "@remotion/eslint-config-internal": "4.0.516",
35
+ "@remotion/player": "4.0.516",
36
36
  "@vitest/browser-webdriverio": "4.0.9",
37
37
  "eslint": "9.19.0",
38
38
  "react": "19.2.3",