@remotion/player
Version:
React component for embedding a Remotion preview into your app
90 lines (89 loc) • 4.24 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import React, { forwardRef, Suspense, useCallback, useImperativeHandle, useMemo, useRef, } from 'react';
import { Internals } from 'remotion';
import { calculateCanvasTransformation, calculateContainerStyle, calculateOuter, calculateOuterStyle, } from './calculate-scale.js';
import { ErrorBoundary } from './error-boundary.js';
import { PLAYER_CSS_CLASSNAME } from './player-css-classname.js';
import { useBufferStateEmitter } from './use-buffer-state-emitter.js';
import { useThumbnail } from './use-thumbnail.js';
import { IS_NODE } from './utils/is-node.js';
import { useElementSize } from './utils/use-element-size.js';
const reactVersion = React.version.split('.')[0];
if (reactVersion === '0') {
throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
}
const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, className }, ref) => {
var _a, _b;
const config = Internals.useUnsafeVideoConfig();
const video = Internals.useVideo();
const container = useRef(null);
const canvasSize = useElementSize(container, {
triggerOnWindowResize: false,
shouldApplyCssTransforms: false,
});
const layout = useMemo(() => {
if (!config || !canvasSize) {
return null;
}
return calculateCanvasTransformation({
canvasSize,
compositionHeight: config.height,
compositionWidth: config.width,
previewSize: 'auto',
});
}, [canvasSize, config]);
const scale = (_a = layout === null || layout === void 0 ? void 0 : layout.scale) !== null && _a !== void 0 ? _a : 1;
const thumbnail = useThumbnail();
useBufferStateEmitter(thumbnail.emitter);
useImperativeHandle(ref, () => {
const methods = {
getContainerNode: () => container.current,
getScale: () => scale,
};
return Object.assign(thumbnail.emitter, methods);
}, [scale, thumbnail.emitter]);
const VideoComponent = video ? video.component : null;
const outerStyle = useMemo(() => {
return calculateOuterStyle({ config, style, canvasSize });
}, [canvasSize, config, style]);
const outer = useMemo(() => {
return calculateOuter({ config, layout, scale });
}, [config, layout, scale]);
const containerStyle = useMemo(() => {
return calculateContainerStyle({
canvasSize,
config,
layout,
scale,
});
}, [canvasSize, config, layout, scale]);
const onError = useCallback((error) => {
// Pay attention to `this context`
thumbnail.emitter.dispatchError(error);
}, [thumbnail.emitter]);
const loadingMarkup = useMemo(() => {
return renderLoading
? renderLoading({
height: outerStyle.height,
width: outerStyle.width,
isBuffering: false,
})
: null;
}, [outerStyle.height, outerStyle.width, renderLoading]);
const currentScaleContext = useMemo(() => {
return {
type: 'scale',
scale,
};
}, [scale]);
if (!config) {
return null;
}
const content = (_jsx("div", { style: outer, children: _jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (_jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: _jsx(Internals.CurrentScaleContext.Provider, { value: currentScaleContext, children: _jsx(VideoComponent, { ...((_b = video === null || video === void 0 ? void 0 : video.props) !== null && _b !== void 0 ? _b : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) }) })) : null }) }));
if (IS_NODE && !doesReactVersionSupportSuspense) {
return (_jsx("div", { ref: container, style: outerStyle, className: className, children: content }));
}
return (_jsx("div", { ref: container, style: outerStyle, className: className, children: _jsx(Suspense, { fallback: loadingMarkup, children: content }) }));
};
export default forwardRef(ThumbnailUI);