Add .gitignore to exclude all node packages and lock files
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
import React from 'react';
|
||||
export declare const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AbsoluteFill = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const hasTailwindClassName = ({ className, classPrefix, type, }) => {
|
||||
if (!className) {
|
||||
return false;
|
||||
}
|
||||
if (type === 'exact') {
|
||||
const split = className.split(' ');
|
||||
return classPrefix.some((token) => {
|
||||
return split.some((part) => {
|
||||
return (part.trim() === token ||
|
||||
part.trim().endsWith(`:${token}`) ||
|
||||
part.trim().endsWith(`!${token}`));
|
||||
});
|
||||
});
|
||||
}
|
||||
return classPrefix.some((prefix) => {
|
||||
return (className.startsWith(prefix) ||
|
||||
className.includes(` ${prefix}`) ||
|
||||
className.includes(`!${prefix}`) ||
|
||||
className.includes(`:${prefix}`));
|
||||
});
|
||||
};
|
||||
const AbsoluteFillRefForwarding = (props, ref) => {
|
||||
const { style, ...other } = props;
|
||||
const actualStyle = (0, react_1.useMemo)(() => {
|
||||
// Make TailwindCSS classes get accepted
|
||||
return {
|
||||
position: 'absolute',
|
||||
top: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: ['top-', 'inset-'],
|
||||
type: 'prefix',
|
||||
})
|
||||
? undefined
|
||||
: 0,
|
||||
left: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: ['left-', 'inset-'],
|
||||
type: 'prefix',
|
||||
})
|
||||
? undefined
|
||||
: 0,
|
||||
right: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: ['right-', 'inset-'],
|
||||
type: 'prefix',
|
||||
})
|
||||
? undefined
|
||||
: 0,
|
||||
bottom: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: ['bottom-', 'inset-'],
|
||||
type: 'prefix',
|
||||
})
|
||||
? undefined
|
||||
: 0,
|
||||
width: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: ['w-'],
|
||||
type: 'prefix',
|
||||
})
|
||||
? undefined
|
||||
: '100%',
|
||||
height: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: ['h-'],
|
||||
type: 'prefix',
|
||||
})
|
||||
? undefined
|
||||
: '100%',
|
||||
display: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: [
|
||||
'block',
|
||||
'inline-block',
|
||||
'inline',
|
||||
'flex',
|
||||
'inline-flex',
|
||||
'flow-root',
|
||||
'grid',
|
||||
'inline-grid',
|
||||
'contents',
|
||||
'list-item',
|
||||
'hidden',
|
||||
],
|
||||
type: 'exact',
|
||||
})
|
||||
? undefined
|
||||
: 'flex',
|
||||
flexDirection: hasTailwindClassName({
|
||||
className: other.className,
|
||||
classPrefix: [
|
||||
'flex-row',
|
||||
'flex-col',
|
||||
'flex-row-reverse',
|
||||
'flex-col-reverse',
|
||||
],
|
||||
type: 'exact',
|
||||
})
|
||||
? undefined
|
||||
: 'column',
|
||||
...style,
|
||||
};
|
||||
}, [other.className, style]);
|
||||
return (0, jsx_runtime_1.jsx)("div", { ref: ref, style: actualStyle, ...other });
|
||||
};
|
||||
/*
|
||||
* @description A helper component which renders an absolutely positioned <div> element with full width, height, and flex display suited for content layering.
|
||||
* @see [Documentation](https://remotion.dev/docs/absolute-fill)
|
||||
*/
|
||||
exports.AbsoluteFill = (0, react_1.forwardRef)(AbsoluteFillRefForwarding);
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import type React from 'react';
|
||||
import type { DownloadBehavior } from './download-behavior';
|
||||
declare const ArtifactThumbnail: unique symbol;
|
||||
export declare const Artifact: React.FC<{
|
||||
readonly filename: string;
|
||||
readonly content: string | Uint8Array | typeof ArtifactThumbnail;
|
||||
readonly downloadBehavior?: DownloadBehavior | null;
|
||||
}> & {
|
||||
Thumbnail: typeof ArtifactThumbnail;
|
||||
};
|
||||
export {};
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Artifact = void 0;
|
||||
const react_1 = require("react");
|
||||
const RenderAssetManager_1 = require("./RenderAssetManager");
|
||||
const use_current_frame_1 = require("./use-current-frame");
|
||||
const use_remotion_environment_1 = require("./use-remotion-environment");
|
||||
const ArtifactThumbnail = Symbol('Thumbnail');
|
||||
const Artifact = ({ filename, content, downloadBehavior }) => {
|
||||
const { registerRenderAsset, unregisterRenderAsset } = (0, react_1.useContext)(RenderAssetManager_1.RenderAssetManager);
|
||||
const env = (0, use_remotion_environment_1.useRemotionEnvironment)();
|
||||
const frame = (0, use_current_frame_1.useCurrentFrame)();
|
||||
const [id] = (0, react_1.useState)(() => {
|
||||
return String(Math.random());
|
||||
});
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
if (!env.isRendering) {
|
||||
return;
|
||||
}
|
||||
if (content instanceof Uint8Array) {
|
||||
registerRenderAsset({
|
||||
type: 'artifact',
|
||||
id,
|
||||
content: btoa(new TextDecoder('utf8').decode(content)),
|
||||
filename,
|
||||
frame,
|
||||
contentType: 'binary',
|
||||
downloadBehavior: downloadBehavior !== null && downloadBehavior !== void 0 ? downloadBehavior : null,
|
||||
});
|
||||
}
|
||||
else if (content === ArtifactThumbnail) {
|
||||
registerRenderAsset({
|
||||
type: 'artifact',
|
||||
id,
|
||||
filename,
|
||||
frame,
|
||||
contentType: 'thumbnail',
|
||||
downloadBehavior: downloadBehavior !== null && downloadBehavior !== void 0 ? downloadBehavior : null,
|
||||
});
|
||||
}
|
||||
else {
|
||||
registerRenderAsset({
|
||||
type: 'artifact',
|
||||
id,
|
||||
content,
|
||||
filename,
|
||||
frame,
|
||||
contentType: 'text',
|
||||
downloadBehavior: downloadBehavior !== null && downloadBehavior !== void 0 ? downloadBehavior : null,
|
||||
});
|
||||
}
|
||||
return () => {
|
||||
return unregisterRenderAsset(id);
|
||||
};
|
||||
}, [
|
||||
content,
|
||||
env.isRendering,
|
||||
filename,
|
||||
frame,
|
||||
id,
|
||||
registerRenderAsset,
|
||||
unregisterRenderAsset,
|
||||
downloadBehavior,
|
||||
]);
|
||||
return null;
|
||||
};
|
||||
exports.Artifact = Artifact;
|
||||
exports.Artifact.Thumbnail = ArtifactThumbnail;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
export declare const CanUseRemotionHooks: React.Context<boolean>;
|
||||
export declare const CanUseRemotionHooksProvider: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CanUseRemotionHooksProvider = exports.CanUseRemotionHooks = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
exports.CanUseRemotionHooks = (0, react_1.createContext)(false);
|
||||
const CanUseRemotionHooksProvider = ({ children }) => {
|
||||
return ((0, jsx_runtime_1.jsx)(exports.CanUseRemotionHooks.Provider, { value: true, children: children }));
|
||||
};
|
||||
exports.CanUseRemotionHooksProvider = CanUseRemotionHooksProvider;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import type React from 'react';
|
||||
/**
|
||||
* @deprecated <Clipper> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.
|
||||
*/
|
||||
export declare const Clipper: React.FC<{}>;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Clipper = void 0;
|
||||
/**
|
||||
* @deprecated <Clipper> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.
|
||||
*/
|
||||
const Clipper = () => {
|
||||
throw new Error('<Clipper> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.');
|
||||
};
|
||||
exports.Clipper = Clipper;
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
import type { ComponentType } from 'react';
|
||||
import React from 'react';
|
||||
import type { AnyZodObject } from 'zod';
|
||||
import type { Codec } from './codec.js';
|
||||
import type { InferProps, PropsIfHasProps } from './props-if-has-props.js';
|
||||
import type { ProResProfile } from './prores-profile.js';
|
||||
import type { PixelFormat, VideoImageFormat } from './render-types.js';
|
||||
type LooseComponentType<T> = ComponentType<T> | ((props: T) => React.ReactNode);
|
||||
export type CompProps<Props> = {
|
||||
lazyComponent: () => Promise<{
|
||||
default: LooseComponentType<Props>;
|
||||
}>;
|
||||
} | {
|
||||
component: LooseComponentType<Props>;
|
||||
};
|
||||
export type CalcMetadataReturnType<T extends Record<string, unknown>> = {
|
||||
durationInFrames?: number;
|
||||
fps?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
props?: T;
|
||||
defaultCodec?: Codec;
|
||||
defaultOutName?: string;
|
||||
defaultVideoImageFormat?: VideoImageFormat;
|
||||
defaultPixelFormat?: PixelFormat;
|
||||
defaultProResProfile?: ProResProfile;
|
||||
};
|
||||
export type CalculateMetadataFunction<T extends Record<string, unknown>> = (options: {
|
||||
defaultProps: T;
|
||||
props: T;
|
||||
abortSignal: AbortSignal;
|
||||
compositionId: string;
|
||||
isRendering: boolean;
|
||||
}) => Promise<CalcMetadataReturnType<T>> | CalcMetadataReturnType<T>;
|
||||
type OptionalDimensions<Schema extends AnyZodObject, Props extends Record<string, unknown>> = {
|
||||
width?: number;
|
||||
height?: number;
|
||||
calculateMetadata: CalculateMetadataFunction<InferProps<Schema, Props>>;
|
||||
};
|
||||
type MandatoryDimensions<Schema extends AnyZodObject, Props extends Record<string, unknown>> = {
|
||||
width: number;
|
||||
height: number;
|
||||
calculateMetadata?: CalculateMetadataFunction<InferProps<Schema, Props>>;
|
||||
};
|
||||
type StillCalculateMetadataOrExplicit<Schema extends AnyZodObject, Props extends Record<string, unknown>> = OptionalDimensions<Schema, Props> | MandatoryDimensions<Schema, Props>;
|
||||
export type CompositionCalculateMetadataOrExplicit<Schema extends AnyZodObject, Props extends Record<string, unknown>> = (OptionalDimensions<Schema, Props> & {
|
||||
fps?: number;
|
||||
durationInFrames?: number;
|
||||
}) | (MandatoryDimensions<Schema, Props> & {
|
||||
fps: number;
|
||||
durationInFrames: number;
|
||||
});
|
||||
export type StillProps<Schema extends AnyZodObject, Props extends Record<string, unknown>> = {
|
||||
id: string;
|
||||
schema?: Schema;
|
||||
} & StillCalculateMetadataOrExplicit<Schema, Props> & CompProps<Props> & PropsIfHasProps<Schema, Props>;
|
||||
export type CompositionProps<Schema extends AnyZodObject, Props extends Record<string, unknown>> = {
|
||||
readonly id: string;
|
||||
readonly schema?: Schema;
|
||||
} & CompositionCalculateMetadataOrExplicit<Schema, Props> & CompProps<Props> & PropsIfHasProps<Schema, Props>;
|
||||
export declare const Composition: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(props: CompositionProps<Schema, Props>) => import("react/jsx-runtime.js").JSX.Element | null;
|
||||
export {};
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Composition = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const react_dom_1 = require("react-dom");
|
||||
const CanUseRemotionHooks_js_1 = require("./CanUseRemotionHooks.js");
|
||||
const CompositionManagerContext_js_1 = require("./CompositionManagerContext.js");
|
||||
const Folder_js_1 = require("./Folder.js");
|
||||
const ResolveCompositionConfig_js_1 = require("./ResolveCompositionConfig.js");
|
||||
const input_props_serialization_js_1 = require("./input-props-serialization.js");
|
||||
const is_player_js_1 = require("./is-player.js");
|
||||
const loading_indicator_js_1 = require("./loading-indicator.js");
|
||||
const nonce_js_1 = require("./nonce.js");
|
||||
const portal_node_js_1 = require("./portal-node.js");
|
||||
const use_delay_render_js_1 = require("./use-delay-render.js");
|
||||
const use_lazy_component_js_1 = require("./use-lazy-component.js");
|
||||
const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
|
||||
const use_video_js_1 = require("./use-video.js");
|
||||
const validate_composition_id_js_1 = require("./validation/validate-composition-id.js");
|
||||
const validate_default_props_js_1 = require("./validation/validate-default-props.js");
|
||||
const Fallback = () => {
|
||||
const { continueRender, delayRender } = (0, use_delay_render_js_1.useDelayRender)();
|
||||
(0, react_1.useEffect)(() => {
|
||||
const fallback = delayRender('Waiting for Root component to unsuspend');
|
||||
return () => continueRender(fallback);
|
||||
}, [continueRender, delayRender]);
|
||||
return null;
|
||||
};
|
||||
const InnerComposition = ({ width, height, fps, durationInFrames, id, defaultProps, schema, ...compProps }) => {
|
||||
var _a, _b, _c;
|
||||
const compManager = (0, react_1.useContext)(CompositionManagerContext_js_1.CompositionSetters);
|
||||
const { registerComposition, unregisterComposition } = compManager;
|
||||
const video = (0, use_video_js_1.useVideo)();
|
||||
const lazy = (0, use_lazy_component_js_1.useLazyComponent)({
|
||||
compProps: compProps,
|
||||
componentName: 'Composition',
|
||||
noSuspense: false,
|
||||
});
|
||||
const nonce = (0, nonce_js_1.useNonce)();
|
||||
const isPlayer = (0, is_player_js_1.useIsPlayer)();
|
||||
const environment = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
||||
const canUseComposition = (0, react_1.useContext)(CanUseRemotionHooks_js_1.CanUseRemotionHooks);
|
||||
// Record seen composition IDs as early as possible so that overlays can access them
|
||||
if (typeof window !== 'undefined') {
|
||||
window.remotion_seenCompositionIds = Array.from(new Set([...((_a = window.remotion_seenCompositionIds) !== null && _a !== void 0 ? _a : []), id]));
|
||||
}
|
||||
if (canUseComposition) {
|
||||
if (isPlayer) {
|
||||
throw new Error('<Composition> was mounted inside the `component` that was passed to the <Player>. See https://remotion.dev/docs/wrong-composition-mount for help.');
|
||||
}
|
||||
throw new Error('<Composition> mounted inside another composition. See https://remotion.dev/docs/wrong-composition-mount for help.');
|
||||
}
|
||||
const { folderName, parentName } = (0, react_1.useContext)(Folder_js_1.FolderContext);
|
||||
(0, react_1.useEffect)(() => {
|
||||
var _a;
|
||||
// Ensure it's a URL safe id
|
||||
if (!id) {
|
||||
throw new Error('No id for composition passed.');
|
||||
}
|
||||
(0, validate_composition_id_js_1.validateCompositionId)(id);
|
||||
(0, validate_default_props_js_1.validateDefaultAndInputProps)(defaultProps, 'defaultProps', id);
|
||||
registerComposition({
|
||||
durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : undefined,
|
||||
fps: fps !== null && fps !== void 0 ? fps : undefined,
|
||||
height: height !== null && height !== void 0 ? height : undefined,
|
||||
width: width !== null && width !== void 0 ? width : undefined,
|
||||
id,
|
||||
folderName,
|
||||
component: lazy,
|
||||
defaultProps: (0, input_props_serialization_js_1.serializeThenDeserializeInStudio)((defaultProps !== null && defaultProps !== void 0 ? defaultProps : {})),
|
||||
nonce,
|
||||
parentFolderName: parentName,
|
||||
schema: schema !== null && schema !== void 0 ? schema : null,
|
||||
calculateMetadata: (_a = compProps.calculateMetadata) !== null && _a !== void 0 ? _a : null,
|
||||
});
|
||||
return () => {
|
||||
unregisterComposition(id);
|
||||
};
|
||||
}, [
|
||||
durationInFrames,
|
||||
fps,
|
||||
height,
|
||||
lazy,
|
||||
id,
|
||||
folderName,
|
||||
defaultProps,
|
||||
width,
|
||||
nonce,
|
||||
parentName,
|
||||
schema,
|
||||
compProps.calculateMetadata,
|
||||
registerComposition,
|
||||
unregisterComposition,
|
||||
]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
window.dispatchEvent(new CustomEvent(ResolveCompositionConfig_js_1.PROPS_UPDATED_EXTERNALLY, {
|
||||
detail: {
|
||||
resetUnsaved: id,
|
||||
},
|
||||
}));
|
||||
}, [defaultProps, id]);
|
||||
const resolved = (0, ResolveCompositionConfig_js_1.useResolvedVideoConfig)(id);
|
||||
if (environment.isStudio &&
|
||||
video &&
|
||||
video.component === lazy &&
|
||||
video.id === id) {
|
||||
const Comp = lazy;
|
||||
if (resolved === null ||
|
||||
(resolved.type !== 'success' &&
|
||||
resolved.type !== 'success-and-refreshing')) {
|
||||
return null;
|
||||
}
|
||||
return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(CanUseRemotionHooks_js_1.CanUseRemotionHooksProvider, { children: (0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: (0, jsx_runtime_1.jsx)(loading_indicator_js_1.Loading, {}), children: (0, jsx_runtime_1.jsx)(Comp, { ...((_b = resolved.result.props) !== null && _b !== void 0 ? _b : {}) }) }) }), (0, portal_node_js_1.portalNode)());
|
||||
}
|
||||
if (environment.isRendering &&
|
||||
video &&
|
||||
video.component === lazy &&
|
||||
video.id === id) {
|
||||
const Comp = lazy;
|
||||
if (resolved === null ||
|
||||
(resolved.type !== 'success' &&
|
||||
resolved.type !== 'success-and-refreshing')) {
|
||||
return null;
|
||||
}
|
||||
return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(CanUseRemotionHooks_js_1.CanUseRemotionHooksProvider, { children: (0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: (0, jsx_runtime_1.jsx)(Fallback, {}), children: (0, jsx_runtime_1.jsx)(Comp, { ...((_c = resolved.result.props) !== null && _c !== void 0 ? _c : {}) }) }) }), (0, portal_node_js_1.portalNode)());
|
||||
}
|
||||
return null;
|
||||
};
|
||||
/*
|
||||
* @description This component is used to register a video to make it renderable and make it show in the sidebar, in dev mode.
|
||||
* @see [Documentation](https://remotion.dev/docs/composition)
|
||||
*/
|
||||
const Composition = (props) => {
|
||||
const { onlyRenderComposition } = (0, react_1.useContext)(CompositionManagerContext_js_1.CompositionSetters);
|
||||
if (onlyRenderComposition && onlyRenderComposition !== props.id) {
|
||||
return null;
|
||||
}
|
||||
// @ts-expect-error
|
||||
return (0, jsx_runtime_1.jsx)(InnerComposition, { ...props });
|
||||
};
|
||||
exports.Composition = Composition;
|
||||
Generated
Vendored
+101
@@ -0,0 +1,101 @@
|
||||
import type { ComponentType, LazyExoticComponent } from 'react';
|
||||
import React from 'react';
|
||||
import type { AnyZodObject } from 'zod';
|
||||
import type { CalculateMetadataFunction } from './Composition.js';
|
||||
import type { DownloadBehavior } from './download-behavior.js';
|
||||
import type { InferProps, PropsIfHasProps } from './props-if-has-props.js';
|
||||
export type TComposition<Schema extends AnyZodObject, Props extends Record<string, unknown>> = {
|
||||
width: number | undefined;
|
||||
height: number | undefined;
|
||||
fps: number | undefined;
|
||||
durationInFrames: number | undefined;
|
||||
id: string;
|
||||
folderName: string | null;
|
||||
parentFolderName: string | null;
|
||||
component: LazyExoticComponent<ComponentType<Props>> | ComponentType<Props>;
|
||||
nonce: number;
|
||||
schema: Schema | null;
|
||||
calculateMetadata: CalculateMetadataFunction<InferProps<Schema, Props>> | null;
|
||||
} & PropsIfHasProps<Schema, Props>;
|
||||
export type AnyComposition = TComposition<AnyZodObject, Record<string, unknown>>;
|
||||
export type TCompMetadataWithCalcFunction<Schema extends AnyZodObject, Props extends Record<string, unknown>> = Pick<TComposition<Schema, Props>, 'id' | 'height' | 'width' | 'fps' | 'durationInFrames' | 'defaultProps' | 'calculateMetadata'>;
|
||||
export type TCompMetadata<Schema extends AnyZodObject, Props extends Record<string, unknown>> = Pick<TComposition<Schema, Props>, 'id' | 'height' | 'width' | 'fps' | 'durationInFrames' | 'defaultProps'>;
|
||||
export type AnyCompMetadata = TCompMetadata<AnyZodObject, Record<string, unknown>>;
|
||||
type EnhancedTSequenceData = {
|
||||
type: 'sequence';
|
||||
} | {
|
||||
type: 'audio';
|
||||
src: string;
|
||||
volume: string | number;
|
||||
doesVolumeChange: boolean;
|
||||
startMediaFrom: number;
|
||||
playbackRate: number;
|
||||
} | {
|
||||
type: 'video';
|
||||
src: string;
|
||||
volume: string | number;
|
||||
doesVolumeChange: boolean;
|
||||
startMediaFrom: number;
|
||||
playbackRate: number;
|
||||
};
|
||||
export type LoopDisplay = {
|
||||
numberOfTimes: number;
|
||||
startOffset: number;
|
||||
durationInFrames: number;
|
||||
};
|
||||
export type TSequence = {
|
||||
from: number;
|
||||
duration: number;
|
||||
id: string;
|
||||
displayName: string;
|
||||
parent: string | null;
|
||||
rootId: string;
|
||||
showInTimeline: boolean;
|
||||
nonce: number;
|
||||
loopDisplay: LoopDisplay | undefined;
|
||||
stack: string | null;
|
||||
premountDisplay: number | null;
|
||||
postmountDisplay: number | null;
|
||||
} & EnhancedTSequenceData;
|
||||
export type AudioOrVideoAsset = {
|
||||
type: 'audio' | 'video';
|
||||
src: string;
|
||||
id: string;
|
||||
frame: number;
|
||||
volume: number;
|
||||
mediaFrame: number;
|
||||
playbackRate: number;
|
||||
toneFrequency: number;
|
||||
audioStartFrame: number;
|
||||
audioStreamIndex: number;
|
||||
};
|
||||
export type InlineAudioAsset = {
|
||||
type: 'inline-audio';
|
||||
id: string;
|
||||
audio: Int16Array | number[];
|
||||
frame: number;
|
||||
timestamp: number;
|
||||
duration: number;
|
||||
toneFrequency: number;
|
||||
};
|
||||
type DiscriminatedArtifact = {
|
||||
contentType: 'binary';
|
||||
content: string;
|
||||
} | {
|
||||
contentType: 'text';
|
||||
content: string;
|
||||
} | {
|
||||
contentType: 'thumbnail';
|
||||
};
|
||||
export type ArtifactAsset = {
|
||||
type: 'artifact';
|
||||
id: string;
|
||||
filename: string;
|
||||
frame: number;
|
||||
downloadBehavior: DownloadBehavior | null;
|
||||
} & DiscriminatedArtifact;
|
||||
export type TRenderAsset = AudioOrVideoAsset | ArtifactAsset | InlineAudioAsset;
|
||||
export declare const compositionsRef: React.RefObject<{
|
||||
getCompositions: () => AnyComposition[];
|
||||
} | null>;
|
||||
export {};
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.compositionsRef = void 0;
|
||||
const react_1 = __importDefault(require("react"));
|
||||
exports.compositionsRef = react_1.default.createRef();
|
||||
Generated
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
import type React from 'react';
|
||||
import type { AnyZodObject } from 'zod';
|
||||
import type { AnyComposition, TComposition } from './CompositionManager.js';
|
||||
import type { TFolder } from './Folder.js';
|
||||
import type { VideoConfig } from './video-config.js';
|
||||
export type BaseMetadata = Pick<VideoConfig, 'durationInFrames' | 'fps' | 'props' | 'height' | 'width' | 'defaultCodec' | 'defaultOutName' | 'defaultVideoImageFormat' | 'defaultPixelFormat' | 'defaultProResProfile'>;
|
||||
export type CanvasContent = {
|
||||
type: 'composition';
|
||||
compositionId: string;
|
||||
} | {
|
||||
type: 'asset';
|
||||
asset: string;
|
||||
} | {
|
||||
type: 'output';
|
||||
path: string;
|
||||
} | {
|
||||
type: 'output-blob';
|
||||
displayName: string;
|
||||
getBlob: () => Promise<Blob>;
|
||||
width: number;
|
||||
height: number;
|
||||
sizeInBytes: number;
|
||||
};
|
||||
export type CompositionManagerSetters = {
|
||||
registerComposition: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(comp: TComposition<Schema, Props>) => void;
|
||||
unregisterComposition: (name: string) => void;
|
||||
registerFolder: (name: string, parent: string | null) => void;
|
||||
unregisterFolder: (name: string, parent: string | null) => void;
|
||||
setCanvasContent: React.Dispatch<React.SetStateAction<CanvasContent | null>>;
|
||||
updateCompositionDefaultProps: (id: string, newDefaultProps: Record<string, unknown>) => void;
|
||||
onlyRenderComposition: string | null;
|
||||
};
|
||||
export type CompositionManagerContext = {
|
||||
compositions: AnyComposition[];
|
||||
currentCompositionMetadata: BaseMetadata | null;
|
||||
folders: TFolder[];
|
||||
canvasContent: CanvasContent | null;
|
||||
};
|
||||
export declare const CompositionManager: React.Context<CompositionManagerContext>;
|
||||
export declare const CompositionSetters: React.Context<CompositionManagerSetters>;
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompositionSetters = exports.CompositionManager = void 0;
|
||||
const react_1 = require("react");
|
||||
exports.CompositionManager = (0, react_1.createContext)({
|
||||
compositions: [],
|
||||
folders: [],
|
||||
currentCompositionMetadata: null,
|
||||
canvasContent: null,
|
||||
});
|
||||
exports.CompositionSetters = (0, react_1.createContext)({
|
||||
registerComposition: () => undefined,
|
||||
unregisterComposition: () => undefined,
|
||||
registerFolder: () => undefined,
|
||||
unregisterFolder: () => undefined,
|
||||
setCanvasContent: () => undefined,
|
||||
updateCompositionDefaultProps: () => undefined,
|
||||
onlyRenderComposition: null,
|
||||
});
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import { type AnyComposition } from './CompositionManager';
|
||||
import type { CanvasContent } from './CompositionManagerContext';
|
||||
import type { BaseMetadata } from './CompositionManagerContext.js';
|
||||
export declare const CompositionManagerProvider: ({ children, onlyRenderComposition, currentCompositionMetadata, initialCompositions, initialCanvasContent, }: {
|
||||
readonly children: React.ReactNode;
|
||||
readonly onlyRenderComposition: string | null;
|
||||
readonly currentCompositionMetadata: BaseMetadata | null;
|
||||
readonly initialCompositions: AnyComposition[];
|
||||
readonly initialCanvasContent: CanvasContent | null;
|
||||
}) => import("react/jsx-runtime").JSX.Element;
|
||||
Generated
Vendored
+100
@@ -0,0 +1,100 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompositionManagerProvider = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const CompositionManager_1 = require("./CompositionManager");
|
||||
const CompositionManagerContext_1 = require("./CompositionManagerContext");
|
||||
const CompositionManagerProvider = ({ children, onlyRenderComposition, currentCompositionMetadata, initialCompositions, initialCanvasContent, }) => {
|
||||
const [folders, setFolders] = (0, react_1.useState)([]);
|
||||
const [canvasContent, setCanvasContent] = (0, react_1.useState)(initialCanvasContent);
|
||||
const [compositions, setCompositions] = (0, react_1.useState)(initialCompositions);
|
||||
// CompositionManagerProvider state
|
||||
const currentcompositionsRef = (0, react_1.useRef)(compositions);
|
||||
const updateCompositions = (0, react_1.useCallback)((updateComps) => {
|
||||
setCompositions((comps) => {
|
||||
const updated = updateComps(comps);
|
||||
currentcompositionsRef.current = updated;
|
||||
return updated;
|
||||
});
|
||||
}, []);
|
||||
const registerComposition = (0, react_1.useCallback)((comp) => {
|
||||
updateCompositions((comps) => {
|
||||
if (comps.find((c) => c.id === comp.id)) {
|
||||
throw new Error(`Multiple composition with id ${comp.id} are registered.`);
|
||||
}
|
||||
const value = [...comps, comp]
|
||||
.slice()
|
||||
.sort((a, b) => a.nonce - b.nonce);
|
||||
return value;
|
||||
});
|
||||
}, [updateCompositions]);
|
||||
const unregisterComposition = (0, react_1.useCallback)((id) => {
|
||||
setCompositions((comps) => {
|
||||
return comps.filter((c) => c.id !== id);
|
||||
});
|
||||
}, []);
|
||||
const registerFolder = (0, react_1.useCallback)((name, parent) => {
|
||||
setFolders((prevFolders) => {
|
||||
return [
|
||||
...prevFolders,
|
||||
{
|
||||
name,
|
||||
parent,
|
||||
},
|
||||
];
|
||||
});
|
||||
}, []);
|
||||
const unregisterFolder = (0, react_1.useCallback)((name, parent) => {
|
||||
setFolders((prevFolders) => {
|
||||
return prevFolders.filter((p) => !(p.name === name && p.parent === parent));
|
||||
});
|
||||
}, []);
|
||||
(0, react_1.useImperativeHandle)(CompositionManager_1.compositionsRef, () => {
|
||||
return {
|
||||
getCompositions: () => currentcompositionsRef.current,
|
||||
};
|
||||
}, []);
|
||||
const updateCompositionDefaultProps = (0, react_1.useCallback)((id, newDefaultProps) => {
|
||||
setCompositions((comps) => {
|
||||
const updated = comps.map((c) => {
|
||||
if (c.id === id) {
|
||||
return {
|
||||
...c,
|
||||
defaultProps: newDefaultProps,
|
||||
};
|
||||
}
|
||||
return c;
|
||||
});
|
||||
return updated;
|
||||
});
|
||||
}, []);
|
||||
const compositionManagerSetters = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
registerComposition,
|
||||
unregisterComposition,
|
||||
registerFolder,
|
||||
unregisterFolder,
|
||||
setCanvasContent,
|
||||
updateCompositionDefaultProps,
|
||||
onlyRenderComposition,
|
||||
};
|
||||
}, [
|
||||
registerComposition,
|
||||
registerFolder,
|
||||
unregisterComposition,
|
||||
unregisterFolder,
|
||||
updateCompositionDefaultProps,
|
||||
onlyRenderComposition,
|
||||
]);
|
||||
const compositionManagerContextValue = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
compositions,
|
||||
folders,
|
||||
currentCompositionMetadata,
|
||||
canvasContent,
|
||||
};
|
||||
}, [compositions, folders, currentCompositionMetadata, canvasContent]);
|
||||
return ((0, jsx_runtime_1.jsx)(CompositionManagerContext_1.CompositionManager.Provider, { value: compositionManagerContextValue, children: (0, jsx_runtime_1.jsx)(CompositionManagerContext_1.CompositionSetters.Provider, { value: compositionManagerSetters, children: children }) }));
|
||||
};
|
||||
exports.CompositionManagerProvider = CompositionManagerProvider;
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import type { SyntheticEvent } from 'react';
|
||||
import React from 'react';
|
||||
type Props = Record<string, Record<string, unknown>>;
|
||||
export type EditorPropsContextType = {
|
||||
props: Props;
|
||||
updateProps: (options: {
|
||||
id: string;
|
||||
defaultProps: Record<string, unknown>;
|
||||
newProps: Record<string, unknown> | ((oldProps: Record<string, unknown>) => Record<string, unknown>);
|
||||
}) => void;
|
||||
resetUnsaved: (compositionId: string) => void;
|
||||
};
|
||||
export declare const EditorPropsContext: React.Context<EditorPropsContextType>;
|
||||
export declare const editorPropsProviderRef: React.RefObject<{
|
||||
getProps: () => Props;
|
||||
setProps: React.Dispatch<React.SetStateAction<Props>>;
|
||||
} | null>;
|
||||
export declare const timeValueRef: React.RefObject<{
|
||||
goToFrame: () => void;
|
||||
seek: (newFrame: number) => void;
|
||||
play: (e?: SyntheticEvent | PointerEvent) => void;
|
||||
pause: () => void;
|
||||
toggle: (e?: SyntheticEvent | PointerEvent) => void;
|
||||
} | null>;
|
||||
export declare const EditorPropsProvider: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
export {};
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EditorPropsProvider = exports.timeValueRef = exports.editorPropsProviderRef = exports.EditorPropsContext = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
exports.EditorPropsContext = (0, react_1.createContext)({
|
||||
props: {},
|
||||
updateProps: () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
resetUnsaved: () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
});
|
||||
exports.editorPropsProviderRef = react_1.default.createRef();
|
||||
exports.timeValueRef = react_1.default.createRef();
|
||||
const EditorPropsProvider = ({ children }) => {
|
||||
const [props, setProps] = react_1.default.useState({});
|
||||
const updateProps = (0, react_1.useCallback)(({ defaultProps, id, newProps, }) => {
|
||||
setProps((prev) => {
|
||||
var _a;
|
||||
return {
|
||||
...prev,
|
||||
[id]: typeof newProps === 'function'
|
||||
? newProps((_a = prev[id]) !== null && _a !== void 0 ? _a : defaultProps)
|
||||
: newProps,
|
||||
};
|
||||
});
|
||||
}, []);
|
||||
const resetUnsaved = (0, react_1.useCallback)((compositionId) => {
|
||||
setProps((prev) => {
|
||||
if (prev[compositionId]) {
|
||||
const newProps = { ...prev };
|
||||
delete newProps[compositionId];
|
||||
return newProps;
|
||||
}
|
||||
return prev;
|
||||
});
|
||||
}, []);
|
||||
(0, react_1.useImperativeHandle)(exports.editorPropsProviderRef, () => {
|
||||
return {
|
||||
getProps: () => props,
|
||||
setProps,
|
||||
};
|
||||
}, [props]);
|
||||
const ctx = (0, react_1.useMemo)(() => {
|
||||
return { props, updateProps, resetUnsaved };
|
||||
}, [props, resetUnsaved, updateProps]);
|
||||
return ((0, jsx_runtime_1.jsx)(exports.EditorPropsContext.Provider, { value: ctx, children: children }));
|
||||
};
|
||||
exports.EditorPropsProvider = EditorPropsProvider;
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import type { FC } from 'react';
|
||||
export type TFolder = {
|
||||
name: string;
|
||||
parent: string | null;
|
||||
};
|
||||
type FolderContextType = {
|
||||
folderName: string | null;
|
||||
parentName: string | null;
|
||||
};
|
||||
export declare const FolderContext: import("react").Context<FolderContextType>;
|
||||
export declare const Folder: FC<{
|
||||
readonly name: string;
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
export {};
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Folder = exports.FolderContext = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const CompositionManagerContext_js_1 = require("./CompositionManagerContext.js");
|
||||
const truthy_js_1 = require("./truthy.js");
|
||||
const validate_folder_name_js_1 = require("./validation/validate-folder-name.js");
|
||||
exports.FolderContext = (0, react_1.createContext)({
|
||||
folderName: null,
|
||||
parentName: null,
|
||||
});
|
||||
/*
|
||||
* @description By wrapping a <Composition /> inside a <Folder />, you can visually categorize it in your sidebar, should you have many compositions.
|
||||
* @see [Documentation](https://remotion.dev/docs/folder)
|
||||
*/
|
||||
const Folder = ({ name, children }) => {
|
||||
const parent = (0, react_1.useContext)(exports.FolderContext);
|
||||
const { registerFolder, unregisterFolder } = (0, react_1.useContext)(CompositionManagerContext_js_1.CompositionSetters);
|
||||
(0, validate_folder_name_js_1.validateFolderName)(name);
|
||||
const parentNameArr = [parent.parentName, parent.folderName].filter(truthy_js_1.truthy);
|
||||
const parentName = parentNameArr.length === 0 ? null : parentNameArr.join('/');
|
||||
const value = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
folderName: name,
|
||||
parentName,
|
||||
};
|
||||
}, [name, parentName]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
registerFolder(name, parentName);
|
||||
return () => {
|
||||
unregisterFolder(name, parentName);
|
||||
};
|
||||
}, [name, parent.folderName, parentName, registerFolder, unregisterFolder]);
|
||||
return ((0, jsx_runtime_1.jsx)(exports.FolderContext.Provider, { value: value, children: children }));
|
||||
};
|
||||
exports.Folder = Folder;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
export declare const IFrame: React.ForwardRefExoticComponent<Omit<React.ClassAttributes<HTMLIFrameElement> & React.IframeHTMLAttributes<HTMLIFrameElement> & {
|
||||
readonly delayRenderRetries?: number;
|
||||
readonly delayRenderTimeoutInMilliseconds?: number;
|
||||
}, "ref"> & React.RefAttributes<HTMLIFrameElement>>;
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.IFrame = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const use_delay_render_js_1 = require("./use-delay-render.js");
|
||||
const IFrameRefForwarding = ({ onLoad, onError, delayRenderRetries, delayRenderTimeoutInMilliseconds, ...props }, ref) => {
|
||||
const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)();
|
||||
const [handle] = (0, react_1.useState)(() => delayRender(`Loading <IFrame> with source ${props.src}`, {
|
||||
retries: delayRenderRetries !== null && delayRenderRetries !== void 0 ? delayRenderRetries : undefined,
|
||||
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds !== null && delayRenderTimeoutInMilliseconds !== void 0 ? delayRenderTimeoutInMilliseconds : undefined,
|
||||
}));
|
||||
const didLoad = (0, react_1.useCallback)((e) => {
|
||||
continueRender(handle);
|
||||
onLoad === null || onLoad === void 0 ? void 0 : onLoad(e);
|
||||
}, [handle, onLoad, continueRender]);
|
||||
const didGetError = (0, react_1.useCallback)((e) => {
|
||||
continueRender(handle);
|
||||
if (onError) {
|
||||
onError(e);
|
||||
}
|
||||
else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Error loading iframe:', e, 'Handle the event using the onError() prop to make this message disappear.');
|
||||
}
|
||||
}, [handle, onError, continueRender]);
|
||||
return ((0, jsx_runtime_1.jsx)("iframe", { referrerPolicy: "strict-origin-when-cross-origin", ...props, ref: ref, onError: didGetError, onLoad: didLoad }));
|
||||
};
|
||||
/*
|
||||
* @description The <IFrame /> can be used like a regular <iframe> HTML tag.
|
||||
* @see [Documentation](https://remotion.dev/docs/iframe)
|
||||
*/
|
||||
exports.IFrame = (0, react_1.forwardRef)(IFrameRefForwarding);
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
type NativeImgProps = Omit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, 'src'>;
|
||||
export type ImgProps = NativeImgProps & {
|
||||
readonly maxRetries?: number;
|
||||
readonly pauseWhenLoading?: boolean;
|
||||
readonly delayRenderRetries?: number;
|
||||
readonly delayRenderTimeoutInMilliseconds?: number;
|
||||
readonly onImageFrame?: (imageElement: HTMLImageElement) => void;
|
||||
readonly src: string;
|
||||
};
|
||||
export declare const Img: React.ForwardRefExoticComponent<Omit<ImgProps, "ref"> & React.RefAttributes<HTMLImageElement>>;
|
||||
export {};
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Img = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const SequenceContext_js_1 = require("./SequenceContext.js");
|
||||
const cancel_render_js_1 = require("./cancel-render.js");
|
||||
const get_cross_origin_value_js_1 = require("./get-cross-origin-value.js");
|
||||
const prefetch_js_1 = require("./prefetch.js");
|
||||
const use_buffer_state_js_1 = require("./use-buffer-state.js");
|
||||
const use_delay_render_js_1 = require("./use-delay-render.js");
|
||||
const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
|
||||
function exponentialBackoff(errorCount) {
|
||||
return 1000 * 2 ** (errorCount - 1);
|
||||
}
|
||||
const ImgRefForwarding = ({ onError, maxRetries = 2, src, pauseWhenLoading, delayRenderRetries, delayRenderTimeoutInMilliseconds, onImageFrame, crossOrigin, ...props }, ref) => {
|
||||
const imageRef = (0, react_1.useRef)(null);
|
||||
const errors = (0, react_1.useRef)({});
|
||||
const { delayPlayback } = (0, use_buffer_state_js_1.useBufferState)();
|
||||
const sequenceContext = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
||||
if (!src) {
|
||||
throw new Error('No "src" prop was passed to <Img>.');
|
||||
}
|
||||
const _propsValid = true;
|
||||
if (!_propsValid) {
|
||||
throw new Error('typecheck error');
|
||||
}
|
||||
(0, react_1.useImperativeHandle)(ref, () => {
|
||||
return imageRef.current;
|
||||
}, []);
|
||||
const actualSrc = (0, prefetch_js_1.usePreload)(src);
|
||||
const retryIn = (0, react_1.useCallback)((timeout) => {
|
||||
if (!imageRef.current) {
|
||||
return;
|
||||
}
|
||||
const currentSrc = imageRef.current.src;
|
||||
setTimeout(() => {
|
||||
var _a;
|
||||
if (!imageRef.current) {
|
||||
// Component has been unmounted, do not retry
|
||||
return;
|
||||
}
|
||||
const newSrc = (_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src;
|
||||
if (newSrc !== currentSrc) {
|
||||
// src has changed, do not retry
|
||||
return;
|
||||
}
|
||||
imageRef.current.removeAttribute('src');
|
||||
imageRef.current.setAttribute('src', newSrc);
|
||||
}, timeout);
|
||||
}, []);
|
||||
const didGetError = (0, react_1.useCallback)((e) => {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
||||
if (!errors.current) {
|
||||
return;
|
||||
}
|
||||
errors.current[(_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src] =
|
||||
((_c = errors.current[(_b = imageRef.current) === null || _b === void 0 ? void 0 : _b.src]) !== null && _c !== void 0 ? _c : 0) + 1;
|
||||
if (onError &&
|
||||
((_e = errors.current[(_d = imageRef.current) === null || _d === void 0 ? void 0 : _d.src]) !== null && _e !== void 0 ? _e : 0) > maxRetries) {
|
||||
onError(e);
|
||||
return;
|
||||
}
|
||||
if (((_g = errors.current[(_f = imageRef.current) === null || _f === void 0 ? void 0 : _f.src]) !== null && _g !== void 0 ? _g : 0) <= maxRetries) {
|
||||
const backoff = exponentialBackoff((_j = errors.current[(_h = imageRef.current) === null || _h === void 0 ? void 0 : _h.src]) !== null && _j !== void 0 ? _j : 0);
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Could not load image with source ${(_k = imageRef.current) === null || _k === void 0 ? void 0 : _k.src}, retrying again in ${backoff}ms`);
|
||||
retryIn(backoff);
|
||||
return;
|
||||
}
|
||||
(0, cancel_render_js_1.cancelRender)('Error loading image with src: ' + ((_l = imageRef.current) === null || _l === void 0 ? void 0 : _l.src));
|
||||
}, [maxRetries, onError, retryIn]);
|
||||
const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)();
|
||||
if (typeof window !== 'undefined') {
|
||||
const isPremounting = Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting);
|
||||
const isPostmounting = Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting);
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
var _a, _b;
|
||||
if (((_b = (_a = window.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.NODE_ENV) === 'test') {
|
||||
if (imageRef.current) {
|
||||
imageRef.current.src = actualSrc;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const { current } = imageRef;
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
const newHandle = delayRender('Loading <Img> with src=' + actualSrc, {
|
||||
retries: delayRenderRetries !== null && delayRenderRetries !== void 0 ? delayRenderRetries : undefined,
|
||||
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds !== null && delayRenderTimeoutInMilliseconds !== void 0 ? delayRenderTimeoutInMilliseconds : undefined,
|
||||
});
|
||||
const unblock = pauseWhenLoading && !isPremounting && !isPostmounting
|
||||
? delayPlayback().unblock
|
||||
: () => undefined;
|
||||
let unmounted = false;
|
||||
const onComplete = () => {
|
||||
var _a, _b, _c, _d;
|
||||
// the decode() promise isn't cancelable -- it may still resolve after unmounting
|
||||
if (unmounted) {
|
||||
continueRender(newHandle);
|
||||
return;
|
||||
}
|
||||
if (((_b = errors.current[(_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src]) !== null && _b !== void 0 ? _b : 0) > 0) {
|
||||
delete errors.current[(_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.src];
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`Retry successful - ${(_d = imageRef.current) === null || _d === void 0 ? void 0 : _d.src} is now loaded`);
|
||||
}
|
||||
if (current) {
|
||||
onImageFrame === null || onImageFrame === void 0 ? void 0 : onImageFrame(current);
|
||||
}
|
||||
unblock();
|
||||
continueRender(newHandle);
|
||||
};
|
||||
if (!imageRef.current) {
|
||||
onComplete();
|
||||
return;
|
||||
}
|
||||
current.src = actualSrc;
|
||||
current
|
||||
.decode()
|
||||
.then(onComplete)
|
||||
.catch((err) => {
|
||||
// fall back to onload event if decode() fails
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(err);
|
||||
if (current.complete) {
|
||||
onComplete();
|
||||
}
|
||||
else {
|
||||
current.addEventListener('load', onComplete);
|
||||
}
|
||||
});
|
||||
// If tag gets unmounted, clear pending handles because image is not going to load
|
||||
return () => {
|
||||
unmounted = true;
|
||||
current.removeEventListener('load', onComplete);
|
||||
unblock();
|
||||
continueRender(newHandle);
|
||||
};
|
||||
}, [
|
||||
actualSrc,
|
||||
delayPlayback,
|
||||
delayRenderRetries,
|
||||
delayRenderTimeoutInMilliseconds,
|
||||
pauseWhenLoading,
|
||||
isPremounting,
|
||||
isPostmounting,
|
||||
onImageFrame,
|
||||
continueRender,
|
||||
delayRender,
|
||||
]);
|
||||
}
|
||||
const { isClientSideRendering } = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
||||
const crossOriginValue = (0, get_cross_origin_value_js_1.getCrossOriginValue)({
|
||||
crossOrigin,
|
||||
requestsVideoFrame: false,
|
||||
isClientSideRendering,
|
||||
});
|
||||
// src gets set once we've loaded and decoded the image.
|
||||
return ((0, jsx_runtime_1.jsx)("img", { ...props, ref: imageRef, crossOrigin: crossOriginValue, onError: didGetError, decoding: "sync" }));
|
||||
};
|
||||
/*
|
||||
* @description Works just like a regular HTML img tag. When you use the <Img> tag, Remotion will ensure that the image is loaded before rendering the frame.
|
||||
* @see [Documentation](https://remotion.dev/docs/img)
|
||||
*/
|
||||
exports.Img = (0, react_1.forwardRef)(ImgRefForwarding);
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* @deprecated <Null /> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.
|
||||
*/
|
||||
export declare const Null: React.FC;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Null = void 0;
|
||||
/**
|
||||
* @deprecated <Null /> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.
|
||||
*/
|
||||
const Null = () => {
|
||||
throw new Error('<Null> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.');
|
||||
};
|
||||
exports.Null = Null;
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import type { LogLevel } from './log.js';
|
||||
export declare const RemotionRootContexts: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
readonly numberOfAudioTags: number;
|
||||
readonly logLevel: LogLevel;
|
||||
readonly audioLatencyHint: AudioContextLatencyCategory;
|
||||
readonly videoEnabled: boolean;
|
||||
readonly audioEnabled: boolean;
|
||||
readonly frameState: Record<string, number> | null;
|
||||
readonly nonceContextSeed: number;
|
||||
}>;
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RemotionRootContexts = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const EditorProps_js_1 = require("./EditorProps.js");
|
||||
const SequenceManager_js_1 = require("./SequenceManager.js");
|
||||
const TimelineContext_js_1 = require("./TimelineContext.js");
|
||||
const shared_audio_tags_js_1 = require("./audio/shared-audio-tags.js");
|
||||
const buffering_js_1 = require("./buffering.js");
|
||||
const log_level_context_js_1 = require("./log-level-context.js");
|
||||
const nonce_js_1 = require("./nonce.js");
|
||||
const prefetch_state_js_1 = require("./prefetch-state.js");
|
||||
const use_media_enabled_js_1 = require("./use-media-enabled.js");
|
||||
const duration_state_js_1 = require("./video/duration-state.js");
|
||||
const RemotionRootContexts = ({ children, numberOfAudioTags, logLevel, audioLatencyHint, videoEnabled, audioEnabled, frameState, nonceContextSeed, }) => {
|
||||
const nonceContext = (0, react_1.useMemo)(() => {
|
||||
let counter = 0;
|
||||
return {
|
||||
getNonce: () => counter++,
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [nonceContextSeed]);
|
||||
const logging = (0, react_1.useMemo)(() => {
|
||||
return { logLevel, mountTime: Date.now() };
|
||||
}, [logLevel]);
|
||||
return ((0, jsx_runtime_1.jsx)(log_level_context_js_1.LogLevelContext.Provider, { value: logging, children: (0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: nonceContext, children: (0, jsx_runtime_1.jsx)(TimelineContext_js_1.TimelineContextProvider, { frameState: frameState, children: (0, jsx_runtime_1.jsx)(use_media_enabled_js_1.MediaEnabledProvider, { videoEnabled: videoEnabled, audioEnabled: audioEnabled, children: (0, jsx_runtime_1.jsx)(EditorProps_js_1.EditorPropsProvider, { children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(SequenceManager_js_1.SequenceManagerProvider, { children: (0, jsx_runtime_1.jsx)(shared_audio_tags_js_1.SharedAudioContextProvider, { numberOfAudioTags: numberOfAudioTags, audioLatencyHint: audioLatencyHint, audioEnabled: audioEnabled, children: (0, jsx_runtime_1.jsx)(duration_state_js_1.DurationsContextProvider, { children: (0, jsx_runtime_1.jsx)(buffering_js_1.BufferingProvider, { children: children }) }) }) }) }) }) }) }) }) }));
|
||||
};
|
||||
exports.RemotionRootContexts = RemotionRootContexts;
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
import type { TRenderAsset } from './CompositionManager.js';
|
||||
export type RenderAssetManagerContext = {
|
||||
registerRenderAsset: (renderAsset: TRenderAsset) => void;
|
||||
unregisterRenderAsset: (id: string) => void;
|
||||
renderAssets: TRenderAsset[];
|
||||
};
|
||||
export declare const RenderAssetManager: import("react").Context<RenderAssetManagerContext>;
|
||||
export type CollectAssetsRef = {
|
||||
collectAssets: () => TRenderAsset[];
|
||||
};
|
||||
export declare const RenderAssetManagerProvider: React.FC<{
|
||||
children: React.ReactNode;
|
||||
collectAssets: null | React.RefObject<CollectAssetsRef | null>;
|
||||
}>;
|
||||
Generated
Vendored
+57
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RenderAssetManagerProvider = exports.RenderAssetManager = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const validate_artifact_js_1 = require("./validation/validate-artifact.js");
|
||||
exports.RenderAssetManager = (0, react_1.createContext)({
|
||||
// Must be undefined, otherwise error in Player
|
||||
registerRenderAsset: () => undefined,
|
||||
unregisterRenderAsset: () => undefined,
|
||||
renderAssets: [],
|
||||
});
|
||||
const RenderAssetManagerProvider = ({ children, collectAssets }) => {
|
||||
const [renderAssets, setRenderAssets] = (0, react_1.useState)([]);
|
||||
const renderAssetsRef = (0, react_1.useRef)([]);
|
||||
const registerRenderAsset = (0, react_1.useCallback)((renderAsset) => {
|
||||
(0, validate_artifact_js_1.validateRenderAsset)(renderAsset);
|
||||
renderAssetsRef.current = [...renderAssetsRef.current, renderAsset];
|
||||
setRenderAssets(renderAssetsRef.current);
|
||||
}, []);
|
||||
if (collectAssets) {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
(0, react_1.useImperativeHandle)(collectAssets, () => {
|
||||
return {
|
||||
collectAssets: () => {
|
||||
const assets = renderAssetsRef.current;
|
||||
renderAssetsRef.current = [];
|
||||
setRenderAssets([]);
|
||||
return assets;
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
const unregisterRenderAsset = (0, react_1.useCallback)((id) => {
|
||||
renderAssetsRef.current = renderAssetsRef.current.filter((a) => a.id !== id);
|
||||
setRenderAssets(renderAssetsRef.current);
|
||||
}, []);
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.remotion_collectAssets = () => {
|
||||
const assets = renderAssetsRef.current;
|
||||
renderAssetsRef.current = [];
|
||||
setRenderAssets([]);
|
||||
return assets;
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
const contextValue = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
registerRenderAsset,
|
||||
unregisterRenderAsset,
|
||||
renderAssets,
|
||||
};
|
||||
}, [renderAssets, registerRenderAsset, unregisterRenderAsset]);
|
||||
return ((0, jsx_runtime_1.jsx)(exports.RenderAssetManager.Provider, { value: contextValue, children: children }));
|
||||
};
|
||||
exports.RenderAssetManagerProvider = RenderAssetManagerProvider;
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
import type { AnyComposition } from './CompositionManager.js';
|
||||
import type { VideoConfig } from './video-config.js';
|
||||
type ResolveCompositionConfigContect = Record<string, VideoConfigState | undefined>;
|
||||
export declare const ResolveCompositionContext: import("react").Context<ResolveCompositionConfigContect | null>;
|
||||
export declare const resolveCompositionsRef: import("react").RefObject<{
|
||||
setCurrentRenderModalComposition: (compositionId: string | null) => void;
|
||||
reloadCurrentlySelectedComposition: () => void;
|
||||
} | null>;
|
||||
type VideoConfigState = {
|
||||
type: 'loading';
|
||||
} | {
|
||||
type: 'success';
|
||||
result: VideoConfig;
|
||||
} | {
|
||||
type: 'success-and-refreshing';
|
||||
result: VideoConfig;
|
||||
} | {
|
||||
type: 'error';
|
||||
error: Error;
|
||||
};
|
||||
export declare const needsResolution: (composition: AnyComposition) => boolean;
|
||||
export declare const PROPS_UPDATED_EXTERNALLY = "remotion.propsUpdatedExternally";
|
||||
export declare const useResolvedVideoConfig: (preferredCompositionId: string | null) => VideoConfigState | null;
|
||||
export {};
|
||||
Generated
Vendored
+98
@@ -0,0 +1,98 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useResolvedVideoConfig = exports.PROPS_UPDATED_EXTERNALLY = exports.needsResolution = exports.resolveCompositionsRef = exports.ResolveCompositionContext = void 0;
|
||||
const react_1 = require("react");
|
||||
const CompositionManagerContext_js_1 = require("./CompositionManagerContext.js");
|
||||
const EditorProps_js_1 = require("./EditorProps.js");
|
||||
const input_props_js_1 = require("./config/input-props.js");
|
||||
const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
|
||||
const validate_dimensions_js_1 = require("./validation/validate-dimensions.js");
|
||||
const validate_duration_in_frames_js_1 = require("./validation/validate-duration-in-frames.js");
|
||||
const validate_fps_js_1 = require("./validation/validate-fps.js");
|
||||
exports.ResolveCompositionContext = (0, react_1.createContext)(null);
|
||||
exports.resolveCompositionsRef = (0, react_1.createRef)();
|
||||
const needsResolution = (composition) => {
|
||||
return Boolean(composition.calculateMetadata);
|
||||
};
|
||||
exports.needsResolution = needsResolution;
|
||||
exports.PROPS_UPDATED_EXTERNALLY = 'remotion.propsUpdatedExternally';
|
||||
const useResolvedVideoConfig = (preferredCompositionId) => {
|
||||
const context = (0, react_1.useContext)(exports.ResolveCompositionContext);
|
||||
const { props: allEditorProps } = (0, react_1.useContext)(EditorProps_js_1.EditorPropsContext);
|
||||
const { compositions, canvasContent, currentCompositionMetadata } = (0, react_1.useContext)(CompositionManagerContext_js_1.CompositionManager);
|
||||
const currentComposition = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
|
||||
const compositionId = preferredCompositionId !== null && preferredCompositionId !== void 0 ? preferredCompositionId : currentComposition;
|
||||
const composition = compositions.find((c) => c.id === compositionId);
|
||||
const selectedEditorProps = (0, react_1.useMemo)(() => {
|
||||
var _a;
|
||||
return composition ? ((_a = allEditorProps[composition.id]) !== null && _a !== void 0 ? _a : {}) : {};
|
||||
}, [allEditorProps, composition]);
|
||||
const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
||||
return (0, react_1.useMemo)(() => {
|
||||
var _a, _b, _c, _d;
|
||||
if (!composition) {
|
||||
return null;
|
||||
}
|
||||
if (currentCompositionMetadata) {
|
||||
return {
|
||||
type: 'success',
|
||||
result: {
|
||||
...currentCompositionMetadata,
|
||||
id: composition.id,
|
||||
defaultProps: (_a = composition.defaultProps) !== null && _a !== void 0 ? _a : {},
|
||||
},
|
||||
};
|
||||
}
|
||||
if (!(0, exports.needsResolution)(composition)) {
|
||||
(0, validate_duration_in_frames_js_1.validateDurationInFrames)(composition.durationInFrames, {
|
||||
allowFloats: false,
|
||||
component: `in <Composition id="${composition.id}">`,
|
||||
});
|
||||
(0, validate_fps_js_1.validateFps)(composition.fps, `in <Composition id="${composition.id}">`, false);
|
||||
(0, validate_dimensions_js_1.validateDimension)(composition.width, 'width', `in <Composition id="${composition.id}">`);
|
||||
(0, validate_dimensions_js_1.validateDimension)(composition.height, 'height', `in <Composition id="${composition.id}">`);
|
||||
return {
|
||||
type: 'success',
|
||||
result: {
|
||||
width: composition.width,
|
||||
height: composition.height,
|
||||
fps: composition.fps,
|
||||
id: composition.id,
|
||||
durationInFrames: composition.durationInFrames,
|
||||
defaultProps: (_b = composition.defaultProps) !== null && _b !== void 0 ? _b : {},
|
||||
props: {
|
||||
...((_c = composition.defaultProps) !== null && _c !== void 0 ? _c : {}),
|
||||
...(selectedEditorProps !== null && selectedEditorProps !== void 0 ? selectedEditorProps : {}),
|
||||
...(typeof window === 'undefined' ||
|
||||
env.isPlayer ||
|
||||
// In tests, we don't set window.remotion_inputProps,
|
||||
// otherwise it should be available here
|
||||
!window.remotion_inputProps
|
||||
? {}
|
||||
: ((_d = (0, input_props_js_1.getInputProps)()) !== null && _d !== void 0 ? _d : {})),
|
||||
},
|
||||
defaultCodec: null,
|
||||
defaultOutName: null,
|
||||
defaultVideoImageFormat: null,
|
||||
defaultPixelFormat: null,
|
||||
defaultProResProfile: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
// Could be the case in selectComposition()
|
||||
if (!context) {
|
||||
return null;
|
||||
}
|
||||
if (!context[composition.id]) {
|
||||
return null;
|
||||
}
|
||||
return context[composition.id];
|
||||
}, [
|
||||
composition,
|
||||
context,
|
||||
currentCompositionMetadata,
|
||||
selectedEditorProps,
|
||||
env.isPlayer,
|
||||
]);
|
||||
};
|
||||
exports.useResolvedVideoConfig = useResolvedVideoConfig;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import type { LoopDisplay } from './CompositionManager.js';
|
||||
export type AbsoluteFillLayout = {
|
||||
layout?: 'absolute-fill';
|
||||
premountFor?: number;
|
||||
postmountFor?: number;
|
||||
style?: React.CSSProperties;
|
||||
styleWhilePremounted?: React.CSSProperties;
|
||||
styleWhilePostmounted?: React.CSSProperties;
|
||||
className?: string;
|
||||
};
|
||||
export type LayoutAndStyle = AbsoluteFillLayout | {
|
||||
layout: 'none';
|
||||
};
|
||||
export type SequencePropsWithoutDuration = {
|
||||
readonly children: React.ReactNode;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly from?: number;
|
||||
readonly name?: string;
|
||||
readonly showInTimeline?: boolean;
|
||||
/**
|
||||
* @deprecated For internal use only.
|
||||
*/
|
||||
readonly _remotionInternalLoopDisplay?: LoopDisplay;
|
||||
/**
|
||||
* @deprecated For internal use only.
|
||||
*/
|
||||
readonly _remotionInternalPremountDisplay?: number | null;
|
||||
/**
|
||||
* @deprecated For internal use only.
|
||||
*/
|
||||
readonly _remotionInternalPostmountDisplay?: number | null;
|
||||
/**
|
||||
* @deprecated For internal use only.
|
||||
*/
|
||||
readonly _remotionInternalStack?: string;
|
||||
/**
|
||||
* @deprecated For internal use only.
|
||||
*/
|
||||
readonly _remotionInternalIsPremounting?: boolean;
|
||||
/**
|
||||
* @deprecated For internal use only.
|
||||
*/
|
||||
readonly _remotionInternalIsPostmounting?: boolean;
|
||||
} & LayoutAndStyle;
|
||||
export type SequenceProps = {
|
||||
readonly durationInFrames?: number;
|
||||
} & SequencePropsWithoutDuration;
|
||||
export declare const Sequence: React.ForwardRefExoticComponent<SequenceProps & React.RefAttributes<HTMLDivElement>>;
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Sequence = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
const react_1 = require("react");
|
||||
const AbsoluteFill_js_1 = require("./AbsoluteFill.js");
|
||||
const SequenceContext_js_1 = require("./SequenceContext.js");
|
||||
const SequenceManager_js_1 = require("./SequenceManager.js");
|
||||
const TimelineContext_js_1 = require("./TimelineContext.js");
|
||||
const nonce_js_1 = require("./nonce.js");
|
||||
const timeline_position_state_js_1 = require("./timeline-position-state.js");
|
||||
const use_video_config_js_1 = require("./use-video-config.js");
|
||||
const freeze_js_1 = require("./freeze.js");
|
||||
const use_current_frame_1 = require("./use-current-frame");
|
||||
const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
|
||||
const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, height, width, showInTimeline = true, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, ...other }, ref) => {
|
||||
var _a;
|
||||
const { layout = 'absolute-fill' } = other;
|
||||
const [id] = (0, react_1.useState)(() => String(Math.random()));
|
||||
const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
||||
const { rootId } = (0, react_1.useContext)(TimelineContext_js_1.TimelineContext);
|
||||
const cumulatedFrom = parentSequence
|
||||
? parentSequence.cumulatedFrom + parentSequence.relativeFrom
|
||||
: 0;
|
||||
const nonce = (0, nonce_js_1.useNonce)();
|
||||
if (layout !== 'absolute-fill' && layout !== 'none') {
|
||||
throw new TypeError(`The layout prop of <Sequence /> expects either "absolute-fill" or "none", but you passed: ${layout}`);
|
||||
}
|
||||
// @ts-expect-error
|
||||
if (layout === 'none' && typeof other.style !== 'undefined') {
|
||||
throw new TypeError('If layout="none", you may not pass a style.');
|
||||
}
|
||||
if (typeof durationInFrames !== 'number') {
|
||||
throw new TypeError(`You passed to durationInFrames an argument of type ${typeof durationInFrames}, but it must be a number.`);
|
||||
}
|
||||
if (durationInFrames <= 0) {
|
||||
throw new TypeError(`durationInFrames must be positive, but got ${durationInFrames}`);
|
||||
}
|
||||
if (typeof from !== 'number') {
|
||||
throw new TypeError(`You passed to the "from" props of your <Sequence> an argument of type ${typeof from}, but it must be a number.`);
|
||||
}
|
||||
if (!Number.isFinite(from)) {
|
||||
throw new TypeError(`The "from" prop of a sequence must be finite, but got ${from}.`);
|
||||
}
|
||||
const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)();
|
||||
const videoConfig = (0, use_video_config_js_1.useVideoConfig)();
|
||||
const parentSequenceDuration = parentSequence
|
||||
? Math.min(parentSequence.durationInFrames - from, durationInFrames)
|
||||
: durationInFrames;
|
||||
const actualDurationInFrames = Math.max(0, Math.min(videoConfig.durationInFrames - from, parentSequenceDuration));
|
||||
const { registerSequence, unregisterSequence } = (0, react_1.useContext)(SequenceManager_js_1.SequenceManager);
|
||||
const { hidden } = (0, react_1.useContext)(SequenceManager_js_1.SequenceVisibilityToggleContext);
|
||||
const premounting = (0, react_1.useMemo)(() => {
|
||||
// || is intentional, ?? would not trigger on `false`
|
||||
return ((parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.premounting) ||
|
||||
Boolean(other._remotionInternalIsPremounting));
|
||||
}, [other._remotionInternalIsPremounting, parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.premounting]);
|
||||
const postmounting = (0, react_1.useMemo)(() => {
|
||||
// || is intentional, ?? would not trigger on `false`
|
||||
return ((parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.postmounting) ||
|
||||
Boolean(other._remotionInternalIsPostmounting));
|
||||
}, [other._remotionInternalIsPostmounting, parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.postmounting]);
|
||||
const contextValue = (0, react_1.useMemo)(() => {
|
||||
var _a, _b, _c;
|
||||
return {
|
||||
cumulatedFrom,
|
||||
relativeFrom: from,
|
||||
durationInFrames: actualDurationInFrames,
|
||||
parentFrom: (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.relativeFrom) !== null && _a !== void 0 ? _a : 0,
|
||||
id,
|
||||
height: (_b = height !== null && height !== void 0 ? height : parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.height) !== null && _b !== void 0 ? _b : null,
|
||||
width: (_c = width !== null && width !== void 0 ? width : parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.width) !== null && _c !== void 0 ? _c : null,
|
||||
premounting,
|
||||
postmounting,
|
||||
premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
|
||||
postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
|
||||
};
|
||||
}, [
|
||||
cumulatedFrom,
|
||||
from,
|
||||
actualDurationInFrames,
|
||||
parentSequence,
|
||||
id,
|
||||
height,
|
||||
width,
|
||||
premounting,
|
||||
postmounting,
|
||||
premountDisplay,
|
||||
postmountDisplay,
|
||||
]);
|
||||
const timelineClipName = (0, react_1.useMemo)(() => {
|
||||
return name !== null && name !== void 0 ? name : '';
|
||||
}, [name]);
|
||||
const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
||||
(0, react_1.useEffect)(() => {
|
||||
var _a;
|
||||
if (!env.isStudio) {
|
||||
return;
|
||||
}
|
||||
registerSequence({
|
||||
from,
|
||||
duration: actualDurationInFrames,
|
||||
id,
|
||||
displayName: timelineClipName,
|
||||
parent: (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id) !== null && _a !== void 0 ? _a : null,
|
||||
type: 'sequence',
|
||||
rootId,
|
||||
showInTimeline,
|
||||
nonce,
|
||||
loopDisplay,
|
||||
stack: stack !== null && stack !== void 0 ? stack : null,
|
||||
premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
|
||||
postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
|
||||
});
|
||||
return () => {
|
||||
unregisterSequence(id);
|
||||
};
|
||||
}, [
|
||||
durationInFrames,
|
||||
id,
|
||||
name,
|
||||
registerSequence,
|
||||
timelineClipName,
|
||||
unregisterSequence,
|
||||
parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id,
|
||||
actualDurationInFrames,
|
||||
rootId,
|
||||
from,
|
||||
showInTimeline,
|
||||
nonce,
|
||||
loopDisplay,
|
||||
stack,
|
||||
premountDisplay,
|
||||
postmountDisplay,
|
||||
env.isStudio,
|
||||
]);
|
||||
// Ceil to support floats
|
||||
// https://github.com/remotion-dev/remotion/issues/2958
|
||||
const endThreshold = Math.ceil(cumulatedFrom + from + durationInFrames - 1);
|
||||
const content = absoluteFrame < cumulatedFrom + from
|
||||
? null
|
||||
: absoluteFrame > endThreshold
|
||||
? null
|
||||
: children;
|
||||
const styleIfThere = other.layout === 'none' ? undefined : other.style;
|
||||
const defaultStyle = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
flexDirection: undefined,
|
||||
...(width ? { width } : {}),
|
||||
...(height ? { height } : {}),
|
||||
...(styleIfThere !== null && styleIfThere !== void 0 ? styleIfThere : {}),
|
||||
};
|
||||
}, [height, styleIfThere, width]);
|
||||
if (ref !== null && layout === 'none') {
|
||||
throw new TypeError('It is not supported to pass both a `ref` and `layout="none"` to <Sequence />.');
|
||||
}
|
||||
const isSequenceHidden = (_a = hidden[id]) !== null && _a !== void 0 ? _a : false;
|
||||
if (isSequenceHidden) {
|
||||
return null;
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsx)(SequenceContext_js_1.SequenceContext.Provider, { value: contextValue, children: content === null ? null : other.layout === 'none' ? (content) : ((0, jsx_runtime_1.jsx)(AbsoluteFill_js_1.AbsoluteFill, { ref: ref, style: defaultStyle, className: other.className, children: content })) }));
|
||||
};
|
||||
const RegularSequence = (0, react_1.forwardRef)(RegularSequenceRefForwardingFunction);
|
||||
const PremountedPostmountedSequenceRefForwardingFunction = (props, ref) => {
|
||||
const frame = (0, use_current_frame_1.useCurrentFrame)();
|
||||
if (props.layout === 'none') {
|
||||
throw new Error('`<Sequence>` with `premountFor` and `postmountFor` props does not support layout="none"');
|
||||
}
|
||||
const { style: passedStyle, from = 0, durationInFrames = Infinity, premountFor = 0, postmountFor = 0, styleWhilePremounted, styleWhilePostmounted, ...otherProps } = props;
|
||||
const endThreshold = Math.ceil(from + durationInFrames - 1);
|
||||
const premountingActive = frame < from && frame >= from - premountFor;
|
||||
const postmountingActive = frame > endThreshold && frame <= endThreshold + postmountFor;
|
||||
// Determine which freeze frame to use
|
||||
const freezeFrame = premountingActive
|
||||
? from
|
||||
: postmountingActive
|
||||
? from + durationInFrames - 1
|
||||
: 0;
|
||||
const isFreezingActive = premountingActive || postmountingActive;
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
var _a;
|
||||
return {
|
||||
...passedStyle,
|
||||
opacity: premountingActive || postmountingActive ? 0 : 1,
|
||||
pointerEvents: premountingActive || postmountingActive
|
||||
? 'none'
|
||||
: ((_a = passedStyle === null || passedStyle === void 0 ? void 0 : passedStyle.pointerEvents) !== null && _a !== void 0 ? _a : undefined),
|
||||
...(premountingActive ? styleWhilePremounted : {}),
|
||||
...(postmountingActive ? styleWhilePostmounted : {}),
|
||||
};
|
||||
}, [
|
||||
passedStyle,
|
||||
premountingActive,
|
||||
postmountingActive,
|
||||
styleWhilePremounted,
|
||||
styleWhilePostmounted,
|
||||
]);
|
||||
return ((0, jsx_runtime_1.jsx)(freeze_js_1.Freeze, { frame: freezeFrame, active: isFreezingActive, children: (0, jsx_runtime_1.jsx)(exports.Sequence, { ref: ref, from: from, durationInFrames: durationInFrames, style: style, _remotionInternalPremountDisplay: premountFor, _remotionInternalPostmountDisplay: postmountFor, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, ...otherProps }) }));
|
||||
};
|
||||
const PremountedPostmountedSequence = (0, react_1.forwardRef)(PremountedPostmountedSequenceRefForwardingFunction);
|
||||
const SequenceRefForwardingFunction = (props, ref) => {
|
||||
const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
||||
if (props.layout !== 'none' && !env.isRendering) {
|
||||
if (props.premountFor || props.postmountFor) {
|
||||
return (0, jsx_runtime_1.jsx)(PremountedPostmountedSequence, { ...props, ref: ref });
|
||||
}
|
||||
}
|
||||
return (0, jsx_runtime_1.jsx)(RegularSequence, { ...props, ref: ref });
|
||||
};
|
||||
/*
|
||||
* @description A component that time-shifts its children and wraps them in an absolutely positioned <div>.
|
||||
* @see [Documentation](https://www.remotion.dev/docs/sequence)
|
||||
*/
|
||||
exports.Sequence = (0, react_1.forwardRef)(SequenceRefForwardingFunction);
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
export declare const SequenceContext: import("react").Context<SequenceContextType | null>;
|
||||
export type SequenceContextType = {
|
||||
cumulatedFrom: number;
|
||||
relativeFrom: number;
|
||||
parentFrom: number;
|
||||
durationInFrames: number;
|
||||
id: string;
|
||||
width: number | null;
|
||||
height: number | null;
|
||||
premounting: boolean;
|
||||
postmounting: boolean;
|
||||
premountDisplay: number | null;
|
||||
postmountDisplay: number | null;
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SequenceContext = void 0;
|
||||
const react_1 = require("react");
|
||||
exports.SequenceContext = (0, react_1.createContext)(null);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import type { TSequence } from './CompositionManager.js';
|
||||
export type SequenceManagerContext = {
|
||||
registerSequence: (seq: TSequence) => void;
|
||||
unregisterSequence: (id: string) => void;
|
||||
sequences: TSequence[];
|
||||
};
|
||||
export declare const SequenceManager: React.Context<SequenceManagerContext>;
|
||||
export type SequenceVisibilityToggleState = {
|
||||
hidden: Record<string, boolean>;
|
||||
setHidden: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
|
||||
};
|
||||
export declare const SequenceVisibilityToggleContext: React.Context<SequenceVisibilityToggleState>;
|
||||
export declare const SequenceManagerProvider: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SequenceManagerProvider = exports.SequenceVisibilityToggleContext = exports.SequenceManager = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
exports.SequenceManager = react_1.default.createContext({
|
||||
registerSequence: () => {
|
||||
throw new Error('SequenceManagerContext not initialized');
|
||||
},
|
||||
unregisterSequence: () => {
|
||||
throw new Error('SequenceManagerContext not initialized');
|
||||
},
|
||||
sequences: [],
|
||||
});
|
||||
exports.SequenceVisibilityToggleContext = react_1.default.createContext({
|
||||
hidden: {},
|
||||
setHidden: () => {
|
||||
throw new Error('SequenceVisibilityToggle not initialized');
|
||||
},
|
||||
});
|
||||
const SequenceManagerProvider = ({ children }) => {
|
||||
const [sequences, setSequences] = (0, react_1.useState)([]);
|
||||
const [hidden, setHidden] = (0, react_1.useState)({});
|
||||
const registerSequence = (0, react_1.useCallback)((seq) => {
|
||||
setSequences((seqs) => {
|
||||
return [...seqs, seq];
|
||||
});
|
||||
}, []);
|
||||
const unregisterSequence = (0, react_1.useCallback)((seq) => {
|
||||
setSequences((seqs) => seqs.filter((s) => s.id !== seq));
|
||||
}, []);
|
||||
const sequenceContext = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
registerSequence,
|
||||
sequences,
|
||||
unregisterSequence,
|
||||
};
|
||||
}, [registerSequence, sequences, unregisterSequence]);
|
||||
const hiddenContext = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
hidden,
|
||||
setHidden,
|
||||
};
|
||||
}, [hidden]);
|
||||
return ((0, jsx_runtime_1.jsx)(exports.SequenceManager.Provider, { value: sequenceContext, children: (0, jsx_runtime_1.jsx)(exports.SequenceVisibilityToggleContext.Provider, { value: hiddenContext, children: children }) }));
|
||||
};
|
||||
exports.SequenceManagerProvider = SequenceManagerProvider;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
import type { AnyZodObject } from 'zod';
|
||||
import type { StillProps } from './Composition.js';
|
||||
export declare const Still: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(props: StillProps<Schema, Props>) => React.DetailedReactHTMLElement<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Still = void 0;
|
||||
const react_1 = __importDefault(require("react"));
|
||||
const Composition_js_1 = require("./Composition.js");
|
||||
/*
|
||||
* @description A `<Still />` is a `<Composition />` that is only 1 frame long.
|
||||
* @see [Documentation](https://www.remotion.dev/docs/still)
|
||||
*/
|
||||
const Still = (props) => {
|
||||
const newProps = {
|
||||
...props,
|
||||
durationInFrames: 1,
|
||||
fps: 1,
|
||||
};
|
||||
// @ts-expect-error TypeScript does not understand it, but should still fail on type mismatch
|
||||
return react_1.default.createElement((Composition_js_1.Composition), newProps);
|
||||
};
|
||||
exports.Still = Still;
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import type { MutableRefObject } from 'react';
|
||||
import React from 'react';
|
||||
import { type PlayableMediaTag } from './timeline-position-state';
|
||||
export type TimelineContextValue = {
|
||||
frame: Record<string, number>;
|
||||
playing: boolean;
|
||||
rootId: string;
|
||||
playbackRate: number;
|
||||
imperativePlaying: MutableRefObject<boolean>;
|
||||
setPlaybackRate: (u: React.SetStateAction<number>) => void;
|
||||
audioAndVideoTags: MutableRefObject<PlayableMediaTag[]>;
|
||||
};
|
||||
export type SetTimelineContextValue = {
|
||||
setFrame: (u: React.SetStateAction<Record<string, number>>) => void;
|
||||
setPlaying: (u: React.SetStateAction<boolean>) => void;
|
||||
};
|
||||
export declare const SetTimelineContext: React.Context<SetTimelineContextValue>;
|
||||
export declare const TimelineContext: React.Context<TimelineContextValue>;
|
||||
export declare const TimelineContextProvider: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
readonly frameState: Record<string, number> | null;
|
||||
}>;
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TimelineContextProvider = exports.TimelineContext = exports.SetTimelineContext = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const random_1 = require("./random");
|
||||
const timeline_position_state_1 = require("./timeline-position-state");
|
||||
const use_delay_render_1 = require("./use-delay-render");
|
||||
exports.SetTimelineContext = (0, react_1.createContext)({
|
||||
setFrame: () => {
|
||||
throw new Error('default');
|
||||
},
|
||||
setPlaying: () => {
|
||||
throw new Error('default');
|
||||
},
|
||||
});
|
||||
exports.TimelineContext = (0, react_1.createContext)({
|
||||
frame: {},
|
||||
playing: false,
|
||||
playbackRate: 1,
|
||||
rootId: '',
|
||||
imperativePlaying: {
|
||||
current: false,
|
||||
},
|
||||
setPlaybackRate: () => {
|
||||
throw new Error('default');
|
||||
},
|
||||
audioAndVideoTags: { current: [] },
|
||||
});
|
||||
const TimelineContextProvider = ({ children, frameState }) => {
|
||||
const [playing, setPlaying] = (0, react_1.useState)(false);
|
||||
const imperativePlaying = (0, react_1.useRef)(false);
|
||||
const [playbackRate, setPlaybackRate] = (0, react_1.useState)(1);
|
||||
const audioAndVideoTags = (0, react_1.useRef)([]);
|
||||
const [remotionRootId] = (0, react_1.useState)(() => String((0, random_1.random)(null)));
|
||||
const [_frame, setFrame] = (0, react_1.useState)(() => (0, timeline_position_state_1.getInitialFrameState)());
|
||||
const frame = frameState !== null && frameState !== void 0 ? frameState : _frame;
|
||||
const { delayRender, continueRender } = (0, use_delay_render_1.useDelayRender)();
|
||||
if (typeof window !== 'undefined') {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
window.remotion_setFrame = (f, composition, attempt) => {
|
||||
window.remotion_attempt = attempt;
|
||||
const id = delayRender(`Setting the current frame to ${f}`);
|
||||
let asyncUpdate = true;
|
||||
setFrame((s) => {
|
||||
var _a;
|
||||
const currentFrame = (_a = s[composition]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame;
|
||||
// Avoid cloning the object
|
||||
if (currentFrame === f) {
|
||||
asyncUpdate = false;
|
||||
return s;
|
||||
}
|
||||
return {
|
||||
...s,
|
||||
[composition]: f,
|
||||
};
|
||||
});
|
||||
// After setting the state, need to wait until it is applied in the next cycle
|
||||
if (asyncUpdate) {
|
||||
requestAnimationFrame(() => continueRender(id));
|
||||
}
|
||||
else {
|
||||
continueRender(id);
|
||||
}
|
||||
};
|
||||
window.remotion_isPlayer = false;
|
||||
}, [continueRender, delayRender]);
|
||||
}
|
||||
const timelineContextValue = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
frame,
|
||||
playing,
|
||||
imperativePlaying,
|
||||
rootId: remotionRootId,
|
||||
playbackRate,
|
||||
setPlaybackRate,
|
||||
audioAndVideoTags,
|
||||
};
|
||||
}, [frame, playbackRate, playing, remotionRootId]);
|
||||
const setTimelineContextValue = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
setFrame,
|
||||
setPlaying,
|
||||
};
|
||||
}, []);
|
||||
return ((0, jsx_runtime_1.jsx)(exports.TimelineContext.Provider, { value: timelineContextValue, children: (0, jsx_runtime_1.jsx)(exports.SetTimelineContext.Provider, { value: setTimelineContextValue, children: children }) }));
|
||||
};
|
||||
exports.TimelineContextProvider = TimelineContextProvider;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const react_1 = require("react");
|
||||
if (typeof react_1.createContext !== 'function') {
|
||||
const err = [
|
||||
'Remotion requires React.createContext, but it is "undefined".',
|
||||
'If you are in a React Server Component, turn it into a client component by adding "use client" at the top of the file.',
|
||||
'',
|
||||
'Before:',
|
||||
' import {useCurrentFrame} from "remotion";',
|
||||
'',
|
||||
'After:',
|
||||
' "use client";',
|
||||
' import {useCurrentFrame} from "remotion";',
|
||||
];
|
||||
throw new Error(err.join('\n'));
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare const getAbsoluteSrc: (relativeSrc: string) => string;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getAbsoluteSrc = void 0;
|
||||
const getAbsoluteSrc = (relativeSrc) => {
|
||||
if (typeof window === 'undefined') {
|
||||
return relativeSrc;
|
||||
}
|
||||
// https://github.com/remotion-dev/remotion/issues/5359
|
||||
if (relativeSrc.startsWith('http://') ||
|
||||
relativeSrc.startsWith('https://') ||
|
||||
relativeSrc.startsWith('file://') ||
|
||||
relativeSrc.startsWith('blob:') ||
|
||||
relativeSrc.startsWith('data:')) {
|
||||
return relativeSrc;
|
||||
}
|
||||
return new URL(relativeSrc, window.origin).href;
|
||||
};
|
||||
exports.getAbsoluteSrc = getAbsoluteSrc;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import type { RemotionAnimatedImageProps } from './props';
|
||||
export declare const AnimatedImage: import("react").ForwardRefExoticComponent<RemotionAnimatedImageProps & import("react").RefAttributes<HTMLCanvasElement>>;
|
||||
Generated
Vendored
+114
@@ -0,0 +1,114 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AnimatedImage = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const cancel_render_js_1 = require("../cancel-render.js");
|
||||
const use_current_frame_js_1 = require("../use-current-frame.js");
|
||||
const use_delay_render_js_1 = require("../use-delay-render.js");
|
||||
const use_video_config_js_1 = require("../use-video-config.js");
|
||||
const canvas_1 = require("./canvas");
|
||||
const decode_image_js_1 = require("./decode-image.js");
|
||||
const resolve_image_source_1 = require("./resolve-image-source");
|
||||
exports.AnimatedImage = (0, react_1.forwardRef)(({ src, width, height, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', ...props }, canvasRef) => {
|
||||
const mountState = (0, react_1.useRef)({ isMounted: true });
|
||||
(0, react_1.useEffect)(() => {
|
||||
const { current } = mountState;
|
||||
current.isMounted = true;
|
||||
return () => {
|
||||
current.isMounted = false;
|
||||
};
|
||||
}, []);
|
||||
const resolvedSrc = (0, resolve_image_source_1.resolveAnimatedImageSource)(src);
|
||||
const [imageDecoder, setImageDecoder] = (0, react_1.useState)(null);
|
||||
const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)();
|
||||
const [decodeHandle] = (0, react_1.useState)(() => delayRender(`Rendering <AnimatedImage/> with src="${resolvedSrc}"`));
|
||||
const frame = (0, use_current_frame_js_1.useCurrentFrame)();
|
||||
const { fps } = (0, use_video_config_js_1.useVideoConfig)();
|
||||
const currentTime = frame / playbackRate / fps;
|
||||
const currentTimeRef = (0, react_1.useRef)(currentTime);
|
||||
currentTimeRef.current = currentTime;
|
||||
const ref = (0, react_1.useRef)(null);
|
||||
(0, react_1.useImperativeHandle)(canvasRef, () => {
|
||||
var _a;
|
||||
const c = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.getCanvas();
|
||||
if (!c) {
|
||||
throw new Error('Canvas ref is not set');
|
||||
}
|
||||
return c;
|
||||
}, []);
|
||||
const [initialLoopBehavior] = (0, react_1.useState)(() => loopBehavior);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const controller = new AbortController();
|
||||
(0, decode_image_js_1.decodeImage)({
|
||||
resolvedSrc,
|
||||
signal: controller.signal,
|
||||
currentTime: currentTimeRef.current,
|
||||
initialLoopBehavior,
|
||||
})
|
||||
.then((d) => {
|
||||
setImageDecoder(d);
|
||||
continueRender(decodeHandle);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.name === 'AbortError') {
|
||||
continueRender(decodeHandle);
|
||||
return;
|
||||
}
|
||||
if (onError) {
|
||||
onError === null || onError === void 0 ? void 0 : onError(err);
|
||||
continueRender(decodeHandle);
|
||||
}
|
||||
else {
|
||||
(0, cancel_render_js_1.cancelRender)(err);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
}, [
|
||||
resolvedSrc,
|
||||
decodeHandle,
|
||||
onError,
|
||||
initialLoopBehavior,
|
||||
continueRender,
|
||||
]);
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
if (!imageDecoder) {
|
||||
return;
|
||||
}
|
||||
const delay = delayRender(`Rendering frame at ${currentTime} of <AnimatedImage src="${src}"/>`);
|
||||
imageDecoder
|
||||
.getFrame(currentTime, loopBehavior)
|
||||
.then((videoFrame) => {
|
||||
var _a, _b;
|
||||
if (mountState.current.isMounted) {
|
||||
if (videoFrame === null) {
|
||||
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.clear();
|
||||
}
|
||||
else {
|
||||
(_b = ref.current) === null || _b === void 0 ? void 0 : _b.draw(videoFrame.frame);
|
||||
}
|
||||
}
|
||||
continueRender(delay);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (onError) {
|
||||
onError(err);
|
||||
continueRender(delay);
|
||||
}
|
||||
else {
|
||||
(0, cancel_render_js_1.cancelRender)(err);
|
||||
}
|
||||
});
|
||||
}, [
|
||||
currentTime,
|
||||
imageDecoder,
|
||||
loopBehavior,
|
||||
onError,
|
||||
src,
|
||||
continueRender,
|
||||
delayRender,
|
||||
]);
|
||||
return ((0, jsx_runtime_1.jsx)(canvas_1.Canvas, { ref: ref, width: width, height: height, fit: fit, ...props }));
|
||||
});
|
||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import type { AnimatedImageFillMode } from './props';
|
||||
type Props = {
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly fit: AnimatedImageFillMode;
|
||||
readonly className?: string;
|
||||
readonly style?: React.CSSProperties;
|
||||
};
|
||||
export type AnimatedImageCanvasRef = {
|
||||
readonly draw: (imageData: VideoFrame) => void;
|
||||
readonly getCanvas: () => HTMLCanvasElement | null;
|
||||
clear: () => void;
|
||||
};
|
||||
export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<AnimatedImageCanvasRef>>;
|
||||
export {};
|
||||
Generated
Vendored
+132
@@ -0,0 +1,132 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Canvas = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const calcArgs = (fit, frameSize, canvasSize) => {
|
||||
switch (fit) {
|
||||
case 'fill': {
|
||||
return [
|
||||
0,
|
||||
0,
|
||||
frameSize.width,
|
||||
frameSize.height,
|
||||
0,
|
||||
0,
|
||||
canvasSize.width,
|
||||
canvasSize.height,
|
||||
];
|
||||
}
|
||||
case 'contain': {
|
||||
const ratio = Math.min(canvasSize.width / frameSize.width, canvasSize.height / frameSize.height);
|
||||
const centerX = (canvasSize.width - frameSize.width * ratio) / 2;
|
||||
const centerY = (canvasSize.height - frameSize.height * ratio) / 2;
|
||||
return [
|
||||
0,
|
||||
0,
|
||||
frameSize.width,
|
||||
frameSize.height,
|
||||
centerX,
|
||||
centerY,
|
||||
frameSize.width * ratio,
|
||||
frameSize.height * ratio,
|
||||
];
|
||||
}
|
||||
case 'cover': {
|
||||
const ratio = Math.max(canvasSize.width / frameSize.width, canvasSize.height / frameSize.height);
|
||||
const centerX = (canvasSize.width - frameSize.width * ratio) / 2;
|
||||
const centerY = (canvasSize.height - frameSize.height * ratio) / 2;
|
||||
return [
|
||||
0,
|
||||
0,
|
||||
frameSize.width,
|
||||
frameSize.height,
|
||||
centerX,
|
||||
centerY,
|
||||
frameSize.width * ratio,
|
||||
frameSize.height * ratio,
|
||||
];
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown fit: ' + fit);
|
||||
}
|
||||
};
|
||||
const CanvasRefForwardingFunction = ({ width, height, fit, className, style }, ref) => {
|
||||
const canvasRef = (0, react_1.useRef)(null);
|
||||
const draw = (0, react_1.useCallback)((imageData) => {
|
||||
var _a;
|
||||
const canvas = canvasRef.current;
|
||||
const canvasWidth = width !== null && width !== void 0 ? width : imageData.displayWidth;
|
||||
const canvasHeight = height !== null && height !== void 0 ? height : imageData.displayHeight;
|
||||
if (!canvas) {
|
||||
throw new Error('Canvas ref is not set');
|
||||
}
|
||||
const ctx = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getContext('2d');
|
||||
if (!ctx) {
|
||||
throw new Error('Could not get 2d context');
|
||||
}
|
||||
canvas.width = canvasWidth;
|
||||
canvas.height = canvasHeight;
|
||||
ctx.drawImage(imageData, ...calcArgs(fit, {
|
||||
height: imageData.displayHeight,
|
||||
width: imageData.displayWidth,
|
||||
}, {
|
||||
width: canvasWidth,
|
||||
height: canvasHeight,
|
||||
}));
|
||||
}, [fit, height, width]);
|
||||
(0, react_1.useImperativeHandle)(ref, () => {
|
||||
return {
|
||||
draw,
|
||||
getCanvas: () => {
|
||||
if (!canvasRef.current) {
|
||||
throw new Error('Canvas ref is not set');
|
||||
}
|
||||
return canvasRef.current;
|
||||
},
|
||||
clear: () => {
|
||||
var _a;
|
||||
const ctx = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getContext('2d');
|
||||
if (!ctx) {
|
||||
throw new Error('Could not get 2d context');
|
||||
}
|
||||
ctx.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);
|
||||
},
|
||||
};
|
||||
}, [draw]);
|
||||
return (0, jsx_runtime_1.jsx)("canvas", { ref: canvasRef, className: className, style: style });
|
||||
};
|
||||
exports.Canvas = react_1.default.forwardRef(CanvasRefForwardingFunction);
|
||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
import type { RemotionAnimatedImageLoopBehavior } from './props';
|
||||
export type AnimatedImageCacheItem = {
|
||||
timeInSeconds: number;
|
||||
frameIndex: number;
|
||||
frame: VideoFrame | null;
|
||||
};
|
||||
export type RemotionImageDecoder = {
|
||||
getFrame: (i: number, loopBehavior: RemotionAnimatedImageLoopBehavior) => Promise<AnimatedImageCacheItem | null>;
|
||||
frameCount: number;
|
||||
};
|
||||
export declare const decodeImage: ({ resolvedSrc, signal, currentTime, initialLoopBehavior, }: {
|
||||
resolvedSrc: string;
|
||||
signal: AbortSignal;
|
||||
currentTime: number;
|
||||
initialLoopBehavior: RemotionAnimatedImageLoopBehavior;
|
||||
}) => Promise<RemotionImageDecoder>;
|
||||
Generated
Vendored
+145
@@ -0,0 +1,145 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.decodeImage = void 0;
|
||||
const CACHE_SIZE = 5;
|
||||
const getActualTime = ({ loopBehavior, durationFound, timeInSec, }) => {
|
||||
return loopBehavior === 'loop'
|
||||
? durationFound
|
||||
? timeInSec % durationFound
|
||||
: timeInSec
|
||||
: Math.min(timeInSec, durationFound || Infinity);
|
||||
};
|
||||
const decodeImage = async ({ resolvedSrc, signal, currentTime, initialLoopBehavior, }) => {
|
||||
if (typeof ImageDecoder === 'undefined') {
|
||||
throw new Error('Your browser does not support the WebCodecs ImageDecoder API.');
|
||||
}
|
||||
const res = await fetch(resolvedSrc, { signal });
|
||||
const { body } = res;
|
||||
if (!body) {
|
||||
throw new Error('Got no body');
|
||||
}
|
||||
const decoder = new ImageDecoder({
|
||||
data: body,
|
||||
type: res.headers.get('Content-Type') || 'image/gif',
|
||||
});
|
||||
await decoder.completed;
|
||||
const { selectedTrack } = decoder.tracks;
|
||||
if (!selectedTrack) {
|
||||
throw new Error('No selected track');
|
||||
}
|
||||
const cache = [];
|
||||
let durationFound = null;
|
||||
const getFrameByIndex = async (frameIndex) => {
|
||||
const foundInCache = cache.find((c) => c.frameIndex === frameIndex);
|
||||
if (foundInCache && foundInCache.frame) {
|
||||
return foundInCache;
|
||||
}
|
||||
const frame = await decoder.decode({
|
||||
frameIndex,
|
||||
completeFramesOnly: true,
|
||||
});
|
||||
if (foundInCache) {
|
||||
foundInCache.frame = frame.image;
|
||||
}
|
||||
else {
|
||||
cache.push({
|
||||
frame: frame.image,
|
||||
frameIndex,
|
||||
timeInSeconds: frame.image.timestamp / 1000000,
|
||||
});
|
||||
}
|
||||
return {
|
||||
frame: frame.image,
|
||||
frameIndex,
|
||||
timeInSeconds: frame.image.timestamp / 1000000,
|
||||
};
|
||||
};
|
||||
const clearCache = (closeToTimeInSec) => {
|
||||
const itemsInCache = cache.filter((c) => c.frame);
|
||||
const sortByClosestToCurrentTime = itemsInCache.sort((a, b) => {
|
||||
const aDiff = Math.abs(a.timeInSeconds - closeToTimeInSec);
|
||||
const bDiff = Math.abs(b.timeInSeconds - closeToTimeInSec);
|
||||
return aDiff - bDiff;
|
||||
});
|
||||
for (let i = 0; i < sortByClosestToCurrentTime.length; i++) {
|
||||
if (i < CACHE_SIZE) {
|
||||
continue;
|
||||
}
|
||||
const item = sortByClosestToCurrentTime[i];
|
||||
item.frame = null;
|
||||
}
|
||||
};
|
||||
const ensureFrameBeforeAndAfter = async ({ timeInSec, loopBehavior, }) => {
|
||||
const actualTimeInSec = getActualTime({
|
||||
durationFound,
|
||||
loopBehavior,
|
||||
timeInSec,
|
||||
});
|
||||
const framesBefore = cache.filter((c) => c.timeInSeconds <= actualTimeInSec);
|
||||
const biggestIndex = framesBefore
|
||||
.map((c) => c.frameIndex)
|
||||
.reduce((a, b) => Math.max(a, b), 0);
|
||||
let i = biggestIndex;
|
||||
while (true) {
|
||||
const f = await getFrameByIndex(i);
|
||||
i++;
|
||||
if (!f.frame) {
|
||||
throw new Error('No frame found');
|
||||
}
|
||||
if (!f.frame.duration) {
|
||||
// non-animated, or AVIF in firefox
|
||||
break;
|
||||
}
|
||||
if (i === selectedTrack.frameCount && durationFound === null) {
|
||||
const duration = (f.frame.timestamp + f.frame.duration) / 1000000;
|
||||
durationFound = duration;
|
||||
}
|
||||
if (f.timeInSeconds > actualTimeInSec || i === selectedTrack.frameCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If close to end, also cache first frame for smooth wrap around
|
||||
if (selectedTrack.frameCount - biggestIndex < 3 &&
|
||||
loopBehavior === 'loop') {
|
||||
await getFrameByIndex(0);
|
||||
}
|
||||
clearCache(actualTimeInSec);
|
||||
};
|
||||
// Twice because might be over total duration
|
||||
await ensureFrameBeforeAndAfter({
|
||||
timeInSec: currentTime,
|
||||
loopBehavior: initialLoopBehavior,
|
||||
});
|
||||
await ensureFrameBeforeAndAfter({
|
||||
timeInSec: currentTime,
|
||||
loopBehavior: initialLoopBehavior,
|
||||
});
|
||||
const getFrame = async (timeInSec, loopBehavior) => {
|
||||
if (durationFound !== null &&
|
||||
timeInSec > durationFound &&
|
||||
loopBehavior === 'clear-after-finish') {
|
||||
return null;
|
||||
}
|
||||
const actualTimeInSec = getActualTime({
|
||||
loopBehavior,
|
||||
durationFound,
|
||||
timeInSec,
|
||||
});
|
||||
await ensureFrameBeforeAndAfter({ timeInSec: actualTimeInSec, loopBehavior });
|
||||
const itemsInCache = cache.filter((c) => c.frame);
|
||||
const closest = itemsInCache.reduce((a, b) => {
|
||||
const aDiff = Math.abs(a.timeInSeconds - actualTimeInSec);
|
||||
const bDiff = Math.abs(b.timeInSeconds - actualTimeInSec);
|
||||
return aDiff < bDiff ? a : b;
|
||||
});
|
||||
if (!closest.frame) {
|
||||
throw new Error('No frame found');
|
||||
}
|
||||
return closest;
|
||||
};
|
||||
return {
|
||||
getFrame,
|
||||
frameCount: selectedTrack.frameCount,
|
||||
};
|
||||
};
|
||||
exports.decodeImage = decodeImage;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export { AnimatedImage } from './AnimatedImage';
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AnimatedImage = void 0;
|
||||
var AnimatedImage_1 = require("./AnimatedImage");
|
||||
Object.defineProperty(exports, "AnimatedImage", { enumerable: true, get: function () { return AnimatedImage_1.AnimatedImage; } });
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
export type RemotionAnimatedImageLoopBehavior = 'loop' | 'pause-after-finish' | 'clear-after-finish';
|
||||
export type RemotionAnimatedImageProps = {
|
||||
src: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
onError?: (error: Error) => void;
|
||||
fit?: AnimatedImageFillMode;
|
||||
playbackRate?: number;
|
||||
style?: React.CSSProperties;
|
||||
loopBehavior?: RemotionAnimatedImageLoopBehavior;
|
||||
id?: string;
|
||||
className?: string;
|
||||
};
|
||||
export type AnimatedImageFillMode = 'contain' | 'cover' | 'fill';
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
skills/remotion-prompt-video/node_modules/remotion/dist/cjs/animated-image/resolve-image-source.d.ts
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare const resolveAnimatedImageSource: (src: string) => string;
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.resolveAnimatedImageSource = void 0;
|
||||
const resolveAnimatedImageSource = (src) => {
|
||||
if (typeof window === 'undefined') {
|
||||
return src;
|
||||
}
|
||||
return new URL(src, window.origin).href;
|
||||
};
|
||||
exports.resolveAnimatedImageSource = resolveAnimatedImageSource;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
declare module '*.webm' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.png' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.mp4' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.mp3' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.wav' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.aac' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.svg';
|
||||
declare module '*.jpg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.jpeg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.bmp' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.gif' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.woff' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.woff2' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
declare module '*.css';
|
||||
+1
@@ -0,0 +1 @@
|
||||
"use strict";
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
import type { RemotionMainAudioProps } from './props.js';
|
||||
/**
|
||||
* @description With this component, you can add audio to your video. All audio formats which are supported by Chromium are supported by the component.
|
||||
* @see [Documentation](https://remotion.dev/docs/html5-audio)
|
||||
*/
|
||||
export declare const Html5Audio: React.ForwardRefExoticComponent<Omit<import("./props.js").NativeAudioProps & {
|
||||
name?: string;
|
||||
volume?: import("../volume-prop.js").VolumeProp;
|
||||
playbackRate?: number;
|
||||
acceptableTimeShiftInSeconds?: number;
|
||||
allowAmplificationDuringRender?: boolean;
|
||||
_remotionInternalNeedsDurationCalculation?: boolean;
|
||||
_remotionInternalNativeLoopPassed?: boolean;
|
||||
toneFrequency?: number;
|
||||
useWebAudioApi?: boolean;
|
||||
pauseWhenBuffering?: boolean;
|
||||
showInTimeline?: boolean;
|
||||
delayRenderTimeoutInMilliseconds?: number;
|
||||
delayRenderRetries?: number;
|
||||
loopVolumeCurveBehavior?: import("./use-audio-frame.js").LoopVolumeCurveBehavior;
|
||||
onError?: (err: Error) => void;
|
||||
audioStreamIndex?: number;
|
||||
} & RemotionMainAudioProps & {
|
||||
/**
|
||||
* @deprecated For internal use only
|
||||
*/
|
||||
readonly stack?: string;
|
||||
}, "ref"> & React.RefAttributes<HTMLAudioElement>>;
|
||||
/**
|
||||
* @deprecated This component has been renamed to `Html5Audio`.
|
||||
* @see [Documentation](https://remotion.dev/docs/mediabunny/new-video)
|
||||
*/
|
||||
export declare const Audio: React.ForwardRefExoticComponent<Omit<import("./props.js").NativeAudioProps & {
|
||||
name?: string;
|
||||
volume?: import("../volume-prop.js").VolumeProp;
|
||||
playbackRate?: number;
|
||||
acceptableTimeShiftInSeconds?: number;
|
||||
allowAmplificationDuringRender?: boolean;
|
||||
_remotionInternalNeedsDurationCalculation?: boolean;
|
||||
_remotionInternalNativeLoopPassed?: boolean;
|
||||
toneFrequency?: number;
|
||||
useWebAudioApi?: boolean;
|
||||
pauseWhenBuffering?: boolean;
|
||||
showInTimeline?: boolean;
|
||||
delayRenderTimeoutInMilliseconds?: number;
|
||||
delayRenderRetries?: number;
|
||||
loopVolumeCurveBehavior?: import("./use-audio-frame.js").LoopVolumeCurveBehavior;
|
||||
onError?: (err: Error) => void;
|
||||
audioStreamIndex?: number;
|
||||
} & RemotionMainAudioProps & {
|
||||
/**
|
||||
* @deprecated For internal use only
|
||||
*/
|
||||
readonly stack?: string;
|
||||
}, "ref"> & React.RefAttributes<HTMLAudioElement>>;
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Audio = exports.Html5Audio = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
const react_1 = require("react");
|
||||
const Sequence_js_1 = require("../Sequence.js");
|
||||
const absolute_src_js_1 = require("../absolute-src.js");
|
||||
const calculate_media_duration_js_1 = require("../calculate-media-duration.js");
|
||||
const cancel_render_js_1 = require("../cancel-render.js");
|
||||
const enable_sequence_stack_traces_js_1 = require("../enable-sequence-stack-traces.js");
|
||||
const index_js_1 = require("../loop/index.js");
|
||||
const prefetch_js_1 = require("../prefetch.js");
|
||||
const use_remotion_environment_js_1 = require("../use-remotion-environment.js");
|
||||
const use_video_config_js_1 = require("../use-video-config.js");
|
||||
const validate_media_props_js_1 = require("../validate-media-props.js");
|
||||
const validate_start_from_props_js_1 = require("../validate-start-from-props.js");
|
||||
const duration_state_js_1 = require("../video/duration-state.js");
|
||||
const AudioForPreview_js_1 = require("./AudioForPreview.js");
|
||||
const AudioForRendering_js_1 = require("./AudioForRendering.js");
|
||||
const shared_audio_tags_js_1 = require("./shared-audio-tags.js");
|
||||
const AudioRefForwardingFunction = (props, ref) => {
|
||||
var _a, _b, _c;
|
||||
const audioContext = (0, react_1.useContext)(shared_audio_tags_js_1.SharedAudioContext);
|
||||
const { startFrom, endAt, trimBefore, trimAfter, name, stack, pauseWhenBuffering, showInTimeline, onError: onRemotionError, ...otherProps } = props;
|
||||
const { loop, ...propsOtherThanLoop } = props;
|
||||
const { fps } = (0, use_video_config_js_1.useVideoConfig)();
|
||||
const environment = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
||||
if (environment.isClientSideRendering) {
|
||||
throw new Error('<Html5Audio> is not supported in @remotion/web-renderer. Use <Audio> from @remotion/media instead. See https://remotion.dev/docs/client-side-rendering/limitations');
|
||||
}
|
||||
const { durations, setDurations } = (0, react_1.useContext)(duration_state_js_1.DurationsContext);
|
||||
if (typeof props.src !== 'string') {
|
||||
throw new TypeError(`The \`<Html5Audio>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
|
||||
}
|
||||
const preloadedSrc = (0, prefetch_js_1.usePreload)(props.src);
|
||||
const onError = (0, react_1.useCallback)((e) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(e.currentTarget.error);
|
||||
// If there is no `loop` property, we don't need to get the duration
|
||||
// and this does not need to be a fatal error
|
||||
const errMessage = `Could not play audio with src ${preloadedSrc}: ${e.currentTarget.error}. See https://remotion.dev/docs/media-playback-error for help.`;
|
||||
if (loop) {
|
||||
if (onRemotionError) {
|
||||
onRemotionError(new Error(errMessage));
|
||||
return;
|
||||
}
|
||||
(0, cancel_render_js_1.cancelRender)(new Error(errMessage));
|
||||
}
|
||||
else {
|
||||
onRemotionError === null || onRemotionError === void 0 ? void 0 : onRemotionError(new Error(errMessage));
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(errMessage);
|
||||
}
|
||||
}, [loop, onRemotionError, preloadedSrc]);
|
||||
const onDuration = (0, react_1.useCallback)((src, durationInSeconds) => {
|
||||
setDurations({ type: 'got-duration', durationInSeconds, src });
|
||||
}, [setDurations]);
|
||||
const durationFetched = (_a = durations[(0, absolute_src_js_1.getAbsoluteSrc)(preloadedSrc)]) !== null && _a !== void 0 ? _a : durations[(0, absolute_src_js_1.getAbsoluteSrc)(props.src)];
|
||||
(0, validate_start_from_props_js_1.validateMediaTrimProps)({ startFrom, endAt, trimBefore, trimAfter });
|
||||
const { trimBeforeValue, trimAfterValue } = (0, validate_start_from_props_js_1.resolveTrimProps)({
|
||||
startFrom,
|
||||
endAt,
|
||||
trimBefore,
|
||||
trimAfter,
|
||||
});
|
||||
if (loop && durationFetched !== undefined) {
|
||||
if (!Number.isFinite(durationFetched)) {
|
||||
return ((0, jsx_runtime_1.jsx)(exports.Html5Audio, { ...propsOtherThanLoop, ref: ref, _remotionInternalNativeLoopPassed: true }));
|
||||
}
|
||||
const duration = durationFetched * fps;
|
||||
return ((0, jsx_runtime_1.jsx)(index_js_1.Loop, { layout: "none", durationInFrames: (0, calculate_media_duration_js_1.calculateMediaDuration)({
|
||||
trimAfter: trimAfterValue,
|
||||
mediaDurationInFrames: duration,
|
||||
playbackRate: (_b = props.playbackRate) !== null && _b !== void 0 ? _b : 1,
|
||||
trimBefore: trimBeforeValue,
|
||||
}), children: (0, jsx_runtime_1.jsx)(exports.Html5Audio, { ...propsOtherThanLoop, ref: ref, _remotionInternalNativeLoopPassed: true }) }));
|
||||
}
|
||||
if (typeof trimBeforeValue !== 'undefined' ||
|
||||
typeof trimAfterValue !== 'undefined') {
|
||||
return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", from: 0 - (trimBeforeValue !== null && trimBeforeValue !== void 0 ? trimBeforeValue : 0), showInTimeline: false, durationInFrames: trimAfterValue, name: name, children: (0, jsx_runtime_1.jsx)(exports.Html5Audio, { _remotionInternalNeedsDurationCalculation: Boolean(loop), pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, ...otherProps, ref: ref }) }));
|
||||
}
|
||||
(0, validate_media_props_js_1.validateMediaProps)({ playbackRate: props.playbackRate, volume: props.volume }, 'Html5Audio');
|
||||
if (environment.isRendering) {
|
||||
return ((0, jsx_runtime_1.jsx)(AudioForRendering_js_1.AudioForRendering, { onDuration: onDuration, ...props, ref: ref, onNativeError: onError, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsx)(AudioForPreview_js_1.AudioForPreview, { _remotionInternalNativeLoopPassed: (_c = props._remotionInternalNativeLoopPassed) !== null && _c !== void 0 ? _c : false, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0, ...props, ref: ref, onNativeError: onError, onDuration: onDuration,
|
||||
// Proposal: Make this default to true in v5
|
||||
pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, _remotionInternalNeedsDurationCalculation: Boolean(loop), showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true }));
|
||||
};
|
||||
/**
|
||||
* @description With this component, you can add audio to your video. All audio formats which are supported by Chromium are supported by the component.
|
||||
* @see [Documentation](https://remotion.dev/docs/html5-audio)
|
||||
*/
|
||||
exports.Html5Audio = (0, react_1.forwardRef)(AudioRefForwardingFunction);
|
||||
(0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(exports.Html5Audio);
|
||||
/**
|
||||
* @deprecated This component has been renamed to `Html5Audio`.
|
||||
* @see [Documentation](https://remotion.dev/docs/mediabunny/new-video)
|
||||
*/
|
||||
exports.Audio = exports.Html5Audio;
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import type { RemotionAudioProps } from './props.js';
|
||||
type AudioForPreviewProps = RemotionAudioProps & {
|
||||
readonly shouldPreMountAudioTags: boolean;
|
||||
readonly onDuration: (src: string, durationInSeconds: number) => void;
|
||||
readonly pauseWhenBuffering: boolean;
|
||||
readonly _remotionInternalNativeLoopPassed: boolean;
|
||||
readonly _remotionInternalStack: string | null;
|
||||
readonly showInTimeline: boolean;
|
||||
readonly stack?: string | undefined;
|
||||
readonly onNativeError: React.ReactEventHandler<HTMLAudioElement>;
|
||||
};
|
||||
export declare const AudioForPreview: React.ForwardRefExoticComponent<Omit<AudioForPreviewProps, "ref"> & React.RefAttributes<HTMLAudioElement>>;
|
||||
export {};
|
||||
Generated
Vendored
+215
@@ -0,0 +1,215 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AudioForPreview = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const SequenceContext_js_1 = require("../SequenceContext.js");
|
||||
const SequenceManager_js_1 = require("../SequenceManager.js");
|
||||
const get_cross_origin_value_js_1 = require("../get-cross-origin-value.js");
|
||||
const log_level_context_js_1 = require("../log-level-context.js");
|
||||
const prefetch_js_1 = require("../prefetch.js");
|
||||
const random_js_1 = require("../random.js");
|
||||
const use_amplification_js_1 = require("../use-amplification.js");
|
||||
const use_media_in_timeline_js_1 = require("../use-media-in-timeline.js");
|
||||
const use_media_playback_js_1 = require("../use-media-playback.js");
|
||||
const use_media_tag_js_1 = require("../use-media-tag.js");
|
||||
const volume_position_state_js_1 = require("../volume-position-state.js");
|
||||
const volume_prop_js_1 = require("../volume-prop.js");
|
||||
const volume_safeguard_js_1 = require("../volume-safeguard.js");
|
||||
const shared_audio_tags_js_1 = require("./shared-audio-tags.js");
|
||||
const use_audio_frame_js_1 = require("./use-audio-frame.js");
|
||||
const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
||||
var _a, _b, _c, _d;
|
||||
const [initialShouldPreMountAudioElements] = (0, react_1.useState)(props.shouldPreMountAudioTags);
|
||||
if (props.shouldPreMountAudioTags !== initialShouldPreMountAudioElements) {
|
||||
throw new Error('Cannot change the behavior for pre-mounting audio tags dynamically.');
|
||||
}
|
||||
const logLevel = (0, log_level_context_js_1.useLogLevel)();
|
||||
const { volume, muted, playbackRate, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, stack, crossOrigin, delayRenderRetries, delayRenderTimeoutInMilliseconds, toneFrequency, useWebAudioApi, onError, onNativeError, audioStreamIndex, ...nativeProps } = props;
|
||||
// Typecheck that we are not accidentially passing unrecognized props
|
||||
// to the DOM
|
||||
const _propsValid = true;
|
||||
if (!_propsValid) {
|
||||
throw new Error('typecheck error');
|
||||
}
|
||||
const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
|
||||
const [mediaMuted] = (0, volume_position_state_js_1.useMediaMutedState)();
|
||||
const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
|
||||
const { hidden } = (0, react_1.useContext)(SequenceManager_js_1.SequenceVisibilityToggleContext);
|
||||
if (!src) {
|
||||
throw new TypeError("No 'src' was passed to <Html5Audio>.");
|
||||
}
|
||||
const preloadedSrc = (0, prefetch_js_1.usePreload)(src);
|
||||
const sequenceContext = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
||||
const [timelineId] = (0, react_1.useState)(() => String(Math.random()));
|
||||
const isSequenceHidden = (_a = hidden[timelineId]) !== null && _a !== void 0 ? _a : false;
|
||||
const userPreferredVolume = (0, volume_prop_js_1.evaluateVolume)({
|
||||
frame: volumePropFrame,
|
||||
volume,
|
||||
mediaVolume,
|
||||
});
|
||||
(0, volume_safeguard_js_1.warnAboutTooHighVolume)(userPreferredVolume);
|
||||
const crossOriginValue = (0, get_cross_origin_value_js_1.getCrossOriginValue)({
|
||||
crossOrigin,
|
||||
requestsVideoFrame: false,
|
||||
isClientSideRendering: false,
|
||||
});
|
||||
const propsToPass = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
muted: muted || mediaMuted || isSequenceHidden || userPreferredVolume <= 0,
|
||||
src: preloadedSrc,
|
||||
loop: _remotionInternalNativeLoopPassed,
|
||||
crossOrigin: crossOriginValue,
|
||||
...nativeProps,
|
||||
};
|
||||
}, [
|
||||
_remotionInternalNativeLoopPassed,
|
||||
isSequenceHidden,
|
||||
mediaMuted,
|
||||
muted,
|
||||
nativeProps,
|
||||
preloadedSrc,
|
||||
userPreferredVolume,
|
||||
crossOriginValue,
|
||||
]);
|
||||
// Generate a string that's as unique as possible for this asset
|
||||
// but at the same time deterministic. We use it to combat strict mode issues.
|
||||
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}`, [
|
||||
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,
|
||||
props.muted,
|
||||
props.loop,
|
||||
]);
|
||||
const { el: audioRef, mediaElementSourceNode, cleanupOnMediaTagUnmount, } = (0, shared_audio_tags_js_1.useSharedAudio)({
|
||||
aud: propsToPass,
|
||||
audioId: id,
|
||||
premounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
|
||||
postmounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting),
|
||||
});
|
||||
(0, use_media_in_timeline_js_1.useMediaInTimeline)({
|
||||
volume,
|
||||
mediaVolume,
|
||||
src,
|
||||
mediaType: 'audio',
|
||||
playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
|
||||
displayName: name !== null && name !== void 0 ? name : null,
|
||||
id: timelineId,
|
||||
stack: _remotionInternalStack,
|
||||
showInTimeline,
|
||||
premountDisplay: (_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premountDisplay) !== null && _b !== void 0 ? _b : null,
|
||||
postmountDisplay: (_c = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmountDisplay) !== null && _c !== void 0 ? _c : null,
|
||||
loopDisplay: undefined,
|
||||
});
|
||||
// putting playback before useVolume
|
||||
// because volume looks at playbackrate
|
||||
(0, use_media_playback_js_1.useMediaPlayback)({
|
||||
mediaRef: audioRef,
|
||||
src,
|
||||
mediaType: 'audio',
|
||||
playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
|
||||
onlyWarnForMediaSeekingError: false,
|
||||
acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : null,
|
||||
isPremounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
|
||||
isPostmounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting),
|
||||
pauseWhenBuffering,
|
||||
onAutoPlayError: null,
|
||||
});
|
||||
(0, use_media_tag_js_1.useMediaTag)({
|
||||
id: timelineId,
|
||||
isPostmounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting),
|
||||
isPremounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
|
||||
mediaRef: audioRef,
|
||||
mediaType: 'audio',
|
||||
onAutoPlayError: null,
|
||||
});
|
||||
(0, use_amplification_js_1.useVolume)({
|
||||
logLevel,
|
||||
mediaRef: audioRef,
|
||||
source: mediaElementSourceNode,
|
||||
volume: userPreferredVolume,
|
||||
shouldUseWebAudioApi: useWebAudioApi !== null && useWebAudioApi !== void 0 ? useWebAudioApi : false,
|
||||
});
|
||||
/**
|
||||
* Effects in React 18 fire twice, and we are looking for a way to only fire it once.
|
||||
* - useInsertionEffect only fires once. If it's available we are in React 18.
|
||||
* - useLayoutEffect only fires once in React 17.
|
||||
*
|
||||
* Need to import it from React to fix React 17 ESM support.
|
||||
*/
|
||||
const effectToUse = (_d = react_1.default.useInsertionEffect) !== null && _d !== void 0 ? _d : react_1.default.useLayoutEffect;
|
||||
// Disconnecting the SharedElementSourceNodes if the Audio tag unmounts to prevent leak.
|
||||
// https://github.com/remotion-dev/remotion/issues/6285
|
||||
// But useInsertionEffect will fire before other effects, meaning the
|
||||
// nodes might still be used. Using rAF to ensure it's after other effects.
|
||||
effectToUse(() => {
|
||||
return () => {
|
||||
requestAnimationFrame(() => {
|
||||
cleanupOnMediaTagUnmount();
|
||||
});
|
||||
};
|
||||
}, [cleanupOnMediaTagUnmount]);
|
||||
(0, react_1.useImperativeHandle)(ref, () => {
|
||||
return audioRef.current;
|
||||
}, [audioRef]);
|
||||
const currentOnDurationCallback = (0, react_1.useRef)(onDuration);
|
||||
currentOnDurationCallback.current = onDuration;
|
||||
(0, react_1.useEffect)(() => {
|
||||
var _a;
|
||||
const { current } = audioRef;
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
if (current.duration) {
|
||||
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, current.src, current.duration);
|
||||
return;
|
||||
}
|
||||
const onLoadedMetadata = () => {
|
||||
var _a;
|
||||
(_a = currentOnDurationCallback.current) === null || _a === void 0 ? void 0 : _a.call(currentOnDurationCallback, current.src, current.duration);
|
||||
};
|
||||
current.addEventListener('loadedmetadata', onLoadedMetadata);
|
||||
return () => {
|
||||
current.removeEventListener('loadedmetadata', onLoadedMetadata);
|
||||
};
|
||||
}, [audioRef, src]);
|
||||
if (initialShouldPreMountAudioElements) {
|
||||
return null;
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsx)("audio", { ref: audioRef, preload: "metadata", crossOrigin: crossOriginValue, ...propsToPass }));
|
||||
};
|
||||
exports.AudioForPreview = (0, react_1.forwardRef)(AudioForDevelopmentForwardRefFunction);
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import type { ForwardRefExoticComponent, RefAttributes } from 'react';
|
||||
import React from 'react';
|
||||
import type { RemotionAudioProps } from './props.js';
|
||||
type AudioForRenderingProps = RemotionAudioProps & {
|
||||
readonly onDuration: (src: string, durationInSeconds: number) => void;
|
||||
readonly onNativeError: React.ReactEventHandler<HTMLAudioElement>;
|
||||
};
|
||||
export declare const AudioForRendering: ForwardRefExoticComponent<AudioForRenderingProps & RefAttributes<HTMLAudioElement>>;
|
||||
export {};
|
||||
Generated
Vendored
+138
@@ -0,0 +1,138 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AudioForRendering = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const RenderAssetManager_js_1 = require("../RenderAssetManager.js");
|
||||
const SequenceContext_js_1 = require("../SequenceContext.js");
|
||||
const absolute_src_js_1 = require("../absolute-src.js");
|
||||
const random_js_1 = require("../random.js");
|
||||
const timeline_position_state_js_1 = require("../timeline-position-state.js");
|
||||
const use_current_frame_js_1 = require("../use-current-frame.js");
|
||||
const use_delay_render_js_1 = require("../use-delay-render.js");
|
||||
const volume_prop_js_1 = require("../volume-prop.js");
|
||||
const volume_safeguard_js_1 = require("../volume-safeguard.js");
|
||||
const use_audio_frame_js_1 = require("./use-audio-frame.js");
|
||||
const AudioForRenderingRefForwardingFunction = (props, ref) => {
|
||||
const audioRef = (0, react_1.useRef)(null);
|
||||
const { volume: volumeProp, playbackRate, allowAmplificationDuringRender, onDuration, toneFrequency, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, acceptableTimeShiftInSeconds, name, onNativeError, delayRenderRetries, delayRenderTimeoutInMilliseconds, loopVolumeCurveBehavior, pauseWhenBuffering, audioStreamIndex, ...nativeProps } = props;
|
||||
const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)();
|
||||
const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
|
||||
const frame = (0, use_current_frame_js_1.useCurrentFrame)();
|
||||
const sequenceContext = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
||||
const { registerRenderAsset, unregisterRenderAsset } = (0, react_1.useContext)(RenderAssetManager_js_1.RenderAssetManager);
|
||||
const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)();
|
||||
// Generate a string that's as unique as possible for this asset
|
||||
// but at the same time the same on all threads
|
||||
const id = (0, react_1.useMemo)(() => {
|
||||
var _a;
|
||||
return `audio-${(0, random_js_1.random)((_a = props.src) !== null && _a !== void 0 ? _a : '')}-${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}`;
|
||||
}, [
|
||||
props.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,
|
||||
]);
|
||||
const volume = (0, volume_prop_js_1.evaluateVolume)({
|
||||
volume: volumeProp,
|
||||
frame: volumePropFrame,
|
||||
mediaVolume: 1,
|
||||
});
|
||||
(0, volume_safeguard_js_1.warnAboutTooHighVolume)(volume);
|
||||
(0, react_1.useImperativeHandle)(ref, () => {
|
||||
return audioRef.current;
|
||||
}, []);
|
||||
(0, react_1.useEffect)(() => {
|
||||
var _a, _b;
|
||||
if (!props.src) {
|
||||
throw new Error('No src passed');
|
||||
}
|
||||
if (!window.remotion_audioEnabled) {
|
||||
return;
|
||||
}
|
||||
if (props.muted) {
|
||||
return;
|
||||
}
|
||||
if (volume <= 0) {
|
||||
return;
|
||||
}
|
||||
registerRenderAsset({
|
||||
type: 'audio',
|
||||
src: (0, absolute_src_js_1.getAbsoluteSrc)(props.src),
|
||||
id,
|
||||
frame: absoluteFrame,
|
||||
volume,
|
||||
mediaFrame: frame,
|
||||
playbackRate: (_a = props.playbackRate) !== null && _a !== void 0 ? _a : 1,
|
||||
toneFrequency: toneFrequency !== null && toneFrequency !== void 0 ? toneFrequency : 1,
|
||||
audioStartFrame: Math.max(0, -((_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom) !== null && _b !== void 0 ? _b : 0)),
|
||||
audioStreamIndex: audioStreamIndex !== null && audioStreamIndex !== void 0 ? audioStreamIndex : 0,
|
||||
});
|
||||
return () => unregisterRenderAsset(id);
|
||||
}, [
|
||||
props.muted,
|
||||
props.src,
|
||||
registerRenderAsset,
|
||||
absoluteFrame,
|
||||
id,
|
||||
unregisterRenderAsset,
|
||||
volume,
|
||||
volumePropFrame,
|
||||
frame,
|
||||
playbackRate,
|
||||
props.playbackRate,
|
||||
toneFrequency,
|
||||
sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom,
|
||||
audioStreamIndex,
|
||||
]);
|
||||
const { src } = props;
|
||||
// The <audio> tag is only rendered if the duration needs to be calculated for the `loop`
|
||||
// attribute to work, or if the user assigns a ref to it.
|
||||
const needsToRenderAudioTag = ref || _remotionInternalNeedsDurationCalculation;
|
||||
// If audio source switches, make new handle
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
var _a, _b;
|
||||
if (((_b = (_a = window.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.NODE_ENV) === 'test') {
|
||||
return;
|
||||
}
|
||||
if (!needsToRenderAudioTag) {
|
||||
return;
|
||||
}
|
||||
const newHandle = delayRender('Loading <Html5Audio> duration with src=' + src, {
|
||||
retries: delayRenderRetries !== null && delayRenderRetries !== void 0 ? delayRenderRetries : undefined,
|
||||
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds !== null && delayRenderTimeoutInMilliseconds !== void 0 ? delayRenderTimeoutInMilliseconds : undefined,
|
||||
});
|
||||
const { current } = audioRef;
|
||||
const didLoad = () => {
|
||||
if (current === null || current === void 0 ? void 0 : current.duration) {
|
||||
onDuration(current.src, current.duration);
|
||||
}
|
||||
continueRender(newHandle);
|
||||
};
|
||||
if (current === null || current === void 0 ? void 0 : current.duration) {
|
||||
onDuration(current.src, current.duration);
|
||||
continueRender(newHandle);
|
||||
}
|
||||
else {
|
||||
current === null || current === void 0 ? void 0 : current.addEventListener('loadedmetadata', didLoad, { once: true });
|
||||
}
|
||||
// If tag gets unmounted, clear pending handles because video metadata is not going to load
|
||||
return () => {
|
||||
current === null || current === void 0 ? void 0 : current.removeEventListener('loadedmetadata', didLoad);
|
||||
continueRender(newHandle);
|
||||
};
|
||||
}, [
|
||||
src,
|
||||
onDuration,
|
||||
needsToRenderAudioTag,
|
||||
delayRenderRetries,
|
||||
delayRenderTimeoutInMilliseconds,
|
||||
continueRender,
|
||||
delayRender,
|
||||
]);
|
||||
if (!needsToRenderAudioTag) {
|
||||
return null;
|
||||
}
|
||||
return (0, jsx_runtime_1.jsx)("audio", { ref: audioRef, ...nativeProps, onError: onNativeError });
|
||||
};
|
||||
exports.AudioForRendering = (0, react_1.forwardRef)(AudioForRenderingRefForwardingFunction);
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { Audio, Html5Audio } from './Audio.js';
|
||||
export * from './props.js';
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Html5Audio = exports.Audio = void 0;
|
||||
var Audio_js_1 = require("./Audio.js");
|
||||
Object.defineProperty(exports, "Audio", { enumerable: true, get: function () { return Audio_js_1.Audio; } });
|
||||
Object.defineProperty(exports, "Html5Audio", { enumerable: true, get: function () { return Audio_js_1.Html5Audio; } });
|
||||
__exportStar(require("./props.js"), exports);
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import type { VolumeProp } from '../volume-prop.js';
|
||||
import type { LoopVolumeCurveBehavior } from './use-audio-frame.js';
|
||||
export type RemotionMainAudioProps = {
|
||||
/**
|
||||
* @deprecated `startFrom` was renamed to `trimBefore`
|
||||
*/
|
||||
startFrom?: number;
|
||||
/**
|
||||
* @deprecated `endAt` was renamed to `trimAfter`
|
||||
*/
|
||||
endAt?: number;
|
||||
/**
|
||||
* Trim of the audio from the left (start) in frames.
|
||||
*/
|
||||
trimBefore?: number;
|
||||
/**
|
||||
* Trim of the audio from the right (end) in frames.
|
||||
*/
|
||||
trimAfter?: number;
|
||||
};
|
||||
export type NativeAudioProps = Omit<React.DetailedHTMLProps<React.AudioHTMLAttributes<HTMLAudioElement>, HTMLAudioElement>, 'autoPlay' | 'controls' | 'onEnded' | 'nonce' | 'onResize' | 'onResizeCapture' | 'onError'>;
|
||||
export type RemotionAudioProps = NativeAudioProps & {
|
||||
name?: string;
|
||||
volume?: VolumeProp;
|
||||
playbackRate?: number;
|
||||
acceptableTimeShiftInSeconds?: number;
|
||||
/**
|
||||
* @deprecated Amplification is now always enabled. To prevent amplification, set `volume` to a value less than 1.
|
||||
*/
|
||||
allowAmplificationDuringRender?: boolean;
|
||||
_remotionInternalNeedsDurationCalculation?: boolean;
|
||||
_remotionInternalNativeLoopPassed?: boolean;
|
||||
toneFrequency?: number;
|
||||
useWebAudioApi?: boolean;
|
||||
pauseWhenBuffering?: boolean;
|
||||
showInTimeline?: boolean;
|
||||
delayRenderTimeoutInMilliseconds?: number;
|
||||
delayRenderRetries?: number;
|
||||
loopVolumeCurveBehavior?: LoopVolumeCurveBehavior;
|
||||
onError?: (err: Error) => void;
|
||||
audioStreamIndex?: number;
|
||||
};
|
||||
type IsNever<T> = [T] extends [never] ? true : false;
|
||||
export type IsExact<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? IsNever<Exclude<keyof T, keyof U>> extends true ? IsNever<Exclude<keyof U, keyof T>> extends true ? true : false : false : false;
|
||||
export {};
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
Generated
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
import type { AudioHTMLAttributes } from 'react';
|
||||
import React from 'react';
|
||||
import type { SharedElementSourceNode } from './shared-element-source-node.js';
|
||||
/**
|
||||
* This functionality of Remotion will keep a certain amount
|
||||
* of <audio> tags pre-mounted and by default filled with an empty audio track.
|
||||
* If the user interacts, the empty audio will be played.
|
||||
* If one of Remotions <Html5Audio /> tags get mounted, the audio will not be rendered at this location, but into one of the prerendered audio tags.
|
||||
*
|
||||
* This helps with autoplay issues on iOS Safari and soon other browsers,
|
||||
* which only allow audio playback upon user interaction.
|
||||
*
|
||||
* The behavior can be disabled by passing `0` as the number of shared audio tracks.
|
||||
*/
|
||||
type AudioElem = {
|
||||
id: number;
|
||||
props: AudioHTMLAttributes<HTMLAudioElement>;
|
||||
el: React.RefObject<HTMLAudioElement | null>;
|
||||
audioId: string;
|
||||
mediaElementSourceNode: SharedElementSourceNode | null;
|
||||
premounting: boolean;
|
||||
postmounting: boolean;
|
||||
audioMounted: boolean;
|
||||
cleanupOnMediaTagUnmount: () => void;
|
||||
};
|
||||
type SharedContext = {
|
||||
registerAudio: (options: {
|
||||
aud: AudioHTMLAttributes<HTMLAudioElement>;
|
||||
audioId: string;
|
||||
premounting: boolean;
|
||||
postmounting: boolean;
|
||||
}) => AudioElem;
|
||||
unregisterAudio: (id: number) => void;
|
||||
updateAudio: (options: {
|
||||
id: number;
|
||||
aud: AudioHTMLAttributes<HTMLAudioElement>;
|
||||
audioId: string;
|
||||
premounting: boolean;
|
||||
postmounting: boolean;
|
||||
}) => void;
|
||||
playAllAudios: () => void;
|
||||
numberOfAudioTags: number;
|
||||
audioContext: AudioContext | null;
|
||||
};
|
||||
export declare const SharedAudioContext: React.Context<SharedContext | null>;
|
||||
export declare const SharedAudioContextProvider: React.FC<{
|
||||
readonly numberOfAudioTags: number;
|
||||
readonly children: React.ReactNode;
|
||||
readonly audioLatencyHint: AudioContextLatencyCategory;
|
||||
readonly audioEnabled: boolean;
|
||||
}>;
|
||||
export declare const useSharedAudio: ({ aud, audioId, premounting, postmounting, }: {
|
||||
aud: AudioHTMLAttributes<HTMLAudioElement>;
|
||||
audioId: string;
|
||||
premounting: boolean;
|
||||
postmounting: boolean;
|
||||
}) => AudioElem;
|
||||
export {};
|
||||
Generated
Vendored
+330
@@ -0,0 +1,330 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useSharedAudio = exports.SharedAudioContextProvider = exports.SharedAudioContext = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const log_level_context_js_1 = require("../log-level-context.js");
|
||||
const play_and_handle_not_allowed_error_js_1 = require("../play-and-handle-not-allowed-error.js");
|
||||
const use_remotion_environment_js_1 = require("../use-remotion-environment.js");
|
||||
const shared_element_source_node_js_1 = require("./shared-element-source-node.js");
|
||||
const use_audio_context_js_1 = require("./use-audio-context.js");
|
||||
const EMPTY_AUDIO = 'data:audio/mp3;base64,/+MYxAAJcAV8AAgAABn//////+/gQ5BAMA+D4Pg+BAQBAEAwD4Pg+D4EBAEAQDAPg++hYBH///hUFQVBUFREDQNHmf///////+MYxBUGkAGIMAAAAP/29Xt6lUxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxDUAAANIAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV';
|
||||
const compareProps = (obj1, obj2) => {
|
||||
const keysA = Object.keys(obj1).sort();
|
||||
const keysB = Object.keys(obj2).sort();
|
||||
if (keysA.length !== keysB.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < keysA.length; i++) {
|
||||
// Not the same keys
|
||||
if (keysA[i] !== keysB[i]) {
|
||||
return false;
|
||||
}
|
||||
// Not the same values
|
||||
if (obj1[keysA[i]] !== obj2[keysB[i]]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const didPropChange = (key, newProp, prevProp) => {
|
||||
// /music.mp3 and http://localhost:3000/music.mp3 are the same
|
||||
if (key === 'src' &&
|
||||
!prevProp.startsWith('data:') &&
|
||||
!newProp.startsWith('data:')) {
|
||||
return (new URL(prevProp, window.origin).toString() !==
|
||||
new URL(newProp, window.origin).toString());
|
||||
}
|
||||
if (prevProp === newProp) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
exports.SharedAudioContext = (0, react_1.createContext)(null);
|
||||
const SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHint, audioEnabled }) => {
|
||||
var _a;
|
||||
const audios = (0, react_1.useRef)([]);
|
||||
const [initialNumberOfAudioTags] = (0, react_1.useState)(numberOfAudioTags);
|
||||
if (numberOfAudioTags !== initialNumberOfAudioTags) {
|
||||
throw new Error('The number of shared audio tags has changed dynamically. Once you have set this property, you cannot change it afterwards.');
|
||||
}
|
||||
const logLevel = (0, log_level_context_js_1.useLogLevel)();
|
||||
const audioContext = (0, use_audio_context_js_1.useSingletonAudioContext)({
|
||||
logLevel,
|
||||
latencyHint: audioLatencyHint,
|
||||
audioEnabled,
|
||||
});
|
||||
const refs = (0, react_1.useMemo)(() => {
|
||||
return new Array(numberOfAudioTags).fill(true).map(() => {
|
||||
const ref = (0, react_1.createRef)();
|
||||
return {
|
||||
id: Math.random(),
|
||||
ref,
|
||||
mediaElementSourceNode: audioContext
|
||||
? (0, shared_element_source_node_js_1.makeSharedElementSourceNode)({
|
||||
audioContext,
|
||||
ref,
|
||||
})
|
||||
: null,
|
||||
};
|
||||
});
|
||||
}, [audioContext, numberOfAudioTags]);
|
||||
/**
|
||||
* Effects in React 18 fire twice, and we are looking for a way to only fire it once.
|
||||
* - useInsertionEffect only fires once. If it's available we are in React 18.
|
||||
* - useLayoutEffect only fires once in React 17.
|
||||
*
|
||||
* Need to import it from React to fix React 17 ESM support.
|
||||
*/
|
||||
const effectToUse = (_a = react_1.default.useInsertionEffect) !== null && _a !== void 0 ? _a : react_1.default.useLayoutEffect;
|
||||
// Disconnecting the SharedElementSourceNodes if the Player unmounts to prevent leak.
|
||||
// https://github.com/remotion-dev/remotion/issues/6285
|
||||
// But useInsertionEffect will fire before other effects, meaning the
|
||||
// nodes might still be used. Using rAF to ensure it's after other effects.
|
||||
effectToUse(() => {
|
||||
return () => {
|
||||
requestAnimationFrame(() => {
|
||||
refs.forEach(({ mediaElementSourceNode }) => {
|
||||
mediaElementSourceNode === null || mediaElementSourceNode === void 0 ? void 0 : mediaElementSourceNode.cleanup();
|
||||
});
|
||||
});
|
||||
};
|
||||
}, [refs]);
|
||||
const takenAudios = (0, react_1.useRef)(new Array(numberOfAudioTags).fill(false));
|
||||
const rerenderAudios = (0, react_1.useCallback)(() => {
|
||||
refs.forEach(({ ref, id }) => {
|
||||
var _a;
|
||||
const data = (_a = audios.current) === null || _a === void 0 ? void 0 : _a.find((a) => a.id === id);
|
||||
const { current } = ref;
|
||||
if (!current) {
|
||||
// Whole player has been unmounted, the refs don't exist anymore.
|
||||
// It is not an error anymore though
|
||||
return;
|
||||
}
|
||||
if (data === undefined) {
|
||||
current.src = EMPTY_AUDIO;
|
||||
return;
|
||||
}
|
||||
if (!data) {
|
||||
throw new TypeError('Expected audio data to be there');
|
||||
}
|
||||
Object.keys(data.props).forEach((key) => {
|
||||
// @ts-expect-error
|
||||
if (didPropChange(key, data.props[key], current[key])) {
|
||||
// @ts-expect-error
|
||||
current[key] = data.props[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [refs]);
|
||||
const registerAudio = (0, react_1.useCallback)((options) => {
|
||||
var _a, _b;
|
||||
const { aud, audioId, premounting, postmounting } = options;
|
||||
const found = (_a = audios.current) === null || _a === void 0 ? void 0 : _a.find((a) => a.audioId === audioId);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
const firstFreeAudio = takenAudios.current.findIndex((a) => a === false);
|
||||
if (firstFreeAudio === -1) {
|
||||
throw new Error(`Tried to simultaneously mount ${numberOfAudioTags + 1} <Html5Audio /> tags at the same time. With the current settings, the maximum amount of <Html5Audio /> tags is limited to ${numberOfAudioTags} at the same time. Remotion pre-mounts silent audio tags to help avoid browser autoplay restrictions. See https://remotion.dev/docs/player/autoplay#using-the-numberofsharedaudiotags-prop for more information on how to increase this limit.`);
|
||||
}
|
||||
const { id, ref, mediaElementSourceNode } = refs[firstFreeAudio];
|
||||
const cloned = [...takenAudios.current];
|
||||
cloned[firstFreeAudio] = id;
|
||||
takenAudios.current = cloned;
|
||||
const newElem = {
|
||||
props: aud,
|
||||
id,
|
||||
el: ref,
|
||||
audioId,
|
||||
mediaElementSourceNode,
|
||||
premounting,
|
||||
audioMounted: Boolean(ref.current),
|
||||
postmounting,
|
||||
cleanupOnMediaTagUnmount: () => {
|
||||
// Don't disconnect here, only when the Player unmounts.
|
||||
},
|
||||
};
|
||||
(_b = audios.current) === null || _b === void 0 ? void 0 : _b.push(newElem);
|
||||
rerenderAudios();
|
||||
return newElem;
|
||||
}, [numberOfAudioTags, refs, rerenderAudios]);
|
||||
const unregisterAudio = (0, react_1.useCallback)((id) => {
|
||||
var _a;
|
||||
const cloned = [...takenAudios.current];
|
||||
const index = refs.findIndex((r) => r.id === id);
|
||||
if (index === -1) {
|
||||
throw new TypeError('Error occured in ');
|
||||
}
|
||||
cloned[index] = false;
|
||||
takenAudios.current = cloned;
|
||||
audios.current = (_a = audios.current) === null || _a === void 0 ? void 0 : _a.filter((a) => a.id !== id);
|
||||
rerenderAudios();
|
||||
}, [refs, rerenderAudios]);
|
||||
const updateAudio = (0, react_1.useCallback)(({ aud, audioId, id, premounting, postmounting, }) => {
|
||||
var _a;
|
||||
let changed = false;
|
||||
audios.current = (_a = audios.current) === null || _a === void 0 ? void 0 : _a.map((prevA) => {
|
||||
const audioMounted = Boolean(prevA.el.current);
|
||||
if (prevA.audioMounted !== audioMounted) {
|
||||
changed = true;
|
||||
}
|
||||
if (prevA.id === id) {
|
||||
const isTheSame = compareProps(aud, prevA.props) &&
|
||||
prevA.premounting === premounting &&
|
||||
prevA.postmounting === postmounting;
|
||||
if (isTheSame) {
|
||||
return prevA;
|
||||
}
|
||||
changed = true;
|
||||
return {
|
||||
...prevA,
|
||||
props: aud,
|
||||
premounting,
|
||||
postmounting,
|
||||
audioId,
|
||||
audioMounted,
|
||||
};
|
||||
}
|
||||
return prevA;
|
||||
});
|
||||
if (changed) {
|
||||
rerenderAudios();
|
||||
}
|
||||
}, [rerenderAudios]);
|
||||
const mountTime = (0, log_level_context_js_1.useMountTime)();
|
||||
const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
||||
const playAllAudios = (0, react_1.useCallback)(() => {
|
||||
refs.forEach((ref) => {
|
||||
const audio = audios.current.find((a) => a.el === ref.ref);
|
||||
if (audio === null || audio === void 0 ? void 0 : audio.premounting) {
|
||||
return;
|
||||
}
|
||||
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)({
|
||||
mediaRef: ref.ref,
|
||||
mediaType: 'audio',
|
||||
onAutoPlayError: null,
|
||||
logLevel,
|
||||
mountTime,
|
||||
reason: 'playing all audios',
|
||||
isPlayer: env.isPlayer,
|
||||
});
|
||||
});
|
||||
audioContext === null || audioContext === void 0 ? void 0 : audioContext.resume();
|
||||
}, [audioContext, logLevel, mountTime, refs, env.isPlayer]);
|
||||
const value = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
registerAudio,
|
||||
unregisterAudio,
|
||||
updateAudio,
|
||||
playAllAudios,
|
||||
numberOfAudioTags,
|
||||
audioContext,
|
||||
};
|
||||
}, [
|
||||
numberOfAudioTags,
|
||||
playAllAudios,
|
||||
registerAudio,
|
||||
unregisterAudio,
|
||||
updateAudio,
|
||||
audioContext,
|
||||
]);
|
||||
return ((0, jsx_runtime_1.jsxs)(exports.SharedAudioContext.Provider, { value: value, children: [refs.map(({ id, ref }) => {
|
||||
return (
|
||||
// Without preload="metadata", iOS will seek the time internally
|
||||
// but not actually with sound. Adding `preload="metadata"` helps here.
|
||||
// https://discord.com/channels/809501355504959528/817306414069710848/1130519583367888906
|
||||
(0, jsx_runtime_1.jsx)("audio", { ref: ref, preload: "metadata", src: EMPTY_AUDIO }, id));
|
||||
}), children] }));
|
||||
};
|
||||
exports.SharedAudioContextProvider = SharedAudioContextProvider;
|
||||
const useSharedAudio = ({ aud, audioId, premounting, postmounting, }) => {
|
||||
var _a;
|
||||
const ctx = (0, react_1.useContext)(exports.SharedAudioContext);
|
||||
/**
|
||||
* We work around this in React 18 so an audio tag will only register itself once
|
||||
*/
|
||||
const [elem] = (0, react_1.useState)(() => {
|
||||
if (ctx && ctx.numberOfAudioTags > 0) {
|
||||
return ctx.registerAudio({ aud, audioId, premounting, postmounting });
|
||||
}
|
||||
// numberOfSharedAudioTags is 0
|
||||
const el = react_1.default.createRef();
|
||||
const mediaElementSourceNode = (ctx === null || ctx === void 0 ? void 0 : ctx.audioContext)
|
||||
? (0, shared_element_source_node_js_1.makeSharedElementSourceNode)({
|
||||
audioContext: ctx.audioContext,
|
||||
ref: el,
|
||||
})
|
||||
: null;
|
||||
return {
|
||||
el,
|
||||
id: Math.random(),
|
||||
props: aud,
|
||||
audioId,
|
||||
mediaElementSourceNode,
|
||||
premounting,
|
||||
audioMounted: Boolean(el.current),
|
||||
postmounting,
|
||||
cleanupOnMediaTagUnmount: () => {
|
||||
mediaElementSourceNode === null || mediaElementSourceNode === void 0 ? void 0 : mediaElementSourceNode.cleanup();
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Effects in React 18 fire twice, and we are looking for a way to only fire it once.
|
||||
* - useInsertionEffect only fires once. If it's available we are in React 18.
|
||||
* - useLayoutEffect only fires once in React 17.
|
||||
*
|
||||
* Need to import it from React to fix React 17 ESM support.
|
||||
*/
|
||||
const effectToUse = (_a = react_1.default.useInsertionEffect) !== null && _a !== void 0 ? _a : react_1.default.useLayoutEffect;
|
||||
if (typeof document !== 'undefined') {
|
||||
effectToUse(() => {
|
||||
if (ctx && ctx.numberOfAudioTags > 0) {
|
||||
ctx.updateAudio({ id: elem.id, aud, audioId, premounting, postmounting });
|
||||
}
|
||||
}, [aud, ctx, elem.id, audioId, premounting, postmounting]);
|
||||
effectToUse(() => {
|
||||
return () => {
|
||||
if (ctx && ctx.numberOfAudioTags > 0) {
|
||||
ctx.unregisterAudio(elem.id);
|
||||
}
|
||||
};
|
||||
}, [ctx, elem.id]);
|
||||
}
|
||||
return elem;
|
||||
};
|
||||
exports.useSharedAudio = useSharedAudio;
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
export declare const makeSharedElementSourceNode: ({ audioContext, ref, }: {
|
||||
audioContext: AudioContext;
|
||||
ref: React.RefObject<HTMLAudioElement | null>;
|
||||
}) => {
|
||||
attemptToConnect: () => void;
|
||||
get: () => MediaElementAudioSourceNode;
|
||||
cleanup: () => void;
|
||||
};
|
||||
export type SharedElementSourceNode = ReturnType<typeof makeSharedElementSourceNode>;
|
||||
Generated
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.makeSharedElementSourceNode = void 0;
|
||||
const makeSharedElementSourceNode = ({ audioContext, ref, }) => {
|
||||
let connected = null;
|
||||
let disposed = false;
|
||||
// We must allow this to cleanup and create a new one due to strict mode.
|
||||
return {
|
||||
attemptToConnect: () => {
|
||||
if (disposed) {
|
||||
throw new Error('SharedElementSourceNode has been disposed');
|
||||
}
|
||||
if (!connected && ref.current) {
|
||||
const mediaElementSourceNode = audioContext.createMediaElementSource(ref.current);
|
||||
connected = mediaElementSourceNode;
|
||||
}
|
||||
},
|
||||
get: () => {
|
||||
if (!connected) {
|
||||
throw new Error('Audio element not connected');
|
||||
}
|
||||
return connected;
|
||||
},
|
||||
cleanup: () => {
|
||||
if (connected) {
|
||||
connected.disconnect();
|
||||
connected = null;
|
||||
}
|
||||
disposed = true;
|
||||
},
|
||||
};
|
||||
};
|
||||
exports.makeSharedElementSourceNode = makeSharedElementSourceNode;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import type { LogLevel } from '../log';
|
||||
export declare const useSingletonAudioContext: ({ logLevel, latencyHint, audioEnabled, }: {
|
||||
logLevel: LogLevel;
|
||||
latencyHint: AudioContextLatencyCategory;
|
||||
audioEnabled: boolean;
|
||||
}) => AudioContext | null;
|
||||
Generated
Vendored
+41
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useSingletonAudioContext = void 0;
|
||||
const react_1 = require("react");
|
||||
const log_1 = require("../log");
|
||||
const use_remotion_environment_1 = require("../use-remotion-environment");
|
||||
let warned = false;
|
||||
const warnOnce = (logLevel) => {
|
||||
if (warned) {
|
||||
return;
|
||||
}
|
||||
warned = true;
|
||||
// Don't pullute logs if in SSR
|
||||
if (typeof window !== 'undefined') {
|
||||
log_1.Log.warn({ logLevel, tag: null }, 'AudioContext is not supported in this browser');
|
||||
}
|
||||
};
|
||||
const useSingletonAudioContext = ({ logLevel, latencyHint, audioEnabled, }) => {
|
||||
const env = (0, use_remotion_environment_1.useRemotionEnvironment)();
|
||||
const audioContext = (0, react_1.useMemo)(() => {
|
||||
if (env.isRendering) {
|
||||
return null;
|
||||
}
|
||||
if (!audioEnabled) {
|
||||
return null;
|
||||
}
|
||||
if (typeof AudioContext === 'undefined') {
|
||||
warnOnce(logLevel);
|
||||
return null;
|
||||
}
|
||||
return new AudioContext({
|
||||
latencyHint,
|
||||
// By default, this can end up being 44100Hz.
|
||||
// Playing a 48000Hz file in a 44100Hz context, such as https://remotion.media/video.mp4 in a @remotion/media tag
|
||||
// we observe some issues that seem to go away when we set the sample rate to 48000 with Sony LinkBuds Bluetooth headphones.
|
||||
sampleRate: 48000,
|
||||
});
|
||||
}, [logLevel, latencyHint, env.isRendering, audioEnabled]);
|
||||
return audioContext;
|
||||
};
|
||||
exports.useSingletonAudioContext = useSingletonAudioContext;
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
export declare const useMediaStartsAt: () => number;
|
||||
export type LoopVolumeCurveBehavior = 'repeat' | 'extend';
|
||||
/**
|
||||
* When passing a function as the prop for `volume`,
|
||||
* we calculate the way more intuitive value for currentFrame
|
||||
*/
|
||||
export declare const useFrameForVolumeProp: (behavior: LoopVolumeCurveBehavior) => number;
|
||||
Generated
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useFrameForVolumeProp = exports.useMediaStartsAt = void 0;
|
||||
const react_1 = require("react");
|
||||
const SequenceContext_js_1 = require("../SequenceContext.js");
|
||||
const index_js_1 = require("../loop/index.js");
|
||||
const use_current_frame_js_1 = require("../use-current-frame.js");
|
||||
const useMediaStartsAt = () => {
|
||||
var _a;
|
||||
const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
||||
const startsAt = Math.min(0, (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.relativeFrom) !== null && _a !== void 0 ? _a : 0);
|
||||
return startsAt;
|
||||
};
|
||||
exports.useMediaStartsAt = useMediaStartsAt;
|
||||
/**
|
||||
* When passing a function as the prop for `volume`,
|
||||
* we calculate the way more intuitive value for currentFrame
|
||||
*/
|
||||
const useFrameForVolumeProp = (behavior) => {
|
||||
const loop = index_js_1.Loop.useLoop();
|
||||
const frame = (0, use_current_frame_js_1.useCurrentFrame)();
|
||||
const startsAt = (0, exports.useMediaStartsAt)();
|
||||
if (behavior === 'repeat' || loop === null) {
|
||||
return frame + startsAt;
|
||||
}
|
||||
return frame + startsAt + loop.durationInFrames * loop.iteration;
|
||||
};
|
||||
exports.useFrameForVolumeProp = useFrameForVolumeProp;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare function bezier(mX1: number, mY1: number, mX2: number, mY2: number): (x: number) => number;
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
"use strict";
|
||||
// Taken from https://github.com/facebook/react-native/blob/0b9ea60b4fee8cacc36e7160e31b91fc114dbc0d/Libraries/Animated/src/bezier.js
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.bezier = bezier;
|
||||
const NEWTON_ITERATIONS = 4;
|
||||
const NEWTON_MIN_SLOPE = 0.001;
|
||||
const SUBDIVISION_PRECISION = 0.0000001;
|
||||
const SUBDIVISION_MAX_ITERATIONS = 10;
|
||||
const kSplineTableSize = 11;
|
||||
const kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
|
||||
const float32ArraySupported = typeof Float32Array === 'function';
|
||||
function a(aA1, aA2) {
|
||||
return 1.0 - 3.0 * aA2 + 3.0 * aA1;
|
||||
}
|
||||
function b(aA1, aA2) {
|
||||
return 3.0 * aA2 - 6.0 * aA1;
|
||||
}
|
||||
function c(aA1) {
|
||||
return 3.0 * aA1;
|
||||
}
|
||||
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
||||
function calcBezier(aT, aA1, aA2) {
|
||||
return ((a(aA1, aA2) * aT + b(aA1, aA2)) * aT + c(aA1)) * aT;
|
||||
}
|
||||
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
|
||||
function getSlope(aT, aA1, aA2) {
|
||||
return 3.0 * a(aA1, aA2) * aT * aT + 2.0 * b(aA1, aA2) * aT + c(aA1);
|
||||
}
|
||||
function binarySubdivide({ aX, _aA, _aB, mX1, mX2, }) {
|
||||
let currentX;
|
||||
let currentT;
|
||||
let i = 0;
|
||||
let aA = _aA;
|
||||
let aB = _aB;
|
||||
do {
|
||||
currentT = aA + (aB - aA) / 2.0;
|
||||
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
||||
if (currentX > 0.0) {
|
||||
aB = currentT;
|
||||
}
|
||||
else {
|
||||
aA = currentT;
|
||||
}
|
||||
} while (Math.abs(currentX) > SUBDIVISION_PRECISION &&
|
||||
++i < SUBDIVISION_MAX_ITERATIONS);
|
||||
return currentT;
|
||||
}
|
||||
function newtonRaphsonIterate(aX, _aGuessT, mX1, mX2) {
|
||||
let aGuessT = _aGuessT;
|
||||
for (let i = 0; i < NEWTON_ITERATIONS; ++i) {
|
||||
const currentSlope = getSlope(aGuessT, mX1, mX2);
|
||||
if (currentSlope === 0.0) {
|
||||
return aGuessT;
|
||||
}
|
||||
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
|
||||
aGuessT -= currentX / currentSlope;
|
||||
}
|
||||
return aGuessT;
|
||||
}
|
||||
function bezier(mX1, mY1, mX2, mY2) {
|
||||
if (!(mX1 >= 0 && mX1 <= 1 && mX2 >= 0 && mX2 <= 1)) {
|
||||
throw new Error('bezier x values must be in [0, 1] range');
|
||||
}
|
||||
// Precompute samples table
|
||||
const sampleValues = float32ArraySupported
|
||||
? new Float32Array(kSplineTableSize)
|
||||
: new Array(kSplineTableSize);
|
||||
if (mX1 !== mY1 || mX2 !== mY2) {
|
||||
for (let i = 0; i < kSplineTableSize; ++i) {
|
||||
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
|
||||
}
|
||||
}
|
||||
function getTForX(aX) {
|
||||
let intervalStart = 0.0;
|
||||
let currentSample = 1;
|
||||
const lastSample = kSplineTableSize - 1;
|
||||
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
|
||||
intervalStart += kSampleStepSize;
|
||||
}
|
||||
--currentSample;
|
||||
// Interpolate to provide an initial guess for t
|
||||
const dist = (aX - sampleValues[currentSample]) /
|
||||
(sampleValues[currentSample + 1] - sampleValues[currentSample]);
|
||||
const guessForT = intervalStart + dist * kSampleStepSize;
|
||||
const initialSlope = getSlope(guessForT, mX1, mX2);
|
||||
if (initialSlope >= NEWTON_MIN_SLOPE) {
|
||||
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
|
||||
}
|
||||
if (initialSlope === 0.0) {
|
||||
return guessForT;
|
||||
}
|
||||
return binarySubdivide({
|
||||
aX,
|
||||
_aA: intervalStart,
|
||||
_aB: intervalStart + kSampleStepSize,
|
||||
mX1,
|
||||
mX2,
|
||||
});
|
||||
}
|
||||
return function (x) {
|
||||
if (mX1 === mY1 && mX2 === mY2) {
|
||||
return x; // linear
|
||||
}
|
||||
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
|
||||
if (x === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (x === 1) {
|
||||
return 1;
|
||||
}
|
||||
return calcBezier(getTForX(x), mY1, mY2);
|
||||
};
|
||||
}
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import type { LogLevel } from './log';
|
||||
export declare const useBufferUntilFirstFrame: ({ mediaRef, mediaType, onVariableFpsVideoDetected, pauseWhenBuffering, logLevel, mountTime, }: {
|
||||
mediaRef: React.RefObject<HTMLVideoElement | HTMLAudioElement | null>;
|
||||
mediaType: "video" | "audio";
|
||||
onVariableFpsVideoDetected: () => void;
|
||||
pauseWhenBuffering: boolean;
|
||||
logLevel: LogLevel;
|
||||
mountTime: number | null;
|
||||
}) => {
|
||||
isBuffering: () => boolean;
|
||||
bufferUntilFirstFrame: (requestedTime: number) => void;
|
||||
};
|
||||
Generated
Vendored
+95
@@ -0,0 +1,95 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useBufferUntilFirstFrame = void 0;
|
||||
const react_1 = require("react");
|
||||
const playback_logging_1 = require("./playback-logging");
|
||||
const use_buffer_state_1 = require("./use-buffer-state");
|
||||
const isSafariWebkit = () => {
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(window.navigator.userAgent);
|
||||
return isSafari;
|
||||
};
|
||||
const useBufferUntilFirstFrame = ({ mediaRef, mediaType, onVariableFpsVideoDetected, pauseWhenBuffering, logLevel, mountTime, }) => {
|
||||
const bufferingRef = (0, react_1.useRef)(false);
|
||||
const { delayPlayback } = (0, use_buffer_state_1.useBufferState)();
|
||||
const bufferUntilFirstFrame = (0, react_1.useCallback)((requestedTime) => {
|
||||
var _a;
|
||||
if (mediaType !== 'video') {
|
||||
return;
|
||||
}
|
||||
if (!pauseWhenBuffering) {
|
||||
return;
|
||||
}
|
||||
const current = mediaRef.current;
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
if (current.readyState >= current.HAVE_FUTURE_DATA && !isSafariWebkit()) {
|
||||
(0, playback_logging_1.playbackLogging)({
|
||||
logLevel,
|
||||
message: `Not using buffer until first frame, because readyState is ${current.readyState} and is not Safari or Desktop Chrome`,
|
||||
mountTime,
|
||||
tag: 'buffer',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!current.requestVideoFrameCallback) {
|
||||
(0, playback_logging_1.playbackLogging)({
|
||||
logLevel,
|
||||
message: `Not using buffer until first frame, because requestVideoFrameCallback is not supported`,
|
||||
mountTime,
|
||||
tag: 'buffer',
|
||||
});
|
||||
return;
|
||||
}
|
||||
bufferingRef.current = true;
|
||||
(0, playback_logging_1.playbackLogging)({
|
||||
logLevel,
|
||||
message: `Buffering ${(_a = mediaRef.current) === null || _a === void 0 ? void 0 : _a.src} until the first frame is received`,
|
||||
mountTime,
|
||||
tag: 'buffer',
|
||||
});
|
||||
const playback = delayPlayback();
|
||||
const unblock = () => {
|
||||
playback.unblock();
|
||||
current.removeEventListener('ended', unblock, {
|
||||
// @ts-expect-error
|
||||
once: true,
|
||||
});
|
||||
current.removeEventListener('pause', unblock, {
|
||||
// @ts-expect-error
|
||||
once: true,
|
||||
});
|
||||
bufferingRef.current = false;
|
||||
};
|
||||
const onEndedOrPauseOrCanPlay = () => {
|
||||
unblock();
|
||||
};
|
||||
current.requestVideoFrameCallback((_, info) => {
|
||||
const differenceFromRequested = Math.abs(info.mediaTime - requestedTime);
|
||||
if (differenceFromRequested > 0.5) {
|
||||
onVariableFpsVideoDetected();
|
||||
}
|
||||
unblock();
|
||||
});
|
||||
current.addEventListener('ended', onEndedOrPauseOrCanPlay, { once: true });
|
||||
current.addEventListener('pause', onEndedOrPauseOrCanPlay, { once: true });
|
||||
current.addEventListener('canplay', onEndedOrPauseOrCanPlay, {
|
||||
once: true,
|
||||
});
|
||||
}, [
|
||||
delayPlayback,
|
||||
logLevel,
|
||||
mediaRef,
|
||||
mediaType,
|
||||
mountTime,
|
||||
onVariableFpsVideoDetected,
|
||||
pauseWhenBuffering,
|
||||
]);
|
||||
return (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
isBuffering: () => bufferingRef.current,
|
||||
bufferUntilFirstFrame,
|
||||
};
|
||||
}, [bufferUntilFirstFrame]);
|
||||
};
|
||||
exports.useBufferUntilFirstFrame = useBufferUntilFirstFrame;
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
type Block = {
|
||||
id: string;
|
||||
};
|
||||
type OnBufferingCallback = () => void;
|
||||
type OnResumeCallback = () => void;
|
||||
type ListenForBuffering = (callback: OnBufferingCallback) => {
|
||||
remove: () => void;
|
||||
};
|
||||
type ListenForResume = (callback: OnResumeCallback) => {
|
||||
remove: () => void;
|
||||
};
|
||||
type AddBlock = (block: Block) => {
|
||||
unblock: () => void;
|
||||
};
|
||||
type BufferManager = {
|
||||
addBlock: AddBlock;
|
||||
listenForBuffering: ListenForBuffering;
|
||||
listenForResume: ListenForResume;
|
||||
buffering: React.MutableRefObject<boolean>;
|
||||
};
|
||||
export declare const BufferingContextReact: React.Context<BufferManager | null>;
|
||||
export declare const BufferingProvider: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
export declare const useIsPlayerBuffering: (bufferManager: BufferManager) => boolean;
|
||||
export {};
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useIsPlayerBuffering = exports.BufferingProvider = exports.BufferingContextReact = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const log_level_context_1 = require("./log-level-context");
|
||||
const playback_logging_1 = require("./playback-logging");
|
||||
const use_remotion_environment_1 = require("./use-remotion-environment");
|
||||
const useBufferManager = (logLevel, mountTime) => {
|
||||
const [blocks, setBlocks] = (0, react_1.useState)([]);
|
||||
const [onBufferingCallbacks, setOnBufferingCallbacks] = (0, react_1.useState)([]);
|
||||
const [onResumeCallbacks, setOnResumeCallbacks] = (0, react_1.useState)([]);
|
||||
const env = (0, use_remotion_environment_1.useRemotionEnvironment)();
|
||||
const rendering = env.isRendering;
|
||||
const buffering = (0, react_1.useRef)(false);
|
||||
const addBlock = (0, react_1.useCallback)((block) => {
|
||||
if (rendering) {
|
||||
return {
|
||||
unblock: () => undefined,
|
||||
};
|
||||
}
|
||||
setBlocks((b) => [...b, block]);
|
||||
return {
|
||||
unblock: () => {
|
||||
setBlocks((b) => {
|
||||
const newArr = b.filter((bx) => bx !== block);
|
||||
if (newArr.length === b.length) {
|
||||
return b;
|
||||
}
|
||||
return newArr;
|
||||
});
|
||||
},
|
||||
};
|
||||
}, [rendering]);
|
||||
const listenForBuffering = (0, react_1.useCallback)((callback) => {
|
||||
setOnBufferingCallbacks((c) => [...c, callback]);
|
||||
return {
|
||||
remove: () => {
|
||||
setOnBufferingCallbacks((c) => c.filter((cb) => cb !== callback));
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
const listenForResume = (0, react_1.useCallback)((callback) => {
|
||||
setOnResumeCallbacks((c) => [...c, callback]);
|
||||
return {
|
||||
remove: () => {
|
||||
setOnResumeCallbacks((c) => c.filter((cb) => cb !== callback));
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (rendering) {
|
||||
return;
|
||||
}
|
||||
if (blocks.length > 0) {
|
||||
onBufferingCallbacks.forEach((c) => c());
|
||||
(0, playback_logging_1.playbackLogging)({
|
||||
logLevel,
|
||||
message: 'Player is entering buffer state',
|
||||
mountTime,
|
||||
tag: 'player',
|
||||
});
|
||||
}
|
||||
// Intentionally only firing when blocks change, not the callbacks
|
||||
// otherwise a buffering callback might remove itself after being called
|
||||
// and trigger again
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [blocks]);
|
||||
if (typeof window !== 'undefined') {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
if (rendering) {
|
||||
return;
|
||||
}
|
||||
if (blocks.length === 0) {
|
||||
onResumeCallbacks.forEach((c) => c());
|
||||
(0, playback_logging_1.playbackLogging)({
|
||||
logLevel,
|
||||
message: 'Player is exiting buffer state',
|
||||
mountTime,
|
||||
tag: 'player',
|
||||
});
|
||||
}
|
||||
// Intentionally only firing when blocks change, not the callbacks
|
||||
// otherwise a resume callback might remove itself after being called
|
||||
// and trigger again
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [blocks]);
|
||||
}
|
||||
return (0, react_1.useMemo)(() => {
|
||||
return { addBlock, listenForBuffering, listenForResume, buffering };
|
||||
}, [addBlock, buffering, listenForBuffering, listenForResume]);
|
||||
};
|
||||
exports.BufferingContextReact = react_1.default.createContext(null);
|
||||
const BufferingProvider = ({ children }) => {
|
||||
const { logLevel, mountTime } = (0, react_1.useContext)(log_level_context_1.LogLevelContext);
|
||||
const bufferManager = useBufferManager(logLevel !== null && logLevel !== void 0 ? logLevel : 'info', mountTime);
|
||||
return ((0, jsx_runtime_1.jsx)(exports.BufferingContextReact.Provider, { value: bufferManager, children: children }));
|
||||
};
|
||||
exports.BufferingProvider = BufferingProvider;
|
||||
const useIsPlayerBuffering = (bufferManager) => {
|
||||
const [isBuffering, setIsBuffering] = (0, react_1.useState)(bufferManager.buffering.current);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const onBuffer = () => {
|
||||
setIsBuffering(true);
|
||||
};
|
||||
const onResume = () => {
|
||||
setIsBuffering(false);
|
||||
};
|
||||
bufferManager.listenForBuffering(onBuffer);
|
||||
bufferManager.listenForResume(onResume);
|
||||
return () => {
|
||||
bufferManager.listenForBuffering(() => undefined);
|
||||
bufferManager.listenForResume(() => undefined);
|
||||
};
|
||||
}, [bufferManager]);
|
||||
return isBuffering;
|
||||
};
|
||||
exports.useIsPlayerBuffering = useIsPlayerBuffering;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
export declare const calculateMediaDuration: ({ trimAfter, mediaDurationInFrames, playbackRate, trimBefore, }: {
|
||||
mediaDurationInFrames: number;
|
||||
playbackRate: number;
|
||||
trimBefore: number | undefined;
|
||||
trimAfter: number | undefined;
|
||||
}) => number;
|
||||
Generated
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.calculateMediaDuration = void 0;
|
||||
const calculateMediaDuration = ({ trimAfter, mediaDurationInFrames, playbackRate, trimBefore, }) => {
|
||||
let duration = mediaDurationInFrames;
|
||||
// Account for trimAfter
|
||||
if (typeof trimAfter !== 'undefined') {
|
||||
duration = trimAfter;
|
||||
}
|
||||
// Account for trimBefore
|
||||
if (typeof trimBefore !== 'undefined') {
|
||||
duration -= trimBefore;
|
||||
}
|
||||
const actualDuration = duration / playbackRate;
|
||||
return Math.floor(actualDuration);
|
||||
};
|
||||
exports.calculateMediaDuration = calculateMediaDuration;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { DelayRenderScope } from './delay-render.js';
|
||||
export declare const getErrorStackWithMessage: (error: Error) => string;
|
||||
/**
|
||||
* Internal function that accepts scope as parameter.
|
||||
* This allows useDelayRender to control its own scope source.
|
||||
* @private
|
||||
*/
|
||||
export declare function cancelRenderInternal(scope: DelayRenderScope | undefined, err: unknown): never;
|
||||
export declare function cancelRender(err: unknown): never;
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getErrorStackWithMessage = void 0;
|
||||
exports.cancelRenderInternal = cancelRenderInternal;
|
||||
exports.cancelRender = cancelRender;
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack
|
||||
const getErrorStackWithMessage = (error) => {
|
||||
var _a;
|
||||
const stack = (_a = error.stack) !== null && _a !== void 0 ? _a : '';
|
||||
return stack.startsWith('Error:') ? stack : `${error.message}\n${stack}`;
|
||||
};
|
||||
exports.getErrorStackWithMessage = getErrorStackWithMessage;
|
||||
const isErrorLike = (err) => {
|
||||
if (err instanceof Error) {
|
||||
return true;
|
||||
}
|
||||
if (err === null) {
|
||||
return false;
|
||||
}
|
||||
if (typeof err !== 'object') {
|
||||
return false;
|
||||
}
|
||||
if (!('stack' in err)) {
|
||||
return false;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
|
||||
// @ts-ignore we just asserted
|
||||
if (typeof err.stack !== 'string') {
|
||||
return false;
|
||||
}
|
||||
if (!('message' in err)) {
|
||||
return false;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
|
||||
// @ts-ignore we just asserted
|
||||
if (typeof err.message !== 'string') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Internal function that accepts scope as parameter.
|
||||
* This allows useDelayRender to control its own scope source.
|
||||
* @private
|
||||
*/
|
||||
function cancelRenderInternal(scope, err) {
|
||||
let error;
|
||||
if (isErrorLike(err)) {
|
||||
error = err;
|
||||
if (!error.stack) {
|
||||
error.stack = new Error(error.message).stack;
|
||||
}
|
||||
}
|
||||
else if (typeof err === 'string') {
|
||||
error = Error(err);
|
||||
}
|
||||
else {
|
||||
error = Error('Rendering was cancelled');
|
||||
}
|
||||
if (scope) {
|
||||
scope.remotion_cancelledError = (0, exports.getErrorStackWithMessage)(error);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
/*
|
||||
* @description When you invoke this function, Remotion will stop rendering all the frames without any retries.
|
||||
* @see [Documentation](https://remotion.dev/docs/cancel-render)
|
||||
*/
|
||||
function cancelRender(err) {
|
||||
return cancelRenderInternal(typeof window !== 'undefined' ? window : undefined, err);
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
export declare const validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "h264-ts", "gif"];
|
||||
export type Codec = (typeof validCodecs)[number];
|
||||
export type CodecOrUndefined = Codec | undefined;
|
||||
export declare const DEFAULT_CODEC: Codec;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DEFAULT_CODEC = exports.validCodecs = void 0;
|
||||
exports.validCodecs = [
|
||||
'h264',
|
||||
'h265',
|
||||
'vp8',
|
||||
'vp9',
|
||||
'mp3',
|
||||
'aac',
|
||||
'wav',
|
||||
'prores',
|
||||
'h264-mkv',
|
||||
'h264-ts',
|
||||
'gif',
|
||||
];
|
||||
exports.DEFAULT_CODEC = 'h264';
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare const getInputProps: <T extends Record<string, unknown> = Record<string, unknown>>() => T;
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getInputProps = void 0;
|
||||
const get_remotion_environment_js_1 = require("../get-remotion-environment.js");
|
||||
const input_props_override_js_1 = require("../input-props-override.js");
|
||||
const input_props_serialization_js_1 = require("../input-props-serialization.js");
|
||||
let didWarnSSRImport = false;
|
||||
const warnOnceSSRImport = () => {
|
||||
if (didWarnSSRImport) {
|
||||
return;
|
||||
}
|
||||
didWarnSSRImport = true;
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('Called `getInputProps()` on the server. This function is not available server-side and has returned an empty object.');
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("To hide this warning, don't call this function on the server:");
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(" typeof window === 'undefined' ? {} : getInputProps()");
|
||||
};
|
||||
const getInputProps = () => {
|
||||
if (typeof window === 'undefined') {
|
||||
warnOnceSSRImport();
|
||||
return {};
|
||||
}
|
||||
if ((0, get_remotion_environment_js_1.getRemotionEnvironment)().isPlayer) {
|
||||
throw new Error('You cannot call `getInputProps()` from a <Player>. Instead, the props are available as React props from component that you passed as `component` prop.');
|
||||
}
|
||||
const override = (0, input_props_override_js_1.getInputPropsOverride)();
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
if (typeof window === 'undefined' ||
|
||||
typeof window.remotion_inputProps === 'undefined') {
|
||||
throw new Error('Cannot call `getInputProps()` - window.remotion_inputProps is not set. This API is only available if you are in the Studio, or while you are rendering server-side.');
|
||||
}
|
||||
const param = window.remotion_inputProps;
|
||||
if (!param) {
|
||||
return {};
|
||||
}
|
||||
const parsed = (0, input_props_serialization_js_1.deserializeJSONWithSpecialTypes)(param);
|
||||
return parsed;
|
||||
};
|
||||
exports.getInputProps = getInputProps;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export declare const injectCSS: (css: string) => (() => void);
|
||||
export declare const OBJECTFIT_CONTAIN_CLASS_NAME = "__remotion_objectfitcontain";
|
||||
export declare const makeDefaultPreviewCSS: (scope: string | null, backgroundColor: string) => string;
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.makeDefaultPreviewCSS = exports.OBJECTFIT_CONTAIN_CLASS_NAME = exports.injectCSS = void 0;
|
||||
const injected = {};
|
||||
const injectCSS = (css) => {
|
||||
// Skip in node
|
||||
if (typeof document === 'undefined') {
|
||||
return () => { };
|
||||
}
|
||||
if (injected[css]) {
|
||||
return () => { };
|
||||
}
|
||||
const head = document.head || document.getElementsByTagName('head')[0];
|
||||
const style = document.createElement('style');
|
||||
style.appendChild(document.createTextNode(css));
|
||||
head.prepend(style);
|
||||
injected[css] = style;
|
||||
return () => {
|
||||
const styleElement = injected[css];
|
||||
if (styleElement) {
|
||||
if (styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement);
|
||||
}
|
||||
delete injected[css];
|
||||
}
|
||||
};
|
||||
};
|
||||
exports.injectCSS = injectCSS;
|
||||
// make object-fit: contain low priority, so it can be overridden by another class name
|
||||
exports.OBJECTFIT_CONTAIN_CLASS_NAME = '__remotion_objectfitcontain';
|
||||
const makeDefaultPreviewCSS = (scope, backgroundColor) => {
|
||||
if (!scope) {
|
||||
return `
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: ${backgroundColor};
|
||||
}
|
||||
.${exports.OBJECTFIT_CONTAIN_CLASS_NAME} {
|
||||
object-fit: contain;
|
||||
}
|
||||
`;
|
||||
}
|
||||
return `
|
||||
${scope} * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
${scope} *:-webkit-full-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
${scope} .${exports.OBJECTFIT_CONTAIN_CLASS_NAME} {
|
||||
object-fit: contain;
|
||||
}
|
||||
`;
|
||||
};
|
||||
exports.makeDefaultPreviewCSS = makeDefaultPreviewCSS;
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
import type { LogLevel } from './log.js';
|
||||
import type { RemotionEnvironment } from './remotion-environment-context.js';
|
||||
export type DelayRenderScope = {
|
||||
remotion_renderReady: boolean;
|
||||
remotion_delayRenderTimeouts: {
|
||||
[key: string]: {
|
||||
label: string | null;
|
||||
timeout: number | Timer;
|
||||
startTime: number;
|
||||
};
|
||||
};
|
||||
remotion_puppeteerTimeout: number;
|
||||
remotion_attempt: number;
|
||||
remotion_delayRenderHandles: number[];
|
||||
remotion_cancelledError?: string;
|
||||
};
|
||||
export declare const DELAY_RENDER_CALLSTACK_TOKEN = "The delayRender was called:";
|
||||
export declare const DELAY_RENDER_RETRIES_LEFT = "Retries left: ";
|
||||
export declare const DELAY_RENDER_RETRY_TOKEN = "- Rendering the frame will be retried.";
|
||||
export declare const DELAY_RENDER_CLEAR_TOKEN = "handle was cleared after";
|
||||
export type DelayRenderOptions = {
|
||||
timeoutInMilliseconds?: number;
|
||||
retries?: number;
|
||||
};
|
||||
/**
|
||||
* Internal function that accepts environment as parameter.
|
||||
* This allows useDelayRender to control its own environment source.
|
||||
* @private
|
||||
*/
|
||||
export declare const delayRenderInternal: ({ scope, environment, label, options, }: {
|
||||
scope: DelayRenderScope;
|
||||
environment: RemotionEnvironment;
|
||||
label: string | null;
|
||||
options: DelayRenderOptions;
|
||||
}) => number;
|
||||
export declare const delayRender: (label?: string, options?: DelayRenderOptions) => number;
|
||||
/**
|
||||
* Internal function that accepts environment as parameter.
|
||||
* @private
|
||||
*/
|
||||
export declare const continueRenderInternal: ({ scope, handle, environment, logLevel, }: {
|
||||
scope: DelayRenderScope;
|
||||
handle: number;
|
||||
environment: RemotionEnvironment;
|
||||
logLevel: LogLevel;
|
||||
}) => void;
|
||||
export declare const continueRender: (handle: number) => void;
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.continueRender = exports.continueRenderInternal = exports.delayRender = exports.delayRenderInternal = exports.DELAY_RENDER_CLEAR_TOKEN = exports.DELAY_RENDER_RETRY_TOKEN = exports.DELAY_RENDER_RETRIES_LEFT = exports.DELAY_RENDER_CALLSTACK_TOKEN = void 0;
|
||||
const cancel_render_js_1 = require("./cancel-render.js");
|
||||
const get_remotion_environment_js_1 = require("./get-remotion-environment.js");
|
||||
const log_js_1 = require("./log.js");
|
||||
const truthy_js_1 = require("./truthy.js");
|
||||
if (typeof window !== 'undefined') {
|
||||
window.remotion_renderReady = false;
|
||||
if (!window.remotion_delayRenderTimeouts) {
|
||||
window.remotion_delayRenderTimeouts = {};
|
||||
}
|
||||
window.remotion_delayRenderHandles = [];
|
||||
}
|
||||
exports.DELAY_RENDER_CALLSTACK_TOKEN = 'The delayRender was called:';
|
||||
exports.DELAY_RENDER_RETRIES_LEFT = 'Retries left: ';
|
||||
exports.DELAY_RENDER_RETRY_TOKEN = '- Rendering the frame will be retried.';
|
||||
exports.DELAY_RENDER_CLEAR_TOKEN = 'handle was cleared after';
|
||||
const defaultTimeout = 30000;
|
||||
/**
|
||||
* Internal function that accepts environment as parameter.
|
||||
* This allows useDelayRender to control its own environment source.
|
||||
* @private
|
||||
*/
|
||||
const delayRenderInternal = ({ scope, environment, label, options, }) => {
|
||||
var _a, _b, _c, _d, _e;
|
||||
if (typeof label !== 'string' && label !== null) {
|
||||
throw new Error('The label parameter of delayRender() must be a string or undefined, got: ' +
|
||||
JSON.stringify(label));
|
||||
}
|
||||
const handle = Math.random();
|
||||
scope.remotion_delayRenderHandles.push(handle);
|
||||
const called = (_b = (_a = Error().stack) === null || _a === void 0 ? void 0 : _a.replace(/^Error/g, '')) !== null && _b !== void 0 ? _b : '';
|
||||
if (environment.isRendering) {
|
||||
const timeoutToUse = ((_d = (_c = options === null || options === void 0 ? void 0 : options.timeoutInMilliseconds) !== null && _c !== void 0 ? _c : scope.remotion_puppeteerTimeout) !== null && _d !== void 0 ? _d : defaultTimeout) - 2000;
|
||||
const retriesLeft = ((_e = options === null || options === void 0 ? void 0 : options.retries) !== null && _e !== void 0 ? _e : 0) - (scope.remotion_attempt - 1);
|
||||
scope.remotion_delayRenderTimeouts[handle] = {
|
||||
label: label !== null && label !== void 0 ? label : null,
|
||||
startTime: Date.now(),
|
||||
timeout: setTimeout(() => {
|
||||
const message = [
|
||||
`A delayRender()`,
|
||||
label ? `"${label}"` : null,
|
||||
`was called but not cleared after ${timeoutToUse}ms. See https://remotion.dev/docs/timeout for help.`,
|
||||
retriesLeft > 0 ? exports.DELAY_RENDER_RETRIES_LEFT + retriesLeft : null,
|
||||
retriesLeft > 0 ? exports.DELAY_RENDER_RETRY_TOKEN : null,
|
||||
exports.DELAY_RENDER_CALLSTACK_TOKEN,
|
||||
called,
|
||||
]
|
||||
.filter(truthy_js_1.truthy)
|
||||
.join(' ');
|
||||
// in client-side rendering, don't throw (would be uncaught from setTimeout)
|
||||
if (environment.isClientSideRendering) {
|
||||
scope.remotion_cancelledError = (0, cancel_render_js_1.getErrorStackWithMessage)(Error(message));
|
||||
}
|
||||
else {
|
||||
(0, cancel_render_js_1.cancelRenderInternal)(scope, Error(message));
|
||||
}
|
||||
}, timeoutToUse),
|
||||
};
|
||||
}
|
||||
scope.remotion_renderReady = false;
|
||||
return handle;
|
||||
};
|
||||
exports.delayRenderInternal = delayRenderInternal;
|
||||
/*
|
||||
* @description Call this function to signal that a frame should not be rendered until an asynchronous task (such as data fetching) is complete. Use continueRender(handle) to proceed with rendering once the task is complete.
|
||||
* @see [Documentation](https://remotion.dev/docs/delay-render)
|
||||
*/
|
||||
const delayRender = (label, options) => {
|
||||
if (typeof window === 'undefined') {
|
||||
return Math.random();
|
||||
}
|
||||
return (0, exports.delayRenderInternal)({
|
||||
scope: window,
|
||||
environment: (0, get_remotion_environment_js_1.getRemotionEnvironment)(),
|
||||
label: label !== null && label !== void 0 ? label : null,
|
||||
options: options !== null && options !== void 0 ? options : {},
|
||||
});
|
||||
};
|
||||
exports.delayRender = delayRender;
|
||||
/**
|
||||
* Internal function that accepts environment as parameter.
|
||||
* @private
|
||||
*/
|
||||
const continueRenderInternal = ({ scope, handle, environment, logLevel, }) => {
|
||||
if (typeof handle === 'undefined') {
|
||||
throw new TypeError('The continueRender() method must be called with a parameter that is the return value of delayRender(). No value was passed.');
|
||||
}
|
||||
if (typeof handle !== 'number') {
|
||||
throw new TypeError('The parameter passed into continueRender() must be the return value of delayRender() which is a number. Got: ' +
|
||||
JSON.stringify(handle));
|
||||
}
|
||||
scope.remotion_delayRenderHandles = scope.remotion_delayRenderHandles.filter((h) => {
|
||||
if (h === handle) {
|
||||
if (environment.isRendering && scope !== undefined) {
|
||||
if (!scope.remotion_delayRenderTimeouts[handle]) {
|
||||
return false;
|
||||
}
|
||||
const { label, startTime, timeout } = scope.remotion_delayRenderTimeouts[handle];
|
||||
clearTimeout(timeout);
|
||||
const message = [
|
||||
label ? `"${label}"` : 'A handle',
|
||||
exports.DELAY_RENDER_CLEAR_TOKEN,
|
||||
`${Date.now() - startTime}ms`,
|
||||
]
|
||||
.filter(truthy_js_1.truthy)
|
||||
.join(' ');
|
||||
log_js_1.Log.verbose({ logLevel, tag: 'delayRender()' }, message);
|
||||
delete scope.remotion_delayRenderTimeouts[handle];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (scope.remotion_delayRenderHandles.length === 0) {
|
||||
scope.remotion_renderReady = true;
|
||||
}
|
||||
};
|
||||
exports.continueRenderInternal = continueRenderInternal;
|
||||
/*
|
||||
* @description Unblock a render that has been blocked by delayRender().
|
||||
* @see [Documentation](https://remotion.dev/docs/continue-render)
|
||||
*/
|
||||
const continueRender = (handle) => {
|
||||
var _a;
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
(0, exports.continueRenderInternal)({
|
||||
scope: window,
|
||||
handle,
|
||||
environment: (0, get_remotion_environment_js_1.getRemotionEnvironment)(),
|
||||
logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info',
|
||||
});
|
||||
};
|
||||
exports.continueRender = continueRender;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
export type DownloadBehavior = {
|
||||
type: 'play-in-browser';
|
||||
} | {
|
||||
type: 'download';
|
||||
fileName: string | null;
|
||||
};
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @description The Easing module implements common easing functions. You can use it with the interpolate() API.
|
||||
* @see [Documentation](https://www.remotion.dev/docs/easing)
|
||||
*/
|
||||
export declare class Easing {
|
||||
static step0(n: number): number;
|
||||
static step1(n: number): number;
|
||||
static linear(t: number): number;
|
||||
static ease(t: number): number;
|
||||
static quad(t: number): number;
|
||||
static cubic(t: number): number;
|
||||
static poly(n: number): (t: number) => number;
|
||||
static sin(t: number): number;
|
||||
static circle(t: number): number;
|
||||
static exp(t: number): number;
|
||||
static elastic(bounciness?: number): (t: number) => number;
|
||||
static back(s?: number): (t: number) => number;
|
||||
static bounce(t: number): number;
|
||||
static bezier(x1: number, y1: number, x2: number, y2: number): (t: number) => number;
|
||||
static in(easing: (t: number) => number): (t: number) => number;
|
||||
static out(easing: (t: number) => number): (t: number) => number;
|
||||
static inOut(easing: (t: number) => number): (t: number) => number;
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
"use strict";
|
||||
// Taken from https://github.com/facebook/react-native/blob/0b9ea60b4fee8cacc36e7160e31b91fc114dbc0d/Libraries/Animated/src/Easing.js
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Easing = void 0;
|
||||
const bezier_js_1 = require("./bezier.js");
|
||||
/**
|
||||
* @description The Easing module implements common easing functions. You can use it with the interpolate() API.
|
||||
* @see [Documentation](https://www.remotion.dev/docs/easing)
|
||||
*/
|
||||
class Easing {
|
||||
static step0(n) {
|
||||
return n > 0 ? 1 : 0;
|
||||
}
|
||||
static step1(n) {
|
||||
return n >= 1 ? 1 : 0;
|
||||
}
|
||||
static linear(t) {
|
||||
return t;
|
||||
}
|
||||
static ease(t) {
|
||||
return Easing.bezier(0.42, 0, 1, 1)(t);
|
||||
}
|
||||
static quad(t) {
|
||||
return t * t;
|
||||
}
|
||||
static cubic(t) {
|
||||
return t * t * t;
|
||||
}
|
||||
static poly(n) {
|
||||
return (t) => t ** n;
|
||||
}
|
||||
static sin(t) {
|
||||
return 1 - Math.cos((t * Math.PI) / 2);
|
||||
}
|
||||
static circle(t) {
|
||||
return 1 - Math.sqrt(1 - t * t);
|
||||
}
|
||||
static exp(t) {
|
||||
return 2 ** (10 * (t - 1));
|
||||
}
|
||||
static elastic(bounciness = 1) {
|
||||
const p = bounciness * Math.PI;
|
||||
return (t) => 1 - Math.cos((t * Math.PI) / 2) ** 3 * Math.cos(t * p);
|
||||
}
|
||||
static back(s = 1.70158) {
|
||||
return (t) => t * t * ((s + 1) * t - s);
|
||||
}
|
||||
static bounce(t) {
|
||||
if (t < 1 / 2.75) {
|
||||
return 7.5625 * t * t;
|
||||
}
|
||||
if (t < 2 / 2.75) {
|
||||
const t2_ = t - 1.5 / 2.75;
|
||||
return 7.5625 * t2_ * t2_ + 0.75;
|
||||
}
|
||||
if (t < 2.5 / 2.75) {
|
||||
const t2_ = t - 2.25 / 2.75;
|
||||
return 7.5625 * t2_ * t2_ + 0.9375;
|
||||
}
|
||||
const t2 = t - 2.625 / 2.75;
|
||||
return 7.5625 * t2 * t2 + 0.984375;
|
||||
}
|
||||
static bezier(x1, y1, x2, y2) {
|
||||
return (0, bezier_js_1.bezier)(x1, y1, x2, y2);
|
||||
}
|
||||
static in(easing) {
|
||||
return easing;
|
||||
}
|
||||
static out(easing) {
|
||||
return (t) => 1 - easing(1 - t);
|
||||
}
|
||||
static inOut(easing) {
|
||||
return (t) => {
|
||||
if (t < 0.5) {
|
||||
return easing(t * 2) / 2;
|
||||
}
|
||||
return 1 - easing((1 - t) * 2) / 2;
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.Easing = Easing;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user