remotion 4.0.20 → 4.0.22

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.
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ import type { TAsset } from './CompositionManager.js';
3
+ export type AssetManagerContext = {
4
+ registerAsset: (asset: TAsset) => void;
5
+ unregisterAsset: (id: string) => void;
6
+ assets: TAsset[];
7
+ };
8
+ export declare const AssetManager: import("react").Context<AssetManagerContext>;
9
+ export declare const AssetManagerProvider: React.FC<{
10
+ children: React.ReactNode;
11
+ }>;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssetManagerProvider = exports.AssetManager = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ exports.AssetManager = (0, react_1.createContext)({
7
+ registerAsset: () => undefined,
8
+ unregisterAsset: () => undefined,
9
+ assets: [],
10
+ });
11
+ const AssetManagerProvider = ({ children }) => {
12
+ const [assets, setAssets] = (0, react_1.useState)([]);
13
+ const registerAsset = (0, react_1.useCallback)((asset) => {
14
+ setAssets((assts) => {
15
+ return [...assts, asset];
16
+ });
17
+ }, []);
18
+ const unregisterAsset = (0, react_1.useCallback)((id) => {
19
+ setAssets((assts) => {
20
+ return assts.filter((a) => a.id !== id);
21
+ });
22
+ }, []);
23
+ (0, react_1.useLayoutEffect)(() => {
24
+ if (typeof window !== 'undefined') {
25
+ window.remotion_collectAssets = () => {
26
+ setAssets([]); // clear assets at next render
27
+ return assets;
28
+ };
29
+ }
30
+ }, [assets]);
31
+ const contextValue = (0, react_1.useMemo)(() => {
32
+ return {
33
+ registerAsset,
34
+ unregisterAsset,
35
+ assets,
36
+ };
37
+ }, [assets, registerAsset, unregisterAsset]);
38
+ return ((0, jsx_runtime_1.jsx)(exports.AssetManager.Provider, { value: contextValue, children: children }));
39
+ };
40
+ exports.AssetManagerProvider = AssetManagerProvider;
@@ -12,7 +12,13 @@ export type SequenceProps = {
12
12
  from?: number;
13
13
  durationInFrames?: number;
14
14
  name?: string;
15
+ /**
16
+ * @deprecated For internal use only.
17
+ */
15
18
  showInTimeline?: boolean;
19
+ /**
20
+ * @deprecated For internal use only.
21
+ */
16
22
  loopDisplay?: LoopDisplay;
17
23
  } & LayoutAndStyle;
