@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.
- package/dist/ZyncScreenplayPlayer.js +35 -0
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.LICENSE.txt +54 -0
- package/dist/index.js +4 -0
- package/dist/screenplay/RemotionRenderer/RemotionRenderer.js +281 -0
- package/dist/screenplay/RemotionRenderer/Root.js +22 -0
- package/dist/screenplay/RemotionRenderer/components/LottieAnimationGlobal.js +116 -0
- package/dist/screenplay/RemotionRenderer/components/backgrounds/VirtualBackground.js +26 -0
- package/dist/screenplay/RemotionRenderer/components/backgrounds/VirtualBackgroundUnderlay.js +41 -0
- package/dist/screenplay/RemotionRenderer/components/captions/CaptionSimple.js +12 -0
- package/dist/screenplay/RemotionRenderer/components/effects/BrollFullscreen.js +27 -0
- package/dist/screenplay/RemotionRenderer/components/effects/GlitchText.js +22 -0
- package/dist/screenplay/RemotionRenderer/components/effects/HandoffNametag.js +7 -0
- package/dist/screenplay/RemotionRenderer/components/effects/LottieAnimation.js +64 -0
- package/dist/screenplay/RemotionRenderer/components/effects/Nametag.js +9 -0
- package/dist/screenplay/RemotionRenderer/components/effects/PhraseRainbowEffect.js +34 -0
- package/dist/screenplay/RemotionRenderer/components/effects/Sentence.js +50 -0
- package/dist/screenplay/RemotionRenderer/components/effects/Title.js +12 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/BrollGreenScreen.js +742 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/BrollSplitScreen.js +714 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/BrollStudioBackdrop.js +620 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/DynamicTriangle.js +618 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/Handoff.js +161 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/IntroVideo.js +1330 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/KeyPointOverlayDepth.js +397 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/Keyword.js +539 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/KeywordStudioBackdrop.js +714 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStill.js +381 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillFullScreen.js +178 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillGreenScreen.js +568 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillGreenScreenV2.js +731 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillStudioBackdrop.js +588 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrame.js +183 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameBroll.js +181 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameSentence.js +17 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameZoomCut.js +13 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/TextWithVideo.js +373 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/quote-bubble-animation.json +1 -0
- package/dist/screenplay/RemotionRenderer/components/utils/BlurOverlay.js +19 -0
- package/dist/screenplay/RemotionRenderer/components/utils/ChromaKeyedVideo.js +59 -0
- package/dist/screenplay/RemotionRenderer/components/utils/FaceCenteredVideo.js +562 -0
- package/dist/screenplay/RemotionRenderer/components/utils/PausableImg.js +124 -0
- package/dist/screenplay/RemotionRenderer/components/utils/README.md +80 -0
- package/dist/screenplay/RemotionRenderer/components/utils/SafeZones.js +69 -0
- package/dist/screenplay/RemotionRenderer/components/utils/StretchText.js +124 -0
- package/dist/screenplay/RemotionRenderer/components/utils/StretchTextDemo.js +66 -0
- package/dist/screenplay/RemotionRenderer/config.js +8 -0
- package/dist/screenplay/RemotionRenderer/development.js +1370 -0
- package/dist/screenplay/RemotionRenderer/helpers/cleanFacemetadata.js +29 -0
- package/dist/screenplay/RemotionRenderer/helpers/convertToSeconds.js +14 -0
- package/dist/screenplay/RemotionRenderer/helpers/faceBasedVideoStyles.js +212 -0
- package/dist/screenplay/RemotionRenderer/helpers/faceCenteredVideoTransforms.js +468 -0
- package/dist/screenplay/RemotionRenderer/helpers/getContrastColor.js +15 -0
- package/dist/screenplay/RemotionRenderer/helpers/getVideoOrientation.js +21 -0
- package/dist/screenplay/RemotionRenderer/helpers/hexToRgb.js +48 -0
- package/dist/screenplay/RemotionRenderer/hooks/useLottieReplaceColor.js +45 -0
- package/dist/screenplay/RemotionRenderer/hooks/useOrientationBased.js +29 -0
- package/dist/screenplay/RemotionRenderer/hooks/useTimeInterpolate.js +54 -0
- package/dist/screenplay/RemotionRenderer/hooks/useVirtualBackground.js +38 -0
- package/dist/screenplay/RemotionRenderer/index.js +3 -0
- package/dist/screenplay/RemotionRenderer/main/lib/Sequence.js +76 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/DefaultLayout.js +72 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/DynamicTriangleLayout.js +54 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/HandoffLayout.js +50 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/IntroVideoLayout.js +33 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/KeywordLayout.js +36 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/LayoutFactory.js +68 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/MotionStillLayout.js +36 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/SimpleFrameLayout.js +43 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/TextWithVideoLayout.js +52 -0
- package/dist/screenplay/RemotionRenderer/main/screenplaySchema.js +92 -0
- package/dist/screenplay/RemotionRenderer/registeredComponents.js +91 -0
- package/dist/screenplay/RemotionRenderer/theme/config.js +8 -0
- package/dist/screenplay/RemotionRenderer/theme/hooks/useTheme.js +24 -0
- package/dist/screenplay/RemotionRenderer/theme/hooks/useThemedComponents.js +101 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldNameTag.js +147 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldSentence.js +138 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldTitle.js +136 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColor.js +67 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColorInverse.js +67 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColorShadow.js +66 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionElegant.js +134 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionEmphasis.js +122 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionPunctuated.js +84 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordBoom.js +88 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordBubble.js +91 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordPopup.js +118 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/DefaultCaption.js +62 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/HandoffNametag/handoffNametagConfig.js +59 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/HandoffNametag.js +173 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Nametag.js +129 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/AnimatedSentence.js +20 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/AnimatedSentenceDefault.js +29 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/SentenceSimple.helpers.js +61 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence.js +86 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Title.js +112 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/constants.js +1 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Nametag.js +134 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Sentence.js +49 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Title.js +108 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/animations.js +30 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/config.js +9 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchNametag.js +252 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchSentence.js +156 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchTitle.js +142 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/DisplacedText.js +66 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/GlitchAnimatedLine.js +38 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/SplitSentence.js +80 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/helpers.js +32 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/none/Nametag.js +3 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/none/Title.js +3 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullNametag.js +165 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullSentence.js +94 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullTitle.js +98 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/designs/sentence.js +92 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/designs/title.js +119 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/Nametag.js +122 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/SportsCaption.js +93 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/SportsSentence.js +76 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/Title.js +90 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/shared.js +62 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/Nametag.js +145 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/SportsBounceSentence.js +148 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/Title.js +160 -0
- package/dist/screenplay/RemotionRenderer/tracks/AudioTrack.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/CaptionsVideoTrack.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/DynamicVideoComposition.js +31 -0
- package/dist/screenplay/RemotionRenderer/tracks/EffectsVideoTrack.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/LayoutVideoTrack.js +141 -0
- package/dist/screenplay/RemotionRenderer/tracks/Soundtrack.js +16 -0
- package/dist/screenplay/RemotionRenderer/tracks/Watermark.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/transitions/GlitchOne.js +92 -0
- package/package.json +45 -0
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
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; }
|
|
3
|
+
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; }
|
|
4
|
+
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; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
6
|
+
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); }
|
|
7
|
+
export var cleanFacemetadata = function cleanFacemetadata(faceMetadata) {
|
|
8
|
+
var _faceMetadata$face_me, _averaged$face_data, _averaged$sample_coun;
|
|
9
|
+
if (!faceMetadata) {
|
|
10
|
+
return faceMetadata;
|
|
11
|
+
}
|
|
12
|
+
var rawFrames = (_faceMetadata$face_me = faceMetadata.face_metadata) !== null && _faceMetadata$face_me !== void 0 ? _faceMetadata$face_me : [];
|
|
13
|
+
var frames = rawFrames.filter(function (_ref) {
|
|
14
|
+
var face_data = _ref.face_data;
|
|
15
|
+
return Boolean(face_data);
|
|
16
|
+
});
|
|
17
|
+
var averaged = rawFrames.find(function (_ref2) {
|
|
18
|
+
var aggregation = _ref2.aggregation;
|
|
19
|
+
return aggregation === "average";
|
|
20
|
+
});
|
|
21
|
+
return _objectSpread(_objectSpread({}, faceMetadata), {}, {
|
|
22
|
+
metadata: {
|
|
23
|
+
videoProperties: faceMetadata.video_properties,
|
|
24
|
+
frames: frames,
|
|
25
|
+
averageFaceData: (_averaged$face_data = averaged === null || averaged === void 0 ? void 0 : averaged.face_data) !== null && _averaged$face_data !== void 0 ? _averaged$face_data : null,
|
|
26
|
+
averageSampleCount: (_averaged$sample_coun = averaged === null || averaged === void 0 ? void 0 : averaged.sample_count) !== null && _averaged$sample_coun !== void 0 ? _averaged$sample_coun : 0
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts seconds and a portion of frames to a numeric value of seconds.
|
|
3
|
+
*
|
|
4
|
+
* @param {number} seconds - The number of full seconds.
|
|
5
|
+
* @param {number} nthFrame - The current frame within the second.
|
|
6
|
+
* @param {number} delayInSeconds - Optional delay that adds up to the calculation
|
|
7
|
+
* @param {number} frameRate - The frame rate (frames per second).
|
|
8
|
+
* @return {number} The total time in seconds (with decimals for frames).
|
|
9
|
+
*/
|
|
10
|
+
export var convertToSeconds = function convertToSeconds(seconds, nthFrame) {
|
|
11
|
+
var delayInSeconds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
12
|
+
var frameRate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 24;
|
|
13
|
+
return seconds + nthFrame / frameRate + delayInSeconds;
|
|
14
|
+
};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
/**
|
|
8
|
+
* Calculate video styles based on face detection metadata
|
|
9
|
+
* This helper adjusts video positioning and transform origin to center faces in the viewport
|
|
10
|
+
* when zooming, accounting for objectFit: "cover" behavior
|
|
11
|
+
*/
|
|
12
|
+
export var getFaceBasedVideoStyles = function getFaceBasedVideoStyles(_ref) {
|
|
13
|
+
var faceMetadata = _ref.faceMetadata,
|
|
14
|
+
videoZoom = _ref.videoZoom,
|
|
15
|
+
sourceVideoOrientation = _ref.sourceVideoOrientation,
|
|
16
|
+
containerWidth = _ref.containerWidth,
|
|
17
|
+
containerHeight = _ref.containerHeight,
|
|
18
|
+
_ref$currentFrame = _ref.currentFrame,
|
|
19
|
+
currentFrame = _ref$currentFrame === void 0 ? 0 : _ref$currentFrame,
|
|
20
|
+
_ref$interpolate = _ref.interpolate,
|
|
21
|
+
interpolate = _ref$interpolate === void 0 ? false : _ref$interpolate,
|
|
22
|
+
_ref$existingTransfor = _ref.existingTransform,
|
|
23
|
+
existingTransform = _ref$existingTransfor === void 0 ? "" : _ref$existingTransfor;
|
|
24
|
+
// Validate inputs
|
|
25
|
+
if (!containerWidth || !containerHeight || containerWidth <= 0 || containerHeight <= 0) {
|
|
26
|
+
console.warn('getFaceBasedVideoStyles: Invalid container dimensions', {
|
|
27
|
+
containerWidth: containerWidth,
|
|
28
|
+
containerHeight: containerHeight
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
styles: {
|
|
32
|
+
transformOrigin: "center center"
|
|
33
|
+
},
|
|
34
|
+
faceDebugInfo: null
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Default styles when no face data or zoom is available
|
|
39
|
+
var defaultStyles = {
|
|
40
|
+
styles: {
|
|
41
|
+
transformOrigin: "center center",
|
|
42
|
+
objectPosition: sourceVideoOrientation === "portrait" ? "0% 30%" : undefined
|
|
43
|
+
},
|
|
44
|
+
faceDebugInfo: null
|
|
45
|
+
};
|
|
46
|
+
if (!(faceMetadata !== null && faceMetadata !== void 0 && faceMetadata.metadata)) {
|
|
47
|
+
return defaultStyles;
|
|
48
|
+
}
|
|
49
|
+
var _faceMetadata$metadat = faceMetadata.metadata,
|
|
50
|
+
videoProperties = _faceMetadata$metadat.videoProperties,
|
|
51
|
+
frames = _faceMetadata$metadat.frames;
|
|
52
|
+
|
|
53
|
+
// Find face data for current frame with interpolation support
|
|
54
|
+
var getFaceDataForFrame = function getFaceDataForFrame(targetFrame) {
|
|
55
|
+
if (!frames || frames.length === 0) return null;
|
|
56
|
+
|
|
57
|
+
// Find exact frame or closest frames for interpolation
|
|
58
|
+
var exactFrame = frames.find(function (f) {
|
|
59
|
+
return f.frame_index === targetFrame && f.face_detected;
|
|
60
|
+
});
|
|
61
|
+
if (exactFrame) return exactFrame.face_data;
|
|
62
|
+
if (!interpolate) {
|
|
63
|
+
// Find closest frame with face data
|
|
64
|
+
var _framesWithFaces = frames.filter(function (f) {
|
|
65
|
+
return f.face_detected && f.face_data;
|
|
66
|
+
});
|
|
67
|
+
if (_framesWithFaces.length === 0) return null;
|
|
68
|
+
return _framesWithFaces.reduce(function (closest, current) {
|
|
69
|
+
var closestDiff = Math.abs(closest.frame_index - targetFrame);
|
|
70
|
+
var currentDiff = Math.abs(current.frame_index - targetFrame);
|
|
71
|
+
return currentDiff < closestDiff ? current : closest;
|
|
72
|
+
}).face_data;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Interpolate between frames
|
|
76
|
+
var framesWithFaces = frames.filter(function (f) {
|
|
77
|
+
return f.face_detected && f.face_data;
|
|
78
|
+
}).sort(function (a, b) {
|
|
79
|
+
return a.frame_index - b.frame_index;
|
|
80
|
+
});
|
|
81
|
+
if (framesWithFaces.length === 0) return null;
|
|
82
|
+
if (framesWithFaces.length === 1) return framesWithFaces[0].face_data;
|
|
83
|
+
|
|
84
|
+
// Find surrounding frames
|
|
85
|
+
var prevFrame = null;
|
|
86
|
+
var nextFrame = null;
|
|
87
|
+
for (var i = 0; i < framesWithFaces.length; i++) {
|
|
88
|
+
if (framesWithFaces[i].frame_index <= targetFrame) {
|
|
89
|
+
prevFrame = framesWithFaces[i];
|
|
90
|
+
}
|
|
91
|
+
if (framesWithFaces[i].frame_index >= targetFrame && !nextFrame) {
|
|
92
|
+
nextFrame = framesWithFaces[i];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// If we only have frames on one side, use the closest one
|
|
97
|
+
if (!prevFrame) return nextFrame.face_data;
|
|
98
|
+
if (!nextFrame) return prevFrame.face_data;
|
|
99
|
+
|
|
100
|
+
// Interpolate between frames
|
|
101
|
+
var progress = (targetFrame - prevFrame.frame_index) / (nextFrame.frame_index - prevFrame.frame_index);
|
|
102
|
+
var _prevFrame$face_data$ = _slicedToArray(prevFrame.face_data.face_center, 2),
|
|
103
|
+
prevX = _prevFrame$face_data$[0],
|
|
104
|
+
prevY = _prevFrame$face_data$[1];
|
|
105
|
+
var _nextFrame$face_data$ = _slicedToArray(nextFrame.face_data.face_center, 2),
|
|
106
|
+
nextX = _nextFrame$face_data$[0],
|
|
107
|
+
nextY = _nextFrame$face_data$[1];
|
|
108
|
+
return {
|
|
109
|
+
face_center: [prevX + (nextX - prevX) * progress, prevY + (nextY - prevY) * progress],
|
|
110
|
+
// Use the closer frame's bbox for simplicity
|
|
111
|
+
face_bbox: progress < 0.5 ? prevFrame.face_data.face_bbox : nextFrame.face_data.face_bbox
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
var faceData = getFaceDataForFrame(currentFrame);
|
|
115
|
+
if (!faceData || !videoProperties) {
|
|
116
|
+
return defaultStyles;
|
|
117
|
+
}
|
|
118
|
+
var face_center = faceData.face_center;
|
|
119
|
+
var _face_center = _slicedToArray(face_center, 2),
|
|
120
|
+
faceCenterX = _face_center[0],
|
|
121
|
+
faceCenterY = _face_center[1];
|
|
122
|
+
var sourceWidth = videoProperties.width,
|
|
123
|
+
sourceHeight = videoProperties.height;
|
|
124
|
+
|
|
125
|
+
// Calculate how objectFit: "cover" affects the video
|
|
126
|
+
var sourceAspectRatio = sourceWidth / sourceHeight;
|
|
127
|
+
var containerAspectRatio = containerWidth / containerHeight;
|
|
128
|
+
var visibleVideoWidth, visibleVideoHeight;
|
|
129
|
+
var cropOffsetX = 0,
|
|
130
|
+
cropOffsetY = 0;
|
|
131
|
+
if (sourceAspectRatio > containerAspectRatio) {
|
|
132
|
+
// Source is wider than container - video will be cropped horizontally
|
|
133
|
+
// The video height will fill the container, width will be cropped
|
|
134
|
+
visibleVideoHeight = sourceHeight;
|
|
135
|
+
visibleVideoWidth = sourceHeight * containerAspectRatio;
|
|
136
|
+
cropOffsetX = (sourceWidth - visibleVideoWidth) / 2;
|
|
137
|
+
} else {
|
|
138
|
+
// Source is taller than container - video will be cropped vertically
|
|
139
|
+
// The video width will fill the container, height will be cropped
|
|
140
|
+
visibleVideoWidth = sourceWidth;
|
|
141
|
+
visibleVideoHeight = sourceWidth / containerAspectRatio;
|
|
142
|
+
cropOffsetY = (sourceHeight - visibleVideoHeight) / 2;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Check if face is within the visible (non-cropped) area
|
|
146
|
+
var faceInVisibleArea = faceCenterX >= cropOffsetX && faceCenterX <= cropOffsetX + visibleVideoWidth && faceCenterY >= cropOffsetY && faceCenterY <= cropOffsetY + visibleVideoHeight;
|
|
147
|
+
if (!faceInVisibleArea) {
|
|
148
|
+
console.warn('Face is outside visible video area after cropping');
|
|
149
|
+
return defaultStyles;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Calculate face position as percentage of the VISIBLE video area
|
|
153
|
+
var faceXInVisible = faceCenterX - cropOffsetX;
|
|
154
|
+
var faceYInVisible = faceCenterY - cropOffsetY;
|
|
155
|
+
var faceXPercent = faceXInVisible / visibleVideoWidth * 100;
|
|
156
|
+
var faceYPercent = faceYInVisible / visibleVideoHeight * 100;
|
|
157
|
+
|
|
158
|
+
// Calculate how much to translate the video to center the face
|
|
159
|
+
// If face is at 10.7% from left, we need to move video right by (50 - 10.7) = 39.3%
|
|
160
|
+
var translateXPercent = 50 - faceXPercent; // Positive = move right
|
|
161
|
+
var translateYPercent = 50 - faceYPercent; // Positive = move down
|
|
162
|
+
|
|
163
|
+
// Convert percentages to actual pixel values based on container size
|
|
164
|
+
var translateXPx = translateXPercent / 100 * containerWidth;
|
|
165
|
+
var translateYPx = translateYPercent / 100 * containerHeight;
|
|
166
|
+
|
|
167
|
+
// Debug logging
|
|
168
|
+
console.log('Face positioning debug:', {
|
|
169
|
+
faceCenterX: faceCenterX,
|
|
170
|
+
faceCenterY: faceCenterY,
|
|
171
|
+
visibleVideoWidth: visibleVideoWidth,
|
|
172
|
+
visibleVideoHeight: visibleVideoHeight,
|
|
173
|
+
cropOffsetX: cropOffsetX,
|
|
174
|
+
cropOffsetY: cropOffsetY,
|
|
175
|
+
faceXInVisible: faceXInVisible,
|
|
176
|
+
faceYInVisible: faceYInVisible,
|
|
177
|
+
faceXPercent: faceXPercent.toFixed(1),
|
|
178
|
+
faceYPercent: faceYPercent.toFixed(1),
|
|
179
|
+
translateXPercent: translateXPercent.toFixed(1),
|
|
180
|
+
translateYPercent: translateYPercent.toFixed(1),
|
|
181
|
+
translateXPx: translateXPx.toFixed(1),
|
|
182
|
+
translateYPx: translateYPx.toFixed(1)
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Combine face positioning with existing transforms
|
|
186
|
+
var faceTransform = "translate(".concat(translateXPx, "px, ").concat(translateYPx, "px)");
|
|
187
|
+
var combinedTransform = existingTransform ? "".concat(existingTransform, " ").concat(faceTransform) : faceTransform;
|
|
188
|
+
return {
|
|
189
|
+
styles: {
|
|
190
|
+
transformOrigin: "".concat(faceXPercent, "% ").concat(faceYPercent, "%"),
|
|
191
|
+
transform: combinedTransform
|
|
192
|
+
},
|
|
193
|
+
faceDebugInfo: {
|
|
194
|
+
faceXPercent: faceXPercent,
|
|
195
|
+
faceYPercent: faceYPercent,
|
|
196
|
+
objectPositionX: objectPositionX,
|
|
197
|
+
objectPositionY: objectPositionY,
|
|
198
|
+
faceCenterX: faceCenterX,
|
|
199
|
+
faceCenterY: faceCenterY,
|
|
200
|
+
sourceWidth: sourceWidth,
|
|
201
|
+
sourceHeight: sourceHeight,
|
|
202
|
+
containerWidth: containerWidth,
|
|
203
|
+
containerHeight: containerHeight,
|
|
204
|
+
visibleVideoWidth: visibleVideoWidth,
|
|
205
|
+
visibleVideoHeight: visibleVideoHeight,
|
|
206
|
+
cropOffsetX: cropOffsetX,
|
|
207
|
+
cropOffsetY: cropOffsetY,
|
|
208
|
+
faceXInVisible: faceXInVisible,
|
|
209
|
+
faceYInVisible: faceYInVisible
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
};
|