@remotion/media 4.0.464 → 4.0.466

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.
@@ -853,6 +853,84 @@ var makeNonceManager = () => {
853
853
  };
854
854
  };
855
855
 
856
+ // src/premount-aware-delay-playback.ts
857
+ class PremountAwareDelayPlayback {
858
+ isPremounting;
859
+ isPostmounting;
860
+ activeHandles = new Set;
861
+ delayPlayback;
862
+ constructor({
863
+ bufferState,
864
+ isPremounting,
865
+ isPostmounting
866
+ }) {
867
+ this.delayPlayback = bufferState.delayPlayback;
868
+ this.isPremounting = isPremounting;
869
+ this.isPostmounting = isPostmounting;
870
+ }
871
+ shouldDelayPlayback() {
872
+ return !this.isPremounting && !this.isPostmounting;
873
+ }
874
+ syncHandles() {
875
+ for (const handle of this.activeHandles) {
876
+ if (this.shouldDelayPlayback()) {
877
+ handle.arm();
878
+ } else {
879
+ handle.disarm();
880
+ }
881
+ }
882
+ }
883
+ setIsPremounting(isPremounting) {
884
+ this.isPremounting = isPremounting;
885
+ this.syncHandles();
886
+ }
887
+ setIsPostmounting(isPostmounting) {
888
+ this.isPostmounting = isPostmounting;
889
+ this.syncHandles();
890
+ }
891
+ createHandle() {
892
+ let armed = false;
893
+ let unblock = null;
894
+ let disposed = false;
895
+ const arm = () => {
896
+ if (armed || disposed) {
897
+ return;
898
+ }
899
+ unblock = this.delayPlayback().unblock;
900
+ armed = true;
901
+ };
902
+ const disarm = () => {
903
+ if (!armed) {
904
+ return;
905
+ }
906
+ unblock?.();
907
+ unblock = null;
908
+ armed = false;
909
+ };
910
+ const entry = {
911
+ arm,
912
+ disarm,
913
+ dispose: () => {}
914
+ };
915
+ entry.dispose = () => {
916
+ if (disposed) {
917
+ return;
918
+ }
919
+ disposed = true;
920
+ disarm();
921
+ this.activeHandles.delete(entry);
922
+ };
923
+ this.activeHandles.add(entry);
924
+ if (this.shouldDelayPlayback()) {
925
+ arm();
926
+ }
927
+ return {
928
+ unblock: entry.dispose,
929
+ [Symbol.dispose]: entry.dispose
930
+ };
931
+ }
932
+ }
933
+
856
934
  // src/video-iterator-manager.ts
857
935
  import { CanvasSink } from "mediabunny";
858
936
  import { Internals as Internals4 } from "remotion";