18
24
  /**
@@ -46,6 +46,7 @@ declare global {
46
46
  siteVersion: '10';
47
47
  remotion_version: string;
48
48
  remotion_imported: string | boolean;
49
+ remotion_unsavedProps: boolean | undefined;
49
50
  }
50
51
  }
51
52
  export type BundleState = {
@@ -8,8 +8,20 @@ const timeline_position_state_js_1 = require("./timeline-position-state.js");
8
8
  const use_current_frame_js_1 = require("./use-current-frame.js");
9
9
  const use_video_config_js_1 = require("./use-video-config.js");
10
10
  const get_current_time_js_1 = require("./video/get-current-time.js");
11
+ const video_fragment_js_1 = require("./video/video-fragment.js");
11
12
  const warn_about_non_seekable_media_js_1 = require("./warn-about-non-seekable-media.js");
12
13
  exports.DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
14
+ const seek = (mediaRef, time) => {
15
+ if (!mediaRef.current) {
16
+ return;
17
+ }
18
+ // iOS seeking does not support multiple decimals
19
+ if ((0, video_fragment_js_1.isIosSafari)()) {
20
+ mediaRef.current.currentTime = Number(time.toFixed(1));
21
+ return;
22
+ }
23
+ mediaRef.current.currentTime = time;
24
+ };
13
25
  const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, }) => {
14
26
  const { playbackRate: globalPlaybackRate } = (0, react_1.useContext)(timeline_position_state_js_1.TimelineContext);
15
27
  const frame = (0, use_current_frame_js_1.useCurrentFrame)();
@@ -53,7 +65,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
53
65
  if (timeShift > acceptableTimeshift) {
54
66
  // If scrubbing around, adjust timing
55
67
  // or if time shift is bigger than 0.45sec
56
- mediaRef.current.currentTime = shouldBeTime;
68
+ seek(mediaRef, shouldBeTime);
57
69
  if (!onlyWarnForMediaSeekingError) {
58
70
  (0, warn_about_non_seekable_media_js_1.warnAboutNonSeekableMedia)(mediaRef.current, onlyWarnForMediaSeekingError ? 'console-warning' : 'console-error');
59
71
  }
@@ -67,12 +79,12 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
67
79
  const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
68
80
  if (!playing || absoluteFrame === 0) {
69
81
  if (makesSenseToSeek) {
70
- mediaRef.current.currentTime = shouldBeTime;
82
+ seek(mediaRef, shouldBeTime);
71
83
  }
72
84
  }
73
85
  if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
74
86
  if (makesSenseToSeek) {
75
- mediaRef.current.currentTime = shouldBeTime;
87
+ seek(mediaRef, shouldBeTime);
76
88
  }
77
89
  (0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType);
78
90
  }
@@ -1 +1 @@
1
- export declare const VERSION = "4.0.20";
1
+ export declare const VERSION = "4.0.22";
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // Automatically generated on publish
5
- exports.VERSION = '4.0.20';
5
+ exports.VERSION = '4.0.22';
@@ -111,7 +111,11 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
111
111
  current.removeEventListener('loadedmetadata', onLoadedMetadata);
112
112
  };
113
113
  }, [src]);
114
- return ((0, jsx_runtime_1.jsx)("video", { ref: videoRef, muted: muted || mediaMuted, playsInline: true, src: actualSrc, ...nativeProps }));
114
+ return ((0, jsx_runtime_1.jsx)("video", { ref: videoRef,
115
+ // Without this, on iOS Safari, the video cannot be seeked.
116
+ // if a seek is triggered before `loadedmetadata` is fired,
117
+ // the video will not seek, even if `loadedmetadata` is fired afterwards.
118
+ preload: "metadata", muted: muted || mediaMuted, playsInline: true, src: actualSrc, ...nativeProps }));
115
119
  };
116
120
  // Copy types from forwardRef but not necessary to remove ref
117
121
  exports.VideoForDevelopment = (0, react_1.forwardRef)(VideoForDevelopmentRefForwardingFunction);
@@ -4,6 +4,7 @@ export declare const useAppendVideoFragment: ({ actualSrc: initialActualSrc, act
4
4
  duration: number;
5
5
  fps: number;
6
6
  }) => string;
7
+ export declare const isIosSafari: () => boolean;
7
8
  export declare const appendVideoFragment: ({ actualSrc, actualFrom, duration, fps, }: {
8
9
  actualSrc: string;
9
10
  actualFrom: number;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.appendVideoFragment = exports.useAppendVideoFragment = void 0;
3
+ exports.appendVideoFragment = exports.isIosSafari = exports.useAppendVideoFragment = void 0;
4
4
  const react_1 = require("react");
5
5
  const toSeconds = (time, fps) => {
6
6
  return Math.round((time / fps) * 100) / 100;
@@ -27,6 +27,11 @@ const useAppendVideoFragment = ({ actualSrc: initialActualSrc, actualFrom: initi
27
27
  return appended;
28
28
  };
29
29
  exports.useAppendVideoFragment = useAppendVideoFragment;
30
+ const isIosSafari = () => {
31
+ return (/iP(ad|od|hone)/i.test(window.navigator.userAgent) &&
32
+ Boolean(navigator.userAgent.match(/Version\/[\d.]+.*Safari/)));
33
+ };
34
+ exports.isIosSafari = isIosSafari;
30
35
  // https://github.com/remotion-dev/remotion/issues/1655
31
36
  const isIOSSafariCase = (actualSrc) => {
32
37
  return typeof window === 'undefined'
@@ -59,7 +59,7 @@ function truthy(value) {
59
59
  }
60
60
 
61
61
  // Automatically generated on publish
62
- const VERSION = '4.0.20';
62
+ const VERSION = '4.0.22';
63
63
 
64
64
  const checkMultipleRemotionVersions = () => {
65
65
  if (typeof globalThis === 'undefined') {
@@ -1722,6 +1722,65 @@ const getMediaTime = ({ fps, frame, src, playbackRate, startFrom, mediaType, })
1722
1722
  return (expectedFrame * msPerFrame + msShift) / 1000;
1723
1723
  };
1724
1724
 
1725
+ const toSeconds = (time, fps) => {
1726
+ return Math.round((time / fps) * 100) / 100;
1727
+ };
1728
+ const isSubsetOfDuration = (prevStartFrom, newStartFrom, prevDuration, newDuration) => {
1729
+ return (prevStartFrom <= newStartFrom &&
1730
+ prevStartFrom + prevDuration >= newStartFrom + newDuration);
1731
+ };
1732
+ const useAppendVideoFragment = ({ actualSrc: initialActualSrc, actualFrom: initialActualFrom, duration: initialDuration, fps, }) => {
1733
+ const actualFromRef = useRef(initialActualFrom);
1734
+ const actualDuration = useRef(initialDuration);
1735
+ const actualSrc = useRef(initialActualSrc);
1736
+ if (!isSubsetOfDuration || initialActualSrc !== actualSrc.current) {
1737
+ actualFromRef.current = initialActualFrom;
1738
+ actualDuration.current = initialDuration;
1739
+ actualSrc.current = initialActualSrc;
1740
+ }
1741
+ const appended = appendVideoFragment({
1742
+ actualSrc: actualSrc.current,
1743
+ actualFrom: actualFromRef.current,
1744
+ duration: actualDuration.current,
1745
+ fps,
1746
+ });
1747
+ return appended;
1748
+ };
1749
+ const isIosSafari = () => {
1750
+ return (/iP(ad|od|hone)/i.test(window.navigator.userAgent) &&
1751
+ Boolean(navigator.userAgent.match(/Version\/[\d.]+.*Safari/)));
1752
+ };
1753
+ // https://github.com/remotion-dev/remotion/issues/1655
1754
+ const isIOSSafariCase = (actualSrc) => {
1755
+ return typeof window === 'undefined'
1756
+ ? false
1757
+ : /iP(ad|od|hone)/i.test(window.navigator.userAgent) &&
1758
+ Boolean(navigator.userAgent.match(/Version\/[\d.]+.*Safari/)) &&
1759
+ actualSrc.startsWith('blob:');
1760
+ };
1761
+ const appendVideoFragment = ({ actualSrc, actualFrom, duration, fps, }) => {
1762
+ var _a;
1763
+ if (isIOSSafariCase(actualSrc)) {
1764
+ return actualSrc;
1765
+ }
1766
+ if (actualSrc.startsWith('data:')) {
1767
+ return actualSrc;
1768
+ }
1769
+ const existingHash = Boolean(new URL(actualSrc, (_a = (typeof window === 'undefined' ? null : window.location.href)) !== null && _a !== void 0 ? _a : 'http://localhost:3000').hash);
1770
+ if (existingHash) {
1771
+ return actualSrc;
1772
+ }
1773
+ if (!Number.isFinite(actualFrom)) {
1774
+ return actualSrc;
1775
+ }
1776
+ actualSrc += `#t=${toSeconds(-actualFrom, fps)}`;
1777
+ if (!Number.isFinite(duration)) {
1778
+ return actualSrc;
1779
+ }
1780
+ actualSrc += `,${toSeconds(duration, fps)}`;
1781
+ return actualSrc;
1782
+ };
1783
+
1725
1784
  const alreadyWarned = {};
1726
1785
  const warnAboutNonSeekableMedia = (ref, type) => {
1727
1786
  // Media is not loaded yet, but this does not yet mean something is wrong with the media
@@ -1754,6 +1813,17 @@ const warnAboutNonSeekableMedia = (ref, type) => {
1754
1813
  };
1755
1814
 
1756
1815
  const DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
1816
+ const seek = (mediaRef, time) => {
1817
+ if (!mediaRef.current) {
1818
+ return;
1819
+ }
1820
+ // iOS seeking does not support multiple decimals
1821
+ if (isIosSafari()) {
1822
+ mediaRef.current.currentTime = Number(time.toFixed(1));
1823
+ return;
1824
+ }
1825
+ mediaRef.current.currentTime = time;
1826
+ };
1757
1827
  const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, }) => {
1758
1828
  const { playbackRate: globalPlaybackRate } = useContext(TimelineContext);
1759
1829
  const frame = useCurrentFrame();
@@ -1797,7 +1867,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
1797
1867
  if (timeShift > acceptableTimeshift) {
1798
1868
  // If scrubbing around, adjust timing
1799
1869
  // or if time shift is bigger than 0.45sec
1800
- mediaRef.current.currentTime = shouldBeTime;
1870
+ seek(mediaRef, shouldBeTime);
1801
1871
  if (!onlyWarnForMediaSeekingError) {
1802
1872
  warnAboutNonSeekableMedia(mediaRef.current, onlyWarnForMediaSeekingError ? 'console-warning' : 'console-error');
1803
1873
  }
@@ -1811,12 +1881,12 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
1811
1881
  const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
1812
1882
  if (!playing || absoluteFrame === 0) {
1813
1883
  if (makesSenseToSeek) {
1814
- mediaRef.current.currentTime = shouldBeTime;
1884
+ seek(mediaRef, shouldBeTime);
1815
1885
  }
1816
1886
  }
1817
1887
  if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
1818
1888
  if (makesSenseToSeek) {
1819
- mediaRef.current.currentTime = shouldBeTime;
1889
+ seek(mediaRef, shouldBeTime);
1820
1890
  }
1821
1891
  playAndHandleNotAllowedError(mediaRef, mediaType);
1822
1892
  }
@@ -4296,61 +4366,6 @@ const OffthreadVideoForRendering = ({ onError, volume: volumeProp, playbackRate,
4296
4366
  return (jsx(Img, { src: actualSrc, className: className, ...props, onError: onErr }));
4297
4367
  };
4298
4368
 
4299
- const toSeconds = (time, fps) => {
4300
- return Math.round((time / fps) * 100) / 100;
4301
- };
4302
- const isSubsetOfDuration = (prevStartFrom, newStartFrom, prevDuration, newDuration) => {
4303
- return (prevStartFrom <= newStartFrom &&
4304
- prevStartFrom + prevDuration >= newStartFrom + newDuration);
4305
- };
4306
- const useAppendVideoFragment = ({ actualSrc: initialActualSrc, actualFrom: initialActualFrom, duration: initialDuration, fps, }) => {
4307
- const actualFromRef = useRef(initialActualFrom);
4308
- const actualDuration = useRef(initialDuration);
4309
- const actualSrc = useRef(initialActualSrc);
4310
- if (!isSubsetOfDuration || initialActualSrc !== actualSrc.current) {
4311
- actualFromRef.current = initialActualFrom;
4312
- actualDuration.current = initialDuration;
4313
- actualSrc.current = initialActualSrc;
4314
- }
4315
- const appended = appendVideoFragment({
4316
- actualSrc: actualSrc.current,
4317
- actualFrom: actualFromRef.current,
4318
- duration: actualDuration.current,
4319
- fps,
4320
- });
4321
- return appended;
4322
- };
4323
- // https://github.com/remotion-dev/remotion/issues/1655
4324
- const isIOSSafariCase = (actualSrc) => {
4325
- return typeof window === 'undefined'
4326
- ? false
4327
- : /iP(ad|od|hone)/i.test(window.navigator.userAgent) &&
4328
- Boolean(navigator.userAgent.match(/Version\/[\d.]+.*Safari/)) &&
4329
- actualSrc.startsWith('blob:');
4330
- };
4331
- const appendVideoFragment = ({ actualSrc, actualFrom, duration, fps, }) => {
4332
- var _a;
4333
- if (isIOSSafariCase(actualSrc)) {
4334
- return actualSrc;
4335
- }
4336
- if (actualSrc.startsWith('data:')) {
4337
- return actualSrc;
4338
- }
4339
- const existingHash = Boolean(new URL(actualSrc, (_a = (typeof window === 'undefined' ? null : window.location.href)) !== null && _a !== void 0 ? _a : 'http://localhost:3000').hash);
4340
- if (existingHash) {
4341
- return actualSrc;
4342
- }
4343
- if (!Number.isFinite(actualFrom)) {
4344
- return actualSrc;
4345
- }
4346
- actualSrc += `#t=${toSeconds(-actualFrom, fps)}`;
4347
- if (!Number.isFinite(duration)) {
4348
- return actualSrc;
4349
- }
4350
- actualSrc += `,${toSeconds(duration, fps)}`;
4351
- return actualSrc;
4352
- };
4353
-
4354
4369
  const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
4355
4370
  var _a, _b;
4356
4371
  const videoRef = useRef(null);
@@ -4449,7 +4464,11 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
4449
4464
  current.removeEventListener('loadedmetadata', onLoadedMetadata);
4450
4465
  };
4451
4466
  }, [src]);
4452
- return (jsx("video", { ref: videoRef, muted: muted || mediaMuted, playsInline: true, src: actualSrc, ...nativeProps }));
4467
+ return (jsx("video", { ref: videoRef,
4468
+ // Without this, on iOS Safari, the video cannot be seeked.
4469
+ // if a seek is triggered before `loadedmetadata` is fired,
4470
+ // the video will not seek, even if `loadedmetadata` is fired afterwards.
4471
+ preload: "metadata", muted: muted || mediaMuted, playsInline: true, src: actualSrc, ...nativeProps }));
4453
4472
  };
4454
4473
  // Copy types from forwardRef but not necessary to remove ref
4455
4474
  const VideoForDevelopment = forwardRef(VideoForDevelopmentRefForwardingFunction);
@@ -1,4 +1,4 @@
1
1
  // Automatically generated on publish
2
- const VERSION = '4.0.20';
2
+ const VERSION = '4.0.22';
3
3
 
4
4
  export { VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remotion",
3
- "version": "4.0.20",
3
+ "version": "4.0.22",
4
4
  "description": "Render videos in React",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/cjs/index.d.ts",