remotion 4.0.481 → 4.0.483

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 (41) hide show
  1. package/dist/cjs/CompositionManager.d.ts +1 -0
  2. package/dist/cjs/HtmlInCanvas.d.ts +74 -0
  3. package/dist/cjs/HtmlInCanvas.js +68 -26
  4. package/dist/cjs/Img.d.ts +7 -0
  5. package/dist/cjs/Img.js +5 -5
  6. package/dist/cjs/Interactive.d.ts +86 -1
  7. package/dist/cjs/Interactive.js +4 -2
  8. package/dist/cjs/Sequence.d.ts +1 -0
  9. package/dist/cjs/Sequence.js +25 -6
  10. package/dist/cjs/audio/AudioForPreview.js +3 -3
  11. package/dist/cjs/audio/html5-audio.js +6 -2
  12. package/dist/cjs/canvas-image/CanvasImage.d.ts +7 -0
  13. package/dist/cjs/canvas-image/CanvasImage.js +2 -2
  14. package/dist/cjs/easing.d.ts +5 -2
  15. package/dist/cjs/easing.js +19 -3
  16. package/dist/cjs/effects/Solid.d.ts +95 -0
  17. package/dist/cjs/effects/Solid.js +14 -5
  18. package/dist/cjs/effects/use-memoized-effects.js +1 -0
  19. package/dist/cjs/get-effective-visual-mode-value.js +2 -0
  20. package/dist/cjs/interactivity-schema.d.ts +116 -1
  21. package/dist/cjs/interactivity-schema.js +81 -1
  22. package/dist/cjs/internals.d.ts +88 -2
  23. package/dist/cjs/internals.js +2 -1
  24. package/dist/cjs/interpolate-keyframed-status.d.ts +2 -1
  25. package/dist/cjs/interpolate-keyframed-status.js +14 -11
  26. package/dist/cjs/interpolate.d.ts +3 -1
  27. package/dist/cjs/interpolate.js +56 -12
  28. package/dist/cjs/no-react.d.ts +7 -0
  29. package/dist/cjs/prefetch.js +15 -10
  30. package/dist/cjs/use-media-in-timeline.js +1 -0
  31. package/dist/cjs/use-schema.d.ts +2 -0
  32. package/dist/cjs/use-schema.js +20 -0
  33. package/dist/cjs/version.d.ts +1 -1
  34. package/dist/cjs/version.js +1 -1
  35. package/dist/cjs/video/VideoForPreview.js +2 -2
  36. package/dist/cjs/volume-position-state.d.ts +4 -4
  37. package/dist/cjs/volume-position-state.js +9 -9
  38. package/dist/esm/index.mjs +351 -79
  39. package/dist/esm/no-react.mjs +70 -11
  40. package/dist/esm/version.mjs +1 -1
  41. package/package.json +2 -2
@@ -1291,7 +1291,7 @@ var addSequenceStackTraces = (component) => {
1291
1291
  };
1292
1292
 
1293
1293
  // src/version.ts
1294
- var VERSION = "4.0.481";
1294
+ var VERSION = "4.0.483";
1295
1295
 
1296
1296
  // src/multiple-versions-warning.ts
1297
1297
  var checkMultipleRemotionVersions = () => {
@@ -1750,6 +1750,77 @@ var transformSchema = {
1750
1750
  }
1751
1751
  };
1752
1752
  var sequenceVisualStyleSchema = transformSchema;
