remotion 4.0.249 → 4.0.251

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 (37) hide show
  1. package/dist/cjs/RemotionRoot.js +2 -1
  2. package/dist/cjs/animated-image/resolve-image-source.js +4 -2
  3. package/dist/cjs/audio/Audio.d.ts +0 -1
  4. package/dist/cjs/audio/Audio.js +2 -2
  5. package/dist/cjs/audio/AudioForPreview.d.ts +0 -1
  6. package/dist/cjs/audio/AudioForPreview.js +1 -2
  7. package/dist/cjs/audio/props.d.ts +0 -1
  8. package/dist/cjs/index.d.ts +1 -0
  9. package/dist/cjs/internals.d.ts +8 -0
  10. package/dist/cjs/internals.js +4 -0
  11. package/dist/cjs/log-level-context.d.ts +4 -0
  12. package/dist/cjs/log-level-context.js +14 -0
  13. package/dist/cjs/log.d.ts +10 -0
  14. package/dist/cjs/log.js +37 -0
  15. package/dist/cjs/prefetch.d.ts +2 -0
  16. package/dist/cjs/prefetch.js +7 -2
  17. package/dist/cjs/seek.d.ts +7 -0
  18. package/dist/cjs/seek.js +13 -0
  19. package/dist/cjs/use-media-buffering.d.ts +3 -1
  20. package/dist/cjs/use-media-buffering.js +18 -10
  21. package/dist/cjs/use-media-playback.d.ts +1 -2
  22. package/dist/cjs/use-media-playback.js +28 -44
  23. package/dist/cjs/version.d.ts +1 -1
  24. package/dist/cjs/version.js +1 -1
  25. package/dist/cjs/video/OffthreadVideo.js +2 -2
  26. package/dist/cjs/video/Video.js +2 -2
  27. package/dist/cjs/video/VideoForPreview.d.ts +0 -1
  28. package/dist/cjs/video/VideoForPreview.js +5 -2
  29. package/dist/cjs/video/VideoForRendering.js +9 -1
  30. package/dist/cjs/video/props.d.ts +0 -1
  31. package/dist/cjs/video/seek-until-right.d.ts +12 -2
  32. package/dist/cjs/video/seek-until-right.js +24 -6
  33. package/dist/cjs/wrap-remotion-context.d.ts +1 -0
  34. package/dist/cjs/wrap-remotion-context.js +5 -1
  35. package/dist/esm/index.mjs +385 -289
  36. package/dist/esm/version.mjs +1 -1
  37. package/package.json +2 -2
@@ -7,6 +7,7 @@ const CompositionManager_js_1 = require("./CompositionManager.js");
7
7
  const EditorProps_js_1 = require("./EditorProps.js");
8
8
  const buffering_js_1 = require("./buffering.js");
9
9
  const delay_render_js_1 = require("./delay-render.js");
10
+ const log_level_context_js_1 = require("./log-level-context.js");
10
11
  const nonce_js_1 = require("./nonce.js");
11
12
  const prefetch_state_js_1 = require("./prefetch-state.js");
12
13
  const random_js_1 = require("./random.js");
@@ -86,6 +87,6 @@ const RemotionRoot = ({ children, numberOfAudioTags }) => {
86
87
  }
87
88
  }
88
89
  }, []);
89
- return ((0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: nonceContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.TimelineContext.Provider, { value: timelineContextValue, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(EditorProps_js_1.EditorPropsProvider, { children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(CompositionManager_js_1.CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: (0, jsx_runtime_1.jsx)(duration_state_js_1.DurationsContextProvider, { children: (0, jsx_runtime_1.jsx)(buffering_js_1.BufferingProvider, { children: children }) }) }) }) }) }) }) }));
90
+ return ((0, jsx_runtime_1.jsx)(log_level_context_js_1.LogLevelContext.Provider, { value: 'info', children: (0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: nonceContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.TimelineContext.Provider, { value: timelineContextValue, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(EditorProps_js_1.EditorPropsProvider, { children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(CompositionManager_js_1.CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: (0, jsx_runtime_1.jsx)(duration_state_js_1.DurationsContextProvider, { children: (0, jsx_runtime_1.jsx)(buffering_js_1.BufferingProvider, { children: children }) }) }) }) }) }) }) }) }));
90
91
  };
91
92
  exports.RemotionRoot = RemotionRoot;
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveAnimatedImageSource = void 0;
4
4
  const resolveAnimatedImageSource = (src) => {
5
- return new URL(src, typeof window === 'undefined' ? undefined : window.origin)
6
- .href;
5
+ if (typeof window === 'undefined') {
6
+ return src;
7
+ }
8
+ return new URL(src, window.origin).href;
7
9
  };
8
10
  exports.resolveAnimatedImageSource = resolveAnimatedImageSource;
