remotion 4.0.88 → 4.0.90

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.
@@ -51,51 +51,27 @@ const Clipper = ({ height, width, x, y }) => {
51
51
  * @see [Documentation](https://www.remotion.dev/docs/get-remotion-environment)
52
52
  */
53
53
  const getRemotionEnvironment = () => {
54
- if (process.env.NODE_ENV === 'production') {
55
- // Check if inside a Remotion bundle.
56
- // Must be a variable in index-html.ts and be defined before setupEnvVariables()
57
- if (typeof window !== 'undefined' &&
58
- typeof window.remotion_editorName !== 'undefined' &&
59
- typeof window.remotion_projectName !== 'undefined') {
60
- return {
61
- isStudio: false,
62
- isRendering: true,
63
- isPlayer: false,
64
- };
65
- }
66
- return {
67
- isStudio: false,
68
- isRendering: false,
69
- isPlayer: typeof window !== 'undefined' && window.remotion_isPlayer,
70
- };
71
- }
72
- // The Vitest framework sets NODE_ENV as test.
73
- // Right now we don't need to treat it in a special
74
- // way which is good - defaulting to `rendering`.
75
- if (process.env.NODE_ENV === 'test') {
76
- return {
77
- isStudio: false,
78
- isRendering: true,
79
- isPlayer: false,
80
- };
81
- }
82
- if (typeof window !== 'undefined' && window.remotion_isPlayer) {
83
- return {
84
- isStudio: false,
85
- isRendering: false,
86
- isPlayer: true,
87
- };
88
- }
54
+ const isPlayer = typeof window !== 'undefined' && window.remotion_isPlayer;
55
+ const isRendering = process.env.NODE_ENV === 'test' ||
56
+ (process.env.NODE_ENV === 'production' &&
57
+ typeof window !== 'undefined' &&
58
+ typeof window.remotion_puppeteerTimeout !== 'undefined');
59
+ const isStudio = typeof window !== 'undefined' && window.remotion_isStudio;
89
60
  return {
90
- isStudio: true,
91
- isRendering: false,
92
- isPlayer: false,
61
+ isStudio,
62
+ isRendering,
63
+ isPlayer,
93
64
  };
94
65
  };
95
66
 
96
67
  const originalCreateElement = React.createElement;
97
68
  const componentsToAddStacksTo = [];
69
+ // Gets called when a new component is added,
70
+ // also when the Studio is mounted
98
71
  const enableSequenceStackTraces = () => {
72
+ if (!getRemotionEnvironment().isStudio) {
73
+ return;
74
+ }
99
75
  const proxy = new Proxy(originalCreateElement, {
100
76
  apply(target, thisArg, argArray) {
101
77
  if (componentsToAddStacksTo.includes(argArray[0])) {
@@ -112,9 +88,6 @@ const enableSequenceStackTraces = () => {
112
88
  React.createElement = proxy;
113
89
  };
114
90
  const addSequenceStackTraces = (component) => {
115
- if (!getRemotionEnvironment().isStudio) {
116
- return;
117
- }
118
91
  componentsToAddStacksTo.push(component);
119
92
  enableSequenceStackTraces();
120
93
  };
@@ -132,7 +105,7 @@ function truthy(value) {
132
105
  }
133
106
 
134
107
  // Automatically generated on publish
135
- const VERSION = '4.0.88';
108
+ const VERSION = '4.0.90';
136
109
 
137
110
  const checkMultipleRemotionVersions = () => {
138
111
  if (typeof globalThis === 'undefined') {
@@ -3477,353 +3450,87 @@ const getPreviewDomElement = () => {
3477
3450
  return document.getElementById(REMOTION_STUDIO_CONTAINER_ELEMENT);
3478
3451
  };
3479
3452
 
3480
- let Root = null;
3481
- let listeners = [];
3482
3453
  /**
3483
- * @description This function registers the root component of the Remotion project
3484
- * @see [Documentation](https://www.remotion.dev/docs/register-root)
3454
+ * Copied from:
3455
+ * https://github.com/software-mansion/react-native-reanimated/blob/master/src/reanimated2/Colors.ts
3485
3456
  */
3486
- const registerRoot = (comp) => {
3487
- if (!comp) {
3488
- throw new Error(`You must pass a React component to registerRoot(), but ${JSON.stringify(comp)} was passed.`);
3457
+ // var INTEGER = '[-+]?\\d+';
3458
+ const NUMBER = '[-+]?\\d*\\.?\\d+';
3459
+ const PERCENTAGE = NUMBER + '%';
3460
+ function call(...args) {
3461
+ return '\\(\\s*(' + args.join(')\\s*,\\s*(') + ')\\s*\\)';
3462
+ }
3463
+ function getMatchers() {
3464
+ const cachedMatchers = {
3465
+ rgb: undefined,
3466
+ rgba: undefined,
3467
+ hsl: undefined,
3468
+ hsla: undefined,
3469
+ hex3: undefined,
3470
+ hex4: undefined,
3471
+ hex5: undefined,
3472
+ hex6: undefined,
3473
+ hex8: undefined,
3474
+ };
3475
+ if (cachedMatchers.rgb === undefined) {
3476
+ cachedMatchers.rgb = new RegExp('rgb' + call(NUMBER, NUMBER, NUMBER));
3477
+ cachedMatchers.rgba = new RegExp('rgba' + call(NUMBER, NUMBER, NUMBER, NUMBER));
3478
+ cachedMatchers.hsl = new RegExp('hsl' + call(NUMBER, PERCENTAGE, PERCENTAGE));
3479
+ cachedMatchers.hsla = new RegExp('hsla' + call(NUMBER, PERCENTAGE, PERCENTAGE, NUMBER));
3480
+ cachedMatchers.hex3 = /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/;
3481
+ cachedMatchers.hex4 =
3482
+ /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/;
3483
+ cachedMatchers.hex6 = /^#([0-9a-fA-F]{6})$/;
3484
+ cachedMatchers.hex8 = /^#([0-9a-fA-F]{8})$/;
3489
3485
  }
3490
- if (Root) {
3491
- throw new Error('registerRoot() was called more than once.');
3486
+ return cachedMatchers;
3487
+ }
3488
+ function hue2rgb(p, q, t) {
3489
+ if (t < 0) {
3490
+ t += 1;
3492
3491
  }
3493
- Root = comp;
3494
- listeners.forEach((l) => {
3495
- l(comp);
3496
- });
3497
- };
3498
- const getRoot = () => {
3499
- return Root;
3500
- };
3501
- const waitForRoot = (fn) => {
3502
- if (Root) {
3503
- fn(Root);
3504
- return () => undefined;
3492
+ if (t > 1) {
3493
+ t -= 1;
3505
3494
  }
3506
- listeners.push(fn);
3507
- return () => {
3508
- listeners = listeners.filter((l) => l !== fn);
3509
- };
3510
- };
3511
-
3512
- const RemotionRoot = ({ children, numberOfAudioTags }) => {
3513
- const [remotionRootId] = useState(() => String(random(null)));
3514
- const [frame, setFrame] = useState(() => getInitialFrameState());
3515
- const [playing, setPlaying] = useState(false);
3516
- const imperativePlaying = useRef(false);
3517
- const [fastRefreshes, setFastRefreshes] = useState(0);
3518
- const [playbackRate, setPlaybackRate] = useState(1);
3519
- const audioAndVideoTags = useRef([]);
3520
- if (typeof window !== 'undefined') {
3521
- // eslint-disable-next-line react-hooks/rules-of-hooks
3522
- useLayoutEffect(() => {
3523
- window.remotion_setFrame = (f, composition) => {
3524
- const id = delayRender(`Setting the current frame to ${f}`);
3525
- setFrame((s) => ({
3526
- ...s,
3527
- [composition]: f,
3528
- }));
3529
- requestAnimationFrame(() => continueRender(id));
3530
- };
3531
- window.remotion_isPlayer = false;
3532
- }, []);
3495
+ if (t < 1 / 6) {
3496
+ return p + (q - p) * 6 * t;
3533
3497
  }
3534
- const timelineContextValue = useMemo(() => {
3535
- return {
3536
- frame,
3537
- playing,
3538
- imperativePlaying,
3539
- rootId: remotionRootId,
3540
- playbackRate,
3541
- setPlaybackRate,
3542
- audioAndVideoTags,
3543
- };
3544
- }, [frame, playbackRate, playing, remotionRootId]);
3545
- const setTimelineContextValue = useMemo(() => {
3546
- return {
3547
- setFrame,
3548
- setPlaying,
3549
- };
3550
- }, []);
3551
- const nonceContext = useMemo(() => {
3552
- let counter = 0;
3553
- return {
3554
- getNonce: () => counter++,
3555
- fastRefreshes,
3556
- };
3557
- }, [fastRefreshes]);
3558
- useEffect(() => {
3559
- if (typeof __webpack_module__ !== 'undefined') {
3560
- if (__webpack_module__.hot) {
3561
- __webpack_module__.hot.addStatusHandler((status) => {
3562
- if (status === 'idle') {
3563
- setFastRefreshes((i) => i + 1);
3564
- }
3565
- });
3566
- }
3567
- }
3568
- }, []);
3569
- return (jsx(NonceContext.Provider, { value: nonceContext, children: jsx(TimelineContext.Provider, { value: timelineContextValue, children: jsx(SetTimelineContext.Provider, { value: setTimelineContextValue, children: jsx(EditorPropsProvider, { children: jsx(PrefetchProvider, { children: jsx(NativeLayersProvider, { children: jsx(CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: jsx(DurationsContextProvider, { children: children }) }) }) }) }) }) }) }));
3570
- };
3571
-
3572
- const getEnvVariables = () => {
3573
- if (getRemotionEnvironment().isRendering) {
3574
- const param = window.remotion_envVariables;
3575
- if (!param) {
3576
- return {};
3577
- }
3578
- return { ...JSON.parse(param), NODE_ENV: process.env.NODE_ENV };
3498
+ if (t < 1 / 2) {
3499
+ return q;
3579
3500
  }
3580
- if (getRemotionEnvironment().isStudio) {
3581
- // For the Studio, we already set the environment variables in index-html.ts.
3582
- // We just add NODE_ENV here.
3583
- return {
3584
- NODE_ENV: 'development',
3585
- };
3501
+ if (t < 2 / 3) {
3502
+ return p + (q - p) * (2 / 3 - t) * 6;
3586
3503
  }
3587
- throw new Error('Can only call getEnvVariables() if environment is `rendering` or `preview`');
3588
- };
3589
- const setupEnvVariables = () => {
3590
- const env = getEnvVariables();
3591
- if (!window.process) {
3592
- window.process = {};
3504
+ return p;
3505
+ }
3506
+ function hslToRgb(h, s, l) {
3507
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
3508
+ const p = 2 * l - q;
3509
+ const r = hue2rgb(p, q, h + 1 / 3);
3510
+ const g = hue2rgb(p, q, h);
3511
+ const b = hue2rgb(p, q, h - 1 / 3);
3512
+ return ((Math.round(r * 255) << 24) |
3513
+ (Math.round(g * 255) << 16) |
3514
+ (Math.round(b * 255) << 8));
3515
+ }
3516
+ function parse255(str) {
3517
+ const int = Number.parseInt(str, 10);
3518
+ if (int < 0) {
3519
+ return 0;
3593
3520
  }
3594
- if (!window.process.env) {
3595
- window.process.env = {};
3521
+ if (int > 255) {
3522
+ return 255;
3596
3523
  }
3597
- Object.keys(env).forEach((key) => {
3598
- window.process.env[key] = env[key];
3599
- });
3600
- };
3601
-
3602
- const WATCH_REMOTION_STATIC_FILES = 'remotion_staticFilesChanged';
3603
- /**
3604
- * @description Watch for changes in a specific static file.
3605
- * @param {string} fileName - The name of the static file to watch for changes.
3606
- * @param {WatcherCallback} callback - A callback function to be called when the file changes.
3607
- * @returns {{cancel: () => void}} A function that can be used to cancel the event listener.
3608
- * @see [Documentation](https://www.remotion.dev/docs/watchstaticfile)
3609
- */
3610
- const watchStaticFile = (fileName, callback) => {
3611
- // Check if function is called in Remotion Studio
3612
- if (!getRemotionEnvironment().isStudio) {
3613
- // eslint-disable-next-line no-console
3614
- console.warn('The API is only available while using the Remotion Studio.');
3615
- return { cancel: () => undefined };
3616
- }
3617
- let prevFileData = window.remotion_staticFiles.find((file) => file.name === fileName);
3618
- // Check if the specified static file has updated or deleted
3619
- const checkFile = (event) => {
3620
- const staticFiles = event.detail.files;
3621
- // Check for user specified file
3622
- const newFileData = staticFiles.find((file) => file.name === fileName);
3623
- if (!newFileData) {
3624
- // File is deleted
3625
- if (prevFileData !== undefined) {
3626
- callback(null);
3627
- }
3628
- prevFileData = undefined;
3629
- return;
3630
- }
3631
- if (prevFileData === undefined ||
3632
- prevFileData.lastModified !== newFileData.lastModified) {
3633
- callback(newFileData); // File is added or modified
3634
- prevFileData = newFileData;
3635
- }
3636
- };
3637
- window.addEventListener(WATCH_REMOTION_STATIC_FILES, checkFile);
3638
- const cancel = () => {
3639
- return window.removeEventListener(WATCH_REMOTION_STATIC_FILES, checkFile);
3640
- };
3641
- return { cancel };
3642
- };
3643
-
3644
- function useRemotionContexts() {
3645
- const compositionManagerCtx = React.useContext(CompositionManager);
3646
- const timelineContext = React.useContext(TimelineContext);
3647
- const setTimelineContext = React.useContext(SetTimelineContext);
3648
- const sequenceContext = React.useContext(SequenceContext);
3649
- const nonceContext = React.useContext(NonceContext);
3650
- const canUseRemotionHooksContext = React.useContext(CanUseRemotionHooks);
3651
- const nativeLayersContext = React.useContext(NativeLayersContext);
3652
- const preloadContext = React.useContext(PreloadContext);
3653
- const resolveCompositionContext = React.useContext(ResolveCompositionContext);
3654
- const renderAssetManagerContext = React.useContext(RenderAssetManager);
3655
- const sequenceManagerContext = React.useContext(SequenceManager);
3656
- return useMemo(() => ({
3657
- compositionManagerCtx,
3658
- timelineContext,
3659
- setTimelineContext,
3660
- sequenceContext,
3661
- nonceContext,
3662
- canUseRemotionHooksContext,
3663
- nativeLayersContext,
3664
- preloadContext,
3665
- resolveCompositionContext,
3666
- renderAssetManagerContext,
3667
- sequenceManagerContext,
3668
- }), [
3669
- compositionManagerCtx,
3670
- nonceContext,
3671
- sequenceContext,
3672
- setTimelineContext,
3673
- timelineContext,
3674
- canUseRemotionHooksContext,
3675
- nativeLayersContext,
3676
- preloadContext,
3677
- resolveCompositionContext,
3678
- renderAssetManagerContext,
3679
- sequenceManagerContext,
3680
- ]);
3681
- }
3682
- const RemotionContextProvider = (props) => {
3683
- const { children, contexts } = props;
3684
- return (jsx(CanUseRemotionHooks.Provider, { value: contexts.canUseRemotionHooksContext, children: jsx(NonceContext.Provider, { value: contexts.nonceContext, children: jsx(NativeLayersContext.Provider, { value: contexts.nativeLayersContext, children: jsx(PreloadContext.Provider, { value: contexts.preloadContext, children: jsx(CompositionManager.Provider, { value: contexts.compositionManagerCtx, children: jsx(SequenceManager.Provider, { value: contexts.sequenceManagerContext, children: jsx(RenderAssetManager.Provider, { value: contexts.renderAssetManagerContext, children: jsx(ResolveCompositionContext.Provider, { value: contexts.resolveCompositionContext, children: jsx(TimelineContext.Provider, { value: contexts.timelineContext, children: jsx(SetTimelineContext.Provider, { value: contexts.setTimelineContext, children: jsx(SequenceContext.Provider, { value: contexts.sequenceContext, children: children }) }) }) }) }) }) }) }) }) }) }));
3685
- };
3686
-
3687
- // Mark them as Internals so use don't assume this is public
3688
- // API and are less likely to use it
3689
- const Internals = {
3690
- useUnsafeVideoConfig,
3691
- Timeline: TimelinePosition,
3692
- CompositionManager,
3693
- SequenceManager,
3694
- SequenceVisibilityToggleContext,
3695
- RemotionRoot,
3696
- useVideo,
3697
- getRoot,
3698
- useMediaVolumeState,
3699
- useMediaMutedState,
3700
- useLazyComponent,
3701
- truthy,
3702
- SequenceContext,
3703
- useRemotionContexts,
3704
- RemotionContextProvider,
3705
- CSSUtils,
3706
- setupEnvVariables,
3707
- MediaVolumeContext,
3708
- SetMediaVolumeContext,
3709
- getRemotionEnvironment,
3710
- SharedAudioContext,
3711
- SharedAudioContextProvider,
3712
- invalidCompositionErrorMessage,
3713
- isCompositionIdValid,
3714
- getPreviewDomElement,
3715
- compositionsRef,
3716
- portalNode,
3717
- waitForRoot,
3718
- CanUseRemotionHooksProvider,
3719
- CanUseRemotionHooks,
3720
- PrefetchProvider,
3721
- DurationsContextProvider,
3722
- IsPlayerContextProvider,
3723
- useIsPlayer,
3724
- EditorPropsProvider,
3725
- EditorPropsContext,
3726
- usePreload,
3727
- NonceContext,
3728
- resolveVideoConfig,
3729
- useResolvedVideoConfig,
3730
- resolveCompositionsRef,
3731
- ResolveCompositionConfig,
3732
- REMOTION_STUDIO_CONTAINER_ELEMENT,
3733
- RenderAssetManager,
3734
- persistCurrentFrame,
3735
- useTimelineSetFrame,
3736
- FILE_TOKEN,
3737
- DATE_TOKEN,
3738
- NativeLayersProvider,
3739
- ClipComposition,
3740
- isIosSafari,
3741
- WATCH_REMOTION_STATIC_FILES,
3742
- addSequenceStackTraces,
3743
- useMediaStartsAt,
3744
- };
3745
-
3746
- /**
3747
- * Copied from:
3748
- * https://github.com/software-mansion/react-native-reanimated/blob/master/src/reanimated2/Colors.ts
3749
- */
3750
- // var INTEGER = '[-+]?\\d+';
3751
- const NUMBER = '[-+]?\\d*\\.?\\d+';
3752
- const PERCENTAGE = NUMBER + '%';
3753
- function call(...args) {
3754
- return '\\(\\s*(' + args.join(')\\s*,\\s*(') + ')\\s*\\)';
3755
- }
3756
- function getMatchers() {
3757
- const cachedMatchers = {
3758
- rgb: undefined,
3759
- rgba: undefined,
3760
- hsl: undefined,
3761
- hsla: undefined,
3762
- hex3: undefined,
3763
- hex4: undefined,
3764
- hex5: undefined,
3765
- hex6: undefined,
3766
- hex8: undefined,
3767
- };
3768
- if (cachedMatchers.rgb === undefined) {
3769
- cachedMatchers.rgb = new RegExp('rgb' + call(NUMBER, NUMBER, NUMBER));
3770
- cachedMatchers.rgba = new RegExp('rgba' + call(NUMBER, NUMBER, NUMBER, NUMBER));
3771
- cachedMatchers.hsl = new RegExp('hsl' + call(NUMBER, PERCENTAGE, PERCENTAGE));
3772
- cachedMatchers.hsla = new RegExp('hsla' + call(NUMBER, PERCENTAGE, PERCENTAGE, NUMBER));
3773
- cachedMatchers.hex3 = /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/;
3774
- cachedMatchers.hex4 =
3775
- /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/;
3776
- cachedMatchers.hex6 = /^#([0-9a-fA-F]{6})$/;
3777
- cachedMatchers.hex8 = /^#([0-9a-fA-F]{8})$/;
3778
- }
3779
- return cachedMatchers;
3780
- }
3781
- function hue2rgb(p, q, t) {
3782
- if (t < 0) {
3783
- t += 1;
3784
- }
3785
- if (t > 1) {
3786
- t -= 1;
3787
- }
3788
- if (t < 1 / 6) {
3789
- return p + (q - p) * 6 * t;
3790
- }
3791
- if (t < 1 / 2) {
3792
- return q;
3793
- }
3794
- if (t < 2 / 3) {
3795
- return p + (q - p) * (2 / 3 - t) * 6;
3796
- }
3797
- return p;
3798
- }
3799
- function hslToRgb(h, s, l) {
3800
- const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
3801
- const p = 2 * l - q;
3802
- const r = hue2rgb(p, q, h + 1 / 3);
3803
- const g = hue2rgb(p, q, h);
3804
- const b = hue2rgb(p, q, h - 1 / 3);
3805
- return ((Math.round(r * 255) << 24) |
3806
- (Math.round(g * 255) << 16) |
3807
- (Math.round(b * 255) << 8));
3808
- }
3809
- function parse255(str) {
3810
- const int = Number.parseInt(str, 10);
3811
- if (int < 0) {
3812
- return 0;
3813
- }
3814
- if (int > 255) {
3815
- return 255;
3816
- }
3817
- return int;
3818
- }
3819
- function parse360(str) {
3820
- const int = Number.parseFloat(str);
3821
- return (((int % 360) + 360) % 360) / 360;
3822
- }
3823
- function parse1(str) {
3824
- const num = Number.parseFloat(str);
3825
- if (num < 0) {
3826
- return 0;
3524
+ return int;
3525
+ }
3526
+ function parse360(str) {
3527
+ const int = Number.parseFloat(str);
3528
+ return (((int % 360) + 360) % 360) / 360;
3529
+ }
3530
+ function parse1(str) {
3531
+ const num = Number.parseFloat(str);
3532
+ if (num < 0) {
3533
+ return 0;
3827
3534
  }
3828
3535
  if (num > 1) {
3829
3536
  return 255;
@@ -3841,7 +3548,7 @@ function parsePercentage(str) {
3841
3548
  }
3842
3549
  return int / 100;
3843
3550
  }
3844
- const names = {
3551
+ const colorNames = {
3845
3552
  transparent: 0x00000000,
3846
3553
  // http://www.w3.org/TR/css3-color/#svg-color
3847
3554
  aliceblue: 0xf0f8ffff,
@@ -4003,8 +3710,8 @@ function normalizeColor(color) {
4003
3710
  return Number.parseInt(match[1] + 'ff', 16) >>> 0;
4004
3711
  }
4005
3712
  }
4006
- if (names[color] !== undefined) {
4007
- return names[color];
3713
+ if (colorNames[color] !== undefined) {
3714
+ return colorNames[color];
4008
3715
  }
4009
3716
  if (matchers.rgb) {
4010
3717
  if ((match = matchers.rgb.exec(color))) {
@@ -4136,6 +3843,274 @@ const interpolateColors = (input, inputRange, outputRange) => {
4136
3843
  return interpolateColorsRGB(input, inputRange, processedOutputRange);
4137
3844
  };
4138
3845
 
3846
+ let Root = null;
3847
+ let listeners = [];
3848
+ /**
3849
+ * @description This function registers the root component of the Remotion project
3850
+ * @see [Documentation](https://www.remotion.dev/docs/register-root)
3851
+ */
3852
+ const registerRoot = (comp) => {
3853
+ if (!comp) {
3854
+ throw new Error(`You must pass a React component to registerRoot(), but ${JSON.stringify(comp)} was passed.`);
3855
+ }
3856
+ if (Root) {
3857
+ throw new Error('registerRoot() was called more than once.');
3858
+ }
3859
+ Root = comp;
3860
+ listeners.forEach((l) => {
3861
+ l(comp);
3862
+ });
3863
+ };
3864
+ const getRoot = () => {
3865
+ return Root;
3866
+ };
3867
+ const waitForRoot = (fn) => {
3868
+ if (Root) {
3869
+ fn(Root);
3870
+ return () => undefined;
3871
+ }
3872
+ listeners.push(fn);
3873
+ return () => {
3874
+ listeners = listeners.filter((l) => l !== fn);
3875
+ };
3876
+ };
3877
+
3878
+ const RemotionRoot = ({ children, numberOfAudioTags }) => {
3879
+ const [remotionRootId] = useState(() => String(random(null)));
3880
+ const [frame, setFrame] = useState(() => getInitialFrameState());
3881
+ const [playing, setPlaying] = useState(false);
3882
+ const imperativePlaying = useRef(false);
3883
+ const [fastRefreshes, setFastRefreshes] = useState(0);
3884
+ const [playbackRate, setPlaybackRate] = useState(1);
3885
+ const audioAndVideoTags = useRef([]);
3886
+ if (typeof window !== 'undefined') {
3887
+ // eslint-disable-next-line react-hooks/rules-of-hooks
3888
+ useLayoutEffect(() => {
3889
+ window.remotion_setFrame = (f, composition) => {
3890
+ const id = delayRender(`Setting the current frame to ${f}`);
3891
+ setFrame((s) => ({
3892
+ ...s,
3893
+ [composition]: f,
3894
+ }));
3895
+ requestAnimationFrame(() => continueRender(id));
3896
+ };
3897
+ window.remotion_isPlayer = false;
3898
+ }, []);
3899
+ }
3900
+ const timelineContextValue = useMemo(() => {
3901
+ return {
3902
+ frame,
3903
+ playing,
3904
+ imperativePlaying,
3905
+ rootId: remotionRootId,
3906
+ playbackRate,
3907
+ setPlaybackRate,
3908
+ audioAndVideoTags,
3909
+ };
3910
+ }, [frame, playbackRate, playing, remotionRootId]);
3911
+ const setTimelineContextValue = useMemo(() => {
3912
+ return {
3913
+ setFrame,
3914
+ setPlaying,
3915
+ };
3916
+ }, []);
3917
+ const nonceContext = useMemo(() => {
3918
+ let counter = 0;
3919
+ return {
3920
+ getNonce: () => counter++,
3921
+ fastRefreshes,
3922
+ };
3923
+ }, [fastRefreshes]);
3924
+ useEffect(() => {
3925
+ if (typeof __webpack_module__ !== 'undefined') {
3926
+ if (__webpack_module__.hot) {
3927
+ __webpack_module__.hot.addStatusHandler((status) => {
3928
+ if (status === 'idle') {
3929
+ setFastRefreshes((i) => i + 1);
3930
+ }
3931
+ });
3932
+ }
3933
+ }
3934
+ }, []);
3935
+ return (jsx(NonceContext.Provider, { value: nonceContext, children: jsx(TimelineContext.Provider, { value: timelineContextValue, children: jsx(SetTimelineContext.Provider, { value: setTimelineContextValue, children: jsx(EditorPropsProvider, { children: jsx(PrefetchProvider, { children: jsx(NativeLayersProvider, { children: jsx(CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: jsx(DurationsContextProvider, { children: children }) }) }) }) }) }) }) }));
3936
+ };
3937
+
3938
+ const getEnvVariables = () => {
3939
+ if (getRemotionEnvironment().isRendering) {
3940
+ const param = window.remotion_envVariables;
3941
+ if (!param) {
3942
+ return {};
3943
+ }
3944
+ return { ...JSON.parse(param), NODE_ENV: process.env.NODE_ENV };
3945
+ }
3946
+ // For the Studio, we already set the environment variables in index-html.ts.
3947
+ // We just add NODE_ENV here.
3948
+ if (!process.env.NODE_ENV) {
3949
+ throw new Error('process.env.NODE_ENV is not set');
3950
+ }
3951
+ return {
3952
+ NODE_ENV: process.env.NODE_ENV,
3953
+ };
3954
+ };
3955
+ const setupEnvVariables = () => {
3956
+ const env = getEnvVariables();
3957
+ if (!window.process) {
3958
+ window.process = {};
3959
+ }
3960
+ if (!window.process.env) {
3961
+ window.process.env = {};
3962
+ }
3963
+ Object.keys(env).forEach((key) => {
3964
+ window.process.env[key] = env[key];
3965
+ });
3966
+ };
3967
+
3968
+ const WATCH_REMOTION_STATIC_FILES = 'remotion_staticFilesChanged';
3969
+ /**
3970
+ * @description Watch for changes in a specific static file.
3971
+ * @param {string} fileName - The name of the static file to watch for changes.
3972
+ * @param {WatcherCallback} callback - A callback function to be called when the file changes.
3973
+ * @returns {{cancel: () => void}} A function that can be used to cancel the event listener.
3974
+ * @see [Documentation](https://www.remotion.dev/docs/watchstaticfile)
3975
+ */
3976
+ const watchStaticFile = (fileName, callback) => {
3977
+ // Check if function is called in Remotion Studio
3978
+ if (!getRemotionEnvironment().isStudio) {
3979
+ // eslint-disable-next-line no-console
3980
+ console.warn('The API is only available while using the Remotion Studio.');
3981
+ return { cancel: () => undefined };
3982
+ }
3983
+ let prevFileData = window.remotion_staticFiles.find((file) => file.name === fileName);
3984
+ // Check if the specified static file has updated or deleted
3985
+ const checkFile = (event) => {
3986
+ const staticFiles = event.detail.files;
3987
+ // Check for user specified file
3988
+ const newFileData = staticFiles.find((file) => file.name === fileName);
3989
+ if (!newFileData) {
3990
+ // File is deleted
3991
+ if (prevFileData !== undefined) {
3992
+ callback(null);
3993
+ }
3994
+ prevFileData = undefined;
3995
+ return;
3996
+ }
3997
+ if (prevFileData === undefined ||
3998
+ prevFileData.lastModified !== newFileData.lastModified) {
3999
+ callback(newFileData); // File is added or modified
4000
+ prevFileData = newFileData;
4001
+ }
4002
+ };
4003
+ window.addEventListener(WATCH_REMOTION_STATIC_FILES, checkFile);
4004
+ const cancel = () => {
4005
+ return window.removeEventListener(WATCH_REMOTION_STATIC_FILES, checkFile);
4006
+ };
4007
+ return { cancel };
4008
+ };
4009
+
4010
+ function useRemotionContexts() {
4011
+ const compositionManagerCtx = React.useContext(CompositionManager);
4012
+ const timelineContext = React.useContext(TimelineContext);
4013
+ const setTimelineContext = React.useContext(SetTimelineContext);
4014
+ const sequenceContext = React.useContext(SequenceContext);
4015
+ const nonceContext = React.useContext(NonceContext);
4016
+ const canUseRemotionHooksContext = React.useContext(CanUseRemotionHooks);
4017
+ const nativeLayersContext = React.useContext(NativeLayersContext);
4018
+ const preloadContext = React.useContext(PreloadContext);
4019
+ const resolveCompositionContext = React.useContext(ResolveCompositionContext);
4020
+ const renderAssetManagerContext = React.useContext(RenderAssetManager);
4021
+ const sequenceManagerContext = React.useContext(SequenceManager);
4022
+ return useMemo(() => ({
4023
+ compositionManagerCtx,
4024
+ timelineContext,
4025
+ setTimelineContext,
4026
+ sequenceContext,
4027
+ nonceContext,
4028
+ canUseRemotionHooksContext,
4029
+ nativeLayersContext,
4030
+ preloadContext,
4031
+ resolveCompositionContext,
4032
+ renderAssetManagerContext,
4033
+ sequenceManagerContext,
4034
+ }), [
4035
+ compositionManagerCtx,
4036
+ nonceContext,
4037
+ sequenceContext,
4038
+ setTimelineContext,
4039
+ timelineContext,
4040
+ canUseRemotionHooksContext,
4041
+ nativeLayersContext,
4042
+ preloadContext,
4043
+ resolveCompositionContext,
4044
+ renderAssetManagerContext,
4045
+ sequenceManagerContext,
4046
+ ]);
4047
+ }
4048
+ const RemotionContextProvider = (props) => {
4049
+ const { children, contexts } = props;
4050
+ return (jsx(CanUseRemotionHooks.Provider, { value: contexts.canUseRemotionHooksContext, children: jsx(NonceContext.Provider, { value: contexts.nonceContext, children: jsx(NativeLayersContext.Provider, { value: contexts.nativeLayersContext, children: jsx(PreloadContext.Provider, { value: contexts.preloadContext, children: jsx(CompositionManager.Provider, { value: contexts.compositionManagerCtx, children: jsx(SequenceManager.Provider, { value: contexts.sequenceManagerContext, children: jsx(RenderAssetManager.Provider, { value: contexts.renderAssetManagerContext, children: jsx(ResolveCompositionContext.Provider, { value: contexts.resolveCompositionContext, children: jsx(TimelineContext.Provider, { value: contexts.timelineContext, children: jsx(SetTimelineContext.Provider, { value: contexts.setTimelineContext, children: jsx(SequenceContext.Provider, { value: contexts.sequenceContext, children: children }) }) }) }) }) }) }) }) }) }) }));
4051
+ };
4052
+
4053
+ // Mark them as Internals so use don't assume this is public
4054
+ // API and are less likely to use it
4055
+ const Internals = {
4056
+ useUnsafeVideoConfig,
4057
+ Timeline: TimelinePosition,
4058
+ CompositionManager,
4059
+ SequenceManager,
4060
+ SequenceVisibilityToggleContext,
4061
+ RemotionRoot,
4062
+ useVideo,
4063
+ getRoot,
4064
+ useMediaVolumeState,
4065
+ useMediaMutedState,
4066
+ useLazyComponent,
4067
+ truthy,
4068
+ SequenceContext,
4069
+ useRemotionContexts,
4070
+ RemotionContextProvider,
4071
+ CSSUtils,
4072
+ setupEnvVariables,
4073
+ MediaVolumeContext,
4074
+ SetMediaVolumeContext,
4075
+ getRemotionEnvironment,
4076
+ SharedAudioContext,
4077
+ SharedAudioContextProvider,
4078
+ invalidCompositionErrorMessage,
4079
+ isCompositionIdValid,
4080
+ getPreviewDomElement,
4081
+ compositionsRef,
4082
+ portalNode,
4083
+ waitForRoot,
4084
+ CanUseRemotionHooksProvider,
4085
+ CanUseRemotionHooks,
4086
+ PrefetchProvider,
4087
+ DurationsContextProvider,
4088
+ IsPlayerContextProvider,
4089
+ useIsPlayer,
4090
+ EditorPropsProvider,
4091
+ EditorPropsContext,
4092
+ usePreload,
4093
+ NonceContext,
4094
+ resolveVideoConfig,
4095
+ useResolvedVideoConfig,
4096
+ resolveCompositionsRef,
4097
+ ResolveCompositionConfig,
4098
+ REMOTION_STUDIO_CONTAINER_ELEMENT,
4099
+ RenderAssetManager,
4100
+ persistCurrentFrame,
4101
+ useTimelineSetFrame,
4102
+ FILE_TOKEN,
4103
+ DATE_TOKEN,
4104
+ NativeLayersProvider,
4105
+ ClipComposition,
4106
+ isIosSafari,
4107
+ WATCH_REMOTION_STATIC_FILES,
4108
+ addSequenceStackTraces,
4109
+ useMediaStartsAt,
4110
+ enableSequenceStackTraces,
4111
+ colorNames,
4112
+ };
4113
+
4139
4114
  const validateFrame = ({ allowFloats, durationInFrames, frame, }) => {
4140
4115
  if (typeof frame === 'undefined') {
4141
4116
  throw new TypeError(`Argument missing for parameter "frame"`);
@@ -4812,7 +4787,7 @@ const seekToTimeMultipleUntilRight = (element, desiredTime, fps) => {
4812
4787
  const firstSeek = seekToTime(element, desiredTime + threshold);
4813
4788
  firstSeek.wait.then((seekedTo) => {
4814
4789
  const difference = Math.abs(desiredTime - seekedTo);
4815
- if (difference < threshold) {
4790
+ if (difference <= threshold) {
4816
4791
  return resolve();
4817
4792
  }
4818
4793
  const sign = desiredTime > seekedTo ? 1 : -1;
@@ -4821,12 +4796,12 @@ const seekToTimeMultipleUntilRight = (element, desiredTime, fps) => {
4821
4796
  newSeek.wait
4822
4797
  .then((newTime) => {
4823
4798
  const newDifference = Math.abs(desiredTime - newTime);
4824
- if (newDifference < threshold) {
4799
+ if (newDifference <= threshold) {
4825
4800
  return resolve();
4826
4801
  }
4827
4802
  const thirdSeek = seekToTime(element, desiredTime);
4828
4803
  currentCancel = thirdSeek.cancel;
4829
- thirdSeek.wait.then(() => {
4804
+ return thirdSeek.wait.then(() => {
4830
4805
  resolve();
4831
4806
  });
4832
4807
  })
@@ -5059,12 +5034,11 @@ const VideoForwardingFunction = (props, ref) => {
5059
5034
  }
5060
5035
  return (jsx(VideoForDevelopment, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref, onDuration: onDuration, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed !== null && _remotionInternalNativeLoopPassed !== void 0 ? _remotionInternalNativeLoopPassed : false }));
5061
5036
  };
5062
- const forward = forwardRef;
5063
5037
  /**
5064
5038
  * @description allows you to include a video file in your Remotion project. It wraps the native HTMLVideoElement.
5065
5039
  * @see [Documentation](https://www.remotion.dev/docs/video)
5066
5040
  */
5067
- const Video = forward(VideoForwardingFunction);
5041
+ const Video = forwardRef(VideoForwardingFunction);
5068
5042
  addSequenceStackTraces(Video);
5069
5043
 
5070
5044
  checkMultipleRemotionVersions();