1753
+ var textSchema = {
1754
+ "style.color": {
1755
+ type: "color",
1756
+ default: undefined,
1757
+ description: "Color"
1758
+ },
1759
+ "style.fontSize": {
1760
+ type: "number",
1761
+ default: undefined,
1762
+ min: 0,
1763
+ step: 1,
1764
+ description: "Font size",
1765
+ hiddenFromList: false
1766
+ },
1767
+ "style.lineHeight": {
1768
+ type: "number",
1769
+ default: undefined,
1770
+ min: 0,
1771
+ step: 0.05,
1772
+ description: "Line height",
1773
+ hiddenFromList: false
1774
+ },
1775
+ "style.fontWeight": {
1776
+ type: "enum",
1777
+ default: "400",
1778
+ description: "Font weight",
1779
+ variants: {
1780
+ "100": {},
1781
+ "200": {},
1782
+ "300": {},
1783
+ "400": {},
1784
+ "500": {},
1785
+ "600": {},
1786
+ "700": {},
1787
+ "800": {},
1788
+ "900": {},
1789
+ normal: {},
1790
+ bold: {}
1791
+ }
1792
+ },
1793
+ "style.fontStyle": {
1794
+ type: "enum",
1795
+ default: "normal",
1796
+ description: "Font style",
1797
+ variants: {
1798
+ normal: {},
1799
+ italic: {},
1800
+ oblique: {}
1801
+ }
1802
+ },
1803
+ "style.textAlign": {
1804
+ type: "enum",
1805
+ default: "left",
1806
+ description: "Text align",
1807
+ variants: {
1808
+ left: {},
1809
+ center: {},
1810
+ right: {},
1811
+ justify: {},
1812
+ start: {},
1813
+ end: {}
1814
+ }
1815
+ },
1816
+ "style.letterSpacing": {
1817
+ type: "number",
1818
+ default: undefined,
1819
+ step: 0.1,
1820
+ description: "Letter spacing",
1821
+ hiddenFromList: false
1822
+ }
1823
+ };
1753
1824
  var premountSchema = {
1754
1825
  premountFor: {
1755
1826
  type: "number",
@@ -1808,6 +1879,13 @@ var fromField = {
1808
1879
  step: 1,
1809
1880
  hiddenFromList: true
1810
1881
  };
1882
+ var trimBeforeField = {
1883
+ type: "number",
1884
+ default: 0,
1885
+ min: 0,
1886
+ step: 1,
1887
+ hiddenFromList: true
1888
+ };
1811
1889
  var freezeField = {
1812
1890
  type: "number",
1813
1891
  default: null,
@@ -1817,6 +1895,7 @@ var freezeField = {
1817
1895
  var baseSchema = {
1818
1896
  durationInFrames: durationInFramesField,
1819
1897
  from: fromField,
1898
+ trimBefore: trimBeforeField,
1820
1899
  freeze: freezeField,
1821
1900
  hidden: hiddenField,
1822
1901
  name: sequenceNameField,
@@ -1836,6 +1915,7 @@ var sequenceSchema = {
1836
1915
  };
1837
1916
  var baseSchemaWithoutFrom = {
1838
1917
  durationInFrames: durationInFramesField,
1918
+ trimBefore: trimBeforeField,
1839
1919
  freeze: freezeField,
1840
1920
  hidden: hiddenField,
1841
1921
  name: sequenceNameField,
@@ -2513,6 +2593,35 @@ function findRange(input, inputRange) {
2513
2593
  return i - 1;
2514
2594
  }
2515
2595
  var defaultEasing = (num) => num;
2596
+ var shouldExtendRightForEasing = (easing) => {
2597
+ return easing.remotionShouldExtendRight === true;
2598
+ };
2599
+ var resolveEasingForSegment = ({
2600
+ easing,
2601
+ segmentIndex
2602
+ }) => {
2603
+ if (easing === undefined) {
2604
+ return defaultEasing;
2605
+ }
2606
+ if (typeof easing === "function") {
2607
+ return easing;
2608
+ }
2609
+ return easing[segmentIndex];
2610
+ };
2611
+ var interpolateSegment = ({
2612
+ input,
2613
+ inputRange,
2614
+ outputRange,
2615
+ easing,
2616
+ extrapolateLeft,
2617
+ extrapolateRight
2618
+ }) => {
2619
+ return interpolateFunction(input, inputRange, outputRange, {
2620
+ easing,
2621
+ extrapolateLeft,
2622
+ extrapolateRight: input > inputRange[1] && extrapolateRight === "clamp" && shouldExtendRightForEasing(easing) ? "extend" : extrapolateRight
2623
+ });
2624
+ };
2516
2625
  var interpolateNumber = ({
2517
2626
  input,
2518
2627
  inputRange,
@@ -2523,15 +2632,6 @@ var interpolateNumber = ({
2523
2632
  return outputRange[0];
2524
2633
  }
2525
2634
  const easingOption = options?.easing;
2526
- const resolveEasingForSegment = (segmentIndex) => {
2527
- if (easingOption === undefined) {
2528
- return defaultEasing;
2529
- }
2530
- if (typeof easingOption === "function") {
2531
- return easingOption;
2532
- }
2533
- return easingOption[segmentIndex];
2534
- };
2535
2635
  let extrapolateLeft = "extend";
2536
2636
  if (options?.extrapolateLeft !== undefined) {
2537
2637
  extrapolateLeft = options.extrapolateLeft;
@@ -2542,11 +2642,41 @@ var interpolateNumber = ({
2542
2642
  }
2543
2643
  const posterizedInput = options?.posterize === undefined ? input : Math.floor(input / options.posterize) * options.posterize;
2544
2644
  const range = findRange(posterizedInput, inputRange);
2545
- return interpolateFunction(posterizedInput, [inputRange[range], inputRange[range + 1]], [outputRange[range], outputRange[range + 1]], {
2546
- easing: resolveEasingForSegment(range),
2645
+ const easing = resolveEasingForSegment({
2646
+ easing: easingOption,
2647
+ segmentIndex: range
2648
+ });
2649
+ let result = interpolateSegment({
2650
+ input: posterizedInput,
2651
+ inputRange: [inputRange[range], inputRange[range + 1]],
2652
+ outputRange: [outputRange[range], outputRange[range + 1]],
2653
+ easing,
2547
2654
  extrapolateLeft,
2548
2655
  extrapolateRight
2549
2656
  });
2657
+ for (let segmentIndex = 0;segmentIndex < range; segmentIndex++) {
2658
+ const previousEasing = resolveEasingForSegment({
2659
+ easing: easingOption,
2660
+ segmentIndex
2661
+ });
2662
+ if (!shouldExtendRightForEasing(previousEasing)) {
2663
+ continue;
2664
+ }
2665
+ const previousSegmentEnd = inputRange[segmentIndex + 1];
2666
+ if (posterizedInput <= previousSegmentEnd) {
2667
+ continue;
2668
+ }
2669
+ const continuedSegmentValue = interpolateSegment({
2670
+ input: posterizedInput,
2671
+ inputRange: [inputRange[segmentIndex], previousSegmentEnd],
2672
+ outputRange: [outputRange[segmentIndex], outputRange[segmentIndex + 1]],
2673
+ easing: previousEasing,
2674
+ extrapolateLeft,
2675
+ extrapolateRight: "extend"
2676
+ });
2677
+ result += continuedSegmentValue - outputRange[segmentIndex + 1];
2678
+ }
2679
+ return result;
2550
2680
  };
2551
2681
  var interpolateString = ({
2552
2682
  input,
@@ -3032,21 +3162,40 @@ class Easing {
3032
3162
  static back(s = 1.70158) {
3033
3163
  return (t) => t * t * ((s + 1) * t - s);
3034
3164
  }
3035
- static spring(config = {}) {
3036
- return (t) => {
3165
+ static spring({
3166
+ allowTail = false,
3167
+ durationRestThreshold,
3168
+ ...config
3169
+ } = {}) {
3170
+ const easing = (t) => {
3037
3171
  if (t <= 0) {
3038
3172
  return 0;
3039
3173
  }
3040
- if (t >= 1) {
3174
+ if (!allowTail && t >= 1) {
3041
3175
  return 1;
3042
3176
  }
3177
+ if (allowTail) {
3178
+ return spring({
3179
+ fps: springEasingDurationInFrames,
3180
+ frame: t * measureSpring({
3181
+ fps: springEasingDurationInFrames,
3182
+ config,
3183
+ threshold: durationRestThreshold
3184
+ }),
3185
+ config
3186
+ });
3187
+ }
3043
3188
  return spring({
3044
3189
  fps: springEasingDurationInFrames,
3045
3190
  frame: t * springEasingDurationInFrames,
3046
3191
  config,
3047
- durationInFrames: springEasingDurationInFrames
3192
+ durationInFrames: springEasingDurationInFrames,
3193
+ durationRestThreshold
3048
3194
  });
3049
3195
  };
3196
+ return Object.assign(easing, {
3197
+ remotionShouldExtendRight: allowTail
3198
+ });
3050
3199
  }
3051
3200
  static bounce(t) {
3052
3201
  const u = clampUnit(t);
@@ -3581,25 +3730,31 @@ var interpolateColors = (input, inputRange, outputRange, options) => {
3581
3730
  };
3582
3731
 
3583
3732
  // src/interpolate-keyframed-status.ts
3584
- var easingToFn = (e) => {
3585
- switch (e.type) {
3733
+ var easingToFn = ({
3734
+ easing,
3735
+ forceSpringAllowTail
3736
+ }) => {
3737
+ switch (easing.type) {
3586
3738
  case "linear":
3587
3739
  return Easing.linear;
3588
3740
  case "spring":
3589
3741
  return Easing.spring({
3590
- damping: e.damping,
3591
- mass: e.mass,
3592
- overshootClamping: e.overshootClamping,
3593
- stiffness: e.stiffness
3742
+ allowTail: forceSpringAllowTail ?? easing.allowTail ?? undefined,
3743
+ damping: easing.damping,
3744
+ durationRestThreshold: easing.durationRestThreshold ?? undefined,
3745
+ mass: easing.mass,
3746
+ overshootClamping: easing.overshootClamping,
3747
+ stiffness: easing.stiffness
3594
3748
  });
3595
3749
  case "bezier":
3596
- return bezier(e.x1, e.y1, e.x2, e.y2);
3750
+ return bezier(easing.x1, easing.y1, easing.x2, easing.y2);
3597
3751
  default:
3598
- throw new TypeError(`Unsupported easing: ${JSON.stringify(e)}`);
3752
+ throw new TypeError(`Unsupported easing: ${JSON.stringify(easing)}`);
3599
3753
  }
3600
3754
  };
3601
3755
  var interpolateKeyframedStatus = ({
3602
3756
  frame,
3757
+ forceSpringAllowTail,
3603
3758
  status
3604
3759
  }) => {
3605
3760
  const { keyframes, easing, clamping, interpolationFunction } = status;
@@ -3618,7 +3773,7 @@ var interpolateKeyframedStatus = ({
3618
3773
  }
3619
3774
  try {
3620
3775
  return interpolateColors(frame, inputRange, outputs, {
3621
- easing: easing.map(easingToFn),
3776
+ easing: easing.map((e) => easingToFn({ easing: e, forceSpringAllowTail })),
3622
3777
  posterize: status.posterize
3623
3778
  });
3624
3779
  } catch {
@@ -3630,7 +3785,7 @@ var interpolateKeyframedStatus = ({
3630
3785
  }
3631
3786
  try {
3632
3787
  return interpolate(frame, inputRange, outputs, {
3633
- easing: easing.map(easingToFn),
3788
+ easing: easing.map((e) => easingToFn({ easing: e, forceSpringAllowTail })),
3634
3789
  extrapolateLeft: clamping.left,
3635
3790
  extrapolateRight: clamping.right,
3636
3791
  posterize: status.posterize
@@ -3655,6 +3810,7 @@ var resolveDragOverrideValue = ({
3655
3810
  return { type: "none" };
3656
3811
  }
3657
3812
  const interpolated = interpolateKeyframedStatus({
3813
+ forceSpringAllowTail: null,
3658
3814
  frame,
3659
3815
  status: dragOverrideValue.status
3660
3816
  });
@@ -3680,6 +3836,7 @@ var getEffectiveVisualModeValue = ({
3680
3836
  if (propStatus.status === "keyframed") {
3681
3837
  if (frame !== null) {
3682
3838
  return interpolateKeyframedStatus({
3839
+ forceSpringAllowTail: null,
3683
3840
  frame,
3684
3841
  status: propStatus
3685
3842
  });
@@ -3753,6 +3910,7 @@ var resolvePropStatusOverrides = (propStatus, frame) => {
3753
3910
  }
3754
3911
  if (status.status === "keyframed") {
3755
3912
  const value = interpolateKeyframedStatus({
3913
+ forceSpringAllowTail: null,
3756
3914
  frame,
3757
3915
  status
3758
3916
  });
@@ -3934,6 +4092,17 @@ var findPropsToDelete = ({
3934
4092
  var DEFAULT_LINEAR_EASING = {
3935
4093
  type: "linear"
3936
4094
  };
4095
+ var getEasingIndexToDuplicate = ({
4096
+ insertedKeyframeIndex,
4097
+ easingLength,
4098
+ keyframeCount
4099
+ }) => {
4100
+ const isSplittingExistingSegment = insertedKeyframeIndex > 0 && insertedKeyframeIndex < keyframeCount - 1;
4101
+ if (!isSplittingExistingSegment || easingLength === 0) {
4102
+ return null;
4103
+ }
4104
+ return Math.min(insertedKeyframeIndex - 1, easingLength - 1);
4105
+ };
3937
4106
  var makeStaticDragOverride = (value) => {
3938
4107
  return { type: "static", value };
3939
4108
  };
@@ -3945,6 +4114,16 @@ var makeKeyframedDragOverride = ({
3945
4114
  const existingIndex = status.keyframes.findIndex((keyframe) => keyframe.frame === frame);
3946
4115
  const keyframes = existingIndex === -1 ? [...status.keyframes, { frame, value }].sort((first, second) => first.frame - second.frame) : status.keyframes.map((keyframe, index) => index === existingIndex ? { frame, value } : keyframe);
3947
4116
  const easing = [...status.easing];
4117
+ if (existingIndex === -1) {
4118
+ const insertedKeyframeIndex = keyframes.findIndex((keyframe) => keyframe.frame === frame);
4119
+ const easingIndexToDuplicate = getEasingIndexToDuplicate({
4120
+ insertedKeyframeIndex,
4121
+ easingLength: easing.length,
4122
+ keyframeCount: keyframes.length
4123
+ });
4124
+ const easingToDuplicate = easingIndexToDuplicate === null ? DEFAULT_LINEAR_EASING : easing[easingIndexToDuplicate];
4125
+ easing.splice(insertedKeyframeIndex, 0, easingToDuplicate);
4126
+ }
3948
4127
  while (easing.length < keyframes.length - 1) {
3949
4128
  easing.push(DEFAULT_LINEAR_EASING);
3950
4129
  }
@@ -4016,6 +4195,7 @@ var computeEffectiveSchemaValuesDotNotation = ({
4016
4195
  value = dragOverride.value;
4017
4196
  } else if (frame !== null) {
4018
4197
  const interpolated = interpolateKeyframedStatus({
4198
+ forceSpringAllowTail: null,
4019
4199
  frame,
4020
4200
  status
4021
4201
  });
@@ -4198,6 +4378,7 @@ import { jsx as jsx12 } from "react/jsx-runtime";
4198
4378
  var EMPTY_EFFECTS = [];
4199
4379
  var RegularSequenceRefForwardingFunction = ({
4200
4380
  from = 0,
4381
+ trimBefore = 0,
4201
4382
  freeze,
4202
4383
  durationInFrames = Infinity,
4203
4384
  children,
@@ -4222,7 +4403,6 @@ var RegularSequenceRefForwardingFunction = ({
4222
4403
  const parentSequence = useContext17(SequenceContext);
4223
4404
  const { rootId } = useTimelineContext();
4224
4405
  const cumulatedFrom = parentSequence ? parentSequence.cumulatedFrom + parentSequence.relativeFrom : 0;
4225
- const absoluteFrom = (parentSequence?.absoluteFrom ?? 0) + from;
4226
4406
  const nonce = useNonce();
4227
4407
  if (layout !== "absolute-fill" && layout !== "none") {
4228
4408
  throw new TypeError(`The layout prop of <Sequence /> expects either "absolute-fill" or "none", but you passed: ${layout}`);
@@ -4242,6 +4422,18 @@ var RegularSequenceRefForwardingFunction = ({
4242
4422
  if (!Number.isFinite(from)) {
4243
4423
  throw new TypeError(`The "from" prop of a sequence must be finite, but got ${from}.`);
4244
4424
  }
4425
+ if (typeof trimBefore !== "number") {
4426
+ throw new TypeError(`You passed to the "trimBefore" prop of your <Sequence> an argument of type ${typeof trimBefore}, but it must be a number.`);
4427
+ }
4428
+ if (trimBefore < 0) {
4429
+ throw new TypeError(`The "trimBefore" prop of <Sequence /> must be greater than or equal to 0, but got ${trimBefore}.`);
4430
+ }
4431
+ if (Number.isNaN(trimBefore)) {
4432
+ throw new TypeError('The "trimBefore" prop of <Sequence /> must be a real number, but it is NaN.');
4433
+ }
4434
+ if (!Number.isFinite(trimBefore)) {
4435
+ throw new TypeError(`The "trimBefore" prop of <Sequence /> must be finite, but it is ${trimBefore}.`);
4436
+ }
4245
4437
  if (typeof freeze !== "undefined" && freeze !== null) {
4246
4438
  if (typeof freeze !== "number") {
4247
4439
  throw new TypeError(`The "freeze" prop of <Sequence /> must be a number, but is of type ${typeof freeze}.`);
@@ -4255,7 +4447,9 @@ var RegularSequenceRefForwardingFunction = ({
4255
4447
  }
4256
4448
  const absoluteFrame = useTimelinePosition();
4257
4449
  const videoConfig = useVideoConfig();
4258
- const parentSequenceDuration = parentSequence ? Math.min(parentSequence.durationInFrames - from, durationInFrames) : durationInFrames;
4450
+ const effectiveRelativeFrom = from - trimBefore;
4451
+ const absoluteFrom = (parentSequence?.absoluteFrom ?? 0) + effectiveRelativeFrom;
4452
+ const parentSequenceDuration = parentSequence ? Math.min(parentSequence.durationInFrames - effectiveRelativeFrom, durationInFrames) : durationInFrames;
4259
4453
  const actualDurationInFrames = Math.max(0, Math.min(videoConfig.durationInFrames - from, parentSequenceDuration));
4260
4454
  const { registerSequence, unregisterSequence } = useContext17(SequenceManager);
4261
4455
  const wrapperRefForOutline = useRef6(null);
@@ -4266,7 +4460,7 @@ var RegularSequenceRefForwardingFunction = ({
4266
4460
  const postmounting = useMemo14(() => {
4267
4461
  return parentSequence?.postmounting || Boolean(other._remotionInternalIsPostmounting);
4268
4462
  }, [other._remotionInternalIsPostmounting, parentSequence?.postmounting]);
4269
- const currentSequenceStart = cumulatedFrom + from;
4463
+ const currentSequenceStart = cumulatedFrom + effectiveRelativeFrom;
4270
4464
  const parentSequenceStart = parentSequence ? parentSequence.cumulatedFrom + parentSequence.relativeFrom : 0;
4271
4465
  const parentFirstFrame = parentSequence ? parentSequenceStart - parentSequence.cumulatedNegativeFrom : 0;
4272
4466
  const firstFrame = Math.max(0, parentFirstFrame, currentSequenceStart);
@@ -4275,7 +4469,7 @@ var RegularSequenceRefForwardingFunction = ({
4275
4469
  return {
4276
4470
  absoluteFrom,
4277
4471
  cumulatedFrom,
4278
- relativeFrom: from,
4472
+ relativeFrom: effectiveRelativeFrom,
4279
4473
  cumulatedNegativeFrom,
4280
4474
  durationInFrames: actualDurationInFrames,
4281
4475
  parentFrom: parentSequence?.relativeFrom ?? 0,
@@ -4290,7 +4484,7 @@ var RegularSequenceRefForwardingFunction = ({
4290
4484
  }, [
4291
4485
  cumulatedFrom,
4292
4486
  absoluteFrom,
4293
- from,
4487
+ effectiveRelativeFrom,
4294
4488
  actualDurationInFrames,
4295
4489
  parentSequence,
4296
4490
  id,
@@ -4312,6 +4506,7 @@ var RegularSequenceRefForwardingFunction = ({
4312
4506
  const stackRef = useRef6(null);
4313
4507
  stackRef.current = stack ?? inheritedStack;
4314
4508
  const registeredFrozenFrame = typeof freeze === "number" ? freeze : null;
4509
+ const registeredTrimBefore = trimBefore === 0 ? null : trimBefore;
4315
4510
  const parentCumulatedNegativeFrom = parentSequence?.cumulatedNegativeFrom ?? 0;
4316
4511
  const startMediaFrom = isMedia && isMedia.type !== "image" ? isMedia.data.startMediaFrom + parentCumulatedNegativeFrom - cumulatedNegativeFrom : null;
4317
4512
  const mediaFrameAtSequenceZero = isMedia && isMedia.type !== "image" ? isMedia.data.startMediaFrom + parentCumulatedNegativeFrom : null;
@@ -4330,6 +4525,7 @@ var RegularSequenceRefForwardingFunction = ({
4330
4525
  documentationLink: resolvedDocumentationLink,
4331
4526
  duration: actualDurationInFrames,
4332
4527
  from,
4528
+ trimBefore: registeredTrimBefore,
4333
4529
  id,
4334
4530
  loopDisplay,
4335
4531
  nonce: nonce.get(),
@@ -4354,6 +4550,7 @@ var RegularSequenceRefForwardingFunction = ({
4354
4550
  doesVolumeChange: isMedia.data.doesVolumeChange,
4355
4551
  duration: actualDurationInFrames,
4356
4552
  from,
4553
+ trimBefore: registeredTrimBefore,
4357
4554
  id,
4358
4555
  loopDisplay,
4359
4556
  nonce: nonce.get(),
@@ -4379,6 +4576,7 @@ var RegularSequenceRefForwardingFunction = ({
4379
4576
  }
4380
4577
  registerSequence({
4381
4578
  from,
4579
+ trimBefore: registeredTrimBefore,
4382
4580
  duration: actualDurationInFrames,
4383
4581
  id,
4384
4582
  displayName: timelineClipName,
@@ -4412,6 +4610,8 @@ var RegularSequenceRefForwardingFunction = ({
4412
4610
  actualDurationInFrames,
4413
4611
  rootId,
4414
4612
  from,
4613
+ trimBefore,
4614
+ registeredTrimBefore,
4415
4615
  showInTimeline,
4416
4616
  nonce,
4417
4617
  loopDisplay,
@@ -5759,13 +5959,15 @@ var prefetch = (src, options) => {
5759
5959
  resolve = res;
5760
5960
  reject = rej;
5761
5961
  });
5962
+ waitUntilDone.catch(() => {
5963
+ return;
5964
+ });
5762
5965
  const controller = new AbortController;
5763
- let canBeAborted = true;
5966
+ let reader = null;
5764
5967
  fetch(srcWithoutHash, {
5765
5968
  signal: controller.signal,
5766
5969
  credentials: options?.credentials ?? undefined
5767
5970
  }).then((res) => {
5768
- canBeAborted = false;
5769
5971
  if (canceled) {
5770
5972
  return null;
5771
5973
  }
@@ -5781,15 +5983,16 @@ var prefetch = (src, options) => {
5781
5983
  if (!res.body) {
5782
5984
  throw new Error(`HTTP response of ${srcWithoutHash} has no body`);
5783
5985
  }
5784
- const reader = res.body.getReader();
5986
+ const responseReader = res.body.getReader();
5987
+ reader = responseReader;
5785
5988
  return getBlobFromReader({
5786
- reader,
5989
+ reader: responseReader,
5787
5990
  contentType: options?.contentType ?? headerContentType ?? null,
5788
5991
  contentLength: res.headers.get("Content-Length") ? parseInt(res.headers.get("Content-Length"), 10) : null,
5789
5992
  onProgress: options?.onProgress
5790
5993
  });
5791
5994
  }).then((buf) => {
5792
- if (!buf) {
5995
+ if (!buf || canceled) {
5793
5996
  return;
5794
5997
  }
5795
5998
  const actualBlob = options?.contentType ? new Blob([buf], { type: options.contentType }) : buf;
@@ -5837,12 +6040,18 @@ var prefetch = (src, options) => {
5837
6040
  return copy;
5838
6041
  });
5839
6042
  } else {
5840
- canceled = true;
5841
- if (canBeAborted) {
5842
- try {
5843
- controller.abort(new Error("free() called"));
5844
- } catch {}
6043
+ if (canceled) {
6044
+ return;
5845
6045
  }
6046
+ canceled = true;
6047
+ const cancellationError = new Error("free() called");
6048
+ reject(cancellationError);
6049
+ try {
6050
+ controller.abort(cancellationError);
6051
+ } catch {}
6052
+ reader?.cancel(cancellationError).catch(() => {
6053
+ return;
6054
+ });
5846
6055
  }
5847
6056
  },
5848
6057
  waitUntilDone: () => {
@@ -7084,6 +7293,7 @@ var useMediaInTimeline = ({
7084
7293
  id,
7085
7294
  duration,
7086
7295
  from: 0,
7296
+ trimBefore: null,
7087
7297
  parent: parentSequence?.id ?? null,
7088
7298
  displayName: finalDisplayName,
7089
7299
  documentationLink,
@@ -8000,11 +8210,11 @@ var useMediaTag = ({
8000
8210
  // src/volume-position-state.ts
8001
8211
  import { createContext as createContext22, useContext as useContext27, useMemo as useMemo26 } from "react";
8002
8212
  var MediaVolumeContext = createContext22({
8003
- mediaMuted: false,
8213
+ playerMuted: false,
8004
8214
  mediaVolume: 1
8005
8215
  });
8006
8216
  var SetMediaVolumeContext = createContext22({
8007
- setMediaMuted: () => {
8217
+ setPlayerMuted: () => {
8008
8218
  throw new Error("default");
8009
8219
  },
8010
8220
  setMediaVolume: () => {
@@ -8018,12 +8228,12 @@ var useMediaVolumeState = () => {
8018
8228
  return [mediaVolume, setMediaVolume];
8019
8229
  }, [mediaVolume, setMediaVolume]);
8020
8230
  };
8021
- var useMediaMutedState = () => {
8022
- const { mediaMuted } = useContext27(MediaVolumeContext);
8023
- const { setMediaMuted } = useContext27(SetMediaVolumeContext);
8231
+ var usePlayerMutedState = () => {
8232
+ const { playerMuted } = useContext27(MediaVolumeContext);
8233
+ const { setPlayerMuted } = useContext27(SetMediaVolumeContext);
8024
8234
  return useMemo26(() => {
8025
- return [mediaMuted, setMediaMuted];
8026
- }, [mediaMuted, setMediaMuted]);
8235
+ return [playerMuted, setPlayerMuted];
8236
+ }, [playerMuted, setPlayerMuted]);
8027
8237
  };
8028
8238
 
8029
8239
  // src/volume-safeguard.ts
@@ -8074,7 +8284,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
8074
8284
  throw new Error("typecheck error");
8075
8285
  }
8076
8286
  const [mediaVolume] = useMediaVolumeState();
8077
- const [mediaMuted] = useMediaMutedState();
8287
+ const [playerMuted] = usePlayerMutedState();
8078
8288
  const volumePropFrame = useFrameForVolumeProp(loopVolumeCurveBehavior ?? "repeat");
8079
8289
  if (!src) {
8080
8290
  throw new TypeError("No 'src' was passed to <Html5Audio>.");
@@ -8095,7 +8305,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
8095
8305
  });
8096
8306
  const propsToPass = useMemo27(() => {
8097
8307
  return {
8098
- muted: muted || mediaMuted || userPreferredVolume <= 0,
8308
+ muted: muted || playerMuted || userPreferredVolume <= 0,
8099
8309
  src: preloadedSrc,
8100
8310
  loop: _remotionInternalNativeLoopPassed,
8101
8311
  crossOrigin: crossOriginValue,
@@ -8103,7 +8313,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
8103
8313
  };
8104
8314
  }, [
8105
8315
  _remotionInternalNativeLoopPassed,
8106
- mediaMuted,
8316
+ playerMuted,
8107
8317
  muted,
8108
8318
  nativeProps,
8109
8319
  preloadedSrc,
@@ -8366,6 +8576,7 @@ var AudioForRendering = forwardRef6(AudioForRenderingRefForwardingFunction);
8366
8576
  import { jsx as jsx23 } from "react/jsx-runtime";
8367
8577
  var AudioRefForwardingFunction = (props, ref) => {
8368
8578
  const audioTagsContext = useContext30(SharedAudioTagsContext);
8579
+ const propsWithFreeze = props;
8369
8580
  const {
8370
8581
  startFrom,
8371
8582
  endAt,
@@ -8376,14 +8587,18 @@ var AudioRefForwardingFunction = (props, ref) => {
8376
8587
  pauseWhenBuffering,
8377
8588
  showInTimeline,
8378
8589
  onError: onRemotionError,
8590
+ freeze,
8379
8591
  ...otherProps
8380
- } = props;
8381
- const { loop, ...propsOtherThanLoop } = props;
8592
+ } = propsWithFreeze;
8593
+ const { loop, freeze: _freeze, ...propsOtherThanLoop } = propsWithFreeze;
8382
8594
  const { fps } = useVideoConfig();
8383
8595
  const environment = useRemotionEnvironment();
8384
8596
  if (environment.isClientSideRendering) {
8385
8597
  throw new Error("<Html5Audio> is not supported in @remotion/web-renderer. Use <Audio> from @remotion/media instead. See https://remotion.dev/docs/client-side-rendering/limitations");
8386
8598
  }
8599
+ if (typeof freeze !== "undefined") {
8600
+ throw new TypeError('The "freeze" prop is not supported on <Html5Audio />. Use <Sequence freeze={...}> to freeze media playback.');
8601
+ }
8387
8602
  const { durations, setDurations } = useContext30(DurationsContext);
8388
8603
  if (typeof props.src !== "string") {
8389
8604
  throw new TypeError(`The \`<Html5Audio>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
@@ -8526,6 +8741,15 @@ var solidSchema = {
8526
8741
  description: "Height",
8527
8742
  hiddenFromList: false
8528
8743
  },
8744
+ pixelDensity: {
8745
+ type: "number",
8746
+ min: 1,
8747
+ max: 3,
8748
+ step: 0.1,
8749
+ default: 1,
8750
+ description: "Pixel density",
8751
+ hiddenFromList: false
8752
+ },
8529
8753
  ...transformSchema
8530
8754
  };
8531
8755
  var SolidInner = ({
@@ -8642,6 +8866,7 @@ var SolidOuter = forwardRef8(({
8642
8866
  style,
8643
8867
  name,
8644
8868
  from,
8869
+ trimBefore,
8645
8870
  freeze,
8646
8871
  hidden,
8647
8872
  showInTimeline,
@@ -8656,6 +8881,7 @@ var SolidOuter = forwardRef8(({
8656
8881
  return /* @__PURE__ */ jsx24(Sequence, {
8657
8882
  layout: "none",
8658
8883
  from,
8884
+ trimBefore,
8659
8885
  freeze,
8660
8886
  hidden,
8661
8887
  showInTimeline,
@@ -8733,6 +8959,10 @@ function resolveHtmlInCanvasPixelDensity(pixelDensity) {
8733
8959
  }
8734
8960
  return pixelDensity;
8735
8961
  }
8962
+ var isMissingPaintRecordError = (error2) => {
8963
+ return error2 instanceof DOMException && error2.name === "InvalidStateError";
8964
+ };
8965
+ var missingPaintRecordMessage = "HtmlInCanvas: Expected the element to be inside the viewport during rendering, but Chrome had no cached paint record for it.";
8736
8966
  var resizeOffscreenCanvas = ({
8737
8967
  offscreen,
8738
8968
  width,
@@ -8776,6 +9006,7 @@ var HtmlInCanvasContent = forwardRef9(({
8776
9006
  const canvasWidth = Math.ceil(width * resolvedPixelDensity);
8777
9007
  const canvasHeight = Math.ceil(height * resolvedPixelDensity);
8778
9008
  const { continueRender: continueRender2, cancelRender: cancelRender2 } = useDelayRender();
9009
+ const { isRendering } = useRemotionEnvironment();
8779
9010
  if (!isHtmlInCanvasSupported()) {
8780
9011
  cancelRender2(new Error(HTML_IN_CANVAS_UNSUPPORTED_MESSAGE));
8781
9012
  }
@@ -8824,34 +9055,53 @@ var HtmlInCanvasContent = forwardRef9(({
8824
9055
  if (!placeholderCanvas) {
8825
9056
  throw new Error("Canvas not found");
8826
9057
  }
8827
- const offscreen2d = offscreen.getContext("2d");
8828
- if (!offscreen2d) {
8829
- throw new Error("Failed to acquire 2D context for <HtmlInCanvas> offscreen canvas");
8830
- }
8831
9058
  const handle = delayRender("onPaint");
8832
9059
  if (!initializedRef.current) {
8833
- initializedRef.current = true;
8834
- const initImage = placeholderCanvas.captureElementImage(element);
8835
- const currentOnInit = onInitRef.current;
8836
- if (currentOnInit) {
8837
- const cleanup = await currentOnInit({
8838
- canvas: offscreen,
8839
- element,
8840
- elementImage: initImage,
8841
- pixelDensity: resolvedPixelDensity
8842
- });
8843
- if (typeof cleanup !== "function") {
8844
- throw new Error("HtmlInCanvas: when `onInit` is provided, it must return a cleanup function, or a Promise that resolves to one.");
8845
- }
8846
- if (unmountedRef.current) {
8847
- cleanup();
9060
+ let initImage = null;
9061
+ try {
9062
+ initImage = placeholderCanvas.captureElementImage(element);
9063
+ } catch (error2) {
9064
+ if (isMissingPaintRecordError(error2) && !isRendering) {} else if (isMissingPaintRecordError(error2)) {
9065
+ throw new Error(missingPaintRecordMessage);
8848
9066
  } else {
8849
- onInitCleanupRef.current = cleanup;
9067
+ throw error2;
9068
+ }
9069
+ }
9070
+ if (initImage) {
9071
+ initializedRef.current = true;
9072
+ const currentOnInit = onInitRef.current;
9073
+ if (currentOnInit) {
9074
+ const cleanup = await currentOnInit({
9075
+ canvas: offscreen,
9076
+ element,
9077
+ elementImage: initImage,
9078
+ pixelDensity: resolvedPixelDensity
9079
+ });
9080
+ if (typeof cleanup !== "function") {
9081
+ throw new Error("HtmlInCanvas: when `onInit` is provided, it must return a cleanup function, or a Promise that resolves to one.");
9082
+ }
9083
+ if (unmountedRef.current) {
9084
+ cleanup();
9085
+ } else {
9086
+ onInitCleanupRef.current = cleanup;
9087
+ }
8850
9088
  }
8851
9089
  }
8852
9090
  }
8853
9091
  const handler = onPaintRef.current ?? defaultOnPaint;
8854
- const elImage = placeholderCanvas.captureElementImage(element);
9092
+ let elImage;
9093
+ try {
9094
+ elImage = placeholderCanvas.captureElementImage(element);
9095
+ } catch (error2) {
9096
+ if (isMissingPaintRecordError(error2) && !isRendering) {
9097
+ continueRender2(handle);
9098
+ return;
9099
+ }
9100
+ if (isMissingPaintRecordError(error2)) {
9101
+ throw new Error(missingPaintRecordMessage);
9102
+ }
9103
+ throw error2;
9104
+ }
8855
9105
  await handler({
8856
9106
  canvas: offscreen,
8857
9107
  element,
@@ -8876,7 +9126,8 @@ var HtmlInCanvasContent = forwardRef9(({
8876
9126
  chainState,
8877
9127
  continueRender2,
8878
9128
  cancelRender2,
8879
- resolvedPixelDensity
9129
+ resolvedPixelDensity,
9130
+ isRendering
8880
9131
  ]);
8881
9132
  useLayoutEffect9(() => {
8882
9133
  const placeholder = canvas2dRef.current;
@@ -9012,6 +9263,15 @@ var HtmlInCanvasInner = forwardRef9(({
9012
9263
  HtmlInCanvasInner.displayName = "HtmlInCanvas";
9013
9264
  var htmlInCanvasSchema = {
9014
9265
  ...baseSchema,
9266
+ pixelDensity: {
9267
+ type: "number",
9268
+ min: 1,
9269
+ max: 3,
9270
+ step: 0.1,
9271
+ default: 1,
9272
+ description: "Pixel density",
9273
+ hiddenFromList: false
9274
+ },
9015
9275
  ...transformSchema
9016
9276
  };
9017
9277
  var HtmlInCanvasWrapped = withInteractivitySchema({
@@ -9345,6 +9605,7 @@ var CanvasImageInner = forwardRef10(({
9345
9605
  delayRenderTimeoutInMilliseconds,
9346
9606
  durationInFrames,
9347
9607
  from,
9608
+ trimBefore,
9348
9609
  freeze,
9349
9610
  hidden,
9350
9611
  name,
@@ -9366,6 +9627,7 @@ var CanvasImageInner = forwardRef10(({
9366
9627
  return /* @__PURE__ */ jsx26(Sequence, {
9367
9628
  layout: "none",
9368
9629
  from: from ?? 0,
9630
+ trimBefore,
9369
9631
  durationInFrames: durationInFrames ?? Infinity,
9370
9632
  freeze,
9371
9633
  hidden,
@@ -9639,6 +9901,7 @@ var NativeImgInner = ({
9639
9901
  showInTimeline,
9640
9902
  src,
9641
9903
  from,
9904
+ trimBefore,
9642
9905
  durationInFrames,
9643
9906
  freeze,
9644
9907
  controls,
@@ -9651,6 +9914,7 @@ var NativeImgInner = ({
9651
9914
  return /* @__PURE__ */ jsx28(Sequence, {
9652
9915
  layout: "none",
9653
9916
  from: from ?? 0,
9917
+ trimBefore,
9654
9918
  durationInFrames: durationInFrames ?? Infinity,
9655
9919
  freeze,
9656
9920
  _remotionInternalStack: stack,
@@ -9724,6 +9988,7 @@ var ImgInner = ({
9724
9988
  showInTimeline,
9725
9989
  src,
9726
9990
  from,
9991
+ trimBefore,
9727
9992
  durationInFrames,
9728
9993
  freeze,
9729
9994
  controls,
@@ -9749,6 +10014,7 @@ var ImgInner = ({
9749
10014
  showInTimeline,
9750
10015
  src,
9751
10016
  from,
10017
+ trimBefore,
9752
10018
  durationInFrames,
9753
10019
  freeze,
9754
10020
  controls,
@@ -9791,6 +10057,7 @@ var ImgInner = ({
9791
10057
  delayRenderRetries,
9792
10058
  delayRenderTimeoutInMilliseconds,
9793
10059
  from,
10060
+ trimBefore,
9794
10061
  durationInFrames,
9795
10062
  freeze,
9796
10063
  hidden,
@@ -9816,7 +10083,8 @@ import React29, { forwardRef as forwardRef12, useCallback as useCallback20, useR
9816
10083
  import { jsx as jsx29 } from "react/jsx-runtime";
9817
10084
  var interactiveElementSchema = {
9818
10085
  ...baseSchema,
9819
- ...transformSchema
10086
+ ...transformSchema,
10087
+ ...textSchema
9820
10088
  };
9821
10089
  var setRef = (ref, value) => {
9822
10090
  if (typeof ref === "function") {
@@ -9830,6 +10098,7 @@ var makeInteractiveElement = (tag, displayName) => {
9830
10098
  const {
9831
10099
  durationInFrames,
9832
10100
  from,
10101
+ trimBefore,
9833
10102
  freeze,
9834
10103
  hidden,
9835
10104
  name,
@@ -9846,6 +10115,7 @@ var makeInteractiveElement = (tag, displayName) => {
9846
10115
  return /* @__PURE__ */ jsx29(Sequence, {
9847
10116
  layout: "none",
9848
10117
  from: from ?? 0,
10118
+ trimBefore,
9849
10119
  durationInFrames: durationInFrames ?? Infinity,
9850
10120
  freeze,
9851
10121
  hidden,
@@ -9876,6 +10146,7 @@ var makeInteractiveElement = (tag, displayName) => {
9876
10146
  var Interactive = {
9877
10147
  baseSchema,
9878
10148
  transformSchema,
10149
+ textSchema,
9879
10150
  premountSchema,
9880
10151
  sequenceSchema,
9881
10152
  withSchema: withInteractivitySchema,
@@ -10858,7 +11129,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
10858
11129
  throw new Error("acceptableTimeShift has been removed. Use acceptableTimeShiftInSeconds instead.");
10859
11130
  }
10860
11131
  const [mediaVolume] = useMediaVolumeState();
10861
- const [mediaMuted] = useMediaMutedState();
11132
+ const [playerMuted] = usePlayerMutedState();
10862
11133
  const userPreferredVolume = evaluateVolume({
10863
11134
  frame: volumePropFrame,
10864
11135
  volume,
@@ -11014,7 +11285,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
11014
11285
  return /* @__PURE__ */ jsx34("video", {
11015
11286
  ...nativeProps,
11016
11287
  ref: videoRef,
11017
- muted: muted || mediaMuted || userPreferredVolume <= 0,
11288
+ muted: muted || playerMuted || userPreferredVolume <= 0,
11018
11289
  playsInline: true,
11019
11290
  src: actualSrc,
11020
11291
  loop: _remotionInternalNativeLoopPassed,
@@ -11350,6 +11621,7 @@ var Internals = {
11350
11621
  sequenceStyleSchema,
11351
11622
  sequenceVisualStyleSchema,
11352
11623
  sequencePremountSchema,
11624
+ textSchema,
11353
11625
  transformSchema,
11354
11626
  premountSchema,
11355
11627
  flattenActiveSchema,
@@ -11359,7 +11631,7 @@ var Internals = {
11359
11631
  useVideo,
11360
11632
  getRoot,
11361
11633
  useMediaVolumeState,
11362
- useMediaMutedState,
11634
+ usePlayerMutedState,
11363
11635
  useMediaInTimeline,
11364
11636
  useLazyComponent,
11365
11637
  truthy,