@@ -8,7 +8,6 @@ export declare const Audio: React.ForwardRefExoticComponent<Omit<Omit<React.Deta
8
8
  allowAmplificationDuringRender?: boolean;
9
9
  _remotionInternalNeedsDurationCalculation?: boolean;
10
10
  _remotionInternalNativeLoopPassed?: boolean;
11
- _remotionDebugSeeking?: boolean;
12
11
  toneFrequency?: number;
13
12
  pauseWhenBuffering?: boolean;
14
13
  showInTimeline?: boolean;
@@ -22,7 +22,7 @@ const shared_audio_tags_js_1 = require("./shared-audio-tags.js");
22
22
  const AudioRefForwardingFunction = (props, ref) => {
23
23
  var _a, _b, _c;
24
24
  const audioContext = (0, react_1.useContext)(shared_audio_tags_js_1.SharedAudioContext);
25
- const { startFrom, endAt, name, stack, pauseWhenBuffering, showInTimeline, _remotionDebugSeeking, ...otherProps } = props;
25
+ const { startFrom, endAt, name, stack, pauseWhenBuffering, showInTimeline, ...otherProps } = props;
26
26
  const { loop, ...propsOtherThanLoop } = props;
27
27
  const { fps } = (0, use_video_config_js_1.useVideoConfig)();
28
28
  const environment = (0, get_remotion_environment_js_1.getRemotionEnvironment)();
@@ -71,7 +71,7 @@ const AudioRefForwardingFunction = (props, ref) => {
71
71
  if (environment.isRendering) {
72
72
  return ((0, jsx_runtime_1.jsx)(AudioForRendering_js_1.AudioForRendering, { onDuration: onDuration, ...props, ref: ref, onError: onError, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
73
73
  }
74
- return ((0, jsx_runtime_1.jsx)(AudioForPreview_js_1.AudioForPreview, { _remotionInternalNativeLoopPassed: (_c = props._remotionInternalNativeLoopPassed) !== null && _c !== void 0 ? _c : false, _remotionDebugSeeking: _remotionDebugSeeking !== null && _remotionDebugSeeking !== void 0 ? _remotionDebugSeeking : false, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0, ...props, ref: ref, onError: onError, onDuration: onDuration,
74
+ return ((0, jsx_runtime_1.jsx)(AudioForPreview_js_1.AudioForPreview, { _remotionInternalNativeLoopPassed: (_c = props._remotionInternalNativeLoopPassed) !== null && _c !== void 0 ? _c : false, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0, ...props, ref: ref, onError: onError, onDuration: onDuration,
75
75
  // Proposal: Make this default to true in v5
76
76
  pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, _remotionInternalNeedsDurationCalculation: Boolean(loop), showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true }));
77
77
  };
@@ -6,7 +6,6 @@ type AudioForPreviewProps = RemotionAudioProps & {
6
6
  readonly pauseWhenBuffering: boolean;
7
7
  readonly _remotionInternalNativeLoopPassed: boolean;
8
8
  readonly _remotionInternalStack: string | null;
9
- readonly _remotionDebugSeeking: boolean;
10
9
  readonly showInTimeline: boolean;
11
10
  readonly stack?: string | undefined;
12
11
  };
@@ -20,7 +20,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
20
20
  if (props.shouldPreMountAudioTags !== initialShouldPreMountAudioElements) {
21
21
  throw new Error('Cannot change the behavior for pre-mounting audio tags dynamically.');
22
22
  }
23
- const { volume, muted, playbackRate, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, _remotionDebugSeeking, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, stack, ...nativeProps } = props;
23
+ const { volume, muted, playbackRate, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, stack, ...nativeProps } = props;
24
24
  const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
25
25
  const [mediaMuted] = (0, volume_position_state_js_1.useMediaMutedState)();
26
26
  const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
@@ -95,7 +95,6 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
95
95
  acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : use_media_playback_js_1.DEFAULT_ACCEPTABLE_TIMESHIFT,
96
96
  isPremounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
97
97
  pauseWhenBuffering,
98
- debugSeeking: _remotionDebugSeeking,
99
98
  onAutoPlayError: null,
100
99
  });
101
100
  (0, react_1.useImperativeHandle)(ref, () => {
@@ -12,7 +12,6 @@ export type RemotionAudioProps = Omit<React.DetailedHTMLProps<React.AudioHTMLAtt
12
12
  allowAmplificationDuringRender?: boolean;
13
13
  _remotionInternalNeedsDurationCalculation?: boolean;
14
14
  _remotionInternalNativeLoopPassed?: boolean;
15
- _remotionDebugSeeking?: boolean;
16
15
  toneFrequency?: number;
17
16
  pauseWhenBuffering?: boolean;
18
17
  showInTimeline?: boolean;
@@ -86,6 +86,7 @@ export * from './IFrame.js';
86
86
  export { Img, ImgProps } from './Img.js';
87
87
  export * from './internals.js';
88
88
  export { interpolateColors } from './interpolate-colors.js';
89
+ export { LogLevel } from './log.js';
89
90
  export { Loop } from './loop/index.js';
90
91
  export { EasingFunction, ExtrapolateType, interpolate, InterpolateOptions, random, RandomSeed, } from './no-react';
91
92
  export { prefetch, PrefetchOnProgress } from './prefetch.js';
@@ -166,5 +166,13 @@ export declare const Internals: {
166
166
  } | null>;
167
167
  readonly PROPS_UPDATED_EXTERNALLY: "remotion.propsUpdatedExternally";
168
168
  readonly validateRenderAsset: (artifact: TRenderAsset) => void;
169
+ readonly Log: {
170
+ trace: (logLevel: import("./log.js").LogLevel, ...args: Parameters<typeof console.log>) => void;
171
+ verbose: (logLevel: import("./log.js").LogLevel, ...args: Parameters<typeof console.log>) => void;
172
+ info: (logLevel: import("./log.js").LogLevel, ...args: Parameters<typeof console.log>) => void;
173
+ warn: (logLevel: import("./log.js").LogLevel, ...args: Parameters<typeof console.log>) => void;
174
+ error: (...args: Parameters<typeof console.log>) => void;
175
+ };
176
+ readonly LogLevelContext: import("react").Context<"error" | "trace" | "verbose" | "info" | "warn" | null>;
169
177
  };
170
178
  export type { CompositionManagerContext, CompProps, MediaVolumeContextValue, RemotionEnvironment, SerializedJSONWithCustomFields, SetMediaVolumeContextValue, SetTimelineContextValue, TRenderAsset as TAsset, TCompMetadata, TComposition, TimelinePosition as Timeline, TimelineContextValue, TSequence, WatchRemotionStaticFilesPayload, };
@@ -36,6 +36,8 @@ const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-trace
36
36
  const get_preview_dom_element_js_1 = require("./get-preview-dom-element.js");
37
37
  const get_remotion_environment_js_1 = require("./get-remotion-environment.js");
38
38
  const is_player_js_1 = require("./is-player.js");
39
+ const log_level_context_js_1 = require("./log-level-context.js");
40
+ const log_js_1 = require("./log.js");
39
41
  const nonce_js_1 = require("./nonce.js");
40
42
  const portal_node_js_1 = require("./portal-node.js");
41
43
  const prefetch_state_js_1 = require("./prefetch-state.js");
@@ -124,4 +126,6 @@ exports.Internals = {
124
126
  editorPropsProviderRef: EditorProps_js_1.editorPropsProviderRef,
125
127
  PROPS_UPDATED_EXTERNALLY: ResolveCompositionConfig_js_1.PROPS_UPDATED_EXTERNALLY,
126
128
  validateRenderAsset: validate_artifact_js_1.validateRenderAsset,
129
+ Log: log_js_1.Log,
130
+ LogLevelContext: log_level_context_js_1.LogLevelContext,
127
131
  };
@@ -0,0 +1,4 @@
1
+ import type { LogLevel } from './log';
2
+ import React = require('react');
3
+ export declare const LogLevelContext: React.Context<"error" | "trace" | "verbose" | "info" | "warn" | null>;
4
+ export declare const useLogLevel: () => LogLevel;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useLogLevel = exports.LogLevelContext = void 0;
4
+ const react_1 = require("react");
5
+ const React = require("react");
6
+ exports.LogLevelContext = (0, react_1.createContext)('info');
7
+ const useLogLevel = () => {
8
+ const logLevel = React.useContext(exports.LogLevelContext);
9
+ if (logLevel === null) {
10
+ throw new Error('useLogLevel must be used within a LogLevelProvider');
11
+ }
12
+ return logLevel;
13
+ };
14
+ exports.useLogLevel = useLogLevel;
@@ -0,0 +1,10 @@
1
+ export declare const logLevels: readonly ["trace", "verbose", "info", "warn", "error"];
2
+ export type LogLevel = (typeof logLevels)[number];
3
+ export declare const isEqualOrBelowLogLevel: (currentLevel: LogLevel, level: LogLevel) => boolean;
4
+ export declare const Log: {
5
+ trace: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
6
+ verbose: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
7
+ info: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
8
+ warn: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
9
+ error: (...args: Parameters<typeof console.log>) => void;
10
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Log = exports.isEqualOrBelowLogLevel = exports.logLevels = void 0;
4
+ /* eslint-disable no-console */
5
+ exports.logLevels = ['trace', 'verbose', 'info', 'warn', 'error'];
6
+ const getNumberForLogLevel = (level) => {
7
+ return exports.logLevels.indexOf(level);
8
+ };
9
+ const isEqualOrBelowLogLevel = (currentLevel, level) => {
10
+ return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
11
+ };
12
+ exports.isEqualOrBelowLogLevel = isEqualOrBelowLogLevel;
13
+ exports.Log = {
14
+ trace: (logLevel, ...args) => {
15
+ if ((0, exports.isEqualOrBelowLogLevel)(logLevel, 'trace')) {
16
+ return console.log(...args);
17
+ }
18
+ },
19
+ verbose: (logLevel, ...args) => {
20
+ if ((0, exports.isEqualOrBelowLogLevel)(logLevel, 'verbose')) {
21
+ return console.log(...args);
22
+ }
23
+ },
24
+ info: (logLevel, ...args) => {
25
+ if ((0, exports.isEqualOrBelowLogLevel)(logLevel, 'info')) {
26
+ return console.log(...args);
27
+ }
28
+ },
29
+ warn: (logLevel, ...args) => {
30
+ if ((0, exports.isEqualOrBelowLogLevel)(logLevel, 'warn')) {
31
+ return console.warn(...args);
32
+ }
33
+ },
34
+ error: (...args) => {
35
+ return console.error(...args);
36
+ },
37
+ };
@@ -1,3 +1,4 @@
1
+ import type { LogLevel } from './log.js';
1
2
  export declare const usePreload: (src: string) => string;
2
3
  type FetchAndPreload = {
3
4
  free: () => void;
@@ -12,5 +13,6 @@ export declare const prefetch: (src: string, options?: {
12
13
  contentType?: string;
13
14
  onProgress?: PrefetchOnProgress;
14
15
  credentials?: RequestCredentials;
16
+ logLevel?: LogLevel;
15
17
  }) => FetchAndPreload;
16
18
  export {};
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.prefetch = exports.usePreload = void 0;
4
4
  const react_1 = require("react");
5
5
  const get_remotion_environment_js_1 = require("./get-remotion-environment.js");
6
+ const log_js_1 = require("./log.js");
6
7
  const prefetch_state_js_1 = require("./prefetch-state.js");
7
8
  const usePreload = (src) => {
8
9
  var _a;
@@ -52,14 +53,16 @@ const getBlobFromReader = async ({ reader, contentType, contentLength, onProgres
52
53
  * @see [Documentation](https://www.remotion.dev/docs/prefetch)
53
54
  */
54
55
  const prefetch = (src, options) => {
55
- var _a, _b;
56
+ var _a, _b, _c;
56
57
  const method = (_a = options === null || options === void 0 ? void 0 : options.method) !== null && _a !== void 0 ? _a : 'blob-url';
58
+ const logLevel = (_b = options === null || options === void 0 ? void 0 : options.logLevel) !== null && _b !== void 0 ? _b : 'info';
57
59
  if ((0, get_remotion_environment_js_1.getRemotionEnvironment)().isRendering) {
58
60
  return {
59
61
  free: () => undefined,
60
62
  waitUntilDone: () => Promise.resolve(src),
61
63
  };
62
64
  }
65
+ log_js_1.Log.verbose(logLevel, `[prefetch] Starting prefetch ${src}`);
63
66
  let canceled = false;
64
67
  let objectUrl = null;
65
68
  let resolve = () => undefined;
@@ -72,7 +75,7 @@ const prefetch = (src, options) => {
72
75
  let canBeAborted = true;
73
76
  fetch(src, {
74
77
  signal: controller.signal,
75
- credentials: (_b = options === null || options === void 0 ? void 0 : options.credentials) !== null && _b !== void 0 ? _b : undefined,
78
+ credentials: (_c = options === null || options === void 0 ? void 0 : options.credentials) !== null && _c !== void 0 ? _c : undefined,
76
79
  })
77
80
  .then((res) => {
78
81
  var _a, _b, _c;
@@ -122,6 +125,7 @@ const prefetch = (src, options) => {
122
125
  if (canceled) {
123
126
  return;
124
127
  }
128
+ log_js_1.Log.trace(logLevel, `[prefetch] Finished prefetch ${src} with method ${method}`);
125
129
  objectUrl = url;
126
130
  (0, prefetch_state_js_1.setPreloads)((p) => ({
127
131
  ...p,
@@ -137,6 +141,7 @@ const prefetch = (src, options) => {
137
141
  });
138
142
  return {
139
143
  free: () => {
144
+ log_js_1.Log.trace(logLevel, `[prefetch] Freeing ${src}`);
140
145
  if (objectUrl) {
141
146
  if (method === 'blob-url') {
142
147
  URL.revokeObjectURL(objectUrl);
@@ -0,0 +1,7 @@
1
+ import type { LogLevel } from './log';
2
+ export declare const seek: ({ mediaRef, time, logLevel, why, }: {
3
+ mediaRef: HTMLVideoElement | HTMLAudioElement;
4
+ time: number;
5
+ logLevel: LogLevel;
6
+ why: string;
7
+ }) => number;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.seek = void 0;
4
+ const log_1 = require("./log");
5
+ const video_fragment_1 = require("./video/video-fragment");
6
+ const seek = ({ mediaRef, time, logLevel, why, }) => {
7
+ // iOS seeking does not support multiple decimals
8
+ const timeToSet = (0, video_fragment_1.isIosSafari)() ? Number(time.toFixed(1)) : time;
9
+ log_1.Log.trace(logLevel, `[seek] from ${mediaRef.currentTime} to ${timeToSet}. Reason: ${why}`);
10
+ mediaRef.currentTime = timeToSet;
11
+ return timeToSet;
12
+ };
13
+ exports.seek = seek;
@@ -1,6 +1,8 @@
1
1
  import type React from 'react';
2
- export declare const useMediaBuffering: ({ element, shouldBuffer, isPremounting, }: {
2
+ import type { LogLevel } from './log';
3
+ export declare const useMediaBuffering: ({ element, shouldBuffer, isPremounting, logLevel, }: {
3
4
  element: React.RefObject<HTMLVideoElement | HTMLAudioElement | null>;
4
5
  shouldBuffer: boolean;
5
6
  isPremounting: boolean;
7
+ logLevel: LogLevel;
6
8
  }) => boolean;
@@ -2,8 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMediaBuffering = void 0;
4
4
  const react_1 = require("react");
5
+ const log_1 = require("./log");
5
6
  const use_buffer_state_1 = require("./use-buffer-state");
6
- const useMediaBuffering = ({ element, shouldBuffer, isPremounting, }) => {
7
+ const useMediaBuffering = ({ element, shouldBuffer, isPremounting, logLevel, }) => {
7
8
  const buffer = (0, use_buffer_state_1.useBufferState)();
8
9
  const [isBuffering, setIsBuffering] = (0, react_1.useState)(false);
9
10
  // Buffer state based on `waiting` and `canplay`
@@ -26,26 +27,28 @@ const useMediaBuffering = ({ element, shouldBuffer, isPremounting, }) => {
26
27
  // Breaks on Firefox though: https://github.com/remotion-dev/remotion/issues/3915
27
28
  if (current.readyState < current.HAVE_FUTURE_DATA) {
28
29
  if (!navigator.userAgent.includes('Firefox/')) {
30
+ log_1.Log.trace(logLevel, `[load] Calling .load() on ${current.src} because readyState is ${current.readyState} and it is not Firefox. Element is premounted`);
29
31
  current.load();
30
32
  }
31
33
  }
32
34
  return;
33
35
  }
34
- const cleanup = () => {
35
- cleanupFns.forEach((fn) => fn());
36
+ const cleanup = (reason) => {
37
+ cleanupFns.forEach((fn) => fn(reason));
36
38
  cleanupFns = [];
37
39
  setIsBuffering(false);
38
40
  };
39
- const onWaiting = () => {
41
+ const blockMedia = (reason) => {
40
42
  setIsBuffering(true);
43
+ log_1.Log.trace(logLevel, `[buffer] buffering ${current.src}. reason = ${reason}`);
41
44
  const { unblock } = buffer.delayPlayback();
42
45
  const onCanPlay = () => {
43
- cleanup();
46
+ cleanup('"canplay" was fired');
44
47
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
45
48
  init();
46
49
  };
47
50
  const onError = () => {
48
- cleanup();
51
+ cleanup('"error" event was occurred');
49
52
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
50
53
  init();
51
54
  };
@@ -61,13 +64,14 @@ const useMediaBuffering = ({ element, shouldBuffer, isPremounting, }) => {
61
64
  cleanupFns.push(() => {
62
65
  current.removeEventListener('error', onError);
63
66
  });
64
- cleanupFns.push(() => {
67
+ cleanupFns.push((cleanupReason) => {
68
+ log_1.Log.trace(logLevel, `unblocking ${current.src} from buffer. reason = ${cleanupReason}`);
65
69
  unblock();
66
70
  });
67
71
  };
68
72
  const init = () => {
69
73
  if (current.readyState < current.HAVE_FUTURE_DATA) {
70
- onWaiting();
74
+ blockMedia(`readyState is ${current.readyState}, which is less than HAVE_FUTURE_DATA`);
71
75
  // Needed by iOS Safari which will not load by default
72
76
  // and therefore not fire the canplay event.
73
77
  // Be cautious about using `current.load()` as it will
@@ -76,10 +80,14 @@ const useMediaBuffering = ({ element, shouldBuffer, isPremounting, }) => {
76
80
  // has no future data.
77
81
  // Breaks on Firefox though: https://github.com/remotion-dev/remotion/issues/3915
78
82
  if (!navigator.userAgent.includes('Firefox/')) {
83
+ log_1.Log.trace(logLevel, `[load] Calling .load() on ${current.src} because readyState is ${current.readyState} and it is not Firefox.`);
79
84
  current.load();
80
85
  }
81
86
  }
82
87
  else {
88
+ const onWaiting = () => {
89
+ blockMedia('"waiting" event was fired');
90
+ };
83
91
  current.addEventListener('waiting', onWaiting);
84
92
  cleanupFns.push(() => {
85
93
  current.removeEventListener('waiting', onWaiting);
@@ -88,9 +96,9 @@ const useMediaBuffering = ({ element, shouldBuffer, isPremounting, }) => {
88
96
  };
89
97
  init();
90
98
  return () => {
91
- cleanup();
99
+ cleanup('element was unmounted or prop changed');
92
100
  };
93
- }, [buffer, element, isPremounting, shouldBuffer]);
101
+ }, [buffer, element, isPremounting, logLevel, shouldBuffer]);
94
102
  return isBuffering;
95
103
  };
96
104
  exports.useMediaBuffering = useMediaBuffering;
@@ -1,6 +1,6 @@
1
1
  import type { RefObject } from 'react';
2
2
  export declare const DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
3
- export declare const useMediaPlayback: ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, debugSeeking, onAutoPlayError, }: {
3
+ export declare const useMediaPlayback: ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, onAutoPlayError, }: {
4
4
  mediaRef: RefObject<HTMLVideoElement | HTMLAudioElement | null>;
5
5
  src: string | undefined;
6
6
  mediaType: "audio" | "video";
@@ -9,6 +9,5 @@ export declare const useMediaPlayback: ({ mediaRef, src, mediaType, playbackRate
9
9
  acceptableTimeshift: number;
10
10
  pauseWhenBuffering: boolean;
11
11
  isPremounting: boolean;
12
- debugSeeking: boolean;
13
12
  onAutoPlayError: null | (() => void);
14
13
  }) => void;
@@ -5,25 +5,19 @@ const react_1 = require("react");
5
5
  const use_audio_frame_js_1 = require("./audio/use-audio-frame.js");
6
6
  const buffer_until_first_frame_js_1 = require("./buffer-until-first-frame.js");
7
7
  const buffering_js_1 = require("./buffering.js");
8
+ const log_level_context_js_1 = require("./log-level-context.js");
9
+ const log_js_1 = require("./log.js");
8
10
  const play_and_handle_not_allowed_error_js_1 = require("./play-and-handle-not-allowed-error.js");
11
+ const seek_js_1 = require("./seek.js");
9
12
  const timeline_position_state_js_1 = require("./timeline-position-state.js");
10
13
  const use_current_frame_js_1 = require("./use-current-frame.js");
11
14
  const use_media_buffering_js_1 = require("./use-media-buffering.js");
12
15
  const use_request_video_callback_time_js_1 = require("./use-request-video-callback-time.js");
13
16
  const use_video_config_js_1 = require("./use-video-config.js");
14
17
  const get_current_time_js_1 = require("./video/get-current-time.js");
15
- const video_fragment_js_1 = require("./video/video-fragment.js");
16
18
  const warn_about_non_seekable_media_js_1 = require("./warn-about-non-seekable-media.js");
17
19
  exports.DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
18
- const seek = (mediaRef, time) => {
19
- if (!mediaRef.current) {
20
- return;
21
- }
22
- // iOS seeking does not support multiple decimals
23
- const timeToSet = (0, video_fragment_js_1.isIosSafari)() ? Number(time.toFixed(1)) : time;
24
- mediaRef.current.currentTime = timeToSet;
25
- };
26
- const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, debugSeeking, onAutoPlayError, }) => {
20
+ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, onAutoPlayError, }) => {
27
21
  const { playbackRate: globalPlaybackRate } = (0, react_1.useContext)(timeline_position_state_js_1.TimelineContext);
28
22
  const frame = (0, use_current_frame_js_1.useCurrentFrame)();
29
23
  const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)();
@@ -33,6 +27,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
33
27
  const mediaStartsAt = (0, use_audio_frame_js_1.useMediaStartsAt)();
34
28
  const lastSeekDueToShift = (0, react_1.useRef)(null);
35
29
  const lastSeek = (0, react_1.useRef)(null);
30
+ const logLevel = (0, log_level_context_js_1.useLogLevel)();
36
31
  if (!buffering) {
37
32
  throw new Error('useMediaPlayback must be used inside a <BufferingContext>');
38
33
  }
@@ -41,12 +36,9 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
41
36
  if (!src) {
42
37
  return;
43
38
  }
44
- if (debugSeeking) {
45
- // eslint-disable-next-line no-console
46
- console.log(`Detected ${src} as a variable FPS video. Disabling buffering while seeking.`);
47
- }
39
+ log_js_1.Log.verbose(logLevel, `Detected ${src} as a variable FPS video. Disabling buffering while seeking.`);
48
40
  isVariableFpsVideoMap.current[src] = true;
49
- }, [debugSeeking, src]);
41
+ }, [logLevel, src]);
50
42
  const currentTime = (0, use_request_video_callback_time_js_1.useRequestVideoCallbackTime)({
51
43
  mediaRef,
52
44
  mediaType,
@@ -63,6 +55,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
63
55
  element: mediaRef,
64
56
  shouldBuffer: pauseWhenBuffering,
65
57
  isPremounting,
58
+ logLevel,
66
59
  });
67
60
  const { bufferUntilFirstFrame, isBuffering } = (0, buffer_until_first_frame_js_1.useBufferUntilFirstFrame)({
68
61
  mediaRef,
@@ -116,34 +109,17 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
116
109
  const timeShift = timeShiftRvcTag && !isVariableFpsVideo
117
110
  ? timeShiftRvcTag
118
111
  : timeShiftMediaTag;
119
- if (debugSeeking) {
120
- // eslint-disable-next-line no-console
121
- console.log({
122
- mediaTagTime,
123
- rvcTime,
124
- shouldBeTime,
125
- state: mediaRef.current.readyState,
126
- playing: !mediaRef.current.paused,
127
- isVariableFpsVideo,
128
- });
129
- }
130
112
  if (timeShift > acceptableTimeShiftButLessThanDuration &&
131
113
  lastSeekDueToShift.current !== shouldBeTime) {
132
114
  // If scrubbing around, adjust timing
133
115
  // or if time shift is bigger than 0.45sec
134
- if (debugSeeking) {
135
- // eslint-disable-next-line no-console
136
- console.log('Seeking', {
137
- shouldBeTime,
138
- isTime: mediaTagTime,
139
- rvcTime,
140
- timeShift,
141
- isVariableFpsVideo,
142
- });
143
- }
144
- seek(mediaRef, shouldBeTime);
145
- lastSeek.current = shouldBeTime;
146
- lastSeekDueToShift.current = shouldBeTime;
116
+ lastSeek.current = (0, seek_js_1.seek)({
117
+ mediaRef: mediaRef.current,
118
+ time: shouldBeTime,
119
+ logLevel,
120
+ why: `because time shift is too big. shouldBeTime = ${shouldBeTime}, isTime = ${mediaTagTime}, requestVideoCallbackTime = ${rvcTime}, timeShift = ${timeShift}, isVariableFpsVideo = ${Boolean(isVariableFpsVideo)}`,
121
+ });
122
+ lastSeekDueToShift.current = lastSeek.current;
147
123
  if (playing && !isVariableFpsVideo) {
148
124
  if (playbackRate > 0) {
149
125
  bufferUntilFirstFrame(shouldBeTime);
@@ -168,8 +144,12 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
168
144
  const isSomethingElseBuffering = buffering.buffering.current && !isMediaTagBufferingOrStalled;
169
145
  if (!playing || isSomethingElseBuffering) {
170
146
  if (makesSenseToSeek) {
171
- seek(mediaRef, shouldBeTime);
172
- lastSeek.current = shouldBeTime;
147
+ lastSeek.current = (0, seek_js_1.seek)({
148
+ mediaRef: mediaRef.current,
149
+ time: shouldBeTime,
150
+ logLevel,
151
+ why: `not playing or something else is buffering. time offset is over seek threshold (${seekThreshold})`,
152
+ });
173
153
  }
174
154
  return;
175
155
  }
@@ -177,8 +157,12 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
177
157
  if ((mediaRef.current.paused && !mediaRef.current.ended) ||
178
158
  absoluteFrame === 0) {
179
159
  if (makesSenseToSeek) {
180
- seek(mediaRef, shouldBeTime);
181
- lastSeek.current = shouldBeTime;
160
+ lastSeek.current = (0, seek_js_1.seek)({
161
+ mediaRef: mediaRef.current,
162
+ time: shouldBeTime,
163
+ logLevel,
164
+ why: `is over timeshift threshold (threshold = ${seekThreshold}) is paused OR has reached end of timeline and is starting over`,
165
+ });
182
166
  }
183
167
  (0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType, onAutoPlayError);
184
168
  if (!isVariableFpsVideo) {
@@ -193,7 +177,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
193
177
  bufferUntilFirstFrame,
194
178
  buffering.buffering,
195
179
  currentTime,
196
- debugSeeking,
180
+ logLevel,
197
181
  desiredUnclampedTime,
198
182
  isBuffering,
199
183
  isMediaTagBuffering,
@@ -3,4 +3,4 @@
3
3
  * @see [Documentation](https://remotion.dev/docs/version)
4
4
  * @returns {string} The current version of the remotion package
5
5
  */
6
- export declare const VERSION = "4.0.249";
6
+ export declare const VERSION = "4.0.251";
@@ -7,4 +7,4 @@ exports.VERSION = void 0;
7
7
  * @see [Documentation](https://remotion.dev/docs/version)
8
8
  * @returns {string} The current version of the remotion package
9
9
  */
10
- exports.VERSION = '4.0.249';
10
+ exports.VERSION = '4.0.251';
@@ -35,7 +35,7 @@ const OffthreadVideo = (props) => {
35
35
  if (environment.isRendering) {
36
36
  return (0, jsx_runtime_1.jsx)(OffthreadVideoForRendering_js_1.OffthreadVideoForRendering, { ...otherProps });
37
37
  }
38
- const { transparent, toneMapped, _remotionDebugSeeking, onAutoPlayError, onVideoFrame, crossOrigin, delayRenderRetries, delayRenderTimeoutInMilliseconds, ...propsForPreview } = otherProps;
39
- return ((0, jsx_runtime_1.jsx)(VideoForPreview_js_1.VideoForPreview, { _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: false, _remotionDebugSeeking: _remotionDebugSeeking !== null && _remotionDebugSeeking !== void 0 ? _remotionDebugSeeking : false, onDuration: onDuration, onlyWarnForMediaSeekingError: true, pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, onAutoPlayError: onAutoPlayError !== null && onAutoPlayError !== void 0 ? onAutoPlayError : undefined, onVideoFrame: onVideoFrame !== null && onVideoFrame !== void 0 ? onVideoFrame : null, crossOrigin: crossOrigin, ...propsForPreview }));
38
+ const { transparent, toneMapped, onAutoPlayError, onVideoFrame, crossOrigin, delayRenderRetries, delayRenderTimeoutInMilliseconds, ...propsForPreview } = otherProps;
39
+ return ((0, jsx_runtime_1.jsx)(VideoForPreview_js_1.VideoForPreview, { _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: false, onDuration: onDuration, onlyWarnForMediaSeekingError: true, pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, onAutoPlayError: onAutoPlayError !== null && onAutoPlayError !== void 0 ? onAutoPlayError : undefined, onVideoFrame: onVideoFrame !== null && onVideoFrame !== void 0 ? onVideoFrame : null, crossOrigin: crossOrigin, ...propsForPreview }));
40
40
  };
41
41
  exports.OffthreadVideo = OffthreadVideo;
@@ -20,7 +20,7 @@ const duration_state_js_1 = require("./duration-state.js");
20
20
  const VideoForwardingFunction = (props, ref) => {
21
21
  var _a, _b;
22
22
  const { startFrom, endAt, name, pauseWhenBuffering, stack, _remotionInternalNativeLoopPassed, showInTimeline, onAutoPlayError, ...otherProps } = props;
23
- const { loop, _remotionDebugSeeking, ...propsOtherThanLoop } = props;
23
+ const { loop, ...propsOtherThanLoop } = props;
24
24
  const { fps } = (0, use_video_config_js_1.useVideoConfig)();
25
25
  const environment = (0, get_remotion_environment_js_1.getRemotionEnvironment)();
26
26
  const { durations, setDurations } = (0, react_1.useContext)(duration_state_js_1.DurationsContext);
@@ -60,7 +60,7 @@ const VideoForwardingFunction = (props, ref) => {
60
60
  }
61
61
  return ((0, jsx_runtime_1.jsx)(VideoForPreview_js_1.VideoForPreview, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref, onVideoFrame: null,
62
62
  // Proposal: Make this default to true in v5
63
- pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, onDuration: onDuration, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed !== null && _remotionInternalNativeLoopPassed !== void 0 ? _remotionInternalNativeLoopPassed : false, _remotionDebugSeeking: _remotionDebugSeeking !== null && _remotionDebugSeeking !== void 0 ? _remotionDebugSeeking : false, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, onAutoPlayError: onAutoPlayError !== null && onAutoPlayError !== void 0 ? onAutoPlayError : undefined }));
63
+ pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, onDuration: onDuration, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed !== null && _remotionInternalNativeLoopPassed !== void 0 ? _remotionInternalNativeLoopPassed : false, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, onAutoPlayError: onAutoPlayError !== null && onAutoPlayError !== void 0 ? onAutoPlayError : undefined }));
64
64
  };
65
65
  /*
66
66
  * @description Wraps the native `<video>` element to include video in your component that is synchronized with Remotion's time.
@@ -6,7 +6,6 @@ type VideoForPreviewProps = RemotionVideoProps & {
6
6
  readonly pauseWhenBuffering: boolean;
7
7
  readonly _remotionInternalNativeLoopPassed: boolean;
8
8
  readonly _remotionInternalStack: string | null;
9
- readonly _remotionDebugSeeking: boolean;
10
9
  readonly showInTimeline: boolean;
11
10
  readonly onVideoFrame: null | OnVideoFrame;
12
11
  readonly crossOrigin?: '' | 'anonymous' | 'use-credentials';