@zync/zync-screnplay-player 0.1.187

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.
Files changed (133) hide show
  1. package/dist/ZyncScreenplayPlayer.js +35 -0
  2. package/dist/bundle.js +2 -0
  3. package/dist/bundle.js.LICENSE.txt +54 -0
  4. package/dist/index.js +4 -0
  5. package/dist/screenplay/RemotionRenderer/RemotionRenderer.js +281 -0
  6. package/dist/screenplay/RemotionRenderer/Root.js +22 -0
  7. package/dist/screenplay/RemotionRenderer/components/LottieAnimationGlobal.js +116 -0
  8. package/dist/screenplay/RemotionRenderer/components/backgrounds/VirtualBackground.js +26 -0
  9. package/dist/screenplay/RemotionRenderer/components/backgrounds/VirtualBackgroundUnderlay.js +41 -0
  10. package/dist/screenplay/RemotionRenderer/components/captions/CaptionSimple.js +12 -0
  11. package/dist/screenplay/RemotionRenderer/components/effects/BrollFullscreen.js +27 -0
  12. package/dist/screenplay/RemotionRenderer/components/effects/GlitchText.js +22 -0
  13. package/dist/screenplay/RemotionRenderer/components/effects/HandoffNametag.js +7 -0
  14. package/dist/screenplay/RemotionRenderer/components/effects/LottieAnimation.js +64 -0
  15. package/dist/screenplay/RemotionRenderer/components/effects/Nametag.js +9 -0
  16. package/dist/screenplay/RemotionRenderer/components/effects/PhraseRainbowEffect.js +34 -0
  17. package/dist/screenplay/RemotionRenderer/components/effects/Sentence.js +50 -0
  18. package/dist/screenplay/RemotionRenderer/components/effects/Title.js +12 -0
  19. package/dist/screenplay/RemotionRenderer/components/layouts/BrollGreenScreen.js +742 -0
  20. package/dist/screenplay/RemotionRenderer/components/layouts/BrollSplitScreen.js +714 -0
  21. package/dist/screenplay/RemotionRenderer/components/layouts/BrollStudioBackdrop.js +620 -0
  22. package/dist/screenplay/RemotionRenderer/components/layouts/DynamicTriangle.js +618 -0
  23. package/dist/screenplay/RemotionRenderer/components/layouts/Handoff.js +161 -0
  24. package/dist/screenplay/RemotionRenderer/components/layouts/IntroVideo.js +1330 -0
  25. package/dist/screenplay/RemotionRenderer/components/layouts/KeyPointOverlayDepth.js +397 -0
  26. package/dist/screenplay/RemotionRenderer/components/layouts/Keyword.js +539 -0
  27. package/dist/screenplay/RemotionRenderer/components/layouts/KeywordStudioBackdrop.js +714 -0
  28. package/dist/screenplay/RemotionRenderer/components/layouts/MotionStill.js +381 -0
  29. package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillFullScreen.js +178 -0
  30. package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillGreenScreen.js +568 -0
  31. package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillGreenScreenV2.js +731 -0
  32. package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillStudioBackdrop.js +588 -0
  33. package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrame.js +183 -0
  34. package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameBroll.js +181 -0
  35. package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameSentence.js +17 -0
  36. package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameZoomCut.js +13 -0
  37. package/dist/screenplay/RemotionRenderer/components/layouts/TextWithVideo.js +373 -0
  38. package/dist/screenplay/RemotionRenderer/components/layouts/quote-bubble-animation.json +1 -0
  39. package/dist/screenplay/RemotionRenderer/components/utils/BlurOverlay.js +19 -0
  40. package/dist/screenplay/RemotionRenderer/components/utils/ChromaKeyedVideo.js +59 -0
  41. package/dist/screenplay/RemotionRenderer/components/utils/FaceCenteredVideo.js +562 -0
  42. package/dist/screenplay/RemotionRenderer/components/utils/PausableImg.js +124 -0
  43. package/dist/screenplay/RemotionRenderer/components/utils/README.md +80 -0
  44. package/dist/screenplay/RemotionRenderer/components/utils/SafeZones.js +69 -0
  45. package/dist/screenplay/RemotionRenderer/components/utils/StretchText.js +124 -0
  46. package/dist/screenplay/RemotionRenderer/components/utils/StretchTextDemo.js +66 -0
  47. package/dist/screenplay/RemotionRenderer/config.js +8 -0
  48. package/dist/screenplay/RemotionRenderer/development.js +1370 -0
  49. package/dist/screenplay/RemotionRenderer/helpers/cleanFacemetadata.js +29 -0
  50. package/dist/screenplay/RemotionRenderer/helpers/convertToSeconds.js +14 -0
  51. package/dist/screenplay/RemotionRenderer/helpers/faceBasedVideoStyles.js +212 -0
  52. package/dist/screenplay/RemotionRenderer/helpers/faceCenteredVideoTransforms.js +468 -0
  53. package/dist/screenplay/RemotionRenderer/helpers/getContrastColor.js +15 -0
  54. package/dist/screenplay/RemotionRenderer/helpers/getVideoOrientation.js +21 -0
  55. package/dist/screenplay/RemotionRenderer/helpers/hexToRgb.js +48 -0
  56. package/dist/screenplay/RemotionRenderer/hooks/useLottieReplaceColor.js +45 -0
  57. package/dist/screenplay/RemotionRenderer/hooks/useOrientationBased.js +29 -0
  58. package/dist/screenplay/RemotionRenderer/hooks/useTimeInterpolate.js +54 -0
  59. package/dist/screenplay/RemotionRenderer/hooks/useVirtualBackground.js +38 -0
  60. package/dist/screenplay/RemotionRenderer/index.js +3 -0
  61. package/dist/screenplay/RemotionRenderer/main/lib/Sequence.js +76 -0
  62. package/dist/screenplay/RemotionRenderer/main/lib/layouts/DefaultLayout.js +72 -0
  63. package/dist/screenplay/RemotionRenderer/main/lib/layouts/DynamicTriangleLayout.js +54 -0
  64. package/dist/screenplay/RemotionRenderer/main/lib/layouts/HandoffLayout.js +50 -0
  65. package/dist/screenplay/RemotionRenderer/main/lib/layouts/IntroVideoLayout.js +33 -0
  66. package/dist/screenplay/RemotionRenderer/main/lib/layouts/KeywordLayout.js +36 -0
  67. package/dist/screenplay/RemotionRenderer/main/lib/layouts/LayoutFactory.js +68 -0
  68. package/dist/screenplay/RemotionRenderer/main/lib/layouts/MotionStillLayout.js +36 -0
  69. package/dist/screenplay/RemotionRenderer/main/lib/layouts/SimpleFrameLayout.js +43 -0
  70. package/dist/screenplay/RemotionRenderer/main/lib/layouts/TextWithVideoLayout.js +52 -0
  71. package/dist/screenplay/RemotionRenderer/main/screenplaySchema.js +92 -0
  72. package/dist/screenplay/RemotionRenderer/registeredComponents.js +91 -0
  73. package/dist/screenplay/RemotionRenderer/theme/config.js +8 -0
  74. package/dist/screenplay/RemotionRenderer/theme/hooks/useTheme.js +24 -0
  75. package/dist/screenplay/RemotionRenderer/theme/hooks/useThemedComponents.js +101 -0
  76. package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldNameTag.js +147 -0
  77. package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldSentence.js +138 -0
  78. package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldTitle.js +136 -0
  79. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColor.js +67 -0
  80. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColorInverse.js +67 -0
  81. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColorShadow.js +66 -0
  82. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionElegant.js +134 -0
  83. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionEmphasis.js +122 -0
  84. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionPunctuated.js +84 -0
  85. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordBoom.js +88 -0
  86. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordBubble.js +91 -0
  87. package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordPopup.js +118 -0
  88. package/dist/screenplay/RemotionRenderer/theme/themes/default/DefaultCaption.js +62 -0
  89. package/dist/screenplay/RemotionRenderer/theme/themes/default/HandoffNametag/handoffNametagConfig.js +59 -0
  90. package/dist/screenplay/RemotionRenderer/theme/themes/default/HandoffNametag.js +173 -0
  91. package/dist/screenplay/RemotionRenderer/theme/themes/default/Nametag.js +129 -0
  92. package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/AnimatedSentence.js +20 -0
  93. package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/AnimatedSentenceDefault.js +29 -0
  94. package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/SentenceSimple.helpers.js +61 -0
  95. package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence.js +86 -0
  96. package/dist/screenplay/RemotionRenderer/theme/themes/default/Title.js +112 -0
  97. package/dist/screenplay/RemotionRenderer/theme/themes/default/constants.js +1 -0
  98. package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Nametag.js +134 -0
  99. package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Sentence.js +49 -0
  100. package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Title.js +108 -0
  101. package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/animations.js +30 -0
  102. package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/config.js +9 -0
  103. package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchNametag.js +252 -0
  104. package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchSentence.js +156 -0
  105. package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchTitle.js +142 -0
  106. package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/DisplacedText.js +66 -0
  107. package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/GlitchAnimatedLine.js +38 -0
  108. package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/SplitSentence.js +80 -0
  109. package/dist/screenplay/RemotionRenderer/theme/themes/glitch/helpers.js +32 -0
  110. package/dist/screenplay/RemotionRenderer/theme/themes/none/Nametag.js +3 -0
  111. package/dist/screenplay/RemotionRenderer/theme/themes/none/Title.js +3 -0
  112. package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullNametag.js +165 -0
  113. package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullSentence.js +94 -0
  114. package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullTitle.js +98 -0
  115. package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/designs/sentence.js +92 -0
  116. package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/designs/title.js +119 -0
  117. package/dist/screenplay/RemotionRenderer/theme/themes/sports/Nametag.js +122 -0
  118. package/dist/screenplay/RemotionRenderer/theme/themes/sports/SportsCaption.js +93 -0
  119. package/dist/screenplay/RemotionRenderer/theme/themes/sports/SportsSentence.js +76 -0
  120. package/dist/screenplay/RemotionRenderer/theme/themes/sports/Title.js +90 -0
  121. package/dist/screenplay/RemotionRenderer/theme/themes/sports/shared.js +62 -0
  122. package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/Nametag.js +145 -0
  123. package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/SportsBounceSentence.js +148 -0
  124. package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/Title.js +160 -0
  125. package/dist/screenplay/RemotionRenderer/tracks/AudioTrack.js +23 -0
  126. package/dist/screenplay/RemotionRenderer/tracks/CaptionsVideoTrack.js +23 -0
  127. package/dist/screenplay/RemotionRenderer/tracks/DynamicVideoComposition.js +31 -0
  128. package/dist/screenplay/RemotionRenderer/tracks/EffectsVideoTrack.js +23 -0
  129. package/dist/screenplay/RemotionRenderer/tracks/LayoutVideoTrack.js +141 -0
  130. package/dist/screenplay/RemotionRenderer/tracks/Soundtrack.js +16 -0
  131. package/dist/screenplay/RemotionRenderer/tracks/Watermark.js +23 -0
  132. package/dist/screenplay/RemotionRenderer/tracks/transitions/GlitchOne.js +92 -0
  133. package/package.json +45 -0
