remotion 4.0.534 → 4.0.536
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/README.md +1 -1
- package/dist/cjs/AbsoluteFill.d.ts +2 -7
- package/dist/cjs/AbsoluteFill.js +1 -1
- package/dist/cjs/Composition.js +15 -20
- package/dist/cjs/CompositionManager.d.ts +0 -4
- package/dist/cjs/CompositionManagerContext.d.ts +1 -6
- package/dist/cjs/CompositionManagerContext.js +0 -4
- package/dist/cjs/CompositionManagerProvider.js +77 -169
- package/dist/cjs/CompositionRegistryProvider.d.ts +5 -0
- package/dist/cjs/CompositionRegistryProvider.js +142 -0
- package/dist/cjs/DefaultPremountContext.d.ts +1 -0
- package/dist/cjs/DefaultPremountContext.js +6 -0
- package/dist/cjs/Folder.js +11 -20
- package/dist/cjs/HtmlInCanvas.d.ts +6 -4
- package/dist/cjs/HtmlInCanvas.js +179 -32
- package/dist/cjs/IFrame.js +40 -8
- package/dist/cjs/Img.d.ts +4 -2
- package/dist/cjs/Img.js +4 -3
- package/dist/cjs/Interactive.d.ts +31 -5
- package/dist/cjs/Interactive.js +40 -8
- package/dist/cjs/RemotionRoot.js +2 -1
- package/dist/cjs/Sequence.d.ts +2 -3
- package/dist/cjs/Sequence.js +117 -39
- package/dist/cjs/SequenceActivityBoundary.d.ts +10 -0
- package/dist/cjs/SequenceActivityBoundary.js +101 -0
- package/dist/cjs/SequenceActivityBudget.d.ts +13 -0
- package/dist/cjs/SequenceActivityBudget.js +196 -0
- package/dist/cjs/SequenceActivitySuspensionProvider.d.ts +4 -0
- package/dist/cjs/SequenceActivitySuspensionProvider.js +45 -0
- package/dist/cjs/SequenceManager.d.ts +9 -22
- package/dist/cjs/SequenceManager.js +54 -196
- package/dist/cjs/SequenceRegistryProvider.d.ts +4 -0
- package/dist/cjs/SequenceRegistryProvider.js +292 -0
- package/dist/cjs/Track.d.ts +10 -3
- package/dist/cjs/Track.js +8 -8
- package/dist/cjs/animated-image/AnimatedImage.d.ts +3 -2
- package/dist/cjs/animated-image/AnimatedImage.js +47 -34
- package/dist/cjs/animated-image/canvas.d.ts +2 -1
- package/dist/cjs/animated-image/canvas.js +2 -2
- package/dist/cjs/animated-image/props.d.ts +2 -1
- package/dist/cjs/asset-types.d.ts +4 -0
- package/dist/cjs/audio/AudioForPreview.js +54 -41
- package/dist/cjs/audio/get-audio-sync-anchor-tolerance.d.ts +1 -0
- package/dist/cjs/audio/get-audio-sync-anchor-tolerance.js +11 -0
- package/dist/cjs/audio/shared-audio-tags.d.ts +1 -1
- package/dist/cjs/audio/shared-audio-tags.js +1 -1
- package/dist/cjs/audio/use-audio-context.js +26 -7
- package/dist/cjs/canvas-image/CanvasImage.d.ts +3 -2
- package/dist/cjs/canvas-image/CanvasImage.js +5 -4
- package/dist/cjs/canvas-image/props.d.ts +2 -1
- package/dist/cjs/committed-metadata.d.ts +68 -0
- package/dist/cjs/committed-metadata.js +39 -0
- package/dist/cjs/component-identity.d.ts +6 -0
- package/dist/cjs/component-identity.js +39 -0
- package/dist/cjs/composition-registry-fallback.d.ts +14 -0
- package/dist/cjs/composition-registry-fallback.js +35 -0
- package/dist/cjs/create-element-source-proxy.d.ts +4 -0
- package/dist/cjs/create-element-source-proxy.js +46 -0
- package/dist/cjs/default-premount-in-seconds.d.ts +3 -0
- package/dist/cjs/default-premount-in-seconds.js +12 -0
- package/dist/cjs/effects/Solid.d.ts +3 -2
- package/dist/cjs/effects/Solid.js +5 -4
- package/dist/cjs/effects/canvas-pool.d.ts +1 -0
- package/dist/cjs/effects/canvas-pool.js +15 -10
- package/dist/cjs/effects/effect-types.d.ts +4 -0
- package/dist/cjs/effects/index.d.ts +1 -1
- package/dist/cjs/effects/run-effect-chain.d.ts +3 -1
- package/dist/cjs/effects/run-effect-chain.js +94 -56
- package/dist/cjs/effects/use-effect-chain-state.d.ts +2 -1
- package/dist/cjs/effects/use-effect-chain-state.js +11 -2
- package/dist/cjs/effects/use-memoized-effects.js +96 -17
- package/dist/cjs/enable-sequence-stack-traces.d.ts +2 -8
- package/dist/cjs/enable-sequence-stack-traces.js +7 -38
- package/dist/cjs/freeze.js +4 -1
- package/dist/cjs/index.d.ts +1 -3
- package/dist/cjs/index.js +0 -2
- package/dist/cjs/interactivity-schema.d.ts +50 -14
- package/dist/cjs/interactivity-schema.js +32 -4
- package/dist/cjs/internals.d.ts +110 -33
- package/dist/cjs/internals.js +29 -8
- package/dist/cjs/interpolate-keyframed-status.d.ts +4 -0
- package/dist/cjs/interpolate-keyframed-status.js +38 -1
- package/dist/cjs/interpolate.d.ts +12 -0
- package/dist/cjs/interpolate.js +15 -1
- package/dist/cjs/no-react.d.ts +5 -1
- package/dist/cjs/no-react.js +6 -0
- package/dist/cjs/optimistic-sequence-deletion.d.ts +17 -0
- package/dist/cjs/optimistic-sequence-deletion.js +114 -0
- package/dist/cjs/registry-store.d.ts +17 -0
- package/dist/cjs/registry-store.js +68 -0
- package/dist/cjs/sequence-activity-context.d.ts +13 -0
- package/dist/cjs/sequence-activity-context.js +21 -0
- package/dist/cjs/sequence-activity-defaults.d.ts +1 -0
- package/dist/cjs/sequence-activity-defaults.js +4 -0
- package/dist/cjs/sequence-outline.js +1 -2
- package/dist/cjs/sequence-registry-context.d.ts +26 -0
- package/dist/cjs/sequence-registry-context.js +71 -0
- package/dist/cjs/series/index.d.ts +2 -1
- package/dist/cjs/series/index.js +12 -4
- package/dist/cjs/timeline-position-state.js +11 -3
- package/dist/cjs/timeline-track-context.d.ts +1 -1
- package/dist/cjs/timeline-track-context.js +1 -2
- package/dist/cjs/use-lazy-component.js +29 -15
- package/dist/cjs/use-media-in-timeline.d.ts +7 -14
- package/dist/cjs/use-media-in-timeline.js +15 -117
- package/dist/cjs/use-premounting.js +3 -4
- package/dist/cjs/use-schema.js +3 -1
- package/dist/cjs/use-sequence-registration.d.ts +1 -1
- package/dist/cjs/use-sequence-registration.js +22 -6
- package/dist/cjs/use-timeline-seek.d.ts +1 -0
- package/dist/cjs/use-timeline-seek.js +10 -0
- package/dist/cjs/use-video.d.ts +7 -2
- package/dist/cjs/use-video.js +11 -3
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/video/VideoForPreview.js +55 -42
- package/dist/cjs/video/seek-until-right.js +11 -7
- package/dist/cjs/with-interactivity-schema.js +40 -14
- package/dist/cjs/wrap-remotion-context.d.ts +15 -3
- package/dist/cjs/wrap-remotion-context.js +101 -7
- package/dist/esm/index.mjs +3562 -2347
- package/dist/esm/no-react.mjs +74 -37
- package/dist/esm/version.mjs +1 -1
- package/package.json +2 -2
- package/dist/cjs/nonce.d.ts +0 -11
- package/dist/cjs/nonce.js +0 -42
- package/dist/cjs/sequence-order-marker.d.ts +0 -58
- package/dist/cjs/sequence-order-marker.js +0 -44
package/dist/cjs/Track.js
CHANGED
|
@@ -8,22 +8,22 @@ const interactivity_schema_js_1 = require("./interactivity-schema.js");
|
|
|
8
8
|
const Sequence_js_1 = require("./Sequence.js");
|
|
9
9
|
const timeline_track_context_js_1 = require("./timeline-track-context.js");
|
|
10
10
|
const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js");
|
|
11
|
+
// A packed row has no container bar to drag. Expose its linear timing in the
|
|
12
|
+
// inspector, but keep looping and freezing as programmatic operations.
|
|
13
|
+
const { freeze: _freeze, layout: _layout, ...trackSequenceSchema } = interactivity_schema_js_1.sequenceSchema;
|
|
11
14
|
const trackSchema = {
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
...trackSequenceSchema,
|
|
16
|
+
...interactivity_schema_js_1.sequenceTimingSchema,
|
|
14
17
|
};
|
|
15
|
-
// Series variants share the Track foundation while retaining their own
|
|
16
|
-
// Sequence props, layout defaults, and interactivity schemas.
|
|
17
18
|
const TrackWithoutSchema = ({ name = 'Track', children, layout = 'none', ...props }) => {
|
|
18
19
|
const [id] = (0, react_1.useState)(() => String(Math.random()));
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
return (jsx_runtime_1.jsx(timeline_track_context_js_1.TimelineTrackContext.Provider, { value: value, children: jsx_runtime_1.jsx(Sequence_js_1.SequenceWithoutSchema, { ...props, name: name, layout: layout, _remotionInternalTimelineTrack: { role: 'track' }, children: children }) }));
|
|
20
|
+
const value = (0, react_1.useMemo)(() => ({ id, name }), [id, name]);
|
|
21
|
+
return (jsx_runtime_1.jsx(timeline_track_context_js_1.TimelineTrackContext.Provider, { value: value, children: jsx_runtime_1.jsx(Sequence_js_1.SequenceWithoutSchema, { _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/track", ...props, name: name, layout: layout, _remotionInternalTimelineTrack: { role: 'track', seriesOffset: null }, children: children }) }));
|
|
22
22
|
};
|
|
23
23
|
exports.TrackWithoutSchema = TrackWithoutSchema;
|
|
24
24
|
/** Groups clips on one Studio timeline row and applies Sequence timing. */
|
|
25
25
|
exports.Track = (0, with_interactivity_schema_js_1.withInteractivitySchema)({
|
|
26
|
-
Component: exports.TrackWithoutSchema,
|
|
26
|
+
Component: (props) => jsx_runtime_1.jsx(exports.TrackWithoutSchema, { ...props, layout: "none" }),
|
|
27
27
|
componentName: '<Track>',
|
|
28
28
|
componentIdentity: 'dev.remotion.remotion.Track',
|
|
29
29
|
schema: trackSchema,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { SequenceControls } from '../CompositionManager.js';
|
|
3
|
-
import type { EffectsProp } from '../effects/effect-types.js';
|
|
3
|
+
import type { EffectsProp, EffectsOutputSize } from '../effects/effect-types.js';
|
|
4
4
|
export declare const animatedImageSchema: {
|
|
5
5
|
readonly 'style.transformOrigin': {
|
|
6
6
|
readonly type: "transform-origin";
|
|
@@ -115,7 +115,7 @@ export declare const animatedImageSchema: {
|
|
|
115
115
|
};
|
|
116
116
|
readonly premountFor: {
|
|
117
117
|
readonly type: "number";
|
|
118
|
-
readonly default:
|
|
118
|
+
readonly default: undefined;
|
|
119
119
|
readonly description: "Premount For";
|
|
120
120
|
readonly min: 0;
|
|
121
121
|
readonly step: 1;
|
|
@@ -236,6 +236,7 @@ export declare const AnimatedImage: React.ComponentType<import("../Interactive.j
|
|
|
236
236
|
requestInit?: RequestInit | undefined;
|
|
237
237
|
} & React.AriaAttributes & Record<`data-${string}`, string | undefined> & {
|
|
238
238
|
readonly effects?: EffectsProp | undefined;
|
|
239
|
+
readonly effectsOutputSize?: EffectsOutputSize | undefined;
|
|
239
240
|
} & {
|
|
240
241
|
readonly controls?: SequenceControls | undefined;
|
|
241
242
|
readonly ref?: React.Ref<HTMLCanvasElement> | undefined;
|
|
@@ -4,12 +4,12 @@ exports.AnimatedImage = exports.animatedImageSchema = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const react_2 = require("react");
|
|
7
|
-
const cancel_render_js_1 = require("../cancel-render.js");
|
|
8
7
|
const use_memoized_effects_js_1 = require("../effects/use-memoized-effects.js");
|
|
9
8
|
const enable_sequence_stack_traces_js_1 = require("../enable-sequence-stack-traces.js");
|
|
10
9
|
const freeze_js_1 = require("../freeze.js");
|
|
11
10
|
const interactivity_schema_js_1 = require("../interactivity-schema.js");
|
|
12
11
|
const resolve_sequence_duration_js_1 = require("../resolve-sequence-duration.js");
|
|
12
|
+
const sequence_activity_context_js_1 = require("../sequence-activity-context.js");
|
|
13
13
|
const Sequence_js_1 = require("../Sequence.js");
|
|
14
14
|
const use_crop_style_js_1 = require("../use-crop-style.js");
|
|
15
15
|
const use_current_frame_js_1 = require("../use-current-frame.js");
|
|
@@ -51,12 +51,12 @@ const getCanvasPropsFromSequenceProps = (props) => {
|
|
|
51
51
|
}
|
|
52
52
|
return canvasProps;
|
|
53
53
|
};
|
|
54
|
-
const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', requestInit, effects, controls, ...props }, canvasRef) => {
|
|
55
|
-
var _a, _b;
|
|
54
|
+
const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', requestInit, effects, effectsOutputSize, controls, ...props }, canvasRef) => {
|
|
55
|
+
var _a, _b, _c;
|
|
56
56
|
const resolvedSrc = (0, resolve_image_source_1.resolveAnimatedImageSource)(src);
|
|
57
|
-
const [
|
|
58
|
-
const
|
|
59
|
-
const
|
|
57
|
+
const [decodedImage, setDecodedImage] = (0, react_2.useState)(null);
|
|
58
|
+
const imageDecoder = (_a = decodedImage === null || decodedImage === void 0 ? void 0 : decodedImage.decoder) !== null && _a !== void 0 ? _a : null;
|
|
59
|
+
const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
|
|
60
60
|
const frame = (0, use_current_frame_js_1.useCurrentFrame)();
|
|
61
61
|
const { fps } = (0, use_video_config_js_1.useVideoConfig)();
|
|
62
62
|
const currentTime = (0, get_current_time_js_1.getCurrentTime)({ frame, playbackRate, fps });
|
|
@@ -68,8 +68,8 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
68
68
|
const ref = (0, react_2.useRef)(null);
|
|
69
69
|
const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
|
|
70
70
|
effects,
|
|
71
|
-
overrideId: (
|
|
72
|
-
videoConfigValues: (
|
|
71
|
+
overrideId: (_b = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _b !== void 0 ? _b : null,
|
|
72
|
+
videoConfigValues: (_c = controls === null || controls === void 0 ? void 0 : controls.videoConfigValues) !== null && _c !== void 0 ? _c : null,
|
|
73
73
|
});
|
|
74
74
|
(0, react_2.useImperativeHandle)(canvasRef, () => {
|
|
75
75
|
var _a;
|
|
@@ -80,7 +80,8 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
80
80
|
return c;
|
|
81
81
|
}, []);
|
|
82
82
|
const [initialLoopBehavior] = (0, react_2.useState)(() => loopBehavior);
|
|
83
|
-
(0, react_2.
|
|
83
|
+
(0, react_2.useLayoutEffect)(() => {
|
|
84
|
+
const decodeHandle = delayRender(`Rendering <AnimatedImage/> with src="${resolvedSrc}"`);
|
|
84
85
|
const controller = new AbortController();
|
|
85
86
|
let cancelled = false;
|
|
86
87
|
let continued = false;
|
|
@@ -103,8 +104,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
103
104
|
d.close();
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
106
|
-
|
|
107
|
-
continueRenderOnce();
|
|
107
|
+
setDecodedImage({ decoder: d, handle: decodeHandle });
|
|
108
108
|
})
|
|
109
109
|
.catch((err) => {
|
|
110
110
|
if (cancelled) {
|
|
@@ -119,7 +119,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
119
119
|
continueRenderOnce();
|
|
120
120
|
}
|
|
121
121
|
else {
|
|
122
|
-
|
|
122
|
+
cancelRender(err);
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
return () => {
|
|
@@ -129,11 +129,12 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
129
129
|
};
|
|
130
130
|
}, [
|
|
131
131
|
resolvedSrc,
|
|
132
|
-
decodeHandle,
|
|
133
132
|
onError,
|
|
134
133
|
requestInitKey,
|
|
135
134
|
initialLoopBehavior,
|
|
136
135
|
continueRender,
|
|
136
|
+
delayRender,
|
|
137
|
+
cancelRender,
|
|
137
138
|
]);
|
|
138
139
|
(0, react_2.useEffect)(() => {
|
|
139
140
|
return () => {
|
|
@@ -141,10 +142,12 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
141
142
|
};
|
|
142
143
|
}, [imageDecoder]);
|
|
143
144
|
(0, react_2.useLayoutEffect)(() => {
|
|
144
|
-
if (!imageDecoder) {
|
|
145
|
+
if (!imageDecoder || !decodedImage) {
|
|
145
146
|
return;
|
|
146
147
|
}
|
|
147
148
|
const delay = delayRender(`Rendering frame at ${currentTime} of <AnimatedImage src="${src}"/>`);
|
|
149
|
+
// The frame hold takes over only after the decoded image has committed.
|
|
150
|
+
continueRender(decodedImage.handle);
|
|
148
151
|
let cancelled = false;
|
|
149
152
|
imageDecoder
|
|
150
153
|
.getFrame(currentTime, loopBehavior)
|
|
@@ -172,7 +175,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
172
175
|
continueRender(delay);
|
|
173
176
|
}
|
|
174
177
|
else {
|
|
175
|
-
|
|
178
|
+
cancelRender(err);
|
|
176
179
|
}
|
|
177
180
|
});
|
|
178
181
|
return () => {
|
|
@@ -182,6 +185,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
182
185
|
}, [
|
|
183
186
|
currentTime,
|
|
184
187
|
imageDecoder,
|
|
188
|
+
decodedImage,
|
|
185
189
|
loopBehavior,
|
|
186
190
|
onError,
|
|
187
191
|
src,
|
|
@@ -191,11 +195,14 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
|
|
|
191
195
|
fit,
|
|
192
196
|
width,
|
|
193
197
|
height,
|
|
198
|
+
cancelRender,
|
|
199
|
+
effectsOutputSize === null || effectsOutputSize === void 0 ? void 0 : effectsOutputSize.width,
|
|
200
|
+
effectsOutputSize === null || effectsOutputSize === void 0 ? void 0 : effectsOutputSize.height,
|
|
194
201
|
]);
|
|
195
|
-
return (jsx_runtime_1.jsx(canvas_1.Canvas, { ref: ref, width: width, height: height, fit: fit, effects: memoizedEffects, ...props }));
|
|
202
|
+
return (jsx_runtime_1.jsx(canvas_1.Canvas, { ref: ref, width: width, height: height, fit: fit, effects: memoizedEffects, effectsOutputSize: effectsOutputSize !== null && effectsOutputSize !== void 0 ? effectsOutputSize : null, ...props }));
|
|
196
203
|
});
|
|
197
204
|
AnimatedImageContent.displayName = 'AnimatedImageContent';
|
|
198
|
-
const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, loopBehavior, id, className, style, durationInFrames, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, cropLeft, cropRight, cropTop, cropBottom, requestInit, effects = [], controls, ref, ...sequenceProps }) => {
|
|
205
|
+
const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, loopBehavior, id, className, style, durationInFrames, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, cropLeft, cropRight, cropTop, cropBottom, requestInit, effects = [], effectsOutputSize, controls, ref, ...sequenceProps }) => {
|
|
199
206
|
const actualRef = (0, react_2.useRef)(null);
|
|
200
207
|
const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
|
|
201
208
|
(0, react_2.useImperativeHandle)(ref, () => {
|
|
@@ -237,20 +244,20 @@ const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, lo
|
|
|
237
244
|
requestInit,
|
|
238
245
|
...canvasProps,
|
|
239
246
|
};
|
|
240
|
-
return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, playbackRate: playbackRate, durationInFrames: durationInFrames, name: "<AnimatedImage>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/animatedimage", controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, ...sequenceProps, children: jsx_runtime_1.jsx(AnimatedImageContent, { ...animatedImageProps, ref: actualRef, effects: effects, controls: controls }) }) }));
|
|
247
|
+
return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, playbackRate: playbackRate, durationInFrames: durationInFrames, name: "<AnimatedImage>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/animatedimage", controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, ...sequenceProps, children: jsx_runtime_1.jsx(sequence_activity_context_js_1.SequenceContent, { children: jsx_runtime_1.jsx(AnimatedImageContent, { ...animatedImageProps, ref: actualRef, effects: effects, effectsOutputSize: effectsOutputSize !== null && effectsOutputSize !== void 0 ? effectsOutputSize : null, controls: controls }) }) }) }));
|
|
241
248
|
};
|
|
242
249
|
const AnimatedImageWithIntrinsicDuration = (props) => {
|
|
243
250
|
const { fps } = (0, use_video_config_js_1.useVideoConfig)();
|
|
244
|
-
const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)();
|
|
251
|
+
const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
|
|
245
252
|
const { src, requestInit, trimBefore } = props;
|
|
246
253
|
const requestInitRef = (0, react_2.useRef)(requestInit);
|
|
247
254
|
requestInitRef.current = requestInit;
|
|
248
255
|
const onErrorRef = (0, react_2.useRef)(props.onError);
|
|
249
256
|
onErrorRef.current = props.onError;
|
|
250
|
-
const [
|
|
251
|
-
const [
|
|
252
|
-
|
|
253
|
-
|
|
257
|
+
const [duration, setDuration] = (0, react_2.useState)(null);
|
|
258
|
+
const [failedHandle, setFailedHandle] = (0, react_2.useState)(null);
|
|
259
|
+
(0, react_2.useLayoutEffect)(() => {
|
|
260
|
+
const handle = delayRender(`Finding duration of <AnimatedImage src="${src}" />`);
|
|
254
261
|
const controller = new AbortController();
|
|
255
262
|
let cancelled = false;
|
|
256
263
|
(0, get_duration_in_seconds_js_1.getAnimatedImageDurationInSeconds)({
|
|
@@ -259,9 +266,12 @@ const AnimatedImageWithIntrinsicDuration = (props) => {
|
|
|
259
266
|
requestInit: requestInitRef.current,
|
|
260
267
|
contentType: null,
|
|
261
268
|
})
|
|
262
|
-
.then((
|
|
269
|
+
.then((durationInSeconds) => {
|
|
263
270
|
if (!cancelled) {
|
|
264
|
-
|
|
271
|
+
setDuration({
|
|
272
|
+
durationInFrames: Math.ceil(durationInSeconds * fps) - (trimBefore !== null && trimBefore !== void 0 ? trimBefore : 0),
|
|
273
|
+
handle,
|
|
274
|
+
});
|
|
265
275
|
}
|
|
266
276
|
})
|
|
267
277
|
.catch((error) => {
|
|
@@ -270,10 +280,10 @@ const AnimatedImageWithIntrinsicDuration = (props) => {
|
|
|
270
280
|
}
|
|
271
281
|
if (onErrorRef.current) {
|
|
272
282
|
onErrorRef.current(error);
|
|
273
|
-
|
|
283
|
+
setFailedHandle(handle);
|
|
274
284
|
}
|
|
275
285
|
else {
|
|
276
|
-
|
|
286
|
+
cancelRender(error);
|
|
277
287
|
}
|
|
278
288
|
});
|
|
279
289
|
return () => {
|
|
@@ -281,16 +291,19 @@ const AnimatedImageWithIntrinsicDuration = (props) => {
|
|
|
281
291
|
controller.abort();
|
|
282
292
|
continueRender(handle);
|
|
283
293
|
};
|
|
284
|
-
}, [continueRender,
|
|
285
|
-
(0, react_2.
|
|
286
|
-
if (
|
|
287
|
-
continueRender(handle);
|
|
294
|
+
}, [cancelRender, continueRender, delayRender, fps, src, trimBefore]);
|
|
295
|
+
(0, react_2.useLayoutEffect)(() => {
|
|
296
|
+
if (duration !== null) {
|
|
297
|
+
continueRender(duration.handle);
|
|
298
|
+
}
|
|
299
|
+
if (failedHandle !== null) {
|
|
300
|
+
continueRender(failedHandle);
|
|
288
301
|
}
|
|
289
|
-
}, [continueRender,
|
|
290
|
-
if (
|
|
302
|
+
}, [continueRender, duration, failedHandle]);
|
|
303
|
+
if (duration === null || failedHandle !== null) {
|
|
291
304
|
return null;
|
|
292
305
|
}
|
|
293
|
-
return jsx_runtime_1.jsx(AnimatedImageInner, { ...props, durationInFrames: durationInFrames });
|
|
306
|
+
return (jsx_runtime_1.jsx(AnimatedImageInner, { ...props, durationInFrames: duration.durationInFrames }));
|
|
294
307
|
};
|
|
295
308
|
const AnimatedImageComponent = (props) => {
|
|
296
309
|
var _a;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { EffectDefinitionAndStack } from '../effects/effect-types.js';
|
|
2
|
+
import type { EffectDefinitionAndStack, EffectsOutputSize } from '../effects/effect-types.js';
|
|
3
3
|
export type AnimatedImageCanvasRef = {
|
|
4
4
|
readonly draw: (imageData: VideoFrame) => Promise<boolean>;
|
|
5
5
|
readonly getCanvas: () => HTMLCanvasElement | null;
|
|
@@ -12,4 +12,5 @@ export declare const Canvas: React.ForwardRefExoticComponent<{
|
|
|
12
12
|
readonly className?: string | undefined;
|
|
13
13
|
readonly style?: React.CSSProperties | undefined;
|
|
14
14
|
readonly effects: EffectDefinitionAndStack<unknown>[];
|
|
15
|
+
readonly effectsOutputSize: EffectsOutputSize | null;
|
|
15
16
|
} & React.AriaAttributes & Record<`data-${string}`, string | undefined> & React.RefAttributes<AnimatedImageCanvasRef>>;
|
|
@@ -39,9 +39,9 @@ const react_1 = __importStar(require("react"));
|
|
|
39
39
|
const calculate_image_fit_js_1 = require("../calculate-image-fit.js");
|
|
40
40
|
const run_effect_chain_js_1 = require("../effects/run-effect-chain.js");
|
|
41
41
|
const use_effect_chain_state_js_1 = require("../effects/use-effect-chain-state.js");
|
|
42
|
-
const CanvasRefForwardingFunction = ({ width, height, fit, className, style, effects, ...props }, ref) => {
|
|
42
|
+
const CanvasRefForwardingFunction = ({ width, height, fit, className, style, effects, effectsOutputSize, ...props }, ref) => {
|
|
43
43
|
const canvasRef = (0, react_1.useRef)(null);
|
|
44
|
-
const chainState = (0, use_effect_chain_state_js_1.useEffectChainState)();
|
|
44
|
+
const chainState = (0, use_effect_chain_state_js_1.useEffectChainState)(effectsOutputSize);
|
|
45
45
|
const sourceCanvas = (0, react_1.useMemo)(() => {
|
|
46
46
|
if (typeof document === 'undefined') {
|
|
47
47
|
return null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ImageFit } from '../calculate-image-fit.js';
|
|
2
|
-
import type { EffectsProp } from '../effects/effect-types.js';
|
|
2
|
+
import type { EffectsProp, EffectsOutputSize } from '../effects/effect-types.js';
|
|
3
3
|
import type { InteractiveBaseProps, InteractiveCropProps, InteractivePremountProps } from '../Interactive.js';
|
|
4
4
|
export type RemotionAnimatedImageLoopBehavior = 'loop' | 'pause-after-finish' | 'clear-after-finish';
|
|
5
5
|
export type AnimatedImageCanvasProps = React.AriaAttributes & Record<`data-${string}`, string | undefined>;
|
|
@@ -18,5 +18,6 @@ export type RemotionAnimatedImageProps = {
|
|
|
18
18
|
} & AnimatedImageCanvasProps;
|
|
19
19
|
export type AnimatedImageProps = InteractiveBaseProps & InteractiveCropProps & InteractivePremountProps & RemotionAnimatedImageProps & {
|
|
20
20
|
readonly effects?: EffectsProp;
|
|
21
|
+
readonly effectsOutputSize?: EffectsOutputSize;
|
|
21
22
|
};
|
|
22
23
|
export type AnimatedImageFillMode = ImageFit;
|
|
@@ -37,11 +37,12 @@ exports.AudioForPreview = void 0;
|
|
|
37
37
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
38
|
const react_1 = require("react");
|
|
39
39
|
const react_2 = __importStar(require("react"));
|
|
40
|
+
const committed_metadata_js_1 = require("../committed-metadata.js");
|
|
40
41
|
const get_cross_origin_value_js_1 = require("../get-cross-origin-value.js");
|
|
41
42
|
const log_level_context_js_1 = require("../log-level-context.js");
|
|
42
43
|
const prefetch_js_1 = require("../prefetch.js");
|
|
43
44
|
const random_js_1 = require("../random.js");
|
|
44
|
-
const
|
|
45
|
+
const sequence_activity_context_js_1 = require("../sequence-activity-context.js");
|
|
45
46
|
const SequenceContext_js_1 = require("../SequenceContext.js");
|
|
46
47
|
const use_amplification_js_1 = require("../use-amplification.js");
|
|
47
48
|
const use_media_in_timeline_js_1 = require("../use-media-in-timeline.js");
|
|
@@ -55,38 +56,24 @@ const shared_audio_tags_js_1 = require("./shared-audio-tags.js");
|
|
|
55
56
|
const use_audio_frame_js_1 = require("./use-audio-frame.js");
|
|
56
57
|
const use_media_audio_state_js_1 = require("./use-media-audio-state.js");
|
|
57
58
|
const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
58
|
-
var _a
|
|
59
|
+
var _a;
|
|
59
60
|
const [initialShouldPreMountAudioElements] = (0, react_2.useState)(props.shouldPreMountAudioTags);
|
|
60
61
|
if (props.shouldPreMountAudioTags !== initialShouldPreMountAudioElements) {
|
|
61
62
|
throw new Error('Cannot change the behavior for pre-mounting audio tags dynamically.');
|
|
62
63
|
}
|
|
63
64
|
const logLevel = (0, log_level_context_js_1.useLogLevel)();
|
|
64
|
-
const { volume, muted, playbackRate, preservePitch, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, crossOrigin, delayRenderRetries, delayRenderTimeoutInMilliseconds, toneFrequency, useWebAudioApi, onError, onNativeError, audioStreamIndex, ...nativeProps } = props;
|
|
65
|
+
const { timelineId, userPreferredVolume, isMutedForPlayback, volume, muted, playbackRate, preservePitch, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, crossOrigin, delayRenderRetries, delayRenderTimeoutInMilliseconds, toneFrequency, useWebAudioApi, onError, onNativeError, audioStreamIndex, ...nativeProps } = props;
|
|
65
66
|
// Typecheck that we are not accidentially passing unrecognized props
|
|
66
67
|
// to the DOM
|
|
67
68
|
const _propsValid = true;
|
|
68
69
|
if (!_propsValid) {
|
|
69
70
|
throw new Error('typecheck error');
|
|
70
71
|
}
|
|
71
|
-
const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
|
|
72
|
-
const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
|
|
73
72
|
if (!src) {
|
|
74
73
|
throw new TypeError("No 'src' was passed to <Html5Audio>.");
|
|
75
74
|
}
|
|
76
75
|
const preloadedSrc = (0, prefetch_js_1.usePreload)(src);
|
|
77
76
|
const sequenceContext = (0, react_2.useContext)(SequenceContext_js_1.SequenceContext);
|
|
78
|
-
const { isStudio } = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
|
79
|
-
const [timelineId] = (0, react_2.useState)(() => String(Math.random()));
|
|
80
|
-
const userPreferredVolume = (0, volume_prop_js_1.evaluateVolume)({
|
|
81
|
-
frame: volumePropFrame,
|
|
82
|
-
volume,
|
|
83
|
-
mediaVolume,
|
|
84
|
-
});
|
|
85
|
-
const { isMutedForTimeline, isMutedForPlayback } = (0, use_media_audio_state_js_1.useMediaAudioState)({
|
|
86
|
-
muted: muted !== null && muted !== void 0 ? muted : false,
|
|
87
|
-
volume: userPreferredVolume,
|
|
88
|
-
audioEnabled: true,
|
|
89
|
-
});
|
|
90
77
|
(0, volume_safeguard_js_1.warnAboutTooHighVolume)(userPreferredVolume);
|
|
91
78
|
const crossOriginValue = (0, get_cross_origin_value_js_1.getCrossOriginValue)({
|
|
92
79
|
crossOrigin,
|
|
@@ -124,26 +111,6 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
124
111
|
premounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
|
|
125
112
|
postmounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting),
|
|
126
113
|
});
|
|
127
|
-
const getStack = (0, react_1.useCallback)(() => {
|
|
128
|
-
return _remotionInternalStack !== null && _remotionInternalStack !== void 0 ? _remotionInternalStack : null;
|
|
129
|
-
}, [_remotionInternalStack]);
|
|
130
|
-
(0, use_media_in_timeline_js_1.useMediaInTimeline)({
|
|
131
|
-
volume,
|
|
132
|
-
mediaVolume,
|
|
133
|
-
src,
|
|
134
|
-
mediaType: 'audio',
|
|
135
|
-
playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
|
|
136
|
-
displayName: name !== null && name !== void 0 ? name : null,
|
|
137
|
-
id: timelineId,
|
|
138
|
-
getStack,
|
|
139
|
-
showInTimeline,
|
|
140
|
-
premountDisplay: (_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premountDisplay) !== null && _a !== void 0 ? _a : null,
|
|
141
|
-
postmountDisplay: (_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmountDisplay) !== null && _b !== void 0 ? _b : null,
|
|
142
|
-
loopDisplay: undefined,
|
|
143
|
-
loopVolumeCurveBehavior: loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat',
|
|
144
|
-
documentationLink: 'https://www.remotion.dev/docs/html5-audio',
|
|
145
|
-
muted: isMutedForTimeline,
|
|
146
|
-
});
|
|
147
114
|
// putting playback before useVolume
|
|
148
115
|
// because volume looks at playbackrate
|
|
149
116
|
(0, use_media_playback_js_1.useMediaPlayback)({
|
|
@@ -181,7 +148,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
181
148
|
*
|
|
182
149
|
* Need to import it from React to fix React 17 ESM support.
|
|
183
150
|
*/
|
|
184
|
-
const effectToUse = (
|
|
151
|
+
const effectToUse = (_a = react_2.default.useInsertionEffect) !== null && _a !== void 0 ? _a : react_2.default.useLayoutEffect;
|
|
185
152
|
// Disconnecting the SharedElementSourceNodes if the Audio tag unmounts to prevent leak.
|
|
186
153
|
// https://github.com/remotion-dev/remotion/issues/6285
|
|
187
154
|
// But useInsertionEffect will fire before other effects, meaning the
|
|
@@ -218,9 +185,55 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
218
185
|
};
|
|
219
186
|
}, [audioRef, src]);
|
|
220
187
|
if (initialShouldPreMountAudioElements) {
|
|
221
|
-
return
|
|
188
|
+
return null;
|
|
222
189
|
}
|
|
223
190
|
const audio = (jsx_runtime_1.jsx("audio", { ref: audioRef, preload: "metadata", crossOrigin: crossOriginValue, ...propsToPass }));
|
|
224
|
-
return
|
|
191
|
+
return audio;
|
|
192
|
+
};
|
|
193
|
+
const AudioForPreviewContent = (0, react_2.forwardRef)(AudioForDevelopmentForwardRefFunction);
|
|
194
|
+
const AudioForPreviewRefForwardingFunction = (props, ref) => {
|
|
195
|
+
var _a, _b;
|
|
196
|
+
const { volume, muted, playbackRate, src, name, _remotionInternalStack, showInTimeline, loopVolumeCurveBehavior, } = props;
|
|
197
|
+
const [timelineId] = (0, react_2.useState)(() => String(Math.random()));
|
|
198
|
+
const sequenceContext = (0, react_2.useContext)(SequenceContext_js_1.SequenceContext);
|
|
199
|
+
const { isStudio } = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
|
200
|
+
const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
|
|
201
|
+
const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
|
|
202
|
+
const userPreferredVolume = (0, volume_prop_js_1.evaluateVolume)({
|
|
203
|
+
frame: volumePropFrame,
|
|
204
|
+
volume,
|
|
205
|
+
mediaVolume,
|
|
206
|
+
});
|
|
207
|
+
const { isMutedForTimeline, isMutedForPlayback } = (0, use_media_audio_state_js_1.useMediaAudioState)({
|
|
208
|
+
muted: muted !== null && muted !== void 0 ? muted : false,
|
|
209
|
+
volume: userPreferredVolume,
|
|
210
|
+
audioEnabled: true,
|
|
211
|
+
});
|
|
212
|
+
const getStack = (0, react_1.useCallback)(() => {
|
|
213
|
+
return _remotionInternalStack !== null && _remotionInternalStack !== void 0 ? _remotionInternalStack : null;
|
|
214
|
+
}, [_remotionInternalStack]);
|
|
215
|
+
const { registration } = (0, use_media_in_timeline_js_1.useMediaInTimelineRegistration)({
|
|
216
|
+
src,
|
|
217
|
+
mediaType: 'audio',
|
|
218
|
+
playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
|
|
219
|
+
displayName: name !== null && name !== void 0 ? name : null,
|
|
220
|
+
id: timelineId,
|
|
221
|
+
getStack,
|
|
222
|
+
showInTimeline,
|
|
223
|
+
premountDisplay: (_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premountDisplay) !== null && _a !== void 0 ? _a : null,
|
|
224
|
+
postmountDisplay: (_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmountDisplay) !== null && _b !== void 0 ? _b : null,
|
|
225
|
+
loopDisplay: undefined,
|
|
226
|
+
documentationLink: 'https://www.remotion.dev/docs/html5-audio',
|
|
227
|
+
muted: isMutedForTimeline,
|
|
228
|
+
});
|
|
229
|
+
const metadata = (0, react_2.useMemo)(() => isStudio || registration !== null
|
|
230
|
+
? {
|
|
231
|
+
type: 'sequence',
|
|
232
|
+
id: timelineId,
|
|
233
|
+
value: registration,
|
|
234
|
+
outlineChildrenRef: null,
|
|
235
|
+
}
|
|
236
|
+
: null, [isStudio, registration, timelineId]);
|
|
237
|
+
return (jsx_runtime_1.jsx(committed_metadata_js_1.CommittedMetadataProvider, { value: null, _remotionCommitMetadata: metadata, children: jsx_runtime_1.jsx(sequence_activity_context_js_1.SequenceContent, { children: jsx_runtime_1.jsx(AudioForPreviewContent, { ...props, ref: ref, timelineId: timelineId, userPreferredVolume: userPreferredVolume, isMutedForPlayback: isMutedForPlayback }) }) }));
|
|
225
238
|
};
|
|
226
|
-
exports.AudioForPreview = (0, react_2.forwardRef)(
|
|
239
|
+
exports.AudioForPreview = (0, react_2.forwardRef)(AudioForPreviewRefForwardingFunction);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getAudioSyncAnchorTolerance: (audioContext: AudioContext) => number;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAudioSyncAnchorTolerance = void 0;
|
|
4
|
+
const ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
|
|
5
|
+
// The tolerance is measured in AudioContext seconds.
|
|
6
|
+
const getAudioSyncAnchorTolerance = (audioContext) => {
|
|
7
|
+
const { baseLatency, outputLatency } = audioContext;
|
|
8
|
+
const safeOutputLatency = outputLatency === 0 ? 0.3 : outputLatency;
|
|
9
|
+
return ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT + baseLatency + safeOutputLatency;
|
|
10
|
+
};
|
|
11
|
+
exports.getAudioSyncAnchorTolerance = getAudioSyncAnchorTolerance;
|
|
@@ -62,7 +62,7 @@ type SharedAudioContextValue = {
|
|
|
62
62
|
resumeAsAutoPlay: () => Promise<void>;
|
|
63
63
|
suspend: () => Promise<void>;
|
|
64
64
|
getIsResumingAudioContext: () => Promise<AudioContextResumeResult> | null;
|
|
65
|
-
unscheduleAudioNode: (node: AudioBufferSourceNode) =>
|
|
65
|
+
unscheduleAudioNode: (node: AudioBufferSourceNode) => boolean;
|
|
66
66
|
_experimentalKeepAudioContextAlive: boolean;
|
|
67
67
|
};
|
|
68
68
|
type SharedAudioTagsContextValue = {
|
|
@@ -127,7 +127,7 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
|
|
|
127
127
|
const prevEndTimes = (0, react_1.useRef)({ scheduledEndTime: null, mediaEndTime: null });
|
|
128
128
|
const nodesToResume = (0, react_1.useRef)(new Map());
|
|
129
129
|
const unscheduleAudioNode = (0, react_1.useCallback)((node) => {
|
|
130
|
-
nodesToResume.current.delete(node);
|
|
130
|
+
return nodesToResume.current.delete(node);
|
|
131
131
|
}, []);
|
|
132
132
|
const scheduleAudioNode = (0, react_1.useMemo)(() => {
|
|
133
133
|
return ({ node, mediaTimestamp, sourceOffset, scheduledTime, duration, offset, originalUnloopedMediaTimestamp, }) => {
|
|
@@ -46,6 +46,8 @@ const useSingletonAudioContext = ({ logLevel, latencyHint, audioEnabled, sampleR
|
|
|
46
46
|
// Tracks the state we are transitioning towards while resume()/suspend()
|
|
47
47
|
// have been called but the native state has not updated yet.
|
|
48
48
|
let transitionTarget = null;
|
|
49
|
+
let transitionId = 0;
|
|
50
|
+
let pendingResume = null;
|
|
49
51
|
const getState = () => {
|
|
50
52
|
const nativeState = audioContext.state;
|
|
51
53
|
if (transitionTarget === 'running' && nativeState !== 'running') {
|
|
@@ -57,24 +59,41 @@ const useSingletonAudioContext = ({ logLevel, latencyHint, audioEnabled, sampleR
|
|
|
57
59
|
return nativeState;
|
|
58
60
|
};
|
|
59
61
|
const resume = () => {
|
|
62
|
+
const id = ++transitionId;
|
|
60
63
|
transitionTarget = 'running';
|
|
64
|
+
// Keep resume synchronous so it retains the browser's user activation.
|
|
61
65
|
const promise = audioContext.resume();
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
pendingResume = promise;
|
|
67
|
+
return promise.finally(() => {
|
|
68
|
+
if (pendingResume === promise) {
|
|
69
|
+
pendingResume = null;
|
|
70
|
+
}
|
|
71
|
+
if (transitionId === id) {
|
|
64
72
|
transitionTarget = null;
|
|
65
73
|
}
|
|
66
74
|
});
|
|
67
|
-
return promise;
|
|
68
75
|
};
|
|
69
76
|
const suspend = () => {
|
|
77
|
+
const id = ++transitionId;
|
|
70
78
|
transitionTarget = 'suspended';
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
// Chromium can freeze the audio clock if suspend runs before an
|
|
80
|
+
// in-flight resume settles, while its reported state is still suspended.
|
|
81
|
+
// A newer playback request must cancel this deferred suspension.
|
|
82
|
+
const promise = pendingResume
|
|
83
|
+
? pendingResume
|
|
84
|
+
.catch(() => { })
|
|
85
|
+
.then(() => {
|
|
86
|
+
if (transitionId !== id) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
return audioContext.suspend();
|
|
90
|
+
})
|
|
91
|
+
: audioContext.suspend();
|
|
92
|
+
return promise.finally(() => {
|
|
93
|
+
if (transitionId === id) {
|
|
74
94
|
transitionTarget = null;
|
|
75
95
|
}
|
|
76
96
|
});
|
|
77
|
-
return promise;
|
|
78
97
|
};
|
|
79
98
|
return {
|
|
80
99
|
audioContext,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EffectsProp } from '../effects/effect-types.js';
|
|
1
|
+
import type { EffectsProp, EffectsOutputSize } from '../effects/effect-types.js';
|
|
2
2
|
import type { CanvasImageCanvasProps } from './props.js';
|
|
3
3
|
export declare const canvasImageSchema: {
|
|
4
4
|
readonly 'style.transformOrigin': {
|
|
@@ -114,7 +114,7 @@ export declare const canvasImageSchema: {
|
|
|
114
114
|
};
|
|
115
115
|
readonly premountFor: {
|
|
116
116
|
readonly type: "number";
|
|
117
|
-
readonly default:
|
|
117
|
+
readonly default: undefined;
|
|
118
118
|
readonly description: "Premount For";
|
|
119
119
|
readonly min: 0;
|
|
120
120
|
readonly step: 1;
|
|
@@ -223,6 +223,7 @@ export declare const CanvasImage: import("react").ComponentType<Omit<import("../
|
|
|
223
223
|
readonly height?: number | undefined;
|
|
224
224
|
readonly fit?: import("../calculate-image-fit.js").ImageFit | undefined;
|
|
225
225
|
readonly effects?: EffectsProp | undefined;
|
|
226
|
+
readonly effectsOutputSize?: EffectsOutputSize | undefined;
|
|
226
227
|
readonly className?: string | undefined;
|
|
227
228
|
readonly style?: import("react").CSSProperties | undefined;
|
|
228
229
|
readonly id?: string | undefined;
|