@@ -1287,9 +1365,7 @@ class MediaPlayer {
1287
1365
  getEffects;
1288
1366
  getEffectChainState;
1289
1367
  initializationPromise = null;
1290
- bufferState;
1291
- isPremounting;
1292
- isPostmounting;
1368
+ premountAwareDelayPlayback;
1293
1369
  seekPromiseChain = Promise.resolve();
1294
1370
  constructor({
1295
1371
  canvas,
@@ -1328,9 +1404,11 @@ class MediaPlayer {
1328
1404
  this.audioStreamIndex = audioStreamIndex;
1329
1405
  this.fps = fps;
1330
1406
  this.debugOverlay = debugOverlay;
1331
- this.bufferState = bufferState;
1332
- this.isPremounting = isPremounting;
1333
- this.isPostmounting = isPostmounting;
1407
+ this.premountAwareDelayPlayback = new PremountAwareDelayPlayback({
1408
+ bufferState,
1409
+ isPremounting,
1410
+ isPostmounting
1411
+ });
1334
1412
  this.sequenceDurationInFrames = durationInFrames;
1335
1413
  this.nonceManager = makeNonceManager();
1336
1414
  this.onVideoFrameCallback = onVideoFrameCallback;
@@ -1586,19 +1664,7 @@ class MediaPlayer {
1586
1664
  this.drawDebugOverlay();
1587
1665
  }
1588
1666
  delayPlaybackHandleIfNotPremounting = () => {
1589
- if (this.isPremounting || this.isPostmounting) {
1590
- return {
1591
- unblock: () => {},
1592
- [Symbol.dispose]: () => {}
1593
- };
1594
- }
1595
- const { unblock } = this.bufferState.delayPlayback();
1596
- return {
1597
- unblock,
1598
- [Symbol.dispose]: () => {
1599
- unblock();
1600
- }
1601
- };
1667
+ return this.premountAwareDelayPlayback.createHandle();
1602
1668
  };
1603
1669
  pause() {
1604
1670
  if (!this.playing) {
@@ -1671,10 +1737,10 @@ class MediaPlayer {
1671
1737
  }
1672
1738
  }
1673
1739
  setIsPremounting(isPremounting) {
1674
- this.isPremounting = isPremounting;
1740
+ this.premountAwareDelayPlayback.setIsPremounting(isPremounting);
1675
1741
  }
1676
1742
  setIsPostmounting(isPostmounting) {
1677
- this.isPostmounting = isPostmounting;
1743
+ this.premountAwareDelayPlayback.setIsPostmounting(isPostmounting);
1678
1744
  }
1679
1745
  async setLoop(loop, unloopedTimeInSeconds) {
1680
1746
  const previousLoop = this.loop;
@@ -4477,6 +4543,7 @@ var AudioInner = (props) => {
4477
4543
  _remotionInternalStack: stack,
4478
4544
  _remotionInternalIsMedia: isMedia,
4479
4545
  name: name ?? "<Audio>",
4546
+ _remotionInternalDocumentationLink: name === undefined ? "https://www.remotion.dev/docs/media/audio" : undefined,
4480
4547
  _experimentalControls: controls,
4481
4548
  _remotionInternalLoopDisplay: loopDisplay,
4482
4549
  showInTimeline: showInTimeline ?? true,
@@ -4600,7 +4667,7 @@ var VideoForPreviewAssertedShowing = ({
4600
4667
  credentials,
4601
4668
  objectFit: objectFitProp,
4602
4669
  _experimentalInitiallyDrawCachedFrame,
4603
- _experimentalEffects,
4670
+ effects,
4604
4671
  setMediaDurationInSeconds
4605
4672
  }) => {
4606
4673
  const src = usePreload2(unpreloadedSrc);
@@ -4630,8 +4697,8 @@ var VideoForPreviewAssertedShowing = ({
4630
4697
  }
4631
4698
  warnAboutTooHighVolume2(userPreferredVolume);
4632
4699
  const effectChainState = useEffectChainState();
4633
- const experimentalEffectsRef = useRef2(_experimentalEffects);
4634
- experimentalEffectsRef.current = _experimentalEffects;
4700
+ const effectsRef = useRef2(effects);
4701
+ effectsRef.current = effects;
4635
4702
  const effectChainStateRef = useRef2(effectChainState);
4636
4703
  effectChainStateRef.current = effectChainState;
4637
4704
  const parentSequence = useContext4(SequenceContext2);
@@ -4738,7 +4805,7 @@ var VideoForPreviewAssertedShowing = ({
4738
4805
  sequenceOffset: initialSequenceOffset.current,
4739
4806
  credentials,
4740
4807
  tagType: "video",
4741
- getEffects: () => experimentalEffectsRef.current,
4808
+ getEffects: () => effectsRef.current,
4742
4809
  getEffectChainState: (width, height) => effectChainStateRef.current?.get(width, height)
4743
4810
  });
4744
4811
  mediaPlayerRef.current = player;
@@ -4880,7 +4947,7 @@ var VideoForPreviewAssertedShowing = ({
4880
4947
  return;
4881
4948
  }
4882
4949
  mediaPlayer.redrawVideoEffects().catch(() => {});
4883
- }, [_experimentalEffects, mediaPlayerReady, mediaPlayerRef]);
4950
+ }, [effects, mediaPlayerReady, mediaPlayerRef]);
4884
4951
  const actualStyle = useMemo4(() => {
4885
4952
  return {
4886
4953
  ...style,
@@ -5319,7 +5386,7 @@ var InnerVideo = ({
5319
5386
  _experimentalControls: controls,
5320
5387
  objectFit,
5321
5388
  _experimentalInitiallyDrawCachedFrame,
5322
- _experimentalEffects,
5389
+ effects,
5323
5390
  setMediaDurationInSeconds
5324
5391
  }) => {
5325
5392
  const environment = useRemotionEnvironment4();
@@ -5391,7 +5458,7 @@ var InnerVideo = ({
5391
5458
  credentials,
5392
5459
  controls,
5393
5460
  objectFit,
5394
- _experimentalEffects,
5461
+ effects,
5395
5462
  _experimentalInitiallyDrawCachedFrame
5396
5463
  });
5397
5464
  };
@@ -5424,7 +5491,7 @@ var VideoInner = ({
5424
5491
  _experimentalControls: controls,
5425
5492
  objectFit,
5426
5493
  _experimentalInitiallyDrawCachedFrame,
5427
- _experimentalEffects,
5494
+ effects,
5428
5495
  durationInFrames,
5429
5496
  from,
5430
5497
  hidden
@@ -5470,10 +5537,10 @@ var VideoInner = ({
5470
5537
  data: basicInfo
5471
5538
  }), [basicInfo]);
5472
5539
  const memoizedEffects = Internals20.useMemoizedEffects({
5473
- effects: _experimentalEffects ?? [],
5540
+ effects: effects ?? [],
5474
5541
  overrideId: controls?.overrideId ?? null
5475
5542
  });
5476
- const memoizedEffectDefinitions = Internals20.useMemoizedEffectDefinitions(_experimentalEffects ?? []);
5543
+ const memoizedEffectDefinitions = Internals20.useMemoizedEffectDefinitions(effects ?? []);
5477
5544
  if (sequenceDurationInFrames === 0) {
5478
5545
  return null;
5479
5546
  }
@@ -5484,9 +5551,10 @@ var VideoInner = ({
5484
5551
  _remotionInternalStack: stack,
5485
5552
  _remotionInternalIsMedia: isMedia,
5486
5553
  name: name ?? "<Video>",
5554
+ _remotionInternalDocumentationLink: name === undefined ? "https://www.remotion.dev/docs/media/video" : undefined,
5487
5555
  _experimentalControls: controls,
5488
5556
  _remotionInternalLoopDisplay: loopDisplay,
5489
- _experimentalEffects: memoizedEffectDefinitions,
5557
+ _remotionInternalEffects: memoizedEffectDefinitions,
5490
5558
  showInTimeline: showInTimeline ?? true,
5491
5559
  hidden,
5492
5560
  children: /* @__PURE__ */ jsx6(InnerVideo, {
@@ -5517,7 +5585,7 @@ var VideoInner = ({
5517
5585
  _experimentalControls: controls,
5518
5586
  objectFit: objectFit ?? "contain",
5519
5587
  _experimentalInitiallyDrawCachedFrame: _experimentalInitiallyDrawCachedFrame ?? false,
5520
- _experimentalEffects: memoizedEffects,
5588
+ effects: memoizedEffects,
5521
5589
  setMediaDurationInSeconds
5522
5590
  })
5523
5591
  });
package/dist/index.d.ts CHANGED
@@ -59,7 +59,7 @@ export declare const experimental_Video: import("react").ComponentType<{
59
59
  credentials: RequestCredentials | undefined;
60
60
  objectFit: import(".").VideoObjectFit;
61
61
  _experimentalInitiallyDrawCachedFrame: boolean;
62
- _experimentalEffects: import("remotion").EffectsProp;
62
+ effects: import("remotion").EffectsProp;
63
63
  }> & Pick<import("remotion").SequenceProps, "durationInFrames" | "from" | "hidden" | "name">>;
64
64
  export { AudioForPreview } from './audio/audio-for-preview';
65
65
  export { AudioProps, FallbackHtml5AudioProps } from './audio/props';
@@ -43,9 +43,7 @@ export declare class MediaPlayer {
43
43
  private getEffects;
44
44
  private getEffectChainState;
45
45
  private initializationPromise;
46
- private bufferState;
47
- private isPremounting;
48
- private isPostmounting;
46
+ private premountAwareDelayPlayback;
49
47
  private seekPromiseChain;
50
48
  constructor({ canvas, src, logLevel, sharedAudioContext, loop, trimBefore, trimAfter, playbackRate, globalPlaybackRate, audioStreamIndex, fps, debugOverlay, bufferState, isPremounting, isPostmounting, durationInFrames, onVideoFrameCallback, playing, sequenceOffset, credentials, tagType, getEffects, getEffectChainState }: {
51
49
  canvas: HTMLCanvasElement | OffscreenCanvas | null;
@@ -0,0 +1,18 @@
1
+ import type { useBufferState } from 'remotion';
2
+ import type { DelayPlaybackIfNotPremounting } from './delay-playback-if-not-premounting';
3
+ export declare class PremountAwareDelayPlayback {
4
+ private isPremounting;
5
+ private isPostmounting;
6
+ private readonly activeHandles;
7
+ private readonly delayPlayback;
8
+ constructor({ bufferState, isPremounting, isPostmounting }: {
9
+ bufferState: ReturnType<typeof useBufferState>;
10
+ isPremounting: boolean;
11
+ isPostmounting: boolean;
12
+ });
13
+ private shouldDelayPlayback;
14
+ private syncHandles;
15
+ setIsPremounting(isPremounting: boolean): void;
16
+ setIsPostmounting(isPostmounting: boolean): void;
17
+ createHandle(): DelayPlaybackIfNotPremounting;
18
+ }
@@ -51,10 +51,10 @@ type OptionalVideoProps = {
51
51
  credentials: RequestCredentials | undefined;
52
52
  objectFit: VideoObjectFit;
53
53
  _experimentalInitiallyDrawCachedFrame: boolean;
54
- _experimentalEffects: EffectsProp;
54
+ effects: EffectsProp;
55
55
  };
56
- export type InnerVideoProps = MandatoryVideoProps & OuterVideoProps & Omit<OptionalVideoProps, '_experimentalEffects'> & {
57
- _experimentalEffects: EffectDefinitionAndStack<unknown>[];
56
+ export type InnerVideoProps = MandatoryVideoProps & OuterVideoProps & Omit<OptionalVideoProps, 'effects'> & {
57
+ effects: EffectDefinitionAndStack<unknown>[];
58
58
  };
59
59
  export type VideoProps = MandatoryVideoProps & Partial<OuterVideoProps> & Partial<OptionalVideoProps> & Pick<SequenceProps, 'durationInFrames' | 'from' | 'name' | 'hidden'>;
60
60
  export {};
@@ -27,7 +27,7 @@ type VideoForPreviewProps = {
27
27
  readonly objectFit: VideoObjectFit;
28
28
  readonly setMediaDurationInSeconds: (durationInSeconds: number) => void;
29
29
  readonly _experimentalInitiallyDrawCachedFrame: boolean;
30
- readonly _experimentalEffects: EffectDefinitionAndStack<unknown>[];
30
+ readonly effects: EffectDefinitionAndStack<unknown>[];
31
31
  };
32
32
  export declare const VideoForPreview: React.FC<VideoForPreviewProps & {
33
33
  readonly controls: SequenceControls | undefined;
@@ -30,5 +30,5 @@ export declare const Video: React.ComponentType<{
30
30
  credentials: RequestCredentials | undefined;
31
31
  objectFit: import("./props").VideoObjectFit;
32
32
  _experimentalInitiallyDrawCachedFrame: boolean;
33
- _experimentalEffects: import("remotion").EffectsProp;
33
+ effects: import("remotion").EffectsProp;
34
34
  }> & Pick<import("remotion").SequenceProps, "durationInFrames" | "from" | "hidden" | "name">>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/media",
3
- "version": "4.0.464",
3
+ "version": "4.0.466",
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.45.0",
26
- "remotion": "4.0.464",
26
+ "remotion": "4.0.466",
27
27
  "zod": "4.3.6"
28
28
  },
29
29
  "peerDependencies": {
@@ -31,7 +31,7 @@
31
31
  "react-dom": ">=16.8.0"
32
32
  },
33
33
  "devDependencies": {
34
- "@remotion/eslint-config-internal": "4.0.464",
34
+ "@remotion/eslint-config-internal": "4.0.466",
35
35
  "@vitest/browser-webdriverio": "4.0.9",
36
36
  "eslint": "9.19.0",
37
37
  "react": "19.2.3",