ugcinc-render 1.8.207 → 1.8.209

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/index.d.mts CHANGED
@@ -84,6 +84,10 @@ interface VideoSegment extends PictureSegment {
84
84
  type: 'video';
85
85
  /** Audio volume percentage 0-100 (0 = muted, 100 = full) (default: 100) */
86
86
  volume?: number;
87
+ /** Loop video when it's shorter than the segment duration (default: false) */
88
+ loop?: boolean;
89
+ /** Natural duration of the source video in milliseconds (required for loop to work) */
90
+ sourceDurationMs?: number;
87
91
  }
88
92
  /**
89
93
  * Image segment - static images or animated GIFs
package/dist/index.d.ts CHANGED
@@ -84,6 +84,10 @@ interface VideoSegment extends PictureSegment {
84
84
  type: 'video';
85
85
  /** Audio volume percentage 0-100 (0 = muted, 100 = full) (default: 100) */
86
86
  volume?: number;
87
+ /** Loop video when it's shorter than the segment duration (default: false) */
88
+ loop?: boolean;
89
+ /** Natural duration of the source video in milliseconds (required for loop to work) */
90
+ sourceDurationMs?: number;
87
91
  }
88
92
  /**
89
93
  * Image segment - static images or animated GIFs
package/dist/index.js CHANGED
@@ -1918,6 +1918,8 @@ function VideoElement({
1918
1918
  const rotation = segment.rotation ?? 0;
1919
1919
  const borderRadius = segment.borderRadius;
1920
1920
  const fadeIn = segment.fadeIn ?? 0;
1921
+ const loop = segment.loop ?? VIDEO_DEFAULTS.loop;
1922
+ const loopSourceDurationMs = segment.sourceDurationMs ?? (segment.duration?.type === "absolute" ? segment.duration.value : void 0);
1921
1923
  const x = segment.xOffset * scale;
1922
1924
  const y = segment.yOffset * scale;
1923
1925
  const width = segment.width * scale;
@@ -1958,16 +1960,22 @@ function VideoElement({
1958
1960
  height: "100%",
1959
1961
  objectFit: fitModeToCss2(fit)
1960
1962
  }), [fit]);
1961
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1963
+ const loopDurationInFrames = (0, import_react4.useMemo)(() => {
1964
+ if (!loop || !loopSourceDurationMs) return void 0;
1965
+ const effectiveDurationMs = loopSourceDurationMs / speed;
1966
+ return Math.max(1, Math.round(effectiveDurationMs / 1e3 * fps));
1967
+ }, [loop, loopSourceDurationMs, speed, fps]);
1968
+ const videoElement = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1962
1969
  import_remotion3.OffthreadVideo,
1963
1970
  {
1964
1971
  src,
1965
1972
  style: videoStyle,
1966
- trimBefore: startFromFrames,
1973
+ startFrom: startFromFrames,
1967
1974
  playbackRate: speed,
1968
1975
  volume
1969
1976
  }
1970
- ) });
1977
+ );
1978
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: containerStyle, children: loop && loopDurationInFrames ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_remotion3.Loop, { durationInFrames: loopDurationInFrames, children: videoElement }) : videoElement });
1971
1979
  }
1972
1980
 
1973
1981
  // src/compositions/VideoEditorComposition.tsx
package/dist/index.mjs CHANGED
@@ -943,7 +943,7 @@ import { AbsoluteFill as AbsoluteFill2, useCurrentFrame as useCurrentFrame3, use
943
943
 
944
944
  // src/components/VideoElement.tsx
945
945
  import { useMemo as useMemo4 } from "react";
946
- import { OffthreadVideo, useCurrentFrame as useCurrentFrame2, useVideoConfig as useVideoConfig2 } from "remotion";
946
+ import { OffthreadVideo, useCurrentFrame as useCurrentFrame2, useVideoConfig as useVideoConfig2, Loop } from "remotion";
947
947
  import { jsx as jsx4 } from "react/jsx-runtime";
948
948
  function fitModeToCss2(fit) {
949
949
  return fit;
@@ -964,6 +964,8 @@ function VideoElement({
964
964
  const rotation = segment.rotation ?? 0;
965
965
  const borderRadius = segment.borderRadius;
966
966
  const fadeIn = segment.fadeIn ?? 0;
967
+ const loop = segment.loop ?? VIDEO_DEFAULTS.loop;
968
+ const loopSourceDurationMs = segment.sourceDurationMs ?? (segment.duration?.type === "absolute" ? segment.duration.value : void 0);
967
969
  const x = segment.xOffset * scale;
968
970
  const y = segment.yOffset * scale;
969
971
  const width = segment.width * scale;
@@ -1004,16 +1006,22 @@ function VideoElement({
1004
1006
  height: "100%",
1005
1007
  objectFit: fitModeToCss2(fit)
1006
1008
  }), [fit]);
1007
- return /* @__PURE__ */ jsx4("div", { style: containerStyle, children: /* @__PURE__ */ jsx4(
1009
+ const loopDurationInFrames = useMemo4(() => {
1010
+ if (!loop || !loopSourceDurationMs) return void 0;
1011
+ const effectiveDurationMs = loopSourceDurationMs / speed;
1012
+ return Math.max(1, Math.round(effectiveDurationMs / 1e3 * fps));
1013
+ }, [loop, loopSourceDurationMs, speed, fps]);
1014
+ const videoElement = /* @__PURE__ */ jsx4(
1008
1015
  OffthreadVideo,
1009
1016
  {
1010
1017
  src,
1011
1018
  style: videoStyle,
1012
- trimBefore: startFromFrames,
1019
+ startFrom: startFromFrames,
1013
1020
  playbackRate: speed,
1014
1021
  volume
1015
1022
  }
1016
- ) });
1023
+ );
1024
+ return /* @__PURE__ */ jsx4("div", { style: containerStyle, children: loop && loopDurationInFrames ? /* @__PURE__ */ jsx4(Loop, { durationInFrames: loopDurationInFrames, children: videoElement }) : videoElement });
1017
1025
  }
1018
1026
 
1019
1027
  // src/compositions/VideoEditorComposition.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc-render",
3
- "version": "1.8.207",
3
+ "version": "1.8.209",
4
4
  "description": "Unified rendering package for UGC Inc - shared types, components, and compositions for pixel-perfect client/server rendering",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",