remotion 3.3.55 → 3.3.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/audio/Audio.d.ts +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/internals.d.ts +1 -1
- package/dist/cjs/use-video.d.ts +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/version.mjs +1 -1
- package/dist/tsconfig-esm.tsbuildinfo +1 -0
- package/package.json +3 -3
- package/tsconfig-esm.json +12 -0
- package/dist/esm/AbsoluteFill.js +0 -25
- package/dist/esm/CanUseRemotionHooks.js +0 -6
- package/dist/esm/Clipper.js +0 -20
- package/dist/esm/Composition.js +0 -112
- package/dist/esm/CompositionManager.js +0 -137
- package/dist/esm/Folder.js +0 -33
- package/dist/esm/IFrame.js +0 -25
- package/dist/esm/Img.js +0 -53
- package/dist/esm/NativeLayers.js +0 -25
- package/dist/esm/Null.js +0 -21
- package/dist/esm/RemotionRoot.js +0 -69
- package/dist/esm/Sequence.js +0 -128
- package/dist/esm/SequenceContext.js +0 -2
- package/dist/esm/Still.js +0 -9
- package/dist/esm/absolute-src.js +0 -3
- package/dist/esm/asset-types.js +0 -1
- package/dist/esm/audio/Audio.js +0 -53
- package/dist/esm/audio/AudioForDevelopment.js +0 -91
- package/dist/esm/audio/AudioForRendering.js +0 -108
- package/dist/esm/audio/index.js +0 -2
- package/dist/esm/audio/props.js +0 -1
- package/dist/esm/audio/shared-audio-tags.js +0 -194
- package/dist/esm/audio/use-audio-frame.js +0 -18
- package/dist/esm/bezier.js +0 -110
- package/dist/esm/cancel-render.js +0 -43
- package/dist/esm/config/input-props.js +0 -27
- package/dist/esm/config.js +0 -17
- package/dist/esm/default-css.js +0 -44
- package/dist/esm/delay-render.js +0 -72
- package/dist/esm/easing.js +0 -77
- package/dist/esm/freeze.js +0 -34
- package/dist/esm/get-asset-file-name.js +0 -10
- package/dist/esm/get-environment.js +0 -29
- package/dist/esm/get-preview-dom-element.js +0 -3
- package/dist/esm/get-static-files.js +0 -31
- package/dist/esm/get-timeline-clip-name.js +0 -21
- package/dist/esm/index.js +0 -49
- package/dist/esm/internals.js +0 -75
- package/dist/esm/interpolate-colors.js +0 -401
- package/dist/esm/interpolate.js +0 -123
- package/dist/esm/is-approximately-the-same.js +0 -4
- package/dist/esm/is-player.js +0 -9
- package/dist/esm/loading-indicator.js +0 -31
- package/dist/esm/loop/index.js +0 -29
- package/dist/esm/multiple-versions-warning.js +0 -28
- package/dist/esm/nonce.js +0 -13
- package/dist/esm/play-and-handle-not-allowed-error.js +0 -40
- package/dist/esm/portal-node.js +0 -19
- package/dist/esm/prefetch-state.js +0 -22
- package/dist/esm/prefetch.js +0 -107
- package/dist/esm/random.js +0 -37
- package/dist/esm/register-root.js +0 -31
- package/dist/esm/series/flatten-children.js +0 -12
- package/dist/esm/series/index.js +0 -61
- package/dist/esm/setup-env-variables.js +0 -32
- package/dist/esm/spring/index.js +0 -50
- package/dist/esm/spring/measure-spring.js +0 -64
- package/dist/esm/spring/spring-utils.js +0 -99
- package/dist/esm/static-file.js +0 -29
- package/dist/esm/test/Img.test.js +0 -20
- package/dist/esm/test/absolute-src.test.js +0 -16
- package/dist/esm/test/audio-for-rendering.test.js +0 -83
- package/dist/esm/test/audio.test.js +0 -51
- package/dist/esm/test/bezier.test.js +0 -50
- package/dist/esm/test/composition-rules.test.js +0 -28
- package/dist/esm/test/composition-validation.test.js +0 -97
- package/dist/esm/test/easing.test.js +0 -189
- package/dist/esm/test/expect-to-throw.js +0 -11
- package/dist/esm/test/freeze.test.js +0 -63
- package/dist/esm/test/get-asset-file-name.test.js +0 -12
- package/dist/esm/test/get-current-time.test.js +0 -72
- package/dist/esm/test/input-props.test.js +0 -29
- package/dist/esm/test/interpolate.test.js +0 -136
- package/dist/esm/test/interpolateColors.test.js +0 -61
- package/dist/esm/test/loop-validation.test.js +0 -68
- package/dist/esm/test/measure-spring.test.js +0 -43
- package/dist/esm/test/media-validation.test.js +0 -45
- package/dist/esm/test/nested-sequences.test.js +0 -130
- package/dist/esm/test/not-all-props-in-media-tags.test.js +0 -28
- package/dist/esm/test/random.test.js +0 -58
- package/dist/esm/test/ready-manager.test.js +0 -27
- package/dist/esm/test/render-hook.js +0 -20
- package/dist/esm/test/sequence-from-initial-offset.test.js +0 -33
- package/dist/esm/test/sequence-validation.test.js +0 -45
- package/dist/esm/test/series.test.js +0 -113
- package/dist/esm/test/spring.test.js +0 -36
- package/dist/esm/test/truthy.test.js +0 -22
- package/dist/esm/test/use-audio-frame.test.js +0 -53
- package/dist/esm/test/use-media-in-timeline.test.js +0 -49
- package/dist/esm/test/use-media-tag-volume.test.js +0 -44
- package/dist/esm/test/use-sync-volume-with-media-tag.test.js +0 -53
- package/dist/esm/test/validate-start-from-props.test.js +0 -37
- package/dist/esm/test/video.test.js +0 -55
- package/dist/esm/test/volume-prop.test.js +0 -93
- package/dist/esm/test/wrap-sequence-context.js +0 -37
- package/dist/esm/timeline-position-state.js +0 -35
- package/dist/esm/truthy.js +0 -3
- package/dist/esm/use-current-frame.js +0 -23
- package/dist/esm/use-lazy-component.js +0 -22
- package/dist/esm/use-media-in-timeline.js +0 -125
- package/dist/esm/use-media-playback.js +0 -73
- package/dist/esm/use-media-tag-volume.js +0 -27
- package/dist/esm/use-sync-volume-with-media-tag.js +0 -17
- package/dist/esm/use-unsafe-video-config.js +0 -23
- package/dist/esm/use-video-config.js +0 -26
- package/dist/esm/use-video.js +0 -24
- package/dist/esm/validate-frame.js +0 -20
- package/dist/esm/validate-media-props.js +0 -20
- package/dist/esm/validate-start-from-props.js +0 -27
- package/dist/esm/validation/validate-composition-id.js +0 -8
- package/dist/esm/validation/validate-dimensions.js +0 -17
- package/dist/esm/validation/validate-duration-in-frames.js +0 -11
- package/dist/esm/validation/validate-folder-name.js +0 -14
- package/dist/esm/validation/validate-fps.js +0 -17
- package/dist/esm/validation/validate-offthreadvideo-image-format.js +0 -11
- package/dist/esm/validation/validation-spring-duration.js +0 -17
- package/dist/esm/version.js +0 -2
- package/dist/esm/video/OffthreadVideo.js +0 -33
- package/dist/esm/video/OffthreadVideoForRendering.js +0 -100
- package/dist/esm/video/Video.js +0 -51
- package/dist/esm/video/VideoForDevelopment.js +0 -110
- package/dist/esm/video/VideoForRendering.js +0 -200
- package/dist/esm/video/duration-state.js +0 -29
- package/dist/esm/video/get-current-time.js +0 -26
- package/dist/esm/video/index.js +0 -2
- package/dist/esm/video/props.js +0 -1
- package/dist/esm/video/video-fragment.js +0 -55
- package/dist/esm/video-config.js +0 -1
- package/dist/esm/volume-position-state.js +0 -27
- package/dist/esm/volume-prop.js +0 -20
- package/dist/esm/warn-about-non-seekable-media.js +0 -30
- package/dist/esm/wrap-remotion-context.js +0 -45
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { useContext, useEffect } from 'react';
|
|
2
|
-
import { useMediaStartsAt } from './audio/use-audio-frame.js';
|
|
3
|
-
import { playAndHandleNotAllowedError } from './play-and-handle-not-allowed-error.js';
|
|
4
|
-
import { TimelineContext, usePlayingState, useTimelinePosition, } from './timeline-position-state.js';
|
|
5
|
-
import { useCurrentFrame } from './use-current-frame.js';
|
|
6
|
-
import { useVideoConfig } from './use-video-config.js';
|
|
7
|
-
import { getMediaTime } from './video/get-current-time.js';
|
|
8
|
-
import { warnAboutNonSeekableMedia } from './warn-about-non-seekable-media.js';
|
|
9
|
-
export const DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
|
|
10
|
-
export const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, }) => {
|
|
11
|
-
const { playbackRate: globalPlaybackRate } = useContext(TimelineContext);
|
|
12
|
-
const frame = useCurrentFrame();
|
|
13
|
-
const absoluteFrame = useTimelinePosition();
|
|
14
|
-
const [playing] = usePlayingState();
|
|
15
|
-
const { fps } = useVideoConfig();
|
|
16
|
-
const mediaStartsAt = useMediaStartsAt();
|
|
17
|
-
const playbackRate = localPlaybackRate * globalPlaybackRate;
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
var _a;
|
|
20
|
-
if (!playing) {
|
|
21
|
-
(_a = mediaRef.current) === null || _a === void 0 ? void 0 : _a.pause();
|
|
22
|
-
}
|
|
23
|
-
}, [mediaRef, mediaType, playing]);
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
const tagName = mediaType === 'audio' ? '<Audio>' : '<Video>';
|
|
26
|
-
if (!mediaRef.current) {
|
|
27
|
-
throw new Error(`No ${mediaType} ref found`);
|
|
28
|
-
}
|
|
29
|
-
if (!src) {
|
|
30
|
-
throw new Error(`No 'src' attribute was passed to the ${tagName} element.`);
|
|
31
|
-
}
|
|
32
|
-
mediaRef.current.playbackRate = Math.max(0, playbackRate);
|
|
33
|
-
const shouldBeTime = getMediaTime({
|
|
34
|
-
fps,
|
|
35
|
-
frame,
|
|
36
|
-
src,
|
|
37
|
-
playbackRate: localPlaybackRate,
|
|
38
|
-
startFrom: -mediaStartsAt,
|
|
39
|
-
mediaType,
|
|
40
|
-
});
|
|
41
|
-
const isTime = mediaRef.current.currentTime;
|
|
42
|
-
const timeShift = Math.abs(shouldBeTime - isTime);
|
|
43
|
-
if (timeShift > acceptableTimeshift && !mediaRef.current.ended) {
|
|
44
|
-
// If scrubbing around, adjust timing
|
|
45
|
-
// or if time shift is bigger than 0.2sec
|
|
46
|
-
mediaRef.current.currentTime = shouldBeTime;
|
|
47
|
-
if (!onlyWarnForMediaSeekingError) {
|
|
48
|
-
warnAboutNonSeekableMedia(mediaRef.current, onlyWarnForMediaSeekingError ? 'console-warning' : 'console-error');
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (!playing || absoluteFrame === 0) {
|
|
52
|
-
mediaRef.current.currentTime = shouldBeTime;
|
|
53
|
-
}
|
|
54
|
-
if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
|
|
55
|
-
const { current } = mediaRef;
|
|
56
|
-
current.currentTime = shouldBeTime;
|
|
57
|
-
playAndHandleNotAllowedError(mediaRef, mediaType);
|
|
58
|
-
}
|
|
59
|
-
}, [
|
|
60
|
-
absoluteFrame,
|
|
61
|
-
fps,
|
|
62
|
-
playbackRate,
|
|
63
|
-
frame,
|
|
64
|
-
mediaRef,
|
|
65
|
-
mediaType,
|
|
66
|
-
playing,
|
|
67
|
-
src,
|
|
68
|
-
mediaStartsAt,
|
|
69
|
-
localPlaybackRate,
|
|
70
|
-
onlyWarnForMediaSeekingError,
|
|
71
|
-
acceptableTimeshift,
|
|
72
|
-
]);
|
|
73
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
// Returns the real volume of the audio or video while playing,
|
|
3
|
-
// no matter what the supposed volume should be
|
|
4
|
-
export const useMediaTagVolume = (mediaRef) => {
|
|
5
|
-
const [actualVolume, setActualVolume] = useState(1);
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
const ref = mediaRef.current;
|
|
8
|
-
if (!ref) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
const onChange = () => {
|
|
12
|
-
setActualVolume(ref.volume);
|
|
13
|
-
};
|
|
14
|
-
ref.addEventListener('volumechange', onChange);
|
|
15
|
-
return () => ref.removeEventListener('volumechange', onChange);
|
|
16
|
-
}, [mediaRef]);
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
const ref = mediaRef.current;
|
|
19
|
-
if (!ref) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
if (ref.volume !== actualVolume) {
|
|
23
|
-
setActualVolume(ref.volume);
|
|
24
|
-
}
|
|
25
|
-
}, [actualVolume, mediaRef]);
|
|
26
|
-
return actualVolume;
|
|
27
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import { isApproximatelyTheSame } from './is-approximately-the-same.js';
|
|
3
|
-
import { evaluateVolume } from './volume-prop.js';
|
|
4
|
-
export const useSyncVolumeWithMediaTag = ({ volumePropFrame, actualVolume, volume, mediaVolume, mediaRef, }) => {
|
|
5
|
-
useEffect(() => {
|
|
6
|
-
const userPreferredVolume = evaluateVolume({
|
|
7
|
-
frame: volumePropFrame,
|
|
8
|
-
volume,
|
|
9
|
-
mediaVolume,
|
|
10
|
-
allowAmplificationDuringRender: false,
|
|
11
|
-
});
|
|
12
|
-
if (!isApproximatelyTheSame(userPreferredVolume, actualVolume) &&
|
|
13
|
-
mediaRef.current) {
|
|
14
|
-
mediaRef.current.volume = userPreferredVolume;
|
|
15
|
-
}
|
|
16
|
-
}, [actualVolume, volumePropFrame, mediaRef, volume, mediaVolume]);
|
|
17
|
-
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { useContext, useMemo } from 'react';
|
|
2
|
-
import { SequenceContext } from './SequenceContext.js';
|
|
3
|
-
import { useVideo } from './use-video.js';
|
|
4
|
-
export const useUnsafeVideoConfig = () => {
|
|
5
|
-
var _a;
|
|
6
|
-
const context = useContext(SequenceContext);
|
|
7
|
-
const ctxDuration = (_a = context === null || context === void 0 ? void 0 : context.durationInFrames) !== null && _a !== void 0 ? _a : null;
|
|
8
|
-
const video = useVideo();
|
|
9
|
-
return useMemo(() => {
|
|
10
|
-
if (!video) {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
const { id, durationInFrames, fps, height, width, defaultProps } = video;
|
|
14
|
-
return {
|
|
15
|
-
id,
|
|
16
|
-
width,
|
|
17
|
-
height,
|
|
18
|
-
fps,
|
|
19
|
-
durationInFrames: ctxDuration !== null && ctxDuration !== void 0 ? ctxDuration : durationInFrames,
|
|
20
|
-
defaultProps,
|
|
21
|
-
};
|
|
22
|
-
}, [ctxDuration, video]);
|
|
23
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
import { CanUseRemotionHooks } from './CanUseRemotionHooks.js';
|
|
3
|
-
import { useIsPlayer } from './is-player.js';
|
|
4
|
-
import { useUnsafeVideoConfig } from './use-unsafe-video-config.js';
|
|
5
|
-
/**
|
|
6
|
-
* /**
|
|
7
|
-
* @description Get some info about the context of the video that you are making.
|
|
8
|
-
* @see [Documentation](https://www.remotion.dev/docs/use-video-config)
|
|
9
|
-
* @returns Returns an object containing `fps`, `width`, `height` and `durationInFrames`, all of type `number`.
|
|
10
|
-
*/
|
|
11
|
-
export const useVideoConfig = () => {
|
|
12
|
-
const videoConfig = useUnsafeVideoConfig();
|
|
13
|
-
const context = useContext(CanUseRemotionHooks);
|
|
14
|
-
const isPlayer = useIsPlayer();
|
|
15
|
-
if (!videoConfig) {
|
|
16
|
-
if ((typeof window !== 'undefined' && window.remotion_isPlayer) ||
|
|
17
|
-
isPlayer) {
|
|
18
|
-
throw new Error('No video config found. You are probably calling useVideoConfig() from outside the component passed to <Player />. See https://www.remotion.dev/docs/player/examples for how to set up the Player correctly.');
|
|
19
|
-
}
|
|
20
|
-
throw new Error('No video config found. You are probably calling useVideoConfig() from a component which has not been registered as a <Composition />. See https://www.remotion.dev/docs/the-fundamentals#defining-compositions for more information.');
|
|
21
|
-
}
|
|
22
|
-
if (!context) {
|
|
23
|
-
throw new Error('Called useVideoConfig() outside a Remotion composition.');
|
|
24
|
-
}
|
|
25
|
-
return videoConfig;
|
|
26
|
-
};
|
package/dist/esm/use-video.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { useContext, useMemo } from 'react';
|
|
2
|
-
import { CompositionManager } from './CompositionManager.js';
|
|
3
|
-
export const useVideo = () => {
|
|
4
|
-
const context = useContext(CompositionManager);
|
|
5
|
-
return useMemo(() => {
|
|
6
|
-
var _a;
|
|
7
|
-
const selected = context.compositions.find((c) => {
|
|
8
|
-
return c.id === context.currentComposition;
|
|
9
|
-
});
|
|
10
|
-
if (selected) {
|
|
11
|
-
return {
|
|
12
|
-
...selected,
|
|
13
|
-
// We override the selected metadata with the metadata that was passed to renderMedia(),
|
|
14
|
-
// and don't allow it to be changed during render anymore
|
|
15
|
-
...((_a = context.currentCompositionMetadata) !== null && _a !== void 0 ? _a : {}),
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
return null;
|
|
19
|
-
}, [
|
|
20
|
-
context.compositions,
|
|
21
|
-
context.currentComposition,
|
|
22
|
-
context.currentCompositionMetadata,
|
|
23
|
-
]);
|
|
24
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export const validateFrame = (frame, durationInFrames) => {
|
|
2
|
-
if (typeof frame === 'undefined') {
|
|
3
|
-
throw new TypeError(`Argument missing for parameter "frame"`);
|
|
4
|
-
}
|
|
5
|
-
if (typeof frame !== 'number') {
|
|
6
|
-
throw new TypeError(`Argument passed for "frame" is not a number: ${frame}`);
|
|
7
|
-
}
|
|
8
|
-
if (!Number.isFinite(frame)) {
|
|
9
|
-
throw new RangeError(`Frame ${frame} is not finite`);
|
|
10
|
-
}
|
|
11
|
-
if (frame % 1 !== 0) {
|
|
12
|
-
throw new RangeError(`Argument for frame must be an integer, but got ${frame}`);
|
|
13
|
-
}
|
|
14
|
-
if (frame < 0 && frame < -durationInFrames) {
|
|
15
|
-
throw new RangeError(`Cannot use frame ${frame}: Duration of composition is ${durationInFrames}, therefore the lowest frame that can be rendered is ${-durationInFrames}`);
|
|
16
|
-
}
|
|
17
|
-
if (frame > durationInFrames - 1) {
|
|
18
|
-
throw new RangeError(`Cannot use frame ${frame}: Duration of composition is ${durationInFrames}, therefore the highest frame that can be rendered is ${durationInFrames - 1}`);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export const validateMediaProps = (props, component) => {
|
|
2
|
-
if (typeof props.volume !== 'number' &&
|
|
3
|
-
typeof props.volume !== 'function' &&
|
|
4
|
-
typeof props.volume !== 'undefined') {
|
|
5
|
-
throw new TypeError(`You have passed a volume of type ${typeof props.volume} to your <${component} /> component. Volume must be a number or a function with the signature '(frame: number) => number' undefined.`);
|
|
6
|
-
}
|
|
7
|
-
if (typeof props.volume === 'number' && props.volume < 0) {
|
|
8
|
-
throw new TypeError(`You have passed a volume below 0 to your <${component} /> component. Volume must be between 0 and 1`);
|
|
9
|
-
}
|
|
10
|
-
if (typeof props.playbackRate !== 'number' &&
|
|
11
|
-
typeof props.playbackRate !== 'undefined') {
|
|
12
|
-
throw new TypeError(`You have passed a playbackRate of type ${typeof props.playbackRate} to your <${component} /> component. Playback rate must a real number or undefined.`);
|
|
13
|
-
}
|
|
14
|
-
if (typeof props.playbackRate === 'number' &&
|
|
15
|
-
(isNaN(props.playbackRate) ||
|
|
16
|
-
!Number.isFinite(props.playbackRate) ||
|
|
17
|
-
props.playbackRate <= 0)) {
|
|
18
|
-
throw new TypeError(`You have passed a playbackRate of ${props.playbackRate} to your <${component} /> component. Playback rate must be a real number above 0.`);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export const validateStartFromProps = (startFrom, endAt) => {
|
|
2
|
-
if (typeof startFrom !== 'undefined') {
|
|
3
|
-
if (typeof startFrom !== 'number') {
|
|
4
|
-
throw new TypeError(`type of startFrom prop must be a number, instead got type ${typeof startFrom}.`);
|
|
5
|
-
}
|
|
6
|
-
if (isNaN(startFrom) || startFrom === Infinity) {
|
|
7
|
-
throw new TypeError('startFrom prop can not be NaN or Infinity.');
|
|
8
|
-
}
|
|
9
|
-
if (startFrom < 0) {
|
|
10
|
-
throw new TypeError(`startFrom must be greater than equal to 0 instead got ${startFrom}.`);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
if (typeof endAt !== 'undefined') {
|
|
14
|
-
if (typeof endAt !== 'number') {
|
|
15
|
-
throw new TypeError(`type of endAt prop must be a number, instead got type ${typeof endAt}.`);
|
|
16
|
-
}
|
|
17
|
-
if (isNaN(endAt)) {
|
|
18
|
-
throw new TypeError('endAt prop can not be NaN.');
|
|
19
|
-
}
|
|
20
|
-
if (endAt <= 0) {
|
|
21
|
-
throw new TypeError(`endAt must be a positive number, instead got ${endAt}.`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (endAt < startFrom) {
|
|
25
|
-
throw new TypeError('endAt prop must be greater than startFrom prop.');
|
|
26
|
-
}
|
|
27
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const validateCompositionId = (id) => {
|
|
2
|
-
if (!isCompositionIdValid(id)) {
|
|
3
|
-
throw new Error(`Composition id can only contain a-z, A-Z, 0-9 and -. You passed ${id}`);
|
|
4
|
-
}
|
|
5
|
-
};
|
|
6
|
-
const getRegex = () => /^([a-zA-Z0-9-])+$/g;
|
|
7
|
-
export const isCompositionIdValid = (id) => id.match(getRegex());
|
|
8
|
-
export const invalidCompositionErrorMessage = `Composition ID must match ${String(getRegex())}`;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const validateDimension = (amount, nameOfProp, location) => {
|
|
2
|
-
if (typeof amount !== 'number') {
|
|
3
|
-
throw new Error(`The "${nameOfProp}" prop ${location} must be a number, but you passed a value of type ${typeof amount}`);
|
|
4
|
-
}
|
|
5
|
-
if (isNaN(amount)) {
|
|
6
|
-
throw new TypeError(`The "${nameOfProp}" prop ${location} must not be NaN, but is NaN.`);
|
|
7
|
-
}
|
|
8
|
-
if (!Number.isFinite(amount)) {
|
|
9
|
-
throw new TypeError(`The "${nameOfProp}" prop ${location} must be finite, but is ${amount}.`);
|
|
10
|
-
}
|
|
11
|
-
if (amount % 1 !== 0) {
|
|
12
|
-
throw new TypeError(`The "${nameOfProp}" prop ${location} must be an integer, but is ${amount}.`);
|
|
13
|
-
}
|
|
14
|
-
if (amount <= 0) {
|
|
15
|
-
throw new TypeError(`The "${nameOfProp}" prop ${location} must be positive, but got ${amount}.`);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const validateDurationInFrames = (durationInFrames, component) => {
|
|
2
|
-
if (typeof durationInFrames !== 'number') {
|
|
3
|
-
throw new Error(`The "durationInFrames" prop ${component} must be a number, but you passed a value of type ${typeof durationInFrames}`);
|
|
4
|
-
}
|
|
5
|
-
if (durationInFrames <= 0) {
|
|
6
|
-
throw new TypeError(`The "durationInFrames" prop ${component} must be positive, but got ${durationInFrames}.`);
|
|
7
|
-
}
|
|
8
|
-
if (durationInFrames % 1 !== 0) {
|
|
9
|
-
throw new TypeError(`The "durationInFrames" prop ${component} must be an integer, but got ${durationInFrames}.`);
|
|
10
|
-
}
|
|
11
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export const validateFolderName = (name) => {
|
|
2
|
-
if (name === undefined || name === null) {
|
|
3
|
-
throw new TypeError('You must pass a name to a <Folder />.');
|
|
4
|
-
}
|
|
5
|
-
if (typeof name !== 'string') {
|
|
6
|
-
throw new TypeError(`The "name" you pass into <Folder /> must be a string. Got: ${typeof name}`);
|
|
7
|
-
}
|
|
8
|
-
if (!isFolderNameValid(name)) {
|
|
9
|
-
throw new Error(`Folder name can only contain a-z, A-Z, 0-9 and -. You passed ${name}`);
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
const getRegex = () => /^([a-zA-Z0-9-])+$/g;
|
|
13
|
-
export const isFolderNameValid = (name) => name.match(getRegex());
|
|
14
|
-
export const invalidFolderNameErrorMessage = `Folder name must match ${String(getRegex())}`;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const validateFps = (fps, location, isGif) => {
|
|
2
|
-
if (typeof fps !== 'number') {
|
|
3
|
-
throw new Error(`"fps" must be a number, but you passed a value of type ${typeof fps} ${location}`);
|
|
4
|
-
}
|
|
5
|
-
if (!Number.isFinite(fps)) {
|
|
6
|
-
throw new Error(`"fps" must be a finite, but you passed ${fps} ${location}`);
|
|
7
|
-
}
|
|
8
|
-
if (isNaN(fps)) {
|
|
9
|
-
throw new Error(`"fps" must not be NaN, but got ${fps} ${location}`);
|
|
10
|
-
}
|
|
11
|
-
if (fps <= 0) {
|
|
12
|
-
throw new TypeError(`"fps" must be positive, but got ${fps} ${location}`);
|
|
13
|
-
}
|
|
14
|
-
if (isGif && fps > 50) {
|
|
15
|
-
throw new TypeError(`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif`);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const validateOffthreadVideoImageFormat = (input) => {
|
|
2
|
-
if (typeof input === 'undefined') {
|
|
3
|
-
return;
|
|
4
|
-
}
|
|
5
|
-
if (typeof input !== 'string') {
|
|
6
|
-
throw new TypeError(`<OffthreadVideo imageFormat=""> must be a string, but got ${JSON.stringify(input)} instead.`);
|
|
7
|
-
}
|
|
8
|
-
if (input !== 'png' && input !== 'jpeg') {
|
|
9
|
-
throw new TypeError(`<OffthreadVideo imageFormat=""> must be either "png" or "jpeg", but got ${input}`);
|
|
10
|
-
}
|
|
11
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const validateSpringDuration = (dur) => {
|
|
2
|
-
if (typeof dur === 'undefined') {
|
|
3
|
-
return;
|
|
4
|
-
}
|
|
5
|
-
if (typeof dur !== 'number') {
|
|
6
|
-
throw new TypeError(`A "duration" of a spring must be a "number" but is "${typeof dur}"`);
|
|
7
|
-
}
|
|
8
|
-
if (Number.isNaN(dur)) {
|
|
9
|
-
throw new TypeError('A "duration" of a spring is NaN, which it must not be');
|
|
10
|
-
}
|
|
11
|
-
if (!Number.isFinite(dur)) {
|
|
12
|
-
throw new TypeError('A "duration" of a spring must be finite, but is ' + dur);
|
|
13
|
-
}
|
|
14
|
-
if (dur <= 0) {
|
|
15
|
-
throw new TypeError('A "duration" of a spring must be positive, but is ' + dur);
|
|
16
|
-
}
|
|
17
|
-
};
|
package/dist/esm/version.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback } from 'react';
|
|
3
|
-
import { useRemotionEnvironment } from '../get-environment.js';
|
|
4
|
-
import { Sequence } from '../Sequence.js';
|
|
5
|
-
import { validateMediaProps } from '../validate-media-props.js';
|
|
6
|
-
import { validateStartFromProps } from '../validate-start-from-props.js';
|
|
7
|
-
import { validateOffthreadVideoImageFormat } from '../validation/validate-offthreadvideo-image-format.js';
|
|
8
|
-
import { OffthreadVideoForRendering } from './OffthreadVideoForRendering.js';
|
|
9
|
-
import { VideoForDevelopment } from './VideoForDevelopment.js';
|
|
10
|
-
/**
|
|
11
|
-
* @description This method imports and displays a video, similar to <Video />. During rendering, it extracts the exact frame from the video and displays it in an <img> tag
|
|
12
|
-
* @see [Documentation](https://www.remotion.dev/docs/offthreadvideo)
|
|
13
|
-
*/
|
|
14
|
-
export const OffthreadVideo = (props) => {
|
|
15
|
-
const { startFrom, endAt, ...otherProps } = props;
|
|
16
|
-
const environment = useRemotionEnvironment();
|
|
17
|
-
const onDuration = useCallback(() => undefined, []);
|
|
18
|
-
if (typeof props.src !== 'string') {
|
|
19
|
-
throw new TypeError(`The \`<OffthreadVideo>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
|
|
20
|
-
}
|
|
21
|
-
if (typeof startFrom !== 'undefined' || typeof endAt !== 'undefined') {
|
|
22
|
-
validateStartFromProps(startFrom, endAt);
|
|
23
|
-
const startFromFrameNo = startFrom !== null && startFrom !== void 0 ? startFrom : 0;
|
|
24
|
-
const endAtFrameNo = endAt !== null && endAt !== void 0 ? endAt : Infinity;
|
|
25
|
-
return (_jsx(Sequence, { layout: "none", from: 0 - startFromFrameNo, showInTimeline: false, durationInFrames: endAtFrameNo, children: _jsx(OffthreadVideo, { ...otherProps }) }));
|
|
26
|
-
}
|
|
27
|
-
validateMediaProps(props, 'Video');
|
|
28
|
-
validateOffthreadVideoImageFormat(props.imageFormat);
|
|
29
|
-
if (environment === 'rendering') {
|
|
30
|
-
return _jsx(OffthreadVideoForRendering, { ...otherProps });
|
|
31
|
-
}
|
|
32
|
-
return (_jsx(VideoForDevelopment, { onDuration: onDuration, onlyWarnForMediaSeekingError: true, ...otherProps }));
|
|
33
|
-
};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useContext, useEffect, useMemo } from 'react';
|
|
3
|
-
import { getAbsoluteSrc } from '../absolute-src.js';
|
|
4
|
-
import { useFrameForVolumeProp, useMediaStartsAt, } from '../audio/use-audio-frame.js';
|
|
5
|
-
import { CompositionManager } from '../CompositionManager.js';
|
|
6
|
-
import { OFFTHREAD_VIDEO_CLASS_NAME } from '../default-css.js';
|
|
7
|
-
import { Img } from '../Img.js';
|
|
8
|
-
import { Internals } from '../internals.js';
|
|
9
|
-
import { random } from '../random.js';
|
|
10
|
-
import { SequenceContext } from '../SequenceContext.js';
|
|
11
|
-
import { useTimelinePosition } from '../timeline-position-state.js';
|
|
12
|
-
import { useCurrentFrame } from '../use-current-frame.js';
|
|
13
|
-
import { useUnsafeVideoConfig } from '../use-unsafe-video-config.js';
|
|
14
|
-
import { evaluateVolume } from '../volume-prop.js';
|
|
15
|
-
import { getExpectedMediaFrameUncorrected } from './get-current-time.js';
|
|
16
|
-
const DEFAULT_IMAGE_FORMAT = 'jpeg';
|
|
17
|
-
export const OffthreadVideoForRendering = ({ onError, volume: volumeProp, playbackRate, src, muted, imageFormat, allowAmplificationDuringRender, ...props }) => {
|
|
18
|
-
const absoluteFrame = useTimelinePosition();
|
|
19
|
-
const frame = useCurrentFrame();
|
|
20
|
-
const volumePropsFrame = useFrameForVolumeProp();
|
|
21
|
-
const videoConfig = useUnsafeVideoConfig();
|
|
22
|
-
const sequenceContext = useContext(SequenceContext);
|
|
23
|
-
const mediaStartsAt = useMediaStartsAt();
|
|
24
|
-
const { registerAsset, unregisterAsset } = useContext(CompositionManager);
|
|
25
|
-
if (!src) {
|
|
26
|
-
throw new TypeError('No `src` was passed to <OffthreadVideo>.');
|
|
27
|
-
}
|
|
28
|
-
// Generate a string that's as unique as possible for this asset
|
|
29
|
-
// but at the same time the same on all threads
|
|
30
|
-
const id = useMemo(() => `offthreadvideo-${random(src !== null && src !== void 0 ? src : '')}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames}`, [
|
|
31
|
-
src,
|
|
32
|
-
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom,
|
|
33
|
-
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom,
|
|
34
|
-
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames,
|
|
35
|
-
]);
|
|
36
|
-
if (!videoConfig) {
|
|
37
|
-
throw new Error('No video config found');
|
|
38
|
-
}
|
|
39
|
-
const volume = evaluateVolume({
|
|
40
|
-
volume: volumeProp,
|
|
41
|
-
frame: volumePropsFrame,
|
|
42
|
-
mediaVolume: 1,
|
|
43
|
-
allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
|
|
44
|
-
});
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (!src) {
|
|
47
|
-
throw new Error('No src passed');
|
|
48
|
-
}
|
|
49
|
-
if (!window.remotion_videoEnabled) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (muted) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
if (volume <= 0) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
registerAsset({
|
|
59
|
-
type: 'video',
|
|
60
|
-
src: getAbsoluteSrc(src),
|
|
61
|
-
id,
|
|
62
|
-
frame: absoluteFrame,
|
|
63
|
-
volume,
|
|
64
|
-
mediaFrame: frame,
|
|
65
|
-
playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
|
|
66
|
-
allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
|
|
67
|
-
});
|
|
68
|
-
return () => unregisterAsset(id);
|
|
69
|
-
}, [
|
|
70
|
-
muted,
|
|
71
|
-
src,
|
|
72
|
-
registerAsset,
|
|
73
|
-
id,
|
|
74
|
-
unregisterAsset,
|
|
75
|
-
volume,
|
|
76
|
-
frame,
|
|
77
|
-
absoluteFrame,
|
|
78
|
-
playbackRate,
|
|
79
|
-
allowAmplificationDuringRender,
|
|
80
|
-
]);
|
|
81
|
-
const currentTime = useMemo(() => {
|
|
82
|
-
return (getExpectedMediaFrameUncorrected({
|
|
83
|
-
frame,
|
|
84
|
-
playbackRate: playbackRate || 1,
|
|
85
|
-
startFrom: -mediaStartsAt,
|
|
86
|
-
}) / videoConfig.fps);
|
|
87
|
-
}, [frame, mediaStartsAt, playbackRate, videoConfig.fps]);
|
|
88
|
-
const actualSrc = useMemo(() => {
|
|
89
|
-
return `http://localhost:${window.remotion_proxyPort}/proxy?src=${encodeURIComponent(getAbsoluteSrc(src))}&time=${encodeURIComponent(currentTime)}&imageFormat=${imageFormat !== null && imageFormat !== void 0 ? imageFormat : DEFAULT_IMAGE_FORMAT}`;
|
|
90
|
-
}, [currentTime, imageFormat, src]);
|
|
91
|
-
const onErr = useCallback((e) => {
|
|
92
|
-
onError === null || onError === void 0 ? void 0 : onError(e);
|
|
93
|
-
}, [onError]);
|
|
94
|
-
const className = useMemo(() => {
|
|
95
|
-
return [OFFTHREAD_VIDEO_CLASS_NAME, props.className]
|
|
96
|
-
.filter(Internals.truthy)
|
|
97
|
-
.join(' ');
|
|
98
|
-
}, [props.className]);
|
|
99
|
-
return (_jsx(Img, { src: actualSrc, className: className, ...props, onError: onErr }));
|
|
100
|
-
};
|
package/dist/esm/video/Video.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef, useCallback, useContext } from 'react';
|
|
3
|
-
import { useRemotionEnvironment } from '../get-environment.js';
|
|
4
|
-
import { Loop } from '../loop/index.js';
|
|
5
|
-
import { Sequence } from '../Sequence.js';
|
|
6
|
-
import { useVideoConfig } from '../use-video-config.js';
|
|
7
|
-
import { validateMediaProps } from '../validate-media-props.js';
|
|
8
|
-
import { validateStartFromProps } from '../validate-start-from-props.js';
|
|
9
|
-
import { DurationsContext } from './duration-state.js';
|
|
10
|
-
import { VideoForDevelopment } from './VideoForDevelopment.js';
|
|
11
|
-
import { VideoForRendering } from './VideoForRendering.js';
|
|
12
|
-
const VideoForwardingFunction = (props, ref) => {
|
|
13
|
-
var _a;
|
|
14
|
-
const { startFrom, endAt, ...otherProps } = props;
|
|
15
|
-
const { loop, ...propsOtherThanLoop } = props;
|
|
16
|
-
const { fps } = useVideoConfig();
|
|
17
|
-
const environment = useRemotionEnvironment();
|
|
18
|
-
const { durations, setDurations } = useContext(DurationsContext);
|
|
19
|
-
if (typeof ref === 'string') {
|
|
20
|
-
throw new Error('string refs are not supported');
|
|
21
|
-
}
|
|
22
|
-
if (typeof props.src !== 'string') {
|
|
23
|
-
throw new TypeError(`The \`<Video>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
|
|
24
|
-
}
|
|
25
|
-
const onDuration = useCallback((src, durationInSeconds) => {
|
|
26
|
-
setDurations({ type: 'got-duration', durationInSeconds, src });
|
|
27
|
-
}, [setDurations]);
|
|
28
|
-
if (loop && props.src && durations[props.src] !== undefined) {
|
|
29
|
-
const naturalDuration = durations[props.src] * fps;
|
|
30
|
-
const playbackRate = (_a = props.playbackRate) !== null && _a !== void 0 ? _a : 1;
|
|
31
|
-
const durationInFrames = Math.floor(naturalDuration / playbackRate);
|
|
32
|
-
return (_jsx(Loop, { durationInFrames: durationInFrames, children: _jsx(Video, { ...propsOtherThanLoop, ref: ref }) }));
|
|
33
|
-
}
|
|
34
|
-
if (typeof startFrom !== 'undefined' || typeof endAt !== 'undefined') {
|
|
35
|
-
validateStartFromProps(startFrom, endAt);
|
|
36
|
-
const startFromFrameNo = startFrom !== null && startFrom !== void 0 ? startFrom : 0;
|
|
37
|
-
const endAtFrameNo = endAt !== null && endAt !== void 0 ? endAt : Infinity;
|
|
38
|
-
return (_jsx(Sequence, { layout: "none", from: 0 - startFromFrameNo, showInTimeline: false, durationInFrames: endAtFrameNo, children: _jsx(Video, { ...otherProps, ref: ref }) }));
|
|
39
|
-
}
|
|
40
|
-
validateMediaProps(props, 'Video');
|
|
41
|
-
if (environment === 'rendering') {
|
|
42
|
-
return (_jsx(VideoForRendering, { onDuration: onDuration, ...otherProps, ref: ref }));
|
|
43
|
-
}
|
|
44
|
-
return (_jsx(VideoForDevelopment, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref, onDuration: onDuration }));
|
|
45
|
-
};
|
|
46
|
-
const forward = forwardRef;
|
|
47
|
-
/**
|
|
48
|
-
* @description allows you to include a video file in your Remotion project. It wraps the native HTMLVideoElement.
|
|
49
|
-
* @see [Documentation](https://www.remotion.dev/docs/video)
|
|
50
|
-
*/
|
|
51
|
-
export const Video = forward(VideoForwardingFunction);
|