@zync/zync-screnplay-player 0.1.232 → 0.1.234
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +1 -1
- package/dist/screenplay/RemotionRenderer/RemotionRenderer.js +4 -3
- package/dist/screenplay/RemotionRenderer/components/LottieAnimationGlobal.js +21 -21
- package/dist/screenplay/RemotionRenderer/components/layouts/ImageInset.js +232 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/VideoInset.js +221 -0
- package/dist/screenplay/RemotionRenderer/components/utils/FaceCenteredVideo.js +50 -50
- package/dist/screenplay/RemotionRenderer/components/utils/PausableImg.js +4 -4
- package/dist/screenplay/RemotionRenderer/components/utils/README.md +80 -80
- package/dist/screenplay/RemotionRenderer/components/utils/StretchTextDemo.js +3 -3
- package/dist/screenplay/RemotionRenderer/development.js +1010 -1582
- package/dist/screenplay/RemotionRenderer/helpers/coerceRenderableText.js +51 -0
- package/dist/screenplay/RemotionRenderer/helpers/convertToSeconds.js +8 -8
- package/dist/screenplay/RemotionRenderer/helpers/faceBasedVideoStyles.js +4 -4
- package/dist/screenplay/RemotionRenderer/helpers/faceCenteredVideoTransforms.js +46 -46
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/LayoutFactory.js +36 -16
- package/dist/screenplay/RemotionRenderer/main/screenplaySchema.js +51 -51
- package/dist/screenplay/RemotionRenderer/registeredComponents.js +6 -2
- package/dist/screenplay/RemotionRenderer/tracks/LayoutVideoTrack.js +20 -20
- package/package.json +49 -49
|
@@ -14,6 +14,7 @@ import { toFrames, toPascalCase } from "./main/lib/Sequence.js";
|
|
|
14
14
|
import { getCreatorCollabEffectProps } from "./main/lib/layouts/creatorCollabProps.js";
|
|
15
15
|
import { transitionThemes } from "./config.js";
|
|
16
16
|
import { normalizeDisabledTranscripts } from "./helpers/normalizeDisabledTranscripts.js";
|
|
17
|
+
import { coerceRenderableText, coerceRenderableTextProps, RENDERABLE_TEXT_PROP_KEYS } from "./helpers/coerceRenderableText.js";
|
|
17
18
|
export var RemotionRenderer = /*#__PURE__*/function () {
|
|
18
19
|
function RemotionRenderer(screenplay) {
|
|
19
20
|
_classCallCheck(this, RemotionRenderer);
|
|
@@ -109,7 +110,7 @@ export var RemotionRenderer = /*#__PURE__*/function () {
|
|
|
109
110
|
var from = this.fps * (screenPlaySegment.data.offset - trimLeft) || 0;
|
|
110
111
|
var durationInFrames = toFrames(this.fps * screenPlaySegment.data.duration);
|
|
111
112
|
var to = from + durationInFrames;
|
|
112
|
-
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, screenPlaySegment.data), creatorCollabProps), inheritedProps), {}, {
|
|
113
|
+
return coerceRenderableTextProps(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, screenPlaySegment.data), creatorCollabProps), inheritedProps), {}, {
|
|
113
114
|
component: component,
|
|
114
115
|
videoUrl: (_screenPlaySegment$da11 = (_screenPlaySegment$da12 = screenPlaySegment.data.sourceVideo) === null || _screenPlaySegment$da12 === void 0 ? void 0 : _screenPlaySegment$da12.videoUrl) !== null && _screenPlaySegment$da11 !== void 0 ? _screenPlaySegment$da11 : creatorCollabProps.videoUrl,
|
|
115
116
|
startVideoFrom: (_ref = typeof ((_screenPlaySegment$da13 = screenPlaySegment.data.sourceVideo) === null || _screenPlaySegment$da13 === void 0 ? void 0 : _screenPlaySegment$da13.start) === "number" ? toFrames(this.fps * screenPlaySegment.data.sourceVideo.start, false, true) : creatorCollabProps.startVideoFrom) !== null && _ref !== void 0 ? _ref : 0,
|
|
@@ -120,7 +121,7 @@ export var RemotionRenderer = /*#__PURE__*/function () {
|
|
|
120
121
|
offset: toFrames(this.fps * (screenPlaySegment.data.offset - trimLeft)) || 0,
|
|
121
122
|
theme: screenPlaySegment.theme,
|
|
122
123
|
themeSettings: screenPlaySegment === null || screenPlaySegment === void 0 ? void 0 : screenPlaySegment.themeSettings
|
|
123
|
-
});
|
|
124
|
+
}), RENDERABLE_TEXT_PROP_KEYS);
|
|
124
125
|
}
|
|
125
126
|
}, {
|
|
126
127
|
key: "toRemotionAudioFragment",
|
|
@@ -183,7 +184,7 @@ export var RemotionRenderer = /*#__PURE__*/function () {
|
|
|
183
184
|
var transcriptFrom = _this3.fps * (transcript.offset - trimLeft) || 0;
|
|
184
185
|
var transcriptDurationInFrames = toFrames(_this3.fps * transcript.duration);
|
|
185
186
|
return {
|
|
186
|
-
text: transcript.text,
|
|
187
|
+
text: coerceRenderableText(transcript.text),
|
|
187
188
|
from: transcriptFrom,
|
|
188
189
|
durationInFrames: transcriptDurationInFrames,
|
|
189
190
|
punctuations: transcript.punctuations ? transcript.punctuations.map(function (p) {
|
|
@@ -8,9 +8,9 @@ import React, { useEffect, useState } from 'react';
|
|
|
8
8
|
import { delayRender, continueRender, cancelRender } from 'remotion';
|
|
9
9
|
import { Lottie } from '@remotion/lottie';
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* Convert a HEX color string (e.g. "#ff8800") to the RGBA float array that
|
|
13
|
-
* Lottie expects: [r, g, b, a] where each component is 0‑1.
|
|
11
|
+
/**
|
|
12
|
+
* Convert a HEX color string (e.g. "#ff8800") to the RGBA float array that
|
|
13
|
+
* Lottie expects: [r, g, b, a] where each component is 0‑1.
|
|
14
14
|
*/
|
|
15
15
|
var hexToRGBA = function hexToRGBA(hex) {
|
|
16
16
|
var clean = hex.replace('#', '');
|
|
@@ -25,9 +25,9 @@ var hexToRGBA = function hexToRGBA(hex) {
|
|
|
25
25
|
];
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* Recursively walks through shape objects and overrides any fill (fl) or
|
|
30
|
-
* stroke (st) color with the provided RGBA array.
|
|
28
|
+
/**
|
|
29
|
+
* Recursively walks through shape objects and overrides any fill (fl) or
|
|
30
|
+
* stroke (st) color with the provided RGBA array.
|
|
31
31
|
*/
|
|
32
32
|
var _applyColor = function applyColor(shapes, rgba) {
|
|
33
33
|
shapes === null || shapes === void 0 ? void 0 : shapes.forEach(function (shape) {
|
|
@@ -40,11 +40,11 @@ var _applyColor = function applyColor(shapes, rgba) {
|
|
|
40
40
|
});
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
/**
|
|
44
|
-
* Traverses all layers (top‑level + asset layers) and applies the primary
|
|
45
|
-
* color to every fill / stroke it encounters. This is useful for Lottie files
|
|
46
|
-
* that were exported with a single static color (e.g. white) and do not use
|
|
47
|
-
* layer naming conventions like "PrimaryColor".
|
|
43
|
+
/**
|
|
44
|
+
* Traverses all layers (top‑level + asset layers) and applies the primary
|
|
45
|
+
* color to every fill / stroke it encounters. This is useful for Lottie files
|
|
46
|
+
* that were exported with a single static color (e.g. white) and do not use
|
|
47
|
+
* layer naming conventions like "PrimaryColor".
|
|
48
48
|
*/
|
|
49
49
|
var replaceGlobalColor = function replaceGlobalColor(data, hex) {
|
|
50
50
|
var _data$assets;
|
|
@@ -60,16 +60,16 @@ var replaceGlobalColor = function replaceGlobalColor(data, hex) {
|
|
|
60
60
|
});
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
/**
|
|
64
|
-
* LottieAnimationGlobal – specialised wrapper to render the provided Lottie
|
|
65
|
-
* (e.g. text‑bubble‑animation.json) while dynamically replacing **all** stroke
|
|
66
|
-
* and fill colors with the supplied `primaryColor`.
|
|
67
|
-
*
|
|
68
|
-
* Props:
|
|
69
|
-
* • animationPath – URL or local path to the json file.
|
|
70
|
-
* • primaryColor – HEX string, defaults to "#ffffff".
|
|
71
|
-
* • autoplay – boolean, whether to start playing immediately.
|
|
72
|
-
* • loop – boolean, whether to loop the animation.
|
|
63
|
+
/**
|
|
64
|
+
* LottieAnimationGlobal – specialised wrapper to render the provided Lottie
|
|
65
|
+
* (e.g. text‑bubble‑animation.json) while dynamically replacing **all** stroke
|
|
66
|
+
* and fill colors with the supplied `primaryColor`.
|
|
67
|
+
*
|
|
68
|
+
* Props:
|
|
69
|
+
* • animationPath – URL or local path to the json file.
|
|
70
|
+
* • primaryColor – HEX string, defaults to "#ffffff".
|
|
71
|
+
* • autoplay – boolean, whether to start playing immediately.
|
|
72
|
+
* • loop – boolean, whether to loop the animation.
|
|
73
73
|
*/
|
|
74
74
|
export var LottieAnimationGlobal = function LottieAnimationGlobal(_ref) {
|
|
75
75
|
var animationPath = _ref.animationPath,
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AbsoluteFill, Audio, Easing, Img, interpolate, OffthreadVideo, useCurrentFrame, useVideoConfig } from "remotion";
|
|
3
|
+
import { useOrientationBased } from "../../hooks/useOrientationBased.js";
|
|
4
|
+
import FaceCenteredVideo from "../utils/FaceCenteredVideo";
|
|
5
|
+
var ANIMATION_SECONDS = 1.2;
|
|
6
|
+
var INSET_ASPECT_RATIO = 9 / 16;
|
|
7
|
+
var getInsetMetrics = function getInsetMetrics(_ref) {
|
|
8
|
+
var width = _ref.width,
|
|
9
|
+
height = _ref.height,
|
|
10
|
+
outputOrientation = _ref.outputOrientation;
|
|
11
|
+
var padding = Math.max(32, Math.min(width, height) * 0.045);
|
|
12
|
+
var rawWidth = width * 0.24;
|
|
13
|
+
var maxWidthByHeight = (height - padding * 2) * INSET_ASPECT_RATIO;
|
|
14
|
+
var insetWidth = Math.min(rawWidth, maxWidthByHeight, 360);
|
|
15
|
+
var finalWidth = outputOrientation === "portrait" ? Math.min(insetWidth, width * 0.36) : insetWidth;
|
|
16
|
+
var finalHeight = finalWidth / INSET_ASPECT_RATIO;
|
|
17
|
+
return {
|
|
18
|
+
borderRadius: Math.max(18, finalWidth * 0.06),
|
|
19
|
+
height: finalHeight,
|
|
20
|
+
left: padding,
|
|
21
|
+
top: height - padding - finalHeight,
|
|
22
|
+
width: finalWidth
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
var SourceVideo = function SourceVideo(_ref2) {
|
|
26
|
+
var faceMetadata = _ref2.faceMetadata,
|
|
27
|
+
height = _ref2.height,
|
|
28
|
+
noBackgroundVideoEffects = _ref2.noBackgroundVideoEffects,
|
|
29
|
+
sourceVideoOrientation = _ref2.sourceVideoOrientation,
|
|
30
|
+
src = _ref2.src,
|
|
31
|
+
startVideoFrom = _ref2.startVideoFrom,
|
|
32
|
+
transparent = _ref2.transparent,
|
|
33
|
+
width = _ref2.width;
|
|
34
|
+
if (!src) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (faceMetadata) {
|
|
38
|
+
return /*#__PURE__*/React.createElement(FaceCenteredVideo, {
|
|
39
|
+
startFrom: startVideoFrom,
|
|
40
|
+
src: src,
|
|
41
|
+
faceMetadata: faceMetadata,
|
|
42
|
+
containerWidth: width,
|
|
43
|
+
containerHeight: height,
|
|
44
|
+
useAveragePosition: true,
|
|
45
|
+
centerHorizontally: false,
|
|
46
|
+
transparent: transparent,
|
|
47
|
+
muted: false,
|
|
48
|
+
noBackgroundVideoEffects: noBackgroundVideoEffects,
|
|
49
|
+
style: {
|
|
50
|
+
filter: transparent && noBackgroundVideoEffects !== null && noBackgroundVideoEffects !== void 0 && noBackgroundVideoEffects.facePop ? "brightness(1.1) contrast(1.15) saturate(1.05)" : undefined
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return /*#__PURE__*/React.createElement(OffthreadVideo, {
|
|
55
|
+
pauseWhenBuffering: true,
|
|
56
|
+
startFrom: startVideoFrom,
|
|
57
|
+
src: src,
|
|
58
|
+
muted: false,
|
|
59
|
+
transparent: transparent,
|
|
60
|
+
style: {
|
|
61
|
+
filter: transparent && noBackgroundVideoEffects !== null && noBackgroundVideoEffects !== void 0 && noBackgroundVideoEffects.facePop ? "brightness(1.1) contrast(1.15) saturate(1.05)" : undefined,
|
|
62
|
+
height: "100%",
|
|
63
|
+
objectFit: "cover",
|
|
64
|
+
objectPosition: sourceVideoOrientation === "portrait" ? "0% 30%" : undefined,
|
|
65
|
+
width: "100%"
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
var ImageInsetContent = function ImageInsetContent(_ref3) {
|
|
70
|
+
var children = _ref3.children,
|
|
71
|
+
disableTransitionSounds = _ref3.disableTransitionSounds,
|
|
72
|
+
durationInFrames = _ref3.durationInFrames,
|
|
73
|
+
faceMetadata = _ref3.faceMetadata,
|
|
74
|
+
frameColor = _ref3.frameColor,
|
|
75
|
+
height = _ref3.height,
|
|
76
|
+
imageUrl = _ref3.imageUrl,
|
|
77
|
+
noBackgroundVideoEffects = _ref3.noBackgroundVideoEffects,
|
|
78
|
+
noBackgroundVideoUrl = _ref3.noBackgroundVideoUrl,
|
|
79
|
+
outputOrientation = _ref3.outputOrientation,
|
|
80
|
+
sourceVideoOrientation = _ref3.sourceVideoOrientation,
|
|
81
|
+
startVideoFrom = _ref3.startVideoFrom,
|
|
82
|
+
videoUrl = _ref3.videoUrl,
|
|
83
|
+
width = _ref3.width;
|
|
84
|
+
var frame = useCurrentFrame();
|
|
85
|
+
var _useVideoConfig = useVideoConfig(),
|
|
86
|
+
fps = _useVideoConfig.fps;
|
|
87
|
+
var animationFrames = fps * ANIMATION_SECONDS;
|
|
88
|
+
var progress = interpolate(frame, [0, animationFrames], [0, 1], {
|
|
89
|
+
easing: Easing.out(Easing.cubic),
|
|
90
|
+
extrapolateLeft: "clamp",
|
|
91
|
+
extrapolateRight: "clamp"
|
|
92
|
+
});
|
|
93
|
+
var sourceSrc = noBackgroundVideoUrl || videoUrl;
|
|
94
|
+
var sourceTransparent = Boolean(noBackgroundVideoUrl);
|
|
95
|
+
var inset = getInsetMetrics({
|
|
96
|
+
width: width,
|
|
97
|
+
height: height,
|
|
98
|
+
outputOrientation: outputOrientation
|
|
99
|
+
});
|
|
100
|
+
var sourceWidth = interpolate(progress, [0, 1], [width, inset.width]);
|
|
101
|
+
var sourceHeight = interpolate(progress, [0, 1], [height, inset.height]);
|
|
102
|
+
var sourceLeft = interpolate(progress, [0, 1], [0, inset.left]);
|
|
103
|
+
var sourceTop = interpolate(progress, [0, 1], [0, inset.top]);
|
|
104
|
+
var sourceBorderRadius = interpolate(progress, [0, 1], [0, inset.borderRadius]);
|
|
105
|
+
var imagePanProgress = interpolate(frame, [0, Math.max(1, (durationInFrames || 1) - 1)], [0, 1], {
|
|
106
|
+
extrapolateLeft: "clamp",
|
|
107
|
+
extrapolateRight: "clamp"
|
|
108
|
+
});
|
|
109
|
+
var shouldPanImage = outputOrientation === "square" || outputOrientation === "portrait";
|
|
110
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, !disableTransitionSounds && /*#__PURE__*/React.createElement(Audio, {
|
|
111
|
+
src: "https://cdn.zync.ai/assets/static/swoosh.mp3",
|
|
112
|
+
volume: 0.25
|
|
113
|
+
}), /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
114
|
+
style: {
|
|
115
|
+
backgroundColor: frameColor || "black",
|
|
116
|
+
height: height,
|
|
117
|
+
overflow: "hidden",
|
|
118
|
+
width: width
|
|
119
|
+
}
|
|
120
|
+
}, imageUrl ? /*#__PURE__*/React.createElement(Img, {
|
|
121
|
+
src: imageUrl,
|
|
122
|
+
style: {
|
|
123
|
+
height: "100%",
|
|
124
|
+
left: shouldPanImage ? imagePanProgress * width : undefined,
|
|
125
|
+
maxWidth: shouldPanImage ? "none" : undefined,
|
|
126
|
+
objectFit: shouldPanImage ? undefined : "cover",
|
|
127
|
+
position: shouldPanImage ? "absolute" : undefined,
|
|
128
|
+
top: 0,
|
|
129
|
+
transform: shouldPanImage ? "translateX(-".concat(imagePanProgress * 100, "%)") : undefined,
|
|
130
|
+
width: shouldPanImage ? "auto" : "100%"
|
|
131
|
+
}
|
|
132
|
+
}) : null, /*#__PURE__*/React.createElement("div", {
|
|
133
|
+
style: {
|
|
134
|
+
borderRadius: sourceBorderRadius,
|
|
135
|
+
boxShadow: progress > 0 ? "0 ".concat(16 * progress, "px ").concat(44 * progress, "px rgba(0, 0, 0, ").concat(0.34 * progress, ")") : undefined,
|
|
136
|
+
height: sourceHeight,
|
|
137
|
+
left: sourceLeft,
|
|
138
|
+
overflow: "hidden",
|
|
139
|
+
position: "absolute",
|
|
140
|
+
top: sourceTop,
|
|
141
|
+
width: sourceWidth,
|
|
142
|
+
zIndex: 2
|
|
143
|
+
}
|
|
144
|
+
}, /*#__PURE__*/React.createElement(SourceVideo, {
|
|
145
|
+
faceMetadata: faceMetadata,
|
|
146
|
+
height: sourceHeight,
|
|
147
|
+
noBackgroundVideoEffects: noBackgroundVideoEffects,
|
|
148
|
+
sourceVideoOrientation: sourceVideoOrientation,
|
|
149
|
+
src: sourceSrc,
|
|
150
|
+
startVideoFrom: startVideoFrom,
|
|
151
|
+
transparent: sourceTransparent,
|
|
152
|
+
width: sourceWidth
|
|
153
|
+
})), /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
154
|
+
style: {
|
|
155
|
+
zIndex: 3
|
|
156
|
+
}
|
|
157
|
+
}, children)));
|
|
158
|
+
};
|
|
159
|
+
export var ImageInset = function ImageInset(_ref4) {
|
|
160
|
+
var _compositionProps$out, _window, _window$screenplayPro, _window$screenplayPro2;
|
|
161
|
+
var children = _ref4.children,
|
|
162
|
+
_ref4$disableTransiti = _ref4.disableTransitionSounds,
|
|
163
|
+
disableTransitionSounds = _ref4$disableTransiti === void 0 ? false : _ref4$disableTransiti,
|
|
164
|
+
durationInFrames = _ref4.durationInFrames,
|
|
165
|
+
faceMetadata = _ref4.faceMetadata,
|
|
166
|
+
frameColor = _ref4.frameColor,
|
|
167
|
+
imageUrl = _ref4.imageUrl,
|
|
168
|
+
noBackgroundVideoEffects = _ref4.noBackgroundVideoEffects,
|
|
169
|
+
noBackgroundVideoUrl = _ref4.noBackgroundVideoUrl,
|
|
170
|
+
sourceVideoOrientation = _ref4.sourceVideoOrientation,
|
|
171
|
+
startVideoFrom = _ref4.startVideoFrom,
|
|
172
|
+
_ref4$useSquareInLand = _ref4.useSquareInLandscape,
|
|
173
|
+
useSquareInLandscape = _ref4$useSquareInLand === void 0 ? false : _ref4$useSquareInLand,
|
|
174
|
+
videoUrl = _ref4.videoUrl;
|
|
175
|
+
var _useVideoConfig2 = useVideoConfig(),
|
|
176
|
+
outputWidth = _useVideoConfig2.width,
|
|
177
|
+
outputHeight = _useVideoConfig2.height,
|
|
178
|
+
_useVideoConfig2$prop = _useVideoConfig2.props,
|
|
179
|
+
compositionProps = _useVideoConfig2$prop === void 0 ? {} : _useVideoConfig2$prop;
|
|
180
|
+
var outputOrientation = (compositionProps === null || compositionProps === void 0 ? void 0 : (_compositionProps$out = compositionProps.output) === null || _compositionProps$out === void 0 ? void 0 : _compositionProps$out.orientation) || (typeof window !== "undefined" ? (_window = window) === null || _window === void 0 ? void 0 : (_window$screenplayPro = _window.screenplayProps) === null || _window$screenplayPro === void 0 ? void 0 : (_window$screenplayPro2 = _window$screenplayPro.output) === null || _window$screenplayPro2 === void 0 ? void 0 : _window$screenplayPro2.orientation : undefined);
|
|
181
|
+
var shouldUseSquareInLandscape = Boolean(useSquareInLandscape) && outputOrientation === "landscape";
|
|
182
|
+
var squareSize = 1080;
|
|
183
|
+
var width = shouldUseSquareInLandscape ? squareSize : outputWidth;
|
|
184
|
+
var height = shouldUseSquareInLandscape ? squareSize : outputHeight;
|
|
185
|
+
var renderOffsetX = shouldUseSquareInLandscape ? (outputWidth - squareSize) / 2 : 0;
|
|
186
|
+
var orientationOverride = shouldUseSquareInLandscape ? "square" : undefined;
|
|
187
|
+
var _useOrientationBased = useOrientationBased({
|
|
188
|
+
portrait: {
|
|
189
|
+
activeOrientation: "portrait"
|
|
190
|
+
},
|
|
191
|
+
landscape: {
|
|
192
|
+
activeOrientation: "landscape"
|
|
193
|
+
},
|
|
194
|
+
square: {
|
|
195
|
+
activeOrientation: "square"
|
|
196
|
+
}
|
|
197
|
+
}, orientationOverride),
|
|
198
|
+
activeOrientation = _useOrientationBased.activeOrientation;
|
|
199
|
+
var content = /*#__PURE__*/React.createElement(ImageInsetContent, {
|
|
200
|
+
disableTransitionSounds: disableTransitionSounds,
|
|
201
|
+
durationInFrames: durationInFrames,
|
|
202
|
+
faceMetadata: faceMetadata,
|
|
203
|
+
frameColor: frameColor,
|
|
204
|
+
height: height,
|
|
205
|
+
imageUrl: imageUrl,
|
|
206
|
+
noBackgroundVideoEffects: noBackgroundVideoEffects,
|
|
207
|
+
noBackgroundVideoUrl: noBackgroundVideoUrl,
|
|
208
|
+
outputOrientation: activeOrientation,
|
|
209
|
+
sourceVideoOrientation: sourceVideoOrientation,
|
|
210
|
+
startVideoFrom: startVideoFrom,
|
|
211
|
+
videoUrl: videoUrl,
|
|
212
|
+
width: width
|
|
213
|
+
}, children);
|
|
214
|
+
if (!shouldUseSquareInLandscape) {
|
|
215
|
+
return content;
|
|
216
|
+
}
|
|
217
|
+
return /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
218
|
+
style: {
|
|
219
|
+
backgroundColor: "black",
|
|
220
|
+
height: outputHeight,
|
|
221
|
+
width: outputWidth
|
|
222
|
+
}
|
|
223
|
+
}, /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
224
|
+
style: {
|
|
225
|
+
height: height,
|
|
226
|
+
left: renderOffsetX,
|
|
227
|
+
overflow: "hidden",
|
|
228
|
+
top: 0,
|
|
229
|
+
width: width
|
|
230
|
+
}
|
|
231
|
+
}, content));
|
|
232
|
+
};
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AbsoluteFill, Audio, Easing, interpolate, OffthreadVideo, useCurrentFrame, useVideoConfig, Video } from "remotion";
|
|
3
|
+
import { useOrientationBased } from "../../hooks/useOrientationBased.js";
|
|
4
|
+
import FaceCenteredVideo from "../utils/FaceCenteredVideo";
|
|
5
|
+
var ANIMATION_SECONDS = 1.2;
|
|
6
|
+
var INSET_ASPECT_RATIO = 9 / 16;
|
|
7
|
+
var getInsetMetrics = function getInsetMetrics(_ref) {
|
|
8
|
+
var width = _ref.width,
|
|
9
|
+
height = _ref.height,
|
|
10
|
+
outputOrientation = _ref.outputOrientation;
|
|
11
|
+
var padding = Math.max(32, Math.min(width, height) * 0.045);
|
|
12
|
+
var rawWidth = width * 0.24;
|
|
13
|
+
var maxWidthByHeight = (height - padding * 2) * INSET_ASPECT_RATIO;
|
|
14
|
+
var insetWidth = Math.min(rawWidth, maxWidthByHeight, 360);
|
|
15
|
+
var finalWidth = outputOrientation === "portrait" ? Math.min(insetWidth, width * 0.36) : insetWidth;
|
|
16
|
+
var finalHeight = finalWidth / INSET_ASPECT_RATIO;
|
|
17
|
+
return {
|
|
18
|
+
borderRadius: Math.max(18, finalWidth * 0.06),
|
|
19
|
+
height: finalHeight,
|
|
20
|
+
left: padding,
|
|
21
|
+
top: height - padding - finalHeight,
|
|
22
|
+
width: finalWidth
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
var SourceVideo = function SourceVideo(_ref2) {
|
|
26
|
+
var faceMetadata = _ref2.faceMetadata,
|
|
27
|
+
height = _ref2.height,
|
|
28
|
+
noBackgroundVideoEffects = _ref2.noBackgroundVideoEffects,
|
|
29
|
+
sourceVideoOrientation = _ref2.sourceVideoOrientation,
|
|
30
|
+
src = _ref2.src,
|
|
31
|
+
startVideoFrom = _ref2.startVideoFrom,
|
|
32
|
+
transparent = _ref2.transparent,
|
|
33
|
+
width = _ref2.width;
|
|
34
|
+
if (!src) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (faceMetadata) {
|
|
38
|
+
return /*#__PURE__*/React.createElement(FaceCenteredVideo, {
|
|
39
|
+
startFrom: startVideoFrom,
|
|
40
|
+
src: src,
|
|
41
|
+
faceMetadata: faceMetadata,
|
|
42
|
+
containerWidth: width,
|
|
43
|
+
containerHeight: height,
|
|
44
|
+
useAveragePosition: true,
|
|
45
|
+
centerHorizontally: false,
|
|
46
|
+
transparent: transparent,
|
|
47
|
+
muted: false,
|
|
48
|
+
noBackgroundVideoEffects: noBackgroundVideoEffects,
|
|
49
|
+
style: {
|
|
50
|
+
filter: transparent && noBackgroundVideoEffects !== null && noBackgroundVideoEffects !== void 0 && noBackgroundVideoEffects.facePop ? "brightness(1.1) contrast(1.15) saturate(1.05)" : undefined
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return /*#__PURE__*/React.createElement(OffthreadVideo, {
|
|
55
|
+
pauseWhenBuffering: true,
|
|
56
|
+
startFrom: startVideoFrom,
|
|
57
|
+
src: src,
|
|
58
|
+
muted: false,
|
|
59
|
+
transparent: transparent,
|
|
60
|
+
style: {
|
|
61
|
+
filter: transparent && noBackgroundVideoEffects !== null && noBackgroundVideoEffects !== void 0 && noBackgroundVideoEffects.facePop ? "brightness(1.1) contrast(1.15) saturate(1.05)" : undefined,
|
|
62
|
+
height: "100%",
|
|
63
|
+
objectFit: "cover",
|
|
64
|
+
objectPosition: sourceVideoOrientation === "portrait" ? "0% 30%" : undefined,
|
|
65
|
+
width: "100%"
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
var VideoInsetContent = function VideoInsetContent(_ref3) {
|
|
70
|
+
var brollUrl = _ref3.brollUrl,
|
|
71
|
+
children = _ref3.children,
|
|
72
|
+
disableTransitionSounds = _ref3.disableTransitionSounds,
|
|
73
|
+
faceMetadata = _ref3.faceMetadata,
|
|
74
|
+
frameColor = _ref3.frameColor,
|
|
75
|
+
height = _ref3.height,
|
|
76
|
+
noBackgroundVideoEffects = _ref3.noBackgroundVideoEffects,
|
|
77
|
+
noBackgroundVideoUrl = _ref3.noBackgroundVideoUrl,
|
|
78
|
+
outputOrientation = _ref3.outputOrientation,
|
|
79
|
+
sourceVideoOrientation = _ref3.sourceVideoOrientation,
|
|
80
|
+
startVideoFrom = _ref3.startVideoFrom,
|
|
81
|
+
videoUrl = _ref3.videoUrl,
|
|
82
|
+
width = _ref3.width;
|
|
83
|
+
var frame = useCurrentFrame();
|
|
84
|
+
var _useVideoConfig = useVideoConfig(),
|
|
85
|
+
fps = _useVideoConfig.fps;
|
|
86
|
+
var animationFrames = fps * ANIMATION_SECONDS;
|
|
87
|
+
var progress = interpolate(frame, [0, animationFrames], [0, 1], {
|
|
88
|
+
easing: Easing.out(Easing.cubic),
|
|
89
|
+
extrapolateLeft: "clamp",
|
|
90
|
+
extrapolateRight: "clamp"
|
|
91
|
+
});
|
|
92
|
+
var sourceSrc = noBackgroundVideoUrl || videoUrl;
|
|
93
|
+
var sourceTransparent = Boolean(noBackgroundVideoUrl);
|
|
94
|
+
var inset = getInsetMetrics({
|
|
95
|
+
width: width,
|
|
96
|
+
height: height,
|
|
97
|
+
outputOrientation: outputOrientation
|
|
98
|
+
});
|
|
99
|
+
var sourceWidth = interpolate(progress, [0, 1], [width, inset.width]);
|
|
100
|
+
var sourceHeight = interpolate(progress, [0, 1], [height, inset.height]);
|
|
101
|
+
var sourceLeft = interpolate(progress, [0, 1], [0, inset.left]);
|
|
102
|
+
var sourceTop = interpolate(progress, [0, 1], [0, inset.top]);
|
|
103
|
+
var sourceBorderRadius = interpolate(progress, [0, 1], [0, inset.borderRadius]);
|
|
104
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, !disableTransitionSounds && /*#__PURE__*/React.createElement(Audio, {
|
|
105
|
+
src: "https://cdn.zync.ai/assets/static/swoosh.mp3",
|
|
106
|
+
volume: 0.25
|
|
107
|
+
}), /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
108
|
+
style: {
|
|
109
|
+
backgroundColor: frameColor || "black",
|
|
110
|
+
height: height,
|
|
111
|
+
overflow: "hidden",
|
|
112
|
+
width: width
|
|
113
|
+
}
|
|
114
|
+
}, brollUrl ? /*#__PURE__*/React.createElement(Video, {
|
|
115
|
+
src: brollUrl,
|
|
116
|
+
loop: true,
|
|
117
|
+
muted: true,
|
|
118
|
+
style: {
|
|
119
|
+
height: "100%",
|
|
120
|
+
objectFit: "cover",
|
|
121
|
+
width: "100%"
|
|
122
|
+
}
|
|
123
|
+
}) : null, /*#__PURE__*/React.createElement("div", {
|
|
124
|
+
style: {
|
|
125
|
+
borderRadius: sourceBorderRadius,
|
|
126
|
+
boxShadow: progress > 0 ? "0 ".concat(16 * progress, "px ").concat(44 * progress, "px rgba(0, 0, 0, ").concat(0.34 * progress, ")") : undefined,
|
|
127
|
+
height: sourceHeight,
|
|
128
|
+
left: sourceLeft,
|
|
129
|
+
overflow: "hidden",
|
|
130
|
+
position: "absolute",
|
|
131
|
+
top: sourceTop,
|
|
132
|
+
width: sourceWidth,
|
|
133
|
+
zIndex: 2
|
|
134
|
+
}
|
|
135
|
+
}, /*#__PURE__*/React.createElement(SourceVideo, {
|
|
136
|
+
faceMetadata: faceMetadata,
|
|
137
|
+
height: sourceHeight,
|
|
138
|
+
noBackgroundVideoEffects: noBackgroundVideoEffects,
|
|
139
|
+
sourceVideoOrientation: sourceVideoOrientation,
|
|
140
|
+
src: sourceSrc,
|
|
141
|
+
startVideoFrom: startVideoFrom,
|
|
142
|
+
transparent: sourceTransparent,
|
|
143
|
+
width: sourceWidth
|
|
144
|
+
})), /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
145
|
+
style: {
|
|
146
|
+
zIndex: 3
|
|
147
|
+
}
|
|
148
|
+
}, children)));
|
|
149
|
+
};
|
|
150
|
+
export var VideoInset = function VideoInset(_ref4) {
|
|
151
|
+
var _compositionProps$out, _window, _window$screenplayPro, _window$screenplayPro2;
|
|
152
|
+
var brollUrl = _ref4.brollUrl,
|
|
153
|
+
children = _ref4.children,
|
|
154
|
+
_ref4$disableTransiti = _ref4.disableTransitionSounds,
|
|
155
|
+
disableTransitionSounds = _ref4$disableTransiti === void 0 ? false : _ref4$disableTransiti,
|
|
156
|
+
faceMetadata = _ref4.faceMetadata,
|
|
157
|
+
frameColor = _ref4.frameColor,
|
|
158
|
+
noBackgroundVideoEffects = _ref4.noBackgroundVideoEffects,
|
|
159
|
+
noBackgroundVideoUrl = _ref4.noBackgroundVideoUrl,
|
|
160
|
+
sourceVideoOrientation = _ref4.sourceVideoOrientation,
|
|
161
|
+
startVideoFrom = _ref4.startVideoFrom,
|
|
162
|
+
_ref4$useSquareInLand = _ref4.useSquareInLandscape,
|
|
163
|
+
useSquareInLandscape = _ref4$useSquareInLand === void 0 ? false : _ref4$useSquareInLand,
|
|
164
|
+
videoUrl = _ref4.videoUrl;
|
|
165
|
+
var _useVideoConfig2 = useVideoConfig(),
|
|
166
|
+
outputWidth = _useVideoConfig2.width,
|
|
167
|
+
outputHeight = _useVideoConfig2.height,
|
|
168
|
+
_useVideoConfig2$prop = _useVideoConfig2.props,
|
|
169
|
+
compositionProps = _useVideoConfig2$prop === void 0 ? {} : _useVideoConfig2$prop;
|
|
170
|
+
var outputOrientation = (compositionProps === null || compositionProps === void 0 ? void 0 : (_compositionProps$out = compositionProps.output) === null || _compositionProps$out === void 0 ? void 0 : _compositionProps$out.orientation) || (typeof window !== "undefined" ? (_window = window) === null || _window === void 0 ? void 0 : (_window$screenplayPro = _window.screenplayProps) === null || _window$screenplayPro === void 0 ? void 0 : (_window$screenplayPro2 = _window$screenplayPro.output) === null || _window$screenplayPro2 === void 0 ? void 0 : _window$screenplayPro2.orientation : undefined);
|
|
171
|
+
var shouldUseSquareInLandscape = Boolean(useSquareInLandscape) && outputOrientation === "landscape";
|
|
172
|
+
var squareSize = 1080;
|
|
173
|
+
var width = shouldUseSquareInLandscape ? squareSize : outputWidth;
|
|
174
|
+
var height = shouldUseSquareInLandscape ? squareSize : outputHeight;
|
|
175
|
+
var renderOffsetX = shouldUseSquareInLandscape ? (outputWidth - squareSize) / 2 : 0;
|
|
176
|
+
var orientationOverride = shouldUseSquareInLandscape ? "square" : undefined;
|
|
177
|
+
var _useOrientationBased = useOrientationBased({
|
|
178
|
+
portrait: {
|
|
179
|
+
activeOrientation: "portrait"
|
|
180
|
+
},
|
|
181
|
+
landscape: {
|
|
182
|
+
activeOrientation: "landscape"
|
|
183
|
+
},
|
|
184
|
+
square: {
|
|
185
|
+
activeOrientation: "square"
|
|
186
|
+
}
|
|
187
|
+
}, orientationOverride),
|
|
188
|
+
activeOrientation = _useOrientationBased.activeOrientation;
|
|
189
|
+
var content = /*#__PURE__*/React.createElement(VideoInsetContent, {
|
|
190
|
+
brollUrl: brollUrl,
|
|
191
|
+
disableTransitionSounds: disableTransitionSounds,
|
|
192
|
+
faceMetadata: faceMetadata,
|
|
193
|
+
frameColor: frameColor,
|
|
194
|
+
height: height,
|
|
195
|
+
noBackgroundVideoEffects: noBackgroundVideoEffects,
|
|
196
|
+
noBackgroundVideoUrl: noBackgroundVideoUrl,
|
|
197
|
+
outputOrientation: activeOrientation,
|
|
198
|
+
sourceVideoOrientation: sourceVideoOrientation,
|
|
199
|
+
startVideoFrom: startVideoFrom,
|
|
200
|
+
videoUrl: videoUrl,
|
|
201
|
+
width: width
|
|
202
|
+
}, children);
|
|
203
|
+
if (!shouldUseSquareInLandscape) {
|
|
204
|
+
return content;
|
|
205
|
+
}
|
|
206
|
+
return /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
207
|
+
style: {
|
|
208
|
+
backgroundColor: "black",
|
|
209
|
+
height: outputHeight,
|
|
210
|
+
width: outputWidth
|
|
211
|
+
}
|
|
212
|
+
}, /*#__PURE__*/React.createElement(AbsoluteFill, {
|
|
213
|
+
style: {
|
|
214
|
+
height: height,
|
|
215
|
+
left: renderOffsetX,
|
|
216
|
+
overflow: "hidden",
|
|
217
|
+
top: 0,
|
|
218
|
+
width: width
|
|
219
|
+
}
|
|
220
|
+
}, content));
|
|
221
|
+
};
|