remotion 4.0.0-alpha5 → 4.0.0-alpha7
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/CompositionManager.d.ts +6 -1
- package/dist/cjs/Sequence.d.ts +2 -1
- package/dist/cjs/Sequence.js +3 -3
- package/dist/cjs/audio/AudioForDevelopment.js +10 -3
- package/dist/cjs/loop/index.js +14 -5
- package/dist/cjs/spring/index.d.ts +5 -1
- package/dist/cjs/spring/index.js +35 -14
- package/dist/cjs/static-file.d.ts +28 -0
- package/dist/cjs/static-file.js +43 -3
- package/dist/cjs/use-media-in-timeline.js +1 -1
- package/dist/cjs/use-media-playback.js +12 -3
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/video/OffthreadVideo.js +2 -2
- package/dist/cjs/video/VideoForDevelopment.js +6 -2
- package/dist/cjs/video/VideoForRendering.js +6 -1
- package/dist/cjs/video/props.d.ts +1 -0
- package/dist/esm/index.mjs +154 -62
- package/dist/esm/version.mjs +1 -1
- package/package.json +1 -1
- package/dist/cjs/config.d.ts +0 -294
- package/dist/cjs/config.js +0 -21
- package/dist/cjs/validation/validate-offthreadvideo-image-format.d.ts +0 -1
- package/dist/cjs/validation/validate-offthreadvideo-image-format.js +0 -15
|
@@ -37,6 +37,11 @@ declare type EnhancedTSequenceData = {
|
|
|
37
37
|
startMediaFrom: number;
|
|
38
38
|
playbackRate: number;
|
|
39
39
|
};
|
|
40
|
+
export declare type LoopDisplay = {
|
|
41
|
+
numberOfTimes: number;
|
|
42
|
+
startOffset: number;
|
|
43
|
+
durationInFrames: number;
|
|
44
|
+
};
|
|
40
45
|
export declare type TSequence = {
|
|
41
46
|
from: number;
|
|
42
47
|
duration: number;
|
|
@@ -46,7 +51,7 @@ export declare type TSequence = {
|
|
|
46
51
|
rootId: string;
|
|
47
52
|
showInTimeline: boolean;
|
|
48
53
|
nonce: number;
|
|
49
|
-
|
|
54
|
+
loopDisplay: LoopDisplay | undefined;
|
|
50
55
|
} & EnhancedTSequenceData;
|
|
51
56
|
export declare type TAsset = {
|
|
52
57
|
type: 'audio' | 'video';
|
package/dist/cjs/Sequence.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { LoopDisplay } from './CompositionManager.js';
|
|
2
3
|
export declare type LayoutAndStyle = {
|
|
3
4
|
layout: 'none';
|
|
4
5
|
} | {
|
|
@@ -12,7 +13,7 @@ export declare type SequenceProps = {
|
|
|
12
13
|
durationInFrames?: number;
|
|
13
14
|
name?: string;
|
|
14
15
|
showInTimeline?: boolean;
|
|
15
|
-
|
|
16
|
+
loopDisplay?: LoopDisplay;
|
|
16
17
|
} & LayoutAndStyle;
|
|
17
18
|
/**
|
|
18
19
|
* @description A component that time-shifts its children and wraps them in an absolutely positioned <div>.
|
package/dist/cjs/Sequence.js
CHANGED
|
@@ -11,7 +11,7 @@ const nonce_js_1 = require("./nonce.js");
|
|
|
11
11
|
const SequenceContext_js_1 = require("./SequenceContext.js");
|
|
12
12
|
const timeline_position_state_js_1 = require("./timeline-position-state.js");
|
|
13
13
|
const use_video_config_js_1 = require("./use-video-config.js");
|
|
14
|
-
const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, showInTimeline = true,
|
|
14
|
+
const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, showInTimeline = true, loopDisplay, ...other }, ref) => {
|
|
15
15
|
const { layout = 'absolute-fill' } = other;
|
|
16
16
|
const [id] = (0, react_1.useState)(() => String(Math.random()));
|
|
17
17
|
const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
|
@@ -81,7 +81,7 @@ const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity,
|
|
|
81
81
|
rootId,
|
|
82
82
|
showInTimeline,
|
|
83
83
|
nonce,
|
|
84
|
-
|
|
84
|
+
loopDisplay,
|
|
85
85
|
});
|
|
86
86
|
return () => {
|
|
87
87
|
unregisterSequence(id);
|
|
@@ -99,7 +99,7 @@ const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity,
|
|
|
99
99
|
from,
|
|
100
100
|
showInTimeline,
|
|
101
101
|
nonce,
|
|
102
|
-
|
|
102
|
+
loopDisplay,
|
|
103
103
|
environment,
|
|
104
104
|
]);
|
|
105
105
|
const endThreshold = cumulatedFrom + from + durationInFrames - 1;
|
|
@@ -36,7 +36,14 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
36
36
|
const sequenceContext = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
|
37
37
|
// Generate a string that's as unique as possible for this asset
|
|
38
38
|
// but at the same time deterministic. We use it to combat strict mode issues.
|
|
39
|
-
const id = (0, react_1.useMemo)(() => `audio-${(0, random_js_1.random)(src !== null && src !== void 0 ? src : '')}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames}-muted:${props.muted}`, [
|
|
39
|
+
const id = (0, react_1.useMemo)(() => `audio-${(0, random_js_1.random)(src !== null && src !== void 0 ? src : '')}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames}-muted:${props.muted}-loop:${props.loop}`, [
|
|
40
|
+
src,
|
|
41
|
+
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom,
|
|
42
|
+
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom,
|
|
43
|
+
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames,
|
|
44
|
+
props.muted,
|
|
45
|
+
props.loop,
|
|
46
|
+
]);
|
|
40
47
|
const audioRef = (0, shared_audio_tags_js_1.useSharedAudio)(propsToPass, id).el;
|
|
41
48
|
const actualVolume = (0, use_media_tag_volume_js_1.useMediaTagVolume)(audioRef);
|
|
42
49
|
(0, use_sync_volume_with_media_tag_js_1.useSyncVolumeWithMediaTag)({
|
|
@@ -74,12 +81,12 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
74
81
|
return;
|
|
75
82
|
}
|
|
76
83
|
if (current.duration) {
|
|
77
|
-
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, src, current.duration);
|
|
84
|
+
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, current.src, current.duration);
|
|
78
85
|
return;
|
|
79
86
|
}
|
|
80
87
|
const onLoadedMetadata = () => {
|
|
81
88
|
var _a;
|
|
82
|
-
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, src, current.duration);
|
|
89
|
+
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, current.src, current.duration);
|
|
83
90
|
};
|
|
84
91
|
current.addEventListener('loadedmetadata', onLoadedMetadata);
|
|
85
92
|
return () => {
|
package/dist/cjs/loop/index.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Loop = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
5
6
|
const Sequence_js_1 = require("../Sequence.js");
|
|
7
|
+
const use_current_frame_js_1 = require("../use-current-frame.js");
|
|
6
8
|
const use_video_config_js_1 = require("../use-video-config.js");
|
|
7
9
|
const validate_duration_in_frames_js_1 = require("../validation/validate-duration-in-frames.js");
|
|
8
10
|
/**
|
|
@@ -10,6 +12,7 @@ const validate_duration_in_frames_js_1 = require("../validation/validate-duratio
|
|
|
10
12
|
* @see [Documentation](https://www.remotion.dev/docs/loop)
|
|
11
13
|
*/
|
|
12
14
|
const Loop = ({ durationInFrames, times = Infinity, children, name, ...props }) => {
|
|
15
|
+
const currentFrame = (0, use_current_frame_js_1.useCurrentFrame)();
|
|
13
16
|
const { durationInFrames: compDuration } = (0, use_video_config_js_1.useVideoConfig)();
|
|
14
17
|
(0, validate_duration_in_frames_js_1.validateDurationInFrames)({
|
|
15
18
|
durationInFrames,
|
|
@@ -28,10 +31,16 @@ const Loop = ({ durationInFrames, times = Infinity, children, name, ...props })
|
|
|
28
31
|
const maxTimes = Math.ceil(compDuration / durationInFrames);
|
|
29
32
|
const actualTimes = Math.min(maxTimes, times);
|
|
30
33
|
const style = props.layout === 'none' ? undefined : props.style;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const maxFrame = durationInFrames * (actualTimes - 1);
|
|
35
|
+
const start = Math.floor(currentFrame / durationInFrames) * durationInFrames;
|
|
36
|
+
const from = Math.min(start, maxFrame);
|
|
37
|
+
const loopDisplay = (0, react_1.useMemo)(() => {
|
|
38
|
+
return {
|
|
39
|
+
numberOfTimes: actualTimes,
|
|
40
|
+
startOffset: -from,
|
|
41
|
+
durationInFrames,
|
|
42
|
+
};
|
|
43
|
+
}, [actualTimes, durationInFrames, from]);
|
|
44
|
+
return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { durationInFrames: durationInFrames, from: from, name: name, loopDisplay: loopDisplay, layout: props.layout, style: style, children: children }));
|
|
36
45
|
};
|
|
37
46
|
exports.Loop = Loop;
|
|
@@ -4,6 +4,7 @@ import type { SpringConfig } from './spring-utils.js';
|
|
|
4
4
|
* @see [Documentation](https://www.remotion.dev/docs/spring)
|
|
5
5
|
* @param {number} frame The current time value. Most of the time you want to pass in the return value of useCurrentFrame.
|
|
6
6
|
* @param {number} fps The framerate at which the animation runs. Pass in the value obtained by `useVideoConfig()`.
|
|
7
|
+
* @param {?boolean} reverse Whether the animation plays in reverse or not. Default `false`.
|
|
7
8
|
* @param {?Object} config optional object that allows you to customize the physical properties of the animation.
|
|
8
9
|
* @param {number} [config.mass=1] The weight of the spring. If you reduce the mass, the animation becomes faster!
|
|
9
10
|
* @param {number} [config.damping=10] How hard the animation decelerates.
|
|
@@ -13,8 +14,9 @@ import type { SpringConfig } from './spring-utils.js';
|
|
|
13
14
|
* @param {?number} [config.to] The end value of the animation. Default `1`
|
|
14
15
|
* @param {?number} [config.durationInFrames] Stretch the duration of an animation to a set value.. Default `undefined`
|
|
15
16
|
* @param {?number} [config.durationThreshold] How close to the end the animation is considered to be done. Default `0.005`
|
|
17
|
+
* @param {?number} [config.delay] Delay the animation for this amount of frames. Default `0`
|
|
16
18
|
*/
|
|
17
|
-
export declare function spring({ frame, fps, config, from, to, durationInFrames, durationRestThreshold, }: {
|
|
19
|
+
export declare function spring({ frame: passedFrame, fps, config, from, to, durationInFrames: passedDurationInFrames, durationRestThreshold, delay, reverse, }: {
|
|
18
20
|
frame: number;
|
|
19
21
|
fps: number;
|
|
20
22
|
config?: Partial<SpringConfig>;
|
|
@@ -22,6 +24,8 @@ export declare function spring({ frame, fps, config, from, to, durationInFrames,
|
|
|
22
24
|
to?: number;
|
|
23
25
|
durationInFrames?: number;
|
|
24
26
|
durationRestThreshold?: number;
|
|
27
|
+
delay?: number;
|
|
28
|
+
reverse?: boolean;
|
|
25
29
|
}): number;
|
|
26
30
|
export { measureSpring } from './measure-spring.js';
|
|
27
31
|
export { SpringConfig } from './spring-utils.js';
|
package/dist/cjs/spring/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const spring_utils_js_1 = require("./spring-utils.js");
|
|
|
11
11
|
* @see [Documentation](https://www.remotion.dev/docs/spring)
|
|
12
12
|
* @param {number} frame The current time value. Most of the time you want to pass in the return value of useCurrentFrame.
|
|
13
13
|
* @param {number} fps The framerate at which the animation runs. Pass in the value obtained by `useVideoConfig()`.
|
|
14
|
+
* @param {?boolean} reverse Whether the animation plays in reverse or not. Default `false`.
|
|
14
15
|
* @param {?Object} config optional object that allows you to customize the physical properties of the animation.
|
|
15
16
|
* @param {number} [config.mass=1] The weight of the spring. If you reduce the mass, the animation becomes faster!
|
|
16
17
|
* @param {number} [config.damping=10] How hard the animation decelerates.
|
|
@@ -20,24 +21,44 @@ const spring_utils_js_1 = require("./spring-utils.js");
|
|
|
20
21
|
* @param {?number} [config.to] The end value of the animation. Default `1`
|
|
21
22
|
* @param {?number} [config.durationInFrames] Stretch the duration of an animation to a set value.. Default `undefined`
|
|
22
23
|
* @param {?number} [config.durationThreshold] How close to the end the animation is considered to be done. Default `0.005`
|
|
24
|
+
* @param {?number} [config.delay] Delay the animation for this amount of frames. Default `0`
|
|
23
25
|
*/
|
|
24
|
-
function spring({ frame, fps, config = {}, from = 0, to = 1, durationInFrames, durationRestThreshold, }) {
|
|
25
|
-
(0, validation_spring_duration_js_1.validateSpringDuration)(
|
|
26
|
-
(0, validate_frame_js_1.validateFrame)({
|
|
26
|
+
function spring({ frame: passedFrame, fps, config = {}, from = 0, to = 1, durationInFrames: passedDurationInFrames, durationRestThreshold, delay = 0, reverse = false, }) {
|
|
27
|
+
(0, validation_spring_duration_js_1.validateSpringDuration)(passedDurationInFrames);
|
|
28
|
+
(0, validate_frame_js_1.validateFrame)({
|
|
29
|
+
frame: passedFrame,
|
|
30
|
+
durationInFrames: Infinity,
|
|
31
|
+
allowFloats: true,
|
|
32
|
+
});
|
|
27
33
|
(0, validate_fps_js_1.validateFps)(fps, 'to spring()', false);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
const needsToCalculateNaturalDuration = reverse || typeof passedDurationInFrames !== 'undefined';
|
|
35
|
+
const naturalDuration = needsToCalculateNaturalDuration
|
|
36
|
+
? (0, measure_spring_js_1.measureSpring)({
|
|
37
|
+
fps,
|
|
38
|
+
config,
|
|
39
|
+
from,
|
|
40
|
+
to,
|
|
41
|
+
threshold: durationRestThreshold,
|
|
42
|
+
})
|
|
43
|
+
: undefined;
|
|
44
|
+
const naturalDurationGetter = needsToCalculateNaturalDuration
|
|
45
|
+
? {
|
|
46
|
+
get: () => naturalDuration,
|
|
47
|
+
}
|
|
48
|
+
: {
|
|
49
|
+
get: () => {
|
|
50
|
+
throw new Error('did not calculate natural duration, this is an error with Remotion. Please report');
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const frame = reverse
|
|
54
|
+
? (passedDurationInFrames !== null && passedDurationInFrames !== void 0 ? passedDurationInFrames : naturalDurationGetter.get()) - passedFrame
|
|
55
|
+
: passedFrame;
|
|
38
56
|
const spr = (0, spring_utils_js_1.springCalculation)({
|
|
39
57
|
fps,
|
|
40
|
-
frame:
|
|
58
|
+
frame: (passedDurationInFrames === undefined
|
|
59
|
+
? frame
|
|
60
|
+
: frame / (passedDurationInFrames / naturalDurationGetter.get())) -
|
|
61
|
+
delay,
|
|
41
62
|
config,
|
|
42
63
|
from,
|
|
43
64
|
to,
|
|
@@ -1,5 +1,33 @@
|
|
|
1
|
+
declare const problematicCharacters: {
|
|
2
|
+
'%3A': string;
|
|
3
|
+
'%2F': string;
|
|
4
|
+
'%3F': string;
|
|
5
|
+
'%23': string;
|
|
6
|
+
'%5B': string;
|
|
7
|
+
'%5D': string;
|
|
8
|
+
'%40': string;
|
|
9
|
+
'%21': string;
|
|
10
|
+
'%24': string;
|
|
11
|
+
'%26': string;
|
|
12
|
+
'%27': string;
|
|
13
|
+
'%28': string;
|
|
14
|
+
'%29': string;
|
|
15
|
+
'%2A': string;
|
|
16
|
+
'%2B': string;
|
|
17
|
+
'%2C': string;
|
|
18
|
+
'%3B': string;
|
|
19
|
+
};
|
|
20
|
+
declare type HexCode = keyof typeof problematicCharacters;
|
|
21
|
+
export declare type HexInfo = {
|
|
22
|
+
containsHex: false;
|
|
23
|
+
} | {
|
|
24
|
+
containsHex: true;
|
|
25
|
+
hexCode: HexCode;
|
|
26
|
+
};
|
|
27
|
+
export declare const includesHexOfUnsafeChar: (path: string) => HexInfo;
|
|
1
28
|
/**
|
|
2
29
|
* @description Reference a file from the public/ folder. If the file does not appear in the autocomplete, type the path manually.
|
|
3
30
|
* @see [Documentation](https://www.remotion.dev/docs/staticfile)
|
|
4
31
|
*/
|
|
5
32
|
export declare const staticFile: (path: string) => string;
|
|
33
|
+
export {};
|
package/dist/cjs/static-file.js
CHANGED
|
@@ -1,9 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.staticFile = void 0;
|
|
3
|
+
exports.staticFile = exports.includesHexOfUnsafeChar = void 0;
|
|
4
|
+
const problematicCharacters = {
|
|
5
|
+
'%3A': ':',
|
|
6
|
+
'%2F': '/',
|
|
7
|
+
'%3F': '?',
|
|
8
|
+
'%23': '#',
|
|
9
|
+
'%5B': '[',
|
|
10
|
+
'%5D': ']',
|
|
11
|
+
'%40': '@',
|
|
12
|
+
'%21': '!',
|
|
13
|
+
'%24': '$',
|
|
14
|
+
'%26': '&',
|
|
15
|
+
'%27': "'",
|
|
16
|
+
'%28': '(',
|
|
17
|
+
'%29': ')',
|
|
18
|
+
'%2A': '*',
|
|
19
|
+
'%2B': '+',
|
|
20
|
+
'%2C': ',',
|
|
21
|
+
'%3B': ';',
|
|
22
|
+
};
|
|
23
|
+
const didWarn = {};
|
|
24
|
+
const warnOnce = (message) => {
|
|
25
|
+
if (didWarn[message]) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
console.warn(message);
|
|
29
|
+
didWarn[message] = true;
|
|
30
|
+
};
|
|
31
|
+
const includesHexOfUnsafeChar = (path) => {
|
|
32
|
+
for (const key of Object.keys(problematicCharacters)) {
|
|
33
|
+
if (path.includes(key)) {
|
|
34
|
+
return { containsHex: true, hexCode: key };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { containsHex: false };
|
|
38
|
+
};
|
|
39
|
+
exports.includesHexOfUnsafeChar = includesHexOfUnsafeChar;
|
|
4
40
|
const trimLeadingSlash = (path) => {
|
|
5
41
|
if (path.startsWith('/')) {
|
|
6
|
-
return trimLeadingSlash(path.
|
|
42
|
+
return trimLeadingSlash(path.substring(1));
|
|
7
43
|
}
|
|
8
44
|
return path;
|
|
9
45
|
};
|
|
@@ -38,7 +74,11 @@ const staticFile = (path) => {
|
|
|
38
74
|
if (path.startsWith('public/')) {
|
|
39
75
|
throw new TypeError(`Do not include the public/ prefix when using staticFile() - got "${path}". See: https://remotion.dev/docs/staticfile-relative-paths`);
|
|
40
76
|
}
|
|
41
|
-
const
|
|
77
|
+
const includesHex = (0, exports.includesHexOfUnsafeChar)(path);
|
|
78
|
+
if (includesHex.containsHex) {
|
|
79
|
+
warnOnce(`WARNING: You seem to pass an already encoded path (path contains ${includesHex.hexCode}). The encoding gets automatically handled by staticFile() `);
|
|
80
|
+
}
|
|
81
|
+
const preparsed = inner(encodeURIComponent(path));
|
|
42
82
|
if (!preparsed.startsWith('/')) {
|
|
43
83
|
return `/${preparsed}`;
|
|
44
84
|
}
|
|
@@ -51,12 +51,21 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
51
51
|
(0, warn_about_non_seekable_media_js_1.warnAboutNonSeekableMedia)(mediaRef.current, onlyWarnForMediaSeekingError ? 'console-warning' : 'console-error');
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
// Only perform a seek if the time is not already the same.
|
|
55
|
+
// Chrome rounds to 6 digits, so 0.033333333 -> 0.033333,
|
|
56
|
+
// therefore a threshold is allowed.
|
|
57
|
+
// Refer to the https://github.com/remotion-dev/video-buffering-example
|
|
58
|
+
// which is fixed by only seeking conditionally.
|
|
59
|
+
const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
|
|
54
60
|
if (!playing || absoluteFrame === 0) {
|
|
55
|
-
|
|
61
|
+
if (makesSenseToSeek) {
|
|
62
|
+
mediaRef.current.currentTime = shouldBeTime;
|
|
63
|
+
}
|
|
56
64
|
}
|
|
57
65
|
if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
if (makesSenseToSeek) {
|
|
67
|
+
mediaRef.current.currentTime = shouldBeTime;
|
|
68
|
+
}
|
|
60
69
|
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType);
|
|
61
70
|
}
|
|
62
71
|
}, [
|
package/dist/cjs/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.0.0-
|
|
1
|
+
export declare const VERSION = "4.0.0-alpha7";
|
package/dist/cjs/version.js
CHANGED
|
@@ -14,7 +14,7 @@ const VideoForDevelopment_js_1 = require("./VideoForDevelopment.js");
|
|
|
14
14
|
* @see [Documentation](https://www.remotion.dev/docs/offthreadvideo)
|
|
15
15
|
*/
|
|
16
16
|
const OffthreadVideo = (props) => {
|
|
17
|
-
const { startFrom, endAt, ...otherProps } = props;
|
|
17
|
+
const { startFrom, endAt, imageFormat, ...otherProps } = props;
|
|
18
18
|
const environment = (0, get_environment_js_1.useRemotionEnvironment)();
|
|
19
19
|
const onDuration = (0, react_1.useCallback)(() => undefined, []);
|
|
20
20
|
if (typeof props.src !== 'string') {
|
|
@@ -31,7 +31,7 @@ const OffthreadVideo = (props) => {
|
|
|
31
31
|
}
|
|
32
32
|
(0, validate_media_props_js_1.validateMediaProps)(props, 'Video');
|
|
33
33
|
if (environment === 'rendering') {
|
|
34
|
-
return (0, jsx_runtime_1.jsx)(OffthreadVideoForRendering_js_1.OffthreadVideoForRendering, { ...otherProps });
|
|
34
|
+
return ((0, jsx_runtime_1.jsx)(OffthreadVideoForRendering_js_1.OffthreadVideoForRendering, { imageFormat: imageFormat, ...otherProps }));
|
|
35
35
|
}
|
|
36
36
|
return ((0, jsx_runtime_1.jsx)(VideoForDevelopment_js_1.VideoForDevelopment, { onDuration: onDuration, onlyWarnForMediaSeekingError: true, ...otherProps }));
|
|
37
37
|
};
|
|
@@ -75,7 +75,11 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
|
|
|
75
75
|
var _a;
|
|
76
76
|
if (current === null || current === void 0 ? void 0 : current.error) {
|
|
77
77
|
console.error('Error occurred in video', current === null || current === void 0 ? void 0 : current.error);
|
|
78
|
-
|
|
78
|
+
// If user is handling the error, we don't cause an unhandled exception
|
|
79
|
+
if (props.onError) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`The browser threw an error while playing the video ${src}: Code ${current.error.code} - ${(_a = current === null || current === void 0 ? void 0 : current.error) === null || _a === void 0 ? void 0 : _a.message}. See https://remotion.dev/docs/media-playback-error for help. Pass an onError() prop to handle the error.`);
|
|
79
83
|
}
|
|
80
84
|
else {
|
|
81
85
|
throw new Error('The browser threw an error');
|
|
@@ -85,7 +89,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
|
|
|
85
89
|
return () => {
|
|
86
90
|
current.removeEventListener('error', errorHandler);
|
|
87
91
|
};
|
|
88
|
-
}, [src]);
|
|
92
|
+
}, [props.onError, src]);
|
|
89
93
|
const currentOnDurationCallback = (0, react_1.useRef)();
|
|
90
94
|
currentOnDurationCallback.current = onDuration;
|
|
91
95
|
(0, react_1.useEffect)(() => {
|
|
@@ -146,7 +146,11 @@ const VideoForRenderingForwardFunction = ({ onError, volume: volumeProp, allowAm
|
|
|
146
146
|
var _a;
|
|
147
147
|
if (current === null || current === void 0 ? void 0 : current.error) {
|
|
148
148
|
console.error('Error occurred in video', current === null || current === void 0 ? void 0 : current.error);
|
|
149
|
-
|
|
149
|
+
// If user is handling the error, we don't cause an unhandled exception
|
|
150
|
+
if (onError) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
throw new Error(`The browser threw an error while playing the video ${props.src}: Code ${current.error.code} - ${(_a = current === null || current === void 0 ? void 0 : current.error) === null || _a === void 0 ? void 0 : _a.message}. See https://remotion.dev/docs/media-playback-error for help. Pass an onError() prop to handle the error.`);
|
|
150
154
|
}
|
|
151
155
|
else {
|
|
152
156
|
throw new Error('The browser threw an error');
|
|
@@ -167,6 +171,7 @@ const VideoForRenderingForwardFunction = ({ onError, volume: volumeProp, allowAm
|
|
|
167
171
|
videoConfig.fps,
|
|
168
172
|
frame,
|
|
169
173
|
mediaStartsAt,
|
|
174
|
+
onError,
|
|
170
175
|
]);
|
|
171
176
|
const { src } = props;
|
|
172
177
|
// If video source switches, make new handle
|
package/dist/esm/index.mjs
CHANGED
|
@@ -58,7 +58,7 @@ function truthy(value) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// Automatically generated on publish
|
|
61
|
-
const VERSION = '4.0.0-
|
|
61
|
+
const VERSION = '4.0.0-alpha7';
|
|
62
62
|
|
|
63
63
|
const checkMultipleRemotionVersions = () => {
|
|
64
64
|
if (typeof globalThis === 'undefined') {
|
|
@@ -666,7 +666,7 @@ const useVideoConfig = () => {
|
|
|
666
666
|
return videoConfig;
|
|
667
667
|
};
|
|
668
668
|
|
|
669
|
-
const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, showInTimeline = true,
|
|
669
|
+
const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, showInTimeline = true, loopDisplay, ...other }, ref) => {
|
|
670
670
|
const { layout = 'absolute-fill' } = other;
|
|
671
671
|
const [id] = useState(() => String(Math.random()));
|
|
672
672
|
const parentSequence = useContext(SequenceContext);
|
|
@@ -736,7 +736,7 @@ const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity,
|
|
|
736
736
|
rootId,
|
|
737
737
|
showInTimeline,
|
|
738
738
|
nonce,
|
|
739
|
-
|
|
739
|
+
loopDisplay,
|
|
740
740
|
});
|
|
741
741
|
return () => {
|
|
742
742
|
unregisterSequence(id);
|
|
@@ -754,7 +754,7 @@ const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity,
|
|
|
754
754
|
from,
|
|
755
755
|
showInTimeline,
|
|
756
756
|
nonce,
|
|
757
|
-
|
|
757
|
+
loopDisplay,
|
|
758
758
|
environment,
|
|
759
759
|
]);
|
|
760
760
|
const endThreshold = cumulatedFrom + from + durationInFrames - 1;
|
|
@@ -781,6 +781,26 @@ const SequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity,
|
|
|
781
781
|
*/
|
|
782
782
|
const Sequence = forwardRef(SequenceRefForwardingFunction);
|
|
783
783
|
|
|
784
|
+
/**
|
|
785
|
+
* @description Get the current frame of the video. Frames are 0-indexed, meaning the first frame is 0, the last frame is the duration of the composition in frames minus one.
|
|
786
|
+
* @see [Documentation](https://remotion.dev/docs/use-current-frame)
|
|
787
|
+
*/
|
|
788
|
+
const useCurrentFrame = () => {
|
|
789
|
+
const canUseRemotionHooks = useContext(CanUseRemotionHooks);
|
|
790
|
+
if (!canUseRemotionHooks) {
|
|
791
|
+
if (typeof window !== 'undefined' && window.remotion_isPlayer) {
|
|
792
|
+
throw new Error(`useCurrentFrame can only be called inside a component that was passed to <Player>. See: https://www.remotion.dev/docs/player/examples`);
|
|
793
|
+
}
|
|
794
|
+
throw new Error(`useCurrentFrame() can only be called inside a component that was registered as a composition. See https://www.remotion.dev/docs/the-fundamentals#defining-compositions`);
|
|
795
|
+
}
|
|
796
|
+
const frame = useTimelinePosition();
|
|
797
|
+
const context = useContext(SequenceContext);
|
|
798
|
+
const contextOffset = context
|
|
799
|
+
? context.cumulatedFrom + context.relativeFrom
|
|
800
|
+
: 0;
|
|
801
|
+
return frame - contextOffset;
|
|
802
|
+
};
|
|
803
|
+
|
|
784
804
|
const validateDurationInFrames = ({ allowFloats, component, durationInFrames, }) => {
|
|
785
805
|
if (typeof durationInFrames !== 'number') {
|
|
786
806
|
throw new Error(`The "durationInFrames" prop ${component} must be a number, but you passed a value of type ${typeof durationInFrames}`);
|
|
@@ -801,6 +821,7 @@ const validateDurationInFrames = ({ allowFloats, component, durationInFrames, })
|
|
|
801
821
|
* @see [Documentation](https://www.remotion.dev/docs/loop)
|
|
802
822
|
*/
|
|
803
823
|
const Loop = ({ durationInFrames, times = Infinity, children, name, ...props }) => {
|
|
824
|
+
const currentFrame = useCurrentFrame();
|
|
804
825
|
const { durationInFrames: compDuration } = useVideoConfig();
|
|
805
826
|
validateDurationInFrames({
|
|
806
827
|
durationInFrames,
|
|
@@ -819,11 +840,17 @@ const Loop = ({ durationInFrames, times = Infinity, children, name, ...props })
|
|
|
819
840
|
const maxTimes = Math.ceil(compDuration / durationInFrames);
|
|
820
841
|
const actualTimes = Math.min(maxTimes, times);
|
|
821
842
|
const style = props.layout === 'none' ? undefined : props.style;
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
843
|
+
const maxFrame = durationInFrames * (actualTimes - 1);
|
|
844
|
+
const start = Math.floor(currentFrame / durationInFrames) * durationInFrames;
|
|
845
|
+
const from = Math.min(start, maxFrame);
|
|
846
|
+
const loopDisplay = useMemo(() => {
|
|
847
|
+
return {
|
|
848
|
+
numberOfTimes: actualTimes,
|
|
849
|
+
startOffset: -from,
|
|
850
|
+
durationInFrames,
|
|
851
|
+
};
|
|
852
|
+
}, [actualTimes, durationInFrames, from]);
|
|
853
|
+
return (jsx(Sequence, { durationInFrames: durationInFrames, from: from, name: name, loopDisplay: loopDisplay, layout: props.layout, style: style, children: children }));
|
|
827
854
|
};
|
|
828
855
|
|
|
829
856
|
const validateMediaProps = (props, component) => {
|
|
@@ -1067,26 +1094,6 @@ const random = (seed, dummy) => {
|
|
|
1067
1094
|
throw new Error('random() argument must be a number or a string');
|
|
1068
1095
|
};
|
|
1069
1096
|
|
|
1070
|
-
/**
|
|
1071
|
-
* @description Get the current frame of the video. Frames are 0-indexed, meaning the first frame is 0, the last frame is the duration of the composition in frames minus one.
|
|
1072
|
-
* @see [Documentation](https://remotion.dev/docs/use-current-frame)
|
|
1073
|
-
*/
|
|
1074
|
-
const useCurrentFrame = () => {
|
|
1075
|
-
const canUseRemotionHooks = useContext(CanUseRemotionHooks);
|
|
1076
|
-
if (!canUseRemotionHooks) {
|
|
1077
|
-
if (typeof window !== 'undefined' && window.remotion_isPlayer) {
|
|
1078
|
-
throw new Error(`useCurrentFrame can only be called inside a component that was passed to <Player>. See: https://www.remotion.dev/docs/player/examples`);
|
|
1079
|
-
}
|
|
1080
|
-
throw new Error(`useCurrentFrame() can only be called inside a component that was registered as a composition. See https://www.remotion.dev/docs/the-fundamentals#defining-compositions`);
|
|
1081
|
-
}
|
|
1082
|
-
const frame = useTimelinePosition();
|
|
1083
|
-
const context = useContext(SequenceContext);
|
|
1084
|
-
const contextOffset = context
|
|
1085
|
-
? context.cumulatedFrom + context.relativeFrom
|
|
1086
|
-
: 0;
|
|
1087
|
-
return frame - contextOffset;
|
|
1088
|
-
};
|
|
1089
|
-
|
|
1090
1097
|
const useMediaStartsAt = () => {
|
|
1091
1098
|
var _a;
|
|
1092
1099
|
const parentSequence = useContext(SequenceContext);
|
|
@@ -1176,13 +1183,13 @@ const evaluateVolume = ({ frame, volume, mediaVolume = 1, allowAmplificationDuri
|
|
|
1176
1183
|
return Math.max(0, Math.min(maxVolume, evaluated));
|
|
1177
1184
|
};
|
|
1178
1185
|
|
|
1179
|
-
const didWarn = {};
|
|
1180
|
-
const warnOnce = (message) => {
|
|
1181
|
-
if (didWarn[message]) {
|
|
1186
|
+
const didWarn$1 = {};
|
|
1187
|
+
const warnOnce$1 = (message) => {
|
|
1188
|
+
if (didWarn$1[message]) {
|
|
1182
1189
|
return;
|
|
1183
1190
|
}
|
|
1184
1191
|
console.warn(message);
|
|
1185
|
-
didWarn[message] = true;
|
|
1192
|
+
didWarn$1[message] = true;
|
|
1186
1193
|
};
|
|
1187
1194
|
const useMediaInTimeline = ({ volume, mediaVolume, mediaRef, src, mediaType, playbackRate, }) => {
|
|
1188
1195
|
const videoConfig = useVideoConfig();
|
|
@@ -1220,7 +1227,7 @@ const useMediaInTimeline = ({ volume, mediaVolume, mediaRef, src, mediaType, pla
|
|
|
1220
1227
|
}, [duration, startsAt, volume, mediaVolume]);
|
|
1221
1228
|
useEffect(() => {
|
|
1222
1229
|
if (typeof volume === 'number' && volume !== initialVolume) {
|
|
1223
|
-
warnOnce(`Remotion: The ${mediaType} with src ${src} has changed it's volume. Prefer the callback syntax for setting volume to get better timeline display: https://www.remotion.dev/docs/using-audio/#controlling-volume`);
|
|
1230
|
+
warnOnce$1(`Remotion: The ${mediaType} with src ${src} has changed it's volume. Prefer the callback syntax for setting volume to get better timeline display: https://www.remotion.dev/docs/using-audio/#controlling-volume`);
|
|
1224
1231
|
}
|
|
1225
1232
|
}, [initialVolume, mediaType, src, volume]);
|
|
1226
1233
|
useEffect(() => {
|
|
@@ -1248,7 +1255,7 @@ const useMediaInTimeline = ({ volume, mediaVolume, mediaRef, src, mediaType, pla
|
|
|
1248
1255
|
nonce,
|
|
1249
1256
|
startMediaFrom: 0 - startsAt,
|
|
1250
1257
|
doesVolumeChange,
|
|
1251
|
-
|
|
1258
|
+
loopDisplay: undefined,
|
|
1252
1259
|
playbackRate,
|
|
1253
1260
|
});
|
|
1254
1261
|
return () => {
|
|
@@ -1505,12 +1512,21 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
1505
1512
|
warnAboutNonSeekableMedia(mediaRef.current, onlyWarnForMediaSeekingError ? 'console-warning' : 'console-error');
|
|
1506
1513
|
}
|
|
1507
1514
|
}
|
|
1515
|
+
// Only perform a seek if the time is not already the same.
|
|
1516
|
+
// Chrome rounds to 6 digits, so 0.033333333 -> 0.033333,
|
|
1517
|
+
// therefore a threshold is allowed.
|
|
1518
|
+
// Refer to the https://github.com/remotion-dev/video-buffering-example
|
|
1519
|
+
// which is fixed by only seeking conditionally.
|
|
1520
|
+
const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
|
|
1508
1521
|
if (!playing || absoluteFrame === 0) {
|
|
1509
|
-
|
|
1522
|
+
if (makesSenseToSeek) {
|
|
1523
|
+
mediaRef.current.currentTime = shouldBeTime;
|
|
1524
|
+
}
|
|
1510
1525
|
}
|
|
1511
1526
|
if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
|
|
1512
|
-
|
|
1513
|
-
|
|
1527
|
+
if (makesSenseToSeek) {
|
|
1528
|
+
mediaRef.current.currentTime = shouldBeTime;
|
|
1529
|
+
}
|
|
1514
1530
|
playAndHandleNotAllowedError(mediaRef, mediaType);
|
|
1515
1531
|
}
|
|
1516
1532
|
}, [
|
|
@@ -1626,7 +1642,14 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
1626
1642
|
const sequenceContext = useContext(SequenceContext);
|
|
1627
1643
|
// Generate a string that's as unique as possible for this asset
|
|
1628
1644
|
// but at the same time deterministic. We use it to combat strict mode issues.
|
|
1629
|
-
const id = useMemo(() => `audio-${random(src !== null && src !== void 0 ? src : '')}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames}-muted:${props.muted}`, [
|
|
1645
|
+
const id = useMemo(() => `audio-${random(src !== null && src !== void 0 ? src : '')}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames}-muted:${props.muted}-loop:${props.loop}`, [
|
|
1646
|
+
src,
|
|
1647
|
+
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom,
|
|
1648
|
+
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom,
|
|
1649
|
+
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames,
|
|
1650
|
+
props.muted,
|
|
1651
|
+
props.loop,
|
|
1652
|
+
]);
|
|
1630
1653
|
const audioRef = useSharedAudio(propsToPass, id).el;
|
|
1631
1654
|
const actualVolume = useMediaTagVolume(audioRef);
|
|
1632
1655
|
useSyncVolumeWithMediaTag({
|
|
@@ -1664,12 +1687,12 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
1664
1687
|
return;
|
|
1665
1688
|
}
|
|
1666
1689
|
if (current.duration) {
|
|
1667
|
-
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, src, current.duration);
|
|
1690
|
+
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, current.src, current.duration);
|
|
1668
1691
|
return;
|
|
1669
1692
|
}
|
|
1670
1693
|
const onLoadedMetadata = () => {
|
|
1671
1694
|
var _a;
|
|
1672
|
-
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, src, current.duration);
|
|
1695
|
+
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, current.src, current.duration);
|
|
1673
1696
|
};
|
|
1674
1697
|
current.addEventListener('loadedmetadata', onLoadedMetadata);
|
|
1675
1698
|
return () => {
|
|
@@ -3552,6 +3575,7 @@ function measureSpring({ fps, config = {}, threshold = 0.005, from = 0, to = 1,
|
|
|
3552
3575
|
* @see [Documentation](https://www.remotion.dev/docs/spring)
|
|
3553
3576
|
* @param {number} frame The current time value. Most of the time you want to pass in the return value of useCurrentFrame.
|
|
3554
3577
|
* @param {number} fps The framerate at which the animation runs. Pass in the value obtained by `useVideoConfig()`.
|
|
3578
|
+
* @param {?boolean} reverse Whether the animation plays in reverse or not. Default `false`.
|
|
3555
3579
|
* @param {?Object} config optional object that allows you to customize the physical properties of the animation.
|
|
3556
3580
|
* @param {number} [config.mass=1] The weight of the spring. If you reduce the mass, the animation becomes faster!
|
|
3557
3581
|
* @param {number} [config.damping=10] How hard the animation decelerates.
|
|
@@ -3561,24 +3585,44 @@ function measureSpring({ fps, config = {}, threshold = 0.005, from = 0, to = 1,
|
|
|
3561
3585
|
* @param {?number} [config.to] The end value of the animation. Default `1`
|
|
3562
3586
|
* @param {?number} [config.durationInFrames] Stretch the duration of an animation to a set value.. Default `undefined`
|
|
3563
3587
|
* @param {?number} [config.durationThreshold] How close to the end the animation is considered to be done. Default `0.005`
|
|
3588
|
+
* @param {?number} [config.delay] Delay the animation for this amount of frames. Default `0`
|
|
3564
3589
|
*/
|
|
3565
|
-
function spring({ frame, fps, config = {}, from = 0, to = 1, durationInFrames, durationRestThreshold, }) {
|
|
3566
|
-
validateSpringDuration(
|
|
3567
|
-
validateFrame({
|
|
3590
|
+
function spring({ frame: passedFrame, fps, config = {}, from = 0, to = 1, durationInFrames: passedDurationInFrames, durationRestThreshold, delay = 0, reverse = false, }) {
|
|
3591
|
+
validateSpringDuration(passedDurationInFrames);
|
|
3592
|
+
validateFrame({
|
|
3593
|
+
frame: passedFrame,
|
|
3594
|
+
durationInFrames: Infinity,
|
|
3595
|
+
allowFloats: true,
|
|
3596
|
+
});
|
|
3568
3597
|
validateFps(fps, 'to spring()', false);
|
|
3569
|
-
const
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3598
|
+
const needsToCalculateNaturalDuration = reverse || typeof passedDurationInFrames !== 'undefined';
|
|
3599
|
+
const naturalDuration = needsToCalculateNaturalDuration
|
|
3600
|
+
? measureSpring({
|
|
3601
|
+
fps,
|
|
3602
|
+
config,
|
|
3603
|
+
from,
|
|
3604
|
+
to,
|
|
3605
|
+
threshold: durationRestThreshold,
|
|
3606
|
+
})
|
|
3607
|
+
: undefined;
|
|
3608
|
+
const naturalDurationGetter = needsToCalculateNaturalDuration
|
|
3609
|
+
? {
|
|
3610
|
+
get: () => naturalDuration,
|
|
3611
|
+
}
|
|
3612
|
+
: {
|
|
3613
|
+
get: () => {
|
|
3614
|
+
throw new Error('did not calculate natural duration, this is an error with Remotion. Please report');
|
|
3615
|
+
},
|
|
3616
|
+
};
|
|
3617
|
+
const frame = reverse
|
|
3618
|
+
? (passedDurationInFrames !== null && passedDurationInFrames !== void 0 ? passedDurationInFrames : naturalDurationGetter.get()) - passedFrame
|
|
3619
|
+
: passedFrame;
|
|
3579
3620
|
const spr = springCalculation({
|
|
3580
3621
|
fps,
|
|
3581
|
-
frame:
|
|
3622
|
+
frame: (passedDurationInFrames === undefined
|
|
3623
|
+
? frame
|
|
3624
|
+
: frame / (passedDurationInFrames / naturalDurationGetter.get())) -
|
|
3625
|
+
delay,
|
|
3582
3626
|
config,
|
|
3583
3627
|
from,
|
|
3584
3628
|
to,
|
|
@@ -3592,9 +3636,44 @@ function spring({ frame, fps, config = {}, from = 0, to = 1, durationInFrames, d
|
|
|
3592
3636
|
return Math.max(spr.current, to);
|
|
3593
3637
|
}
|
|
3594
3638
|
|
|
3639
|
+
const problematicCharacters = {
|
|
3640
|
+
'%3A': ':',
|
|
3641
|
+
'%2F': '/',
|
|
3642
|
+
'%3F': '?',
|
|
3643
|
+
'%23': '#',
|
|
3644
|
+
'%5B': '[',
|
|
3645
|
+
'%5D': ']',
|
|
3646
|
+
'%40': '@',
|
|
3647
|
+
'%21': '!',
|
|
3648
|
+
'%24': '$',
|
|
3649
|
+
'%26': '&',
|
|
3650
|
+
'%27': "'",
|
|
3651
|
+
'%28': '(',
|
|
3652
|
+
'%29': ')',
|
|
3653
|
+
'%2A': '*',
|
|
3654
|
+
'%2B': '+',
|
|
3655
|
+
'%2C': ',',
|
|
3656
|
+
'%3B': ';',
|
|
3657
|
+
};
|
|
3658
|
+
const didWarn = {};
|
|
3659
|
+
const warnOnce = (message) => {
|
|
3660
|
+
if (didWarn[message]) {
|
|
3661
|
+
return;
|
|
3662
|
+
}
|
|
3663
|
+
console.warn(message);
|
|
3664
|
+
didWarn[message] = true;
|
|
3665
|
+
};
|
|
3666
|
+
const includesHexOfUnsafeChar = (path) => {
|
|
3667
|
+
for (const key of Object.keys(problematicCharacters)) {
|
|
3668
|
+
if (path.includes(key)) {
|
|
3669
|
+
return { containsHex: true, hexCode: key };
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3672
|
+
return { containsHex: false };
|
|
3673
|
+
};
|
|
3595
3674
|
const trimLeadingSlash = (path) => {
|
|
3596
3675
|
if (path.startsWith('/')) {
|
|
3597
|
-
return trimLeadingSlash(path.
|
|
3676
|
+
return trimLeadingSlash(path.substring(1));
|
|
3598
3677
|
}
|
|
3599
3678
|
return path;
|
|
3600
3679
|
};
|
|
@@ -3629,7 +3708,11 @@ const staticFile = (path) => {
|
|
|
3629
3708
|
if (path.startsWith('public/')) {
|
|
3630
3709
|
throw new TypeError(`Do not include the public/ prefix when using staticFile() - got "${path}". See: https://remotion.dev/docs/staticfile-relative-paths`);
|
|
3631
3710
|
}
|
|
3632
|
-
const
|
|
3711
|
+
const includesHex = includesHexOfUnsafeChar(path);
|
|
3712
|
+
if (includesHex.containsHex) {
|
|
3713
|
+
warnOnce(`WARNING: You seem to pass an already encoded path (path contains ${includesHex.hexCode}). The encoding gets automatically handled by staticFile() `);
|
|
3714
|
+
}
|
|
3715
|
+
const preparsed = inner(encodeURIComponent(path));
|
|
3633
3716
|
if (!preparsed.startsWith('/')) {
|
|
3634
3717
|
return `/${preparsed}`;
|
|
3635
3718
|
}
|
|
@@ -3852,7 +3935,11 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
|
|
|
3852
3935
|
var _a;
|
|
3853
3936
|
if (current === null || current === void 0 ? void 0 : current.error) {
|
|
3854
3937
|
console.error('Error occurred in video', current === null || current === void 0 ? void 0 : current.error);
|
|
3855
|
-
|
|
3938
|
+
// If user is handling the error, we don't cause an unhandled exception
|
|
3939
|
+
if (props.onError) {
|
|
3940
|
+
return;
|
|
3941
|
+
}
|
|
3942
|
+
throw new Error(`The browser threw an error while playing the video ${src}: Code ${current.error.code} - ${(_a = current === null || current === void 0 ? void 0 : current.error) === null || _a === void 0 ? void 0 : _a.message}. See https://remotion.dev/docs/media-playback-error for help. Pass an onError() prop to handle the error.`);
|
|
3856
3943
|
}
|
|
3857
3944
|
else {
|
|
3858
3945
|
throw new Error('The browser threw an error');
|
|
@@ -3862,7 +3949,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
|
|
|
3862
3949
|
return () => {
|
|
3863
3950
|
current.removeEventListener('error', errorHandler);
|
|
3864
3951
|
};
|
|
3865
|
-
}, [src]);
|
|
3952
|
+
}, [props.onError, src]);
|
|
3866
3953
|
const currentOnDurationCallback = useRef();
|
|
3867
3954
|
currentOnDurationCallback.current = onDuration;
|
|
3868
3955
|
useEffect(() => {
|
|
@@ -3894,7 +3981,7 @@ const VideoForDevelopment = forwardRef(VideoForDevelopmentRefForwardingFunction)
|
|
|
3894
3981
|
* @see [Documentation](https://www.remotion.dev/docs/offthreadvideo)
|
|
3895
3982
|
*/
|
|
3896
3983
|
const OffthreadVideo = (props) => {
|
|
3897
|
-
const { startFrom, endAt, ...otherProps } = props;
|
|
3984
|
+
const { startFrom, endAt, imageFormat, ...otherProps } = props;
|
|
3898
3985
|
const environment = useRemotionEnvironment();
|
|
3899
3986
|
const onDuration = useCallback(() => undefined, []);
|
|
3900
3987
|
if (typeof props.src !== 'string') {
|
|
@@ -3911,7 +3998,7 @@ const OffthreadVideo = (props) => {
|
|
|
3911
3998
|
}
|
|
3912
3999
|
validateMediaProps(props, 'Video');
|
|
3913
4000
|
if (environment === 'rendering') {
|
|
3914
|
-
return jsx(OffthreadVideoForRendering, { ...otherProps });
|
|
4001
|
+
return (jsx(OffthreadVideoForRendering, { imageFormat: imageFormat, ...otherProps }));
|
|
3915
4002
|
}
|
|
3916
4003
|
return (jsx(VideoForDevelopment, { onDuration: onDuration, onlyWarnForMediaSeekingError: true, ...otherProps }));
|
|
3917
4004
|
};
|
|
@@ -4045,7 +4132,11 @@ const VideoForRenderingForwardFunction = ({ onError, volume: volumeProp, allowAm
|
|
|
4045
4132
|
var _a;
|
|
4046
4133
|
if (current === null || current === void 0 ? void 0 : current.error) {
|
|
4047
4134
|
console.error('Error occurred in video', current === null || current === void 0 ? void 0 : current.error);
|
|
4048
|
-
|
|
4135
|
+
// If user is handling the error, we don't cause an unhandled exception
|
|
4136
|
+
if (onError) {
|
|
4137
|
+
return;
|
|
4138
|
+
}
|
|
4139
|
+
throw new Error(`The browser threw an error while playing the video ${props.src}: Code ${current.error.code} - ${(_a = current === null || current === void 0 ? void 0 : current.error) === null || _a === void 0 ? void 0 : _a.message}. See https://remotion.dev/docs/media-playback-error for help. Pass an onError() prop to handle the error.`);
|
|
4049
4140
|
}
|
|
4050
4141
|
else {
|
|
4051
4142
|
throw new Error('The browser threw an error');
|
|
@@ -4066,6 +4157,7 @@ const VideoForRenderingForwardFunction = ({ onError, volume: volumeProp, allowAm
|
|
|
4066
4157
|
videoConfig.fps,
|
|
4067
4158
|
frame,
|
|
4068
4159
|
mediaStartsAt,
|
|
4160
|
+
onError,
|
|
4069
4161
|
]);
|
|
4070
4162
|
const { src } = props;
|
|
4071
4163
|
// If video source switches, make new handle
|
package/dist/esm/version.mjs
CHANGED
package/package.json
CHANGED
package/dist/cjs/config.d.ts
DELETED
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The configuration has moved to @remotion/cli.
|
|
3
|
-
* For the moment the type definitions are going to stay here
|
|
4
|
-
*/
|
|
5
|
-
import type { Configuration } from 'webpack';
|
|
6
|
-
declare type Concurrency = number | null;
|
|
7
|
-
declare type BrowserExecutable = string | null;
|
|
8
|
-
declare type FrameRange = number | [number, number];
|
|
9
|
-
declare type FfmpegExecutable = string | null;
|
|
10
|
-
declare type Loop = number | null;
|
|
11
|
-
declare type CodecOrUndefined = 'h264' | 'h265' | 'vp8' | 'vp9' | 'mp3' | 'aac' | 'wav' | 'prores' | 'h264-mkv' | 'gif' | undefined;
|
|
12
|
-
declare type Crf = number | undefined;
|
|
13
|
-
export declare type WebpackConfiguration = Configuration;
|
|
14
|
-
export declare type WebpackOverrideFn = (currentConfiguration: WebpackConfiguration) => WebpackConfiguration;
|
|
15
|
-
declare type FlatConfig = RemotionConfigObject['Bundling'] & RemotionConfigObject['Log'] & RemotionConfigObject['Preview'] & RemotionConfigObject['Puppeteer'] & RemotionConfigObject['Output'] & RemotionConfigObject['Rendering'] & {
|
|
16
|
-
/**
|
|
17
|
-
* Set the audio codec to use for the output video.
|
|
18
|
-
* See the Encoding guide in the docs for defaults and available options.
|
|
19
|
-
*/
|
|
20
|
-
setAudioCodec: (codec: 'pcm-16' | 'aac' | 'mp3' | 'opus') => void;
|
|
21
|
-
};
|
|
22
|
-
declare global {
|
|
23
|
-
interface RemotionBundlingOptions {
|
|
24
|
-
/**
|
|
25
|
-
* Specify the entry point so you don't have to specify it in the
|
|
26
|
-
* CLI command
|
|
27
|
-
*/
|
|
28
|
-
readonly setEntryPoint: (src: string) => void;
|
|
29
|
-
/**
|
|
30
|
-
* Whether Webpack bundles should be cached to make
|
|
31
|
-
* subsequent renders faster. Default: true
|
|
32
|
-
*/
|
|
33
|
-
readonly setCachingEnabled: (flag: boolean) => void;
|
|
34
|
-
/**
|
|
35
|
-
* Define on which port Remotion should start it's HTTP servers during preview and rendering.
|
|
36
|
-
* By default, Remotion will try to find a free port.
|
|
37
|
-
* If you specify a port, but it's not available, Remotion will throw an error.
|
|
38
|
-
*/
|
|
39
|
-
readonly setPort: (port: number | undefined) => void;
|
|
40
|
-
/**
|
|
41
|
-
* Define the location of the public/ directory.
|
|
42
|
-
* By default it is a folder named "public" inside the current working directory.
|
|
43
|
-
* You can set an absolute path or a relative path that will be resolved from the closest package.json location.
|
|
44
|
-
*/
|
|
45
|
-
readonly setPublicDir: (publicDir: string | null) => void;
|
|
46
|
-
readonly overrideWebpackConfig: (f: WebpackOverrideFn) => void;
|
|
47
|
-
}
|
|
48
|
-
interface RemotionConfigObject {
|
|
49
|
-
/**
|
|
50
|
-
* @deprecated New flat config format: You can now replace `Config.Preview.` with `Config.`
|
|
51
|
-
*/
|
|
52
|
-
readonly Preview: {
|
|
53
|
-
/**
|
|
54
|
-
* Change the maximum amount of tracks that are shown in the timeline.
|
|
55
|
-
* @param maxTracks The maximum amount of timeline tracks that you would like to show.
|
|
56
|
-
* @default 15
|
|
57
|
-
*/
|
|
58
|
-
readonly setMaxTimelineTracks: (maxTracks: number) => void;
|
|
59
|
-
/**
|
|
60
|
-
* Enable Keyboard shortcuts in the Remotion Preview.
|
|
61
|
-
* @param enabled Boolean whether to enable the keyboard shortcuts
|
|
62
|
-
* @default true
|
|
63
|
-
*/
|
|
64
|
-
readonly setKeyboardShortcutsEnabled: (enableShortcuts: boolean) => void;
|
|
65
|
-
/**
|
|
66
|
-
* Set number of shared audio tags. https://www.remotion.dev/docs/player/autoplay#use-the-numberofsharedaudiotags-property
|
|
67
|
-
* @param numberOfAudioTags
|
|
68
|
-
* @default 0
|
|
69
|
-
*/
|
|
70
|
-
readonly setNumberOfSharedAudioTags: (numberOfAudioTags: number) => void;
|
|
71
|
-
/**
|
|
72
|
-
* Enable Webpack polling instead of file system listeners for hot reloading in the preview.
|
|
73
|
-
* This is useful if you are using a remote directory or a virtual machine.
|
|
74
|
-
* @param interval
|
|
75
|
-
* @default null
|
|
76
|
-
*/
|
|
77
|
-
readonly setWebpackPollingInMilliseconds: (interval: number | null) => void;
|
|
78
|
-
/**
|
|
79
|
-
* Whether Remotion should open a browser when starting the Preview.
|
|
80
|
-
* @param should
|
|
81
|
-
* @default true
|
|
82
|
-
*/
|
|
83
|
-
readonly setShouldOpenBrowser: (should: boolean) => void;
|
|
84
|
-
};
|
|
85
|
-
/**
|
|
86
|
-
* @deprecated New flat config format: You can now replace `Config.Bundling.` with `Config.`
|
|
87
|
-
*/
|
|
88
|
-
readonly Bundling: RemotionBundlingOptions;
|
|
89
|
-
/**
|
|
90
|
-
* @deprecated New flat config format: You can now replace `Config.Log.` with `Config.`
|
|
91
|
-
*/
|
|
92
|
-
readonly Log: {
|
|
93
|
-
/**
|
|
94
|
-
* Set the log level.
|
|
95
|
-
* Acceptable values: 'error' | 'warning' | 'info' | 'verbose'
|
|
96
|
-
* Default value: 'info'
|
|
97
|
-
*
|
|
98
|
-
* Set this to 'verbose' to get browser logs and other IO.
|
|
99
|
-
*/
|
|
100
|
-
readonly setLevel: (newLogLevel: 'verbose' | 'info' | 'warn' | 'error') => void;
|
|
101
|
-
};
|
|
102
|
-
/**
|
|
103
|
-
* @deprecated New flat config format: You can now replace `Config.Puppeteer.` with `Config.`
|
|
104
|
-
*/
|
|
105
|
-
readonly Puppeteer: {
|
|
106
|
-
/**
|
|
107
|
-
* Specify executable path for the browser to use.
|
|
108
|
-
* Default: null, which will make Remotion find or download a version of said browser.
|
|
109
|
-
*/
|
|
110
|
-
readonly setBrowserExecutable: (newBrowserExecutablePath: BrowserExecutable) => void;
|
|
111
|
-
/**
|
|
112
|
-
* Set how many milliseconds a frame may take to render before it times out.
|
|
113
|
-
* Default: `30000`
|
|
114
|
-
*/
|
|
115
|
-
readonly setDelayRenderTimeoutInMilliseconds: (newPuppeteerTimeout: number) => void;
|
|
116
|
-
/**
|
|
117
|
-
* @deprecated Renamed to `setDelayRenderTimeoutInMilliseconds`.
|
|
118
|
-
* Set how many milliseconds a frame may take to render before it times out.
|
|
119
|
-
* Default: `30000`
|
|
120
|
-
*/
|
|
121
|
-
readonly setTimeoutInMilliseconds: (newPuppeteerTimeout: number) => void;
|
|
122
|
-
/**
|
|
123
|
-
* Setting deciding whether to disable CORS and other Chrome security features.
|
|
124
|
-
* Default: false
|
|
125
|
-
*/
|
|
126
|
-
readonly setChromiumDisableWebSecurity: (should: boolean) => void;
|
|
127
|
-
/**
|
|
128
|
-
* Setting whether to ignore any invalid SSL certificates, such as self-signed ones.
|
|
129
|
-
* Default: false
|
|
130
|
-
*/
|
|
131
|
-
readonly setChromiumIgnoreCertificateErrors: (should: boolean) => void;
|
|
132
|
-
/**
|
|
133
|
-
* If false, will open an actual browser during rendering to observe progress.
|
|
134
|
-
* Default: true
|
|
135
|
-
*/
|
|
136
|
-
readonly setChromiumHeadlessMode: (should: boolean) => void;
|
|
137
|
-
/**
|
|
138
|
-
* Set the OpenGL rendering backend for Chrome. Possible values: 'egl', 'angle', 'swiftshader' and 'swangle'.
|
|
139
|
-
* Default: 'swangle' in Lambda, null elsewhere.
|
|
140
|
-
*/
|
|
141
|
-
readonly setChromiumOpenGlRenderer: (renderer: 'swangle' | 'angle' | 'egl' | 'swiftshader') => void;
|
|
142
|
-
/**
|
|
143
|
-
* Set the user agent for Chrome. Only works during rendering.
|
|
144
|
-
* Default:
|
|
145
|
-
*/
|
|
146
|
-
readonly setChromiumUserAgent: (userAgent: string | null) => void;
|
|
147
|
-
};
|
|
148
|
-
/**
|
|
149
|
-
* @deprecated New flat config format: You can now replace `Config.Rendering.` with `Config.`
|
|
150
|
-
*/
|
|
151
|
-
readonly Rendering: {
|
|
152
|
-
/**
|
|
153
|
-
* Set a custom location for a .env file.
|
|
154
|
-
* Default: `.env`
|
|
155
|
-
*/
|
|
156
|
-
readonly setDotEnvLocation: (file: string) => void;
|
|
157
|
-
/**
|
|
158
|
-
* Sets how many Puppeteer instances will work on rendering your video in parallel.
|
|
159
|
-
* Default: `null`, meaning half of the threads available on your CPU.
|
|
160
|
-
*/
|
|
161
|
-
readonly setConcurrency: (newConcurrency: Concurrency) => void;
|
|
162
|
-
/**
|
|
163
|
-
* Set the JPEG quality for the frames.
|
|
164
|
-
* Must be between 0 and 100.
|
|
165
|
-
* Must be between 0 and 100.
|
|
166
|
-
* Default: 80
|
|
167
|
-
*/
|
|
168
|
-
readonly setQuality: (q: number | undefined) => void;
|
|
169
|
-
/** Decide in which image format to render. Can be either 'jpeg' or 'png'.
|
|
170
|
-
* PNG is slower, but supports transparency.
|
|
171
|
-
*/
|
|
172
|
-
readonly setImageFormat: (format: 'png' | 'jpeg' | 'none') => void;
|
|
173
|
-
/**
|
|
174
|
-
* Render only a subset of a video.
|
|
175
|
-
* Pass in a tuple [20, 30] to only render frames 20-30 into a video.
|
|
176
|
-
* Pass in a single number `20` to only render a single frame as an image.
|
|
177
|
-
* The frame count starts at 0.
|
|
178
|
-
*/
|
|
179
|
-
readonly setFrameRange: (newFrameRange: FrameRange | null) => void;
|
|
180
|
-
/**
|
|
181
|
-
* Specify local ffmpeg executable.
|
|
182
|
-
* Default: null, which will use ffmpeg available in PATH.
|
|
183
|
-
*/
|
|
184
|
-
readonly setFfmpegExecutable: (ffmpegPath: FfmpegExecutable) => void;
|
|
185
|
-
/**
|
|
186
|
-
* Specify local ffprobe executable.
|
|
187
|
-
* Default: null, which will use ffprobe available in PATH.
|
|
188
|
-
*/
|
|
189
|
-
readonly setFfprobeExecutable: (ffprobePath: FfmpegExecutable) => void;
|
|
190
|
-
/**
|
|
191
|
-
* Scales the output dimensions by a factor.
|
|
192
|
-
* Default: 1.
|
|
193
|
-
*/
|
|
194
|
-
readonly setScale: (newScale: number) => void;
|
|
195
|
-
/**
|
|
196
|
-
* Specify which frames should be picked for rendering a GIF
|
|
197
|
-
* Default: 1, which means every frame
|
|
198
|
-
* https://remotion.dev/docs/render-as-gif
|
|
199
|
-
*/
|
|
200
|
-
readonly setEveryNthFrame: (frame: number) => void;
|
|
201
|
-
/**
|
|
202
|
-
* Specify the number of Loop a GIF should have.
|
|
203
|
-
* Default: null (means GIF will loop infinite)
|
|
204
|
-
*/
|
|
205
|
-
readonly setNumberOfGifLoops: (newLoop: Loop) => void;
|
|
206
|
-
/**
|
|
207
|
-
* Disable audio output.
|
|
208
|
-
* Default: false
|
|
209
|
-
*/
|
|
210
|
-
readonly setMuted: (muted: boolean) => void;
|
|
211
|
-
/**
|
|
212
|
-
* Don't render an audio track if it would be silent.
|
|
213
|
-
* Default: true
|
|
214
|
-
*/
|
|
215
|
-
readonly setEnforceAudioTrack: (enforceAudioTrack: boolean) => void;
|
|
216
|
-
};
|
|
217
|
-
/**
|
|
218
|
-
* @deprecated New flat config format: You can now replace `Config.Output.` with `Config.`
|
|
219
|
-
*/
|
|
220
|
-
readonly Output: {
|
|
221
|
-
/**
|
|
222
|
-
* Set the output file location string. Default: `out/{composition}.{codec}`
|
|
223
|
-
*/
|
|
224
|
-
readonly setOutputLocation: (newOutputLocation: string) => void;
|
|
225
|
-
/**
|
|
226
|
-
* If the video file already exists, should Remotion overwrite
|
|
227
|
-
* the output? Default: true
|
|
228
|
-
*/
|
|
229
|
-
readonly setOverwriteOutput: (newOverwrite: boolean) => void;
|
|
230
|
-
/**
|
|
231
|
-
* Sets the pixel format in FFMPEG.
|
|
232
|
-
* See https://trac.ffmpeg.org/wiki/Chroma%20Subsampling for an explanation.
|
|
233
|
-
* You can override this using the `--pixel-format` Cli flag.
|
|
234
|
-
*/
|
|
235
|
-
readonly setPixelFormat: (format: 'yuv420p' | 'yuva420p' | 'yuv422p' | 'yuv444p' | 'yuv420p10le' | 'yuv422p10le' | 'yuv444p10le' | 'yuva444p10le') => void;
|
|
236
|
-
/**
|
|
237
|
-
* @deprecated Use setCodec() and setImageSequence() instead.
|
|
238
|
-
* Specify what kind of output you, either `mp4` or `png-sequence`.
|
|
239
|
-
*/
|
|
240
|
-
readonly setOutputFormat: (newLegacyFormat: 'mp4' | 'png-sequence') => void;
|
|
241
|
-
/**
|
|
242
|
-
* Specify the codec for stitching the frames into a video.
|
|
243
|
-
* Can be `h264` (default), `h265`, `vp8` or `vp9`
|
|
244
|
-
*/
|
|
245
|
-
readonly setCodec: (newCodec: CodecOrUndefined) => void;
|
|
246
|
-
/**
|
|
247
|
-
* Set the Constant Rate Factor to pass to FFMPEG.
|
|
248
|
-
* Lower values mean better quality, but be aware that the ranges of
|
|
249
|
-
* possible values greatly differs between codecs.
|
|
250
|
-
*/
|
|
251
|
-
readonly setCrf: (newCrf: Crf) => void;
|
|
252
|
-
/**
|
|
253
|
-
* Set to true if don't want a video but an image sequence as the output.
|
|
254
|
-
*/
|
|
255
|
-
readonly setImageSequence: (newImageSequence: boolean) => void;
|
|
256
|
-
/**
|
|
257
|
-
* Overrides the height of a composition
|
|
258
|
-
*/
|
|
259
|
-
readonly overrideHeight: (newHeight: number) => void;
|
|
260
|
-
/**
|
|
261
|
-
* Overrides the width of a composition
|
|
262
|
-
*/
|
|
263
|
-
readonly overrideWidth: (newWidth: number) => void;
|
|
264
|
-
/**
|
|
265
|
-
* Set the ProRes profile.
|
|
266
|
-
* This method is only valid if the codec has been set to 'prores'.
|
|
267
|
-
* Possible values: 4444-xq, 4444, hq, standard, light, proxy. Default: 'hq'
|
|
268
|
-
* See https://avpres.net/FFmpeg/im_ProRes.html for meaning of possible values.
|
|
269
|
-
*/
|
|
270
|
-
readonly setProResProfile: (profile: '4444-xq' | '4444' | 'hq' | 'standard' | 'light' | 'proxy' | undefined) => void;
|
|
271
|
-
/**
|
|
272
|
-
* Override the arguments that Remotion passes to FFMPEG.
|
|
273
|
-
* Consult https://remotion.dev/docs/renderer/render-media#ffmpegoverride before using this feature.
|
|
274
|
-
*/
|
|
275
|
-
readonly overrideFfmpegCommand: (command: (info: {
|
|
276
|
-
type: 'pre-stitcher' | 'stitcher';
|
|
277
|
-
args: string[];
|
|
278
|
-
}) => string[]) => void;
|
|
279
|
-
/**
|
|
280
|
-
* Set a target audio bitrate to be passed to FFMPEG.
|
|
281
|
-
*/
|
|
282
|
-
readonly setAudioBitrate: (bitrate: string | null) => void;
|
|
283
|
-
/**
|
|
284
|
-
* Set a target video bitrate to be passed to FFMPEG.
|
|
285
|
-
* Mutually exclusive with setCrf().
|
|
286
|
-
*/
|
|
287
|
-
readonly setVideoBitrate: (bitrate: string | null) => void;
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
export declare type ConfigType = RemotionConfigObject & FlatConfig;
|
|
292
|
-
export type { Concurrency };
|
|
293
|
-
export declare const Config: ConfigType;
|
|
294
|
-
export declare const enableLegacyRemotionConfig: () => void;
|
package/dist/cjs/config.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.enableLegacyRemotionConfig = exports.Config = void 0;
|
|
4
|
-
const conf = {};
|
|
5
|
-
let enabled = false;
|
|
6
|
-
exports.Config = new Proxy(conf, {
|
|
7
|
-
get(target, prop, receiver) {
|
|
8
|
-
if (!enabled) {
|
|
9
|
-
if (typeof document !== 'undefined') {
|
|
10
|
-
// We are in the browser
|
|
11
|
-
return {};
|
|
12
|
-
}
|
|
13
|
-
throw new Error('To use the Remotion config file, you need to have @remotion/cli installed.\n- Make sure that all versions of Remotion are the same.\n- Make sure that @remotion/cli is installed.\n- Make sure Config is imported from "@remotion/cli", not "remotion".');
|
|
14
|
-
}
|
|
15
|
-
return Reflect.get(target, prop, receiver);
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
const enableLegacyRemotionConfig = () => {
|
|
19
|
-
enabled = true;
|
|
20
|
-
};
|
|
21
|
-
exports.enableLegacyRemotionConfig = enableLegacyRemotionConfig;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const validateOffthreadVideoImageFormat: (input: unknown) => void;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateOffthreadVideoImageFormat = void 0;
|
|
4
|
-
const validateOffthreadVideoImageFormat = (input) => {
|
|
5
|
-
if (typeof input === 'undefined') {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
if (typeof input !== 'string') {
|
|
9
|
-
throw new TypeError(`<OffthreadVideo imageFormat=""> must be a string, but got ${JSON.stringify(input)} instead.`);
|
|
10
|
-
}
|
|
11
|
-
if (input !== 'png' && input !== 'jpeg') {
|
|
12
|
-
throw new TypeError(`<OffthreadVideo imageFormat=""> must be either "png" or "jpeg", but got ${input}`);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
exports.validateOffthreadVideoImageFormat = validateOffthreadVideoImageFormat;
|