@@ -0,0 +1,562 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ var _excluded = ["src", "faceMetadata", "containerWidth", "containerHeight", "enableInterpolation", "useAveragePosition", "centerHorizontally", "translateX", "translateY", "showDebugInfo", "style", "className", "containerStyle", "noBackgroundVideoEffects", "noBackgroundEffects", "transparent"];
3
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
7
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
8
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
9
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
10
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
11
+ /**
12
+ * Face-Centered Video Component
13
+ *
14
+ * A reusable component that wraps OffthreadVideo to ensure the video is always
15
+ * centered on a person's face within a flexible container.
16
+ *
17
+ * The video maintains its source dimensions and is positioned using translateX/translateY
18
+ * to center the face within the container, regardless of container size.
19
+ */
20
+
21
+ import React from "react";
22
+ import { OffthreadVideo, useCurrentFrame } from "remotion";
23
+ import { useOrientationBased } from "../../hooks/useOrientationBased.js";
24
+
25
+ /**
26
+ * Calculate face-centered translation for flexible container
27
+ * @param {Object} params - Configuration object
28
+ * @param {Object} params.faceMetadata - Face detection metadata
29
+ * @param {number} params.containerWidth - Container width in pixels
30
+ * @param {number} params.containerHeight - Container height in pixels
31
+ * @param {number} params.currentFrame - Current frame number (optional)
32
+ * @param {boolean} params.enableInterpolation - Whether to interpolate between frames
33
+ * @param {boolean} params.useAveragePosition - Whether to use average face position
34
+ * @param {boolean} params.centerHorizontally - Whether to only center horizontally
35
+ * @param {number} params.translateX - Additional translateX offset
36
+ * @param {number} params.translateY - Additional translateY offset
37
+ * @param {string} params.orientation - Viewport orientation (portrait, square, landscape)
38
+ * @returns {Object} Transform styles and debug info
39
+ */
40
+ var calculateFaceCenteredTranslation = function calculateFaceCenteredTranslation(_ref) {
41
+ var _faceMetadata$metadat, _faceMetadata$metadat2;
42
+ var faceMetadata = _ref.faceMetadata,
43
+ containerWidth = _ref.containerWidth,
44
+ containerHeight = _ref.containerHeight,
45
+ _ref$currentFrame = _ref.currentFrame,
46
+ currentFrame = _ref$currentFrame === void 0 ? null : _ref$currentFrame,
47
+ _ref$enableInterpolat = _ref.enableInterpolation,
48
+ enableInterpolation = _ref$enableInterpolat === void 0 ? true : _ref$enableInterpolat,
49
+ _ref$useAveragePositi = _ref.useAveragePosition,
50
+ useAveragePosition = _ref$useAveragePositi === void 0 ? false : _ref$useAveragePositi,
51
+ _ref$centerHorizontal = _ref.centerHorizontally,
52
+ centerHorizontally = _ref$centerHorizontal === void 0 ? false : _ref$centerHorizontal,
53
+ _ref$translateX = _ref.translateX,
54
+ translateX = _ref$translateX === void 0 ? 0 : _ref$translateX,
55
+ _ref$translateY = _ref.translateY,
56
+ translateY = _ref$translateY === void 0 ? 0 : _ref$translateY,
57
+ _ref$orientation = _ref.orientation,
58
+ orientation = _ref$orientation === void 0 ? "landscape" : _ref$orientation;
59
+ // Get current frame if not provided
60
+ var frameIndex = currentFrame;
61
+ if (frameIndex === null) {
62
+ try {
63
+ var remotionFrame = useCurrentFrame();
64
+ frameIndex = remotionFrame;
65
+ } catch (error) {
66
+ frameIndex = 0;
67
+ }
68
+ }
69
+
70
+ // Validate inputs
71
+ if (!(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat = faceMetadata.metadata) !== null && _faceMetadata$metadat !== void 0 && _faceMetadata$metadat.frames) || !(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat2 = faceMetadata.metadata) !== null && _faceMetadata$metadat2 !== void 0 && _faceMetadata$metadat2.videoProperties)) {
72
+ return {
73
+ transform: "translate(".concat(translateX, "px, ").concat(translateY, "px)"),
74
+ debugInfo: {
75
+ error: "Invalid face metadata"
76
+ }
77
+ };
78
+ }
79
+ var _faceMetadata$metadat3 = faceMetadata.metadata,
80
+ frames = _faceMetadata$metadat3.frames,
81
+ videoProperties = _faceMetadata$metadat3.videoProperties,
82
+ averageFaceData = _faceMetadata$metadat3.averageFaceData;
83
+ var sourceWidth = videoProperties.width,
84
+ sourceHeight = videoProperties.height;
85
+ var faceData = useAveragePosition ? averageFaceData !== null && averageFaceData !== void 0 ? averageFaceData : getAverageFaceData(frames) : getFaceDataForFrame(frames, frameIndex, enableInterpolation);
86
+ if (!faceData) {
87
+ return {
88
+ transform: "translate(".concat(translateX, "px, ").concat(translateY, "px)"),
89
+ debugInfo: {
90
+ error: "No face data available"
91
+ }
92
+ };
93
+ }
94
+
95
+ // Convert absolute face coordinates to relative (0-1 range)
96
+ var relativeFaceX = faceData.face_center[0] / sourceWidth;
97
+ var relativeFaceY = faceData.face_center[1] / sourceHeight;
98
+
99
+ // Calculate face position in source video (absolute pixels)
100
+ var faceX = relativeFaceX * sourceWidth;
101
+ var faceY = relativeFaceY * sourceHeight;
102
+
103
+ // Calculate container center
104
+ var containerCenterX = containerWidth / 2;
105
+ var containerCenterY = containerHeight / 2;
106
+
107
+ // Calculate scale factor if video is smaller than container height
108
+ var scale = 1;
109
+ if (sourceHeight < containerHeight) {
110
+ scale = containerHeight / sourceHeight;
111
+ }
112
+
113
+ // Portrait sources displayed in wider containers should still fill width
114
+ var hasDimensions = typeof sourceWidth === "number" && typeof sourceHeight === "number";
115
+ var isPortrait = hasDimensions && sourceHeight > sourceWidth;
116
+ if (hasDimensions && isPortrait && orientation === "square" && containerWidth > 0 && sourceWidth > 0) {
117
+ var widthScale = containerWidth / sourceWidth;
118
+ if (widthScale > scale) {
119
+ scale = widthScale;
120
+ }
121
+ }
122
+
123
+ // Calculate translation needed to center the face in the container
124
+ // When scale > 1, translate happens in scaled coordinate system, so we need to adjust
125
+ var baseTranslateX = containerCenterX - faceX + translateX;
126
+ var baseTranslateY = centerHorizontally ? translateY : containerCenterY - faceY + translateY;
127
+
128
+ // Adjust translation for scaling - divide by scale factor when scale > 1
129
+ var finalTranslateX = scale > 1 ? baseTranslateX / scale : baseTranslateX;
130
+ var finalTranslateY = scale > 1 ? baseTranslateY / scale : baseTranslateY;
131
+
132
+ // Add additional translateY adjustment when scale > 1 to keep video contained within container
133
+ if (!centerHorizontally) {
134
+ // Calculate the scaled video height
135
+ var scaledVideoHeight = sourceHeight * scale;
136
+
137
+ // When scaling with transform origin at face position, we need to calculate
138
+ // where the video edges will be after scaling and translation
139
+ var faceOffsetFromTop = faceY;
140
+ var faceOffsetFromBottom = sourceHeight - faceY;
141
+
142
+ // After scaling, these offsets become larger
143
+ var scaledOffsetFromTop = faceOffsetFromTop * scale;
144
+ var scaledOffsetFromBottom = faceOffsetFromBottom * scale;
145
+
146
+ // Face will be at containerCenterY after translation
147
+ // So video edges will be at:
148
+ var videoTop = containerCenterY - scaledOffsetFromTop;
149
+ var videoBottom = containerCenterY + scaledOffsetFromBottom;
150
+
151
+ // Calculate how much the video extends beyond container bounds
152
+ var overflowTop = videoTop < 0 ? Math.abs(videoTop) : 0;
153
+ var overflowBottom = videoBottom > containerHeight ? videoBottom - containerHeight : 0;
154
+
155
+ // If there's overflow, adjust translateY to keep video contained
156
+ if (overflowTop > 0 || overflowBottom > 0) {
157
+ // Calculate the adjustment needed to eliminate overflow
158
+ var adjustment = 0;
159
+ if (overflowBottom > 0 && overflowTop === 0) {
160
+ // Only bottom overflow - move up by the overflow amount
161
+ adjustment = overflowBottom;
162
+ } else if (overflowTop > 0 && overflowBottom === 0) {
163
+ // Only top overflow - move down by the overflow amount
164
+ adjustment = -overflowTop;
165
+ } else if (overflowTop > 0 && overflowBottom > 0) {
166
+ // Both overflows - center the video in the container
167
+ adjustment = (overflowBottom - overflowTop) / 2;
168
+ }
169
+ // Adjust for scaling - divide by scale factor since translate happens in scaled coordinate system
170
+ finalTranslateY -= adjustment / scale;
171
+ }
172
+ }
173
+
174
+ // Calculate horizontal offset based on scale
175
+ var offsetResult = calculateNegativeSpaceOffset(faceMetadata, containerWidth, containerHeight, scale);
176
+ var horizontalOffset = offsetResult.horizontalOffset;
177
+
178
+ // When scale > 1, we need to adjust the horizontal offset to work in the scaled coordinate system
179
+ if (scale > 1) {
180
+ horizontalOffset = horizontalOffset / scale;
181
+ }
182
+
183
+ // Create transform string with scale and translate
184
+ var transform = scale > 1 ? "scale(".concat(scale, ") translate(").concat(finalTranslateX + horizontalOffset, "px, ").concat(finalTranslateY, "px)") : "translate(".concat(finalTranslateX + horizontalOffset, "px, ").concat(finalTranslateY, "px)");
185
+
186
+ // Transform origin should be at the face position for proper scaling
187
+ var transformOriginX = (relativeFaceX * 100).toFixed(2);
188
+ var transformOriginY = (relativeFaceY * 100).toFixed(2);
189
+ var transformOrigin = "".concat(transformOriginX, "% ").concat(transformOriginY, "%");
190
+ return {
191
+ transform: transform,
192
+ transformOrigin: transformOrigin,
193
+ debugInfo: {
194
+ frameIndex: useAveragePosition ? "AVERAGE" : frameIndex,
195
+ relativeFaceX: relativeFaceX.toFixed(3),
196
+ relativeFaceY: relativeFaceY.toFixed(3),
197
+ faceX: faceX.toFixed(1),
198
+ faceY: faceY.toFixed(1),
199
+ containerCenterX: containerCenterX.toFixed(1),
200
+ containerCenterY: containerCenterY.toFixed(1),
201
+ finalTranslateX: finalTranslateX.toFixed(1),
202
+ finalTranslateY: finalTranslateY.toFixed(1),
203
+ scale: scale.toFixed(3),
204
+ transformOrigin: transformOrigin,
205
+ sourceWidth: sourceWidth,
206
+ sourceHeight: sourceHeight,
207
+ containerWidth: containerWidth,
208
+ containerHeight: containerHeight,
209
+ useAveragePosition: useAveragePosition,
210
+ centerHorizontally: centerHorizontally,
211
+ scalingApplied: scale > 1,
212
+ orientation: orientation
213
+ }
214
+ };
215
+ };
216
+
217
+ /**
218
+ * Get face data for a specific frame with optional interpolation
219
+ */
220
+ function getFaceDataForFrame(frames, frameIndex, enableInterpolation) {
221
+ var _prevFrame, _nextFrame;
222
+ if (!frames || frames.length === 0) return null;
223
+
224
+ // Clamp frame index to valid range
225
+ var clampedIndex = Math.max(0, Math.min(frameIndex, frames.length - 1));
226
+
227
+ // Try to get exact frame data
228
+ var exactFrame = frames[clampedIndex];
229
+ if (exactFrame && exactFrame.face_detected && exactFrame.face_data) {
230
+ return exactFrame.face_data;
231
+ }
232
+ if (!enableInterpolation) {
233
+ // Find nearest frame with face data
234
+ for (var i = 0; i < frames.length; i++) {
235
+ var frame = frames[i];
236
+ if (frame && frame.face_detected && frame.face_data) {
237
+ return frame.face_data;
238
+ }
239
+ }
240
+ return null;
241
+ }
242
+
243
+ // Interpolation logic - find surrounding frames with face data
244
+ var prevFrame = null;
245
+ var nextFrame = null;
246
+ for (var _i = clampedIndex; _i >= 0; _i--) {
247
+ if (frames[_i] && frames[_i].face_detected && frames[_i].face_data) {
248
+ prevFrame = {
249
+ index: _i,
250
+ data: frames[_i].face_data
251
+ };
252
+ break;
253
+ }
254
+ }
255
+ for (var _i2 = clampedIndex; _i2 < frames.length; _i2++) {
256
+ if (frames[_i2] && frames[_i2].face_detected && frames[_i2].face_data) {
257
+ nextFrame = {
258
+ index: _i2,
259
+ data: frames[_i2].face_data
260
+ };
261
+ break;
262
+ }
263
+ }
264
+ if (prevFrame && nextFrame && prevFrame.index !== nextFrame.index) {
265
+ // Interpolate between frames
266
+ var t = (clampedIndex - prevFrame.index) / (nextFrame.index - prevFrame.index);
267
+ return {
268
+ face_center: [prevFrame.data.face_center[0] + t * (nextFrame.data.face_center[0] - prevFrame.data.face_center[0]), prevFrame.data.face_center[1] + t * (nextFrame.data.face_center[1] - prevFrame.data.face_center[1])],
269
+ face_bbox: prevFrame.data.face_bbox || nextFrame.data.face_bbox
270
+ };
271
+ }
272
+
273
+ // Return the closest available frame
274
+ return ((_prevFrame = prevFrame) === null || _prevFrame === void 0 ? void 0 : _prevFrame.data) || ((_nextFrame = nextFrame) === null || _nextFrame === void 0 ? void 0 : _nextFrame.data) || null;
275
+ }
276
+
277
+ /**
278
+ * Calculate average face position from all frames with face data
279
+ */
280
+ function getAverageFaceData(frames) {
281
+ if (!frames || frames.length === 0) return null;
282
+ var framesWithFaces = frames.filter(function (f) {
283
+ return f.face_detected && f.face_data;
284
+ });
285
+ if (framesWithFaces.length === 0) return null;
286
+ var totalFaceX = 0;
287
+ var totalFaceY = 0;
288
+ var totalFaceWidth = 0;
289
+ var totalFaceHeight = 0;
290
+ var validBboxCount = 0;
291
+ framesWithFaces.forEach(function (frame) {
292
+ var _frame$face_data = frame.face_data,
293
+ face_center = _frame$face_data.face_center,
294
+ face_bbox = _frame$face_data.face_bbox;
295
+ totalFaceX += face_center[0];
296
+ totalFaceY += face_center[1];
297
+ if (face_bbox && face_bbox.length >= 4) {
298
+ totalFaceWidth += face_bbox[2];
299
+ totalFaceHeight += face_bbox[3];
300
+ validBboxCount++;
301
+ }
302
+ });
303
+ var avgFaceX = totalFaceX / framesWithFaces.length;
304
+ var avgFaceY = totalFaceY / framesWithFaces.length;
305
+ return {
306
+ face_center: [avgFaceX, avgFaceY],
307
+ face_bbox: validBboxCount > 0 ? [0, 0,
308
+ // x, y position not needed for average
309
+ totalFaceWidth / validBboxCount, totalFaceHeight / validBboxCount] : null
310
+ };
311
+ }
312
+
313
+ /**
314
+ * Calculate the negative space offset when face-centering a video
315
+ *
316
+ * @param {Object} faceMetadata - Face detection metadata object
317
+ * @param {number} containerWidth - Container width in pixels
318
+ * @param {number} containerHeight - Container height in pixels
319
+ * @param {number} scale - Scale factor applied to the video
320
+ * @returns {Object} Object containing horizontal and vertical offsets and which side has negative space
321
+ */
322
+ export var calculateNegativeSpaceOffset = function calculateNegativeSpaceOffset(faceMetadata, containerWidth, containerHeight) {
323
+ var _faceMetadata$metadat4, _faceMetadata$metadat5;
324
+ var scale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
325
+ // Validate inputs
326
+ if (!(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat4 = faceMetadata.metadata) !== null && _faceMetadata$metadat4 !== void 0 && _faceMetadata$metadat4.frames) || !(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat5 = faceMetadata.metadata) !== null && _faceMetadata$metadat5 !== void 0 && _faceMetadata$metadat5.videoProperties)) {
327
+ return {
328
+ horizontalOffset: 0,
329
+ verticalOffset: 0,
330
+ side: "none",
331
+ error: "Invalid face metadata"
332
+ };
333
+ }
334
+ var _faceMetadata$metadat6 = faceMetadata.metadata,
335
+ frames = _faceMetadata$metadat6.frames,
336
+ videoProperties = _faceMetadata$metadat6.videoProperties;
337
+ var sourceWidth = videoProperties.width,
338
+ sourceHeight = videoProperties.height;
339
+
340
+ // When scaling is applied, use the scaled dimensions
341
+ var scaledWidth = sourceWidth * scale;
342
+ var scaledHeight = sourceHeight * scale;
343
+
344
+ // Get average face position from all frames with face data
345
+ var framesWithFaces = frames.filter(function (f) {
346
+ return f.face_detected && f.face_data;
347
+ });
348
+ if (framesWithFaces.length === 0) {
349
+ return {
350
+ horizontalOffset: 0,
351
+ verticalOffset: 0,
352
+ side: "none",
353
+ error: "No face data available"
354
+ };
355
+ }
356
+
357
+ // Calculate average face position
358
+ var totalFaceX = 0;
359
+ var totalFaceY = 0;
360
+ framesWithFaces.forEach(function (frame) {
361
+ totalFaceX += frame.face_data.face_center[0];
362
+ totalFaceY += frame.face_data.face_center[1];
363
+ });
364
+ var avgFaceX = totalFaceX / framesWithFaces.length;
365
+ var avgFaceY = totalFaceY / framesWithFaces.length;
366
+
367
+ // When scaling, face position also scales
368
+ var scaledFaceX = avgFaceX * scale;
369
+ var scaledFaceY = avgFaceY * scale;
370
+
371
+ // Calculate how much the video needs to shift to center the face
372
+ var containerCenterX = containerWidth / 2;
373
+ var containerCenterY = containerHeight / 2;
374
+ var translateX = containerCenterX - scaledFaceX;
375
+ var translateY = containerCenterY - scaledFaceY;
376
+
377
+ // Calculate negative space
378
+ var horizontalOffset = 0;
379
+ var side = "none";
380
+
381
+ // Check if video extends beyond container after translation
382
+ var videoLeftEdge = translateX;
383
+ var videoRightEdge = translateX + scaledWidth;
384
+ if (videoLeftEdge > 0) {
385
+ // Negative space on the left
386
+ horizontalOffset = -videoLeftEdge;
387
+ side = "left";
388
+ } else if (videoRightEdge < containerWidth) {
389
+ // Negative space on the right
390
+ horizontalOffset = containerWidth - videoRightEdge;
391
+ side = "right";
392
+ }
393
+
394
+ // Calculate vertical negative space
395
+ var verticalOffset = 0;
396
+ var videoTopEdge = translateY;
397
+ var videoBottomEdge = translateY + sourceHeight;
398
+ if (videoTopEdge > 0) {
399
+ verticalOffset = -videoTopEdge;
400
+ } else if (videoBottomEdge < containerHeight) {
401
+ verticalOffset = containerHeight - videoBottomEdge;
402
+ }
403
+ return {
404
+ horizontalOffset: Math.round(horizontalOffset),
405
+ verticalOffset: Math.round(verticalOffset),
406
+ side: side,
407
+ avgFacePosition: {
408
+ x: Math.round(avgFaceX),
409
+ y: Math.round(avgFaceY)
410
+ },
411
+ translation: {
412
+ x: Math.round(translateX),
413
+ y: Math.round(translateY)
414
+ }
415
+ };
416
+ };
417
+
418
+ /**
419
+ * FaceCenteredVideo Component
420
+ * @param {Object} props - Component props
421
+ * @param {string} props.src - Video source URL
422
+ * @param {Object} props.faceMetadata - Face detection metadata
423
+ * @param {number} props.containerWidth - Container width in pixels (required)
424
+ * @param {number} props.containerHeight - Container height in pixels (required)
425
+ * @param {boolean} props.enableInterpolation - Whether to interpolate between frames
426
+ * @param {boolean} props.useAveragePosition - Whether to use average face position for entire video duration
427
+ * @param {boolean} props.centerHorizontally - Whether to only center horizontally (X axis), not vertically (Y axis)
428
+ * @param {number} props.translateX - Additional translateX offset (optional)
429
+ * @param {number} props.translateY - Additional translateY offset (optional)
430
+ * @param {boolean} props.showDebugInfo - Whether to show debug information
431
+ * @param {Object} props.style - Additional styles to apply to video
432
+ * @param {string} props.className - CSS class name
433
+ * @param {...Object} props.otherProps - Other props to pass to OffthreadVideo
434
+ */
435
+ export var FaceCenteredVideo = function FaceCenteredVideo(_ref2) {
436
+ var _faceMetadata$metadat7, _faceMetadata$metadat8, _faceMetadata$metadat9, _faceMetadata$metadat10;
437
+ var src = _ref2.src,
438
+ faceMetadata = _ref2.faceMetadata,
439
+ containerWidth = _ref2.containerWidth,
440
+ containerHeight = _ref2.containerHeight,
441
+ _ref2$enableInterpola = _ref2.enableInterpolation,
442
+ enableInterpolation = _ref2$enableInterpola === void 0 ? true : _ref2$enableInterpola,
443
+ _ref2$useAveragePosit = _ref2.useAveragePosition,
444
+ useAveragePosition = _ref2$useAveragePosit === void 0 ? true : _ref2$useAveragePosit,
445
+ _ref2$centerHorizonta = _ref2.centerHorizontally,
446
+ centerHorizontally = _ref2$centerHorizonta === void 0 ? false : _ref2$centerHorizonta,
447
+ _ref2$translateX = _ref2.translateX,
448
+ translateX = _ref2$translateX === void 0 ? 0 : _ref2$translateX,
449
+ _ref2$translateY = _ref2.translateY,
450
+ translateY = _ref2$translateY === void 0 ? 0 : _ref2$translateY,
451
+ _ref2$showDebugInfo = _ref2.showDebugInfo,
452
+ showDebugInfo = _ref2$showDebugInfo === void 0 ? false : _ref2$showDebugInfo,
453
+ _ref2$style = _ref2.style,
454
+ style = _ref2$style === void 0 ? {} : _ref2$style,
455
+ _ref2$className = _ref2.className,
456
+ className = _ref2$className === void 0 ? "" : _ref2$className,
457
+ _ref2$containerStyle = _ref2.containerStyle,
458
+ containerStyle = _ref2$containerStyle === void 0 ? {} : _ref2$containerStyle,
459
+ _ref2$noBackgroundVid = _ref2.noBackgroundVideoEffects,
460
+ noBackgroundVideoEffects = _ref2$noBackgroundVid === void 0 ? {} : _ref2$noBackgroundVid,
461
+ _ref2$noBackgroundEff = _ref2.noBackgroundEffects,
462
+ noBackgroundEffects = _ref2$noBackgroundEff === void 0 ? {} : _ref2$noBackgroundEff,
463
+ _ref2$transparent = _ref2.transparent,
464
+ transparent = _ref2$transparent === void 0 ? false : _ref2$transparent,
465
+ otherProps = _objectWithoutProperties(_ref2, _excluded);
466
+ var _useOrientationBased = useOrientationBased({
467
+ portrait: {},
468
+ landscape: {},
469
+ square: {}
470
+ }),
471
+ orientation = _useOrientationBased.orientation;
472
+
473
+ // Get source video dimensions
474
+ var sourceWidth = faceMetadata === null || faceMetadata === void 0 ? void 0 : (_faceMetadata$metadat7 = faceMetadata.metadata) === null || _faceMetadata$metadat7 === void 0 ? void 0 : (_faceMetadata$metadat8 = _faceMetadata$metadat7.videoProperties) === null || _faceMetadata$metadat8 === void 0 ? void 0 : _faceMetadata$metadat8.width;
475
+ var sourceHeight = faceMetadata === null || faceMetadata === void 0 ? void 0 : (_faceMetadata$metadat9 = faceMetadata.metadata) === null || _faceMetadata$metadat9 === void 0 ? void 0 : (_faceMetadata$metadat10 = _faceMetadata$metadat9.videoProperties) === null || _faceMetadata$metadat10 === void 0 ? void 0 : _faceMetadata$metadat10.height;
476
+
477
+ // Calculate face-centered translation and scaling
478
+ var _calculateFaceCentere = calculateFaceCenteredTranslation({
479
+ faceMetadata: faceMetadata,
480
+ containerWidth: containerWidth,
481
+ containerHeight: containerHeight,
482
+ enableInterpolation: enableInterpolation,
483
+ useAveragePosition: useAveragePosition,
484
+ centerHorizontally: centerHorizontally,
485
+ translateX: translateX,
486
+ translateY: translateY,
487
+ orientation: orientation
488
+ }),
489
+ transform = _calculateFaceCentere.transform,
490
+ transformOrigin = _calculateFaceCentere.transformOrigin,
491
+ debugInfo = _calculateFaceCentere.debugInfo;
492
+ var videoStyle = _objectSpread({
493
+ width: sourceWidth || "100%",
494
+ height: sourceHeight || "100%",
495
+ transform: sourceHeight === containerHeight && sourceWidth === containerWidth ? undefined : transform,
496
+ transformOrigin: transformOrigin || "center center",
497
+ position: "absolute",
498
+ top: 0,
499
+ left: 0,
500
+ maxWidth: "unset",
501
+ filter: noBackgroundVideoEffects !== null && noBackgroundVideoEffects !== void 0 && noBackgroundVideoEffects.facePop ? "brightness(1.1) contrast(1.15) saturate(1.05)" : undefined
502
+ }, style);
503
+
504
+ // Validate required props
505
+ if (!containerWidth || !containerHeight) {
506
+ console.error("FaceCenteredVideo: containerWidth and containerHeight are required props");
507
+ return null;
508
+ }
509
+ return /*#__PURE__*/React.createElement("div", {
510
+ className: "face-centered-video-container ".concat(className),
511
+ style: _objectSpread({
512
+ position: "relative",
513
+ width: containerWidth,
514
+ height: containerHeight,
515
+ overflow: "hidden",
516
+ isolation: "isolate"
517
+ }, containerStyle)
518
+ }, /*#__PURE__*/React.createElement(OffthreadVideo, _extends({
519
+ src: src,
520
+ style: videoStyle,
521
+ transparent: transparent
522
+ }, otherProps)), showDebugInfo && debugInfo && /*#__PURE__*/React.createElement("div", {
523
+ style: {
524
+ position: "absolute",
525
+ top: 10,
526
+ left: 10,
527
+ background: "rgba(0, 0, 0, 0.8)",
528
+ color: "white",
529
+ padding: "8px",
530
+ fontSize: "12px",
531
+ fontFamily: "monospace",
532
+ borderRadius: "30px",
533
+ zIndex: 1000,
534
+ maxWidth: "300px"
535
+ }
536
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Face-Centered Video Debug")), /*#__PURE__*/React.createElement("div", {
537
+ style: {
538
+ color: "lightblue"
539
+ }
540
+ }, debugInfo.scalingApplied ? "Using Scale + Translation" : "Using Translation"), /*#__PURE__*/React.createElement("div", null, "Frame: ", debugInfo.frameIndex), /*#__PURE__*/React.createElement("div", null, "Face Position: (", debugInfo.relativeFaceX, ", ", debugInfo.relativeFaceY, ")"), /*#__PURE__*/React.createElement("div", null, "Face Absolute: (", debugInfo.faceX, "px, ", debugInfo.faceY, "px)"), /*#__PURE__*/React.createElement("div", null, "Container Center: (", debugInfo.containerCenterX, "px,", " ", debugInfo.containerCenterY, "px)"), /*#__PURE__*/React.createElement("div", null, "Translation: (", debugInfo.finalTranslateX, "px,", " ", debugInfo.finalTranslateY, "px)"), debugInfo.scalingApplied && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
541
+ style: {
542
+ color: "orange"
543
+ }
544
+ }, "Scale: ", debugInfo.scale, "x"), /*#__PURE__*/React.createElement("div", {
545
+ style: {
546
+ color: "orange"
547
+ }
548
+ }, "Transform Origin: ", debugInfo.transformOrigin)), /*#__PURE__*/React.createElement("div", null, "Source: ", debugInfo.sourceWidth, "x", debugInfo.sourceHeight), /*#__PURE__*/React.createElement("div", null, "Container: ", debugInfo.containerWidth, "x", debugInfo.containerHeight), debugInfo.useAveragePosition && /*#__PURE__*/React.createElement("div", {
549
+ style: {
550
+ color: "yellow"
551
+ }
552
+ }, "Using Average Position"), debugInfo.centerHorizontally && /*#__PURE__*/React.createElement("div", {
553
+ style: {
554
+ color: "cyan"
555
+ }
556
+ }, "Center Horizontally Only"), debugInfo.error && /*#__PURE__*/React.createElement("div", {
557
+ style: {
558
+ color: "red"
559
+ }
560
+ }, "Error: ", debugInfo.error)));
561
+ };
562
+ export default FaceCenteredVideo;