remotion 4.0.186 → 4.0.188
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/_check-rsc.d.ts +1 -0
- package/dist/cjs/_check-rsc.js +17 -0
- package/dist/cjs/audio/AudioForPreview.js +2 -0
- package/dist/cjs/audio/shared-audio-tags.d.ts +3 -3
- package/dist/cjs/audio/shared-audio-tags.js +1 -1
- package/dist/cjs/buffer-until-first-frame.d.ts +2 -1
- package/dist/cjs/buffer-until-first-frame.js +11 -2
- package/dist/cjs/check-rsc.d.ts +1 -0
- package/dist/cjs/check-rsc.js +6 -0
- package/dist/cjs/internals.d.ts +3 -3
- package/dist/cjs/play-and-handle-not-allowed-error.d.ts +1 -1
- package/dist/cjs/play-and-handle-not-allowed-error.js +10 -1
- package/dist/cjs/use-media-in-timeline.d.ts +2 -1
- package/dist/cjs/use-media-in-timeline.js +3 -3
- package/dist/cjs/use-media-playback.d.ts +2 -1
- package/dist/cjs/use-media-playback.js +27 -15
- package/dist/cjs/use-request-video-callback-time.d.ts +6 -1
- package/dist/cjs/use-request-video-callback-time.js +16 -2
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/video/OffthreadVideo.js +2 -2
- package/dist/cjs/video/OffthreadVideoForRendering.js +13 -3
- package/dist/cjs/video/Video.d.ts +1 -0
- package/dist/cjs/video/Video.js +2 -2
- package/dist/cjs/video/VideoForPreview.js +3 -1
- package/dist/cjs/video/VideoForRendering.d.ts +1 -0
- package/dist/cjs/video/props.d.ts +2 -0
- package/dist/esm/index.mjs +119 -102
- package/dist/esm/no-react.mjs +6 -6
- package/dist/esm/version.mjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const react_1 = require("react");
|
|
4
|
+
if (typeof react_1.createContext !== 'function') {
|
|
5
|
+
const err = [
|
|
6
|
+
'Remotion requires React.createContext, but it is "undefined".',
|
|
7
|
+
'If you are in a React Server Component, turn it into a client component by adding "use client" at the top of the file.',
|
|
8
|
+
'',
|
|
9
|
+
'Before:',
|
|
10
|
+
' import {useCurrentFrame} from "remotion";',
|
|
11
|
+
'',
|
|
12
|
+
'After:',
|
|
13
|
+
' "use client";',
|
|
14
|
+
' import {useCurrentFrame} from "remotion";',
|
|
15
|
+
];
|
|
16
|
+
throw new Error(err.join('\n'));
|
|
17
|
+
}
|
|
@@ -86,6 +86,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
86
86
|
stack: _remotionInternalStack,
|
|
87
87
|
showInTimeline,
|
|
88
88
|
premountDisplay: null,
|
|
89
|
+
onAutoPlayError: null,
|
|
89
90
|
});
|
|
90
91
|
(0, use_media_playback_js_1.useMediaPlayback)({
|
|
91
92
|
mediaRef: audioRef,
|
|
@@ -97,6 +98,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
97
98
|
isPremounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
|
|
98
99
|
pauseWhenBuffering,
|
|
99
100
|
debugSeeking: _remotionDebugSeeking,
|
|
101
|
+
onAutoPlayError: null,
|
|
100
102
|
});
|
|
101
103
|
(0, react_1.useImperativeHandle)(ref, () => {
|
|
102
104
|
return audioRef.current;
|
|
@@ -31,9 +31,9 @@ type SharedContext = {
|
|
|
31
31
|
};
|
|
32
32
|
export declare const SharedAudioContext: React.Context<SharedContext | null>;
|
|
33
33
|
export declare const SharedAudioContextProvider: React.FC<{
|
|
34
|
-
numberOfAudioTags: number;
|
|
35
|
-
children: React.ReactNode;
|
|
36
|
-
component: LazyExoticComponent<ComponentType<Record<string, unknown>>> | null;
|
|
34
|
+
readonly numberOfAudioTags: number;
|
|
35
|
+
readonly children: React.ReactNode;
|
|
36
|
+
readonly component: LazyExoticComponent<ComponentType<Record<string, unknown>>> | null;
|
|
37
37
|
}>;
|
|
38
38
|
export declare const useSharedAudio: (aud: RemotionAudioProps, audioId: string) => AudioElem;
|
|
39
39
|
export {};
|
|
@@ -158,7 +158,7 @@ const SharedAudioContextProvider = ({ children, numberOfAudioTags, component })
|
|
|
158
158
|
}, [rerenderAudios]);
|
|
159
159
|
const playAllAudios = (0, react_1.useCallback)(() => {
|
|
160
160
|
refs.forEach((ref) => {
|
|
161
|
-
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(ref.ref, 'audio');
|
|
161
|
+
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(ref.ref, 'audio', null);
|
|
162
162
|
});
|
|
163
163
|
}, [refs]);
|
|
164
164
|
const value = (0, react_1.useMemo)(() => {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export declare const useBufferUntilFirstFrame: ({ mediaRef, mediaType, onVariableFpsVideoDetected, }: {
|
|
1
|
+
export declare const useBufferUntilFirstFrame: ({ mediaRef, mediaType, onVariableFpsVideoDetected, pauseWhenBuffering, }: {
|
|
2
2
|
mediaRef: React.RefObject<HTMLVideoElement | HTMLAudioElement>;
|
|
3
3
|
mediaType: 'video' | 'audio';
|
|
4
4
|
onVariableFpsVideoDetected: () => void;
|
|
5
|
+
pauseWhenBuffering: boolean;
|
|
5
6
|
}) => {
|
|
6
7
|
isBuffering: () => boolean;
|
|
7
8
|
bufferUntilFirstFrame: (requestedTime: number) => void;
|
|
@@ -3,13 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.useBufferUntilFirstFrame = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const use_buffer_state_1 = require("./use-buffer-state");
|
|
6
|
-
const useBufferUntilFirstFrame = ({ mediaRef, mediaType, onVariableFpsVideoDetected, }) => {
|
|
6
|
+
const useBufferUntilFirstFrame = ({ mediaRef, mediaType, onVariableFpsVideoDetected, pauseWhenBuffering, }) => {
|
|
7
7
|
const bufferingRef = (0, react_1.useRef)(false);
|
|
8
8
|
const { delayPlayback } = (0, use_buffer_state_1.useBufferState)();
|
|
9
9
|
const bufferUntilFirstFrame = (0, react_1.useCallback)((requestedTime) => {
|
|
10
10
|
if (mediaType !== 'video') {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
+
if (!pauseWhenBuffering) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
13
16
|
const current = mediaRef.current;
|
|
14
17
|
if (!current) {
|
|
15
18
|
return;
|
|
@@ -47,7 +50,13 @@ const useBufferUntilFirstFrame = ({ mediaRef, mediaType, onVariableFpsVideoDetec
|
|
|
47
50
|
});
|
|
48
51
|
current.addEventListener('ended', onEndedOrPause, { once: true });
|
|
49
52
|
current.addEventListener('pause', onEndedOrPause, { once: true });
|
|
50
|
-
}, [
|
|
53
|
+
}, [
|
|
54
|
+
delayPlayback,
|
|
55
|
+
mediaRef,
|
|
56
|
+
mediaType,
|
|
57
|
+
onVariableFpsVideoDetected,
|
|
58
|
+
pauseWhenBuffering,
|
|
59
|
+
]);
|
|
51
60
|
return (0, react_1.useMemo)(() => {
|
|
52
61
|
return {
|
|
53
62
|
isBuffering: () => bufferingRef.current,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cjs/internals.d.ts
CHANGED
|
@@ -56,9 +56,9 @@ export declare const Internals: {
|
|
|
56
56
|
numberOfAudioTags: number;
|
|
57
57
|
} | null>;
|
|
58
58
|
readonly SharedAudioContextProvider: import("react").FC<{
|
|
59
|
-
numberOfAudioTags: number;
|
|
60
|
-
children: import("react").ReactNode;
|
|
61
|
-
component: import("react").LazyExoticComponent<import("react").ComponentType<Record<string, unknown>>> | null;
|
|
59
|
+
readonly numberOfAudioTags: number;
|
|
60
|
+
readonly children: import("react").ReactNode;
|
|
61
|
+
readonly component: import("react").LazyExoticComponent<import("react").ComponentType<Record<string, unknown>>> | null;
|
|
62
62
|
}>;
|
|
63
63
|
readonly invalidCompositionErrorMessage: string;
|
|
64
64
|
readonly isCompositionIdValid: (id: string) => RegExpMatchArray | null;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { RefObject } from 'react';
|
|
2
|
-
export declare const playAndHandleNotAllowedError: (mediaRef: RefObject<HTMLVideoElement | HTMLAudioElement>, mediaType: 'audio' | 'video') => void;
|
|
2
|
+
export declare const playAndHandleNotAllowedError: (mediaRef: RefObject<HTMLVideoElement | HTMLAudioElement>, mediaType: 'audio' | 'video', onAutoPlayError: null | (() => void)) => void;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.playAndHandleNotAllowedError = void 0;
|
|
4
|
-
const
|
|
4
|
+
const get_remotion_environment_1 = require("./get-remotion-environment");
|
|
5
|
+
const playAndHandleNotAllowedError = (mediaRef, mediaType, onAutoPlayError) => {
|
|
5
6
|
const { current } = mediaRef;
|
|
6
7
|
if (!current) {
|
|
7
8
|
return;
|
|
@@ -35,8 +36,16 @@ const playAndHandleNotAllowedError = (mediaRef, mediaType) => {
|
|
|
35
36
|
// eslint-disable-next-line no-console
|
|
36
37
|
console.log(`Could not play ${mediaType} due to following error: `, err);
|
|
37
38
|
if (!current.muted) {
|
|
39
|
+
if (onAutoPlayError) {
|
|
40
|
+
onAutoPlayError();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
38
43
|
// eslint-disable-next-line no-console
|
|
39
44
|
console.log(`The video will be muted and we'll retry playing it.`);
|
|
45
|
+
if (mediaType === 'video' && (0, get_remotion_environment_1.getRemotionEnvironment)().isPlayer) {
|
|
46
|
+
// eslint-disable-next-line no-console
|
|
47
|
+
console.log('Use onAutoPlayError() to handle this error yourself.');
|
|
48
|
+
}
|
|
40
49
|
current.muted = true;
|
|
41
50
|
current.play();
|
|
42
51
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RefObject } from 'react';
|
|
2
2
|
import type { VolumeProp } from './volume-prop.js';
|
|
3
|
-
export declare const useMediaInTimeline: ({ volume, mediaVolume, mediaRef, src, mediaType, playbackRate, displayName, id, stack, showInTimeline, premountDisplay, }: {
|
|
3
|
+
export declare const useMediaInTimeline: ({ volume, mediaVolume, mediaRef, src, mediaType, playbackRate, displayName, id, stack, showInTimeline, premountDisplay, onAutoPlayError, }: {
|
|
4
4
|
volume: VolumeProp | undefined;
|
|
5
5
|
mediaVolume: number;
|
|
6
6
|
mediaRef: RefObject<HTMLAudioElement | HTMLVideoElement>;
|
|
@@ -12,4 +12,5 @@ export declare const useMediaInTimeline: ({ volume, mediaVolume, mediaRef, src,
|
|
|
12
12
|
stack: string | null;
|
|
13
13
|
showInTimeline: boolean;
|
|
14
14
|
premountDisplay: number | null;
|
|
15
|
+
onAutoPlayError: null | (() => void);
|
|
15
16
|
}) => void;
|
|
@@ -21,7 +21,7 @@ const warnOnce = (message) => {
|
|
|
21
21
|
console.warn(message);
|
|
22
22
|
didWarn[message] = true;
|
|
23
23
|
};
|
|
24
|
-
const useMediaInTimeline = ({ volume, mediaVolume, mediaRef, src, mediaType, playbackRate, displayName, id, stack, showInTimeline, premountDisplay, }) => {
|
|
24
|
+
const useMediaInTimeline = ({ volume, mediaVolume, mediaRef, src, mediaType, playbackRate, displayName, id, stack, showInTimeline, premountDisplay, onAutoPlayError, }) => {
|
|
25
25
|
const videoConfig = (0, use_video_config_js_1.useVideoConfig)();
|
|
26
26
|
const { rootId, audioAndVideoTags } = (0, react_1.useContext)(timeline_position_state_js_1.TimelineContext);
|
|
27
27
|
const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
|
@@ -125,13 +125,13 @@ const useMediaInTimeline = ({ volume, mediaVolume, mediaRef, src, mediaType, pla
|
|
|
125
125
|
// Don't play if for example in a <Freeze> state.
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
|
-
return (0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType);
|
|
128
|
+
return (0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType, onAutoPlayError);
|
|
129
129
|
},
|
|
130
130
|
};
|
|
131
131
|
audioAndVideoTags.current.push(tag);
|
|
132
132
|
return () => {
|
|
133
133
|
audioAndVideoTags.current = audioAndVideoTags.current.filter((a) => a.id !== id);
|
|
134
134
|
};
|
|
135
|
-
}, [audioAndVideoTags, id, mediaRef, mediaType, playing]);
|
|
135
|
+
}, [audioAndVideoTags, id, mediaRef, mediaType, onAutoPlayError, playing]);
|
|
136
136
|
};
|
|
137
137
|
exports.useMediaInTimeline = useMediaInTimeline;
|
|
@@ -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, }: {
|
|
3
|
+
export declare const useMediaPlayback: ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, debugSeeking, onAutoPlayError, }: {
|
|
4
4
|
mediaRef: RefObject<HTMLVideoElement | HTMLAudioElement>;
|
|
5
5
|
src: string | undefined;
|
|
6
6
|
mediaType: 'audio' | 'video';
|
|
@@ -10,4 +10,5 @@ export declare const useMediaPlayback: ({ mediaRef, src, mediaType, playbackRate
|
|
|
10
10
|
pauseWhenBuffering: boolean;
|
|
11
11
|
isPremounting: boolean;
|
|
12
12
|
debugSeeking: boolean;
|
|
13
|
+
onAutoPlayError: null | (() => void);
|
|
13
14
|
}) => void;
|
|
@@ -23,7 +23,7 @@ const seek = (mediaRef, time) => {
|
|
|
23
23
|
const timeToSet = (0, video_fragment_js_1.isIosSafari)() ? Number(time.toFixed(1)) : time;
|
|
24
24
|
mediaRef.current.currentTime = timeToSet;
|
|
25
25
|
};
|
|
26
|
-
const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, debugSeeking, }) => {
|
|
26
|
+
const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, debugSeeking, onAutoPlayError, }) => {
|
|
27
27
|
const { playbackRate: globalPlaybackRate } = (0, react_1.useContext)(timeline_position_state_js_1.TimelineContext);
|
|
28
28
|
const frame = (0, use_current_frame_js_1.useCurrentFrame)();
|
|
29
29
|
const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)();
|
|
@@ -32,21 +32,10 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
32
32
|
const { fps } = (0, use_video_config_js_1.useVideoConfig)();
|
|
33
33
|
const mediaStartsAt = (0, use_audio_frame_js_1.useMediaStartsAt)();
|
|
34
34
|
const lastSeekDueToShift = (0, react_1.useRef)(null);
|
|
35
|
+
const lastSeek = (0, react_1.useRef)(null);
|
|
35
36
|
if (!buffering) {
|
|
36
37
|
throw new Error('useMediaPlayback must be used inside a <BufferingContext>');
|
|
37
38
|
}
|
|
38
|
-
const currentTime = (0, use_request_video_callback_time_js_1.useRequestVideoCallbackTime)(mediaRef, mediaType);
|
|
39
|
-
const desiredUnclampedTime = (0, get_current_time_js_1.getMediaTime)({
|
|
40
|
-
frame,
|
|
41
|
-
playbackRate: localPlaybackRate,
|
|
42
|
-
startFrom: -mediaStartsAt,
|
|
43
|
-
fps,
|
|
44
|
-
});
|
|
45
|
-
const isMediaTagBuffering = (0, use_media_buffering_js_1.useMediaBuffering)({
|
|
46
|
-
element: mediaRef,
|
|
47
|
-
shouldBuffer: pauseWhenBuffering,
|
|
48
|
-
isPremounting,
|
|
49
|
-
});
|
|
50
39
|
const isVariableFpsVideoMap = (0, react_1.useRef)({});
|
|
51
40
|
const onVariableFpsVideoDetected = (0, react_1.useCallback)(() => {
|
|
52
41
|
if (!src) {
|
|
@@ -58,10 +47,28 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
58
47
|
}
|
|
59
48
|
isVariableFpsVideoMap.current[src] = true;
|
|
60
49
|
}, [debugSeeking, src]);
|
|
50
|
+
const currentTime = (0, use_request_video_callback_time_js_1.useRequestVideoCallbackTime)({
|
|
51
|
+
mediaRef,
|
|
52
|
+
mediaType,
|
|
53
|
+
lastSeek,
|
|
54
|
+
onVariableFpsVideoDetected,
|
|
55
|
+
});
|
|
56
|
+
const desiredUnclampedTime = (0, get_current_time_js_1.getMediaTime)({
|
|
57
|
+
frame,
|
|
58
|
+
playbackRate: localPlaybackRate,
|
|
59
|
+
startFrom: -mediaStartsAt,
|
|
60
|
+
fps,
|
|
61
|
+
});
|
|
62
|
+
const isMediaTagBuffering = (0, use_media_buffering_js_1.useMediaBuffering)({
|
|
63
|
+
element: mediaRef,
|
|
64
|
+
shouldBuffer: pauseWhenBuffering,
|
|
65
|
+
isPremounting,
|
|
66
|
+
});
|
|
61
67
|
const { bufferUntilFirstFrame, isBuffering } = (0, buffer_until_first_frame_js_1.useBufferUntilFirstFrame)({
|
|
62
68
|
mediaRef,
|
|
63
69
|
mediaType,
|
|
64
70
|
onVariableFpsVideoDetected,
|
|
71
|
+
pauseWhenBuffering,
|
|
65
72
|
});
|
|
66
73
|
const playbackRate = localPlaybackRate * globalPlaybackRate;
|
|
67
74
|
// For short audio, a lower acceptable time shift is used
|
|
@@ -137,14 +144,16 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
137
144
|
isTime: mediaTagTime,
|
|
138
145
|
rvcTime,
|
|
139
146
|
timeShift,
|
|
147
|
+
isVariableFpsVideo,
|
|
140
148
|
});
|
|
141
149
|
}
|
|
142
150
|
seek(mediaRef, shouldBeTime);
|
|
151
|
+
lastSeek.current = shouldBeTime;
|
|
143
152
|
lastSeekDueToShift.current = shouldBeTime;
|
|
144
153
|
if (playing && !isVariableFpsVideo) {
|
|
145
154
|
bufferUntilFirstFrame(shouldBeTime);
|
|
146
155
|
if (mediaRef.current.paused) {
|
|
147
|
-
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType);
|
|
156
|
+
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType, onAutoPlayError);
|
|
148
157
|
}
|
|
149
158
|
}
|
|
150
159
|
if (!onlyWarnForMediaSeekingError) {
|
|
@@ -164,6 +173,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
164
173
|
if (!playing || isSomethingElseBuffering) {
|
|
165
174
|
if (makesSenseToSeek) {
|
|
166
175
|
seek(mediaRef, shouldBeTime);
|
|
176
|
+
lastSeek.current = shouldBeTime;
|
|
167
177
|
}
|
|
168
178
|
return;
|
|
169
179
|
}
|
|
@@ -172,8 +182,9 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
172
182
|
absoluteFrame === 0) {
|
|
173
183
|
if (makesSenseToSeek) {
|
|
174
184
|
seek(mediaRef, shouldBeTime);
|
|
185
|
+
lastSeek.current = shouldBeTime;
|
|
175
186
|
}
|
|
176
|
-
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType);
|
|
187
|
+
(0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType, onAutoPlayError);
|
|
177
188
|
if (!isVariableFpsVideo) {
|
|
178
189
|
bufferUntilFirstFrame(shouldBeTime);
|
|
179
190
|
}
|
|
@@ -194,6 +205,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
|
|
|
194
205
|
playbackRate,
|
|
195
206
|
playing,
|
|
196
207
|
src,
|
|
208
|
+
onAutoPlayError,
|
|
197
209
|
]);
|
|
198
210
|
};
|
|
199
211
|
exports.useMediaPlayback = useMediaPlayback;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { RefObject } from 'react';
|
|
2
|
-
export declare const useRequestVideoCallbackTime: (mediaRef
|
|
2
|
+
export declare const useRequestVideoCallbackTime: ({ mediaRef, mediaType, lastSeek, onVariableFpsVideoDetected, }: {
|
|
3
|
+
mediaRef: RefObject<HTMLVideoElement | HTMLAudioElement>;
|
|
4
|
+
mediaType: 'video' | 'audio';
|
|
5
|
+
lastSeek: React.MutableRefObject<number | null>;
|
|
6
|
+
onVariableFpsVideoDetected: () => void;
|
|
7
|
+
}) => import("react").MutableRefObject<number | null>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useRequestVideoCallbackTime = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
const useRequestVideoCallbackTime = (mediaRef, mediaType) => {
|
|
5
|
+
const useRequestVideoCallbackTime = ({ mediaRef, mediaType, lastSeek, onVariableFpsVideoDetected, }) => {
|
|
6
6
|
const currentTime = (0, react_1.useRef)(null);
|
|
7
7
|
(0, react_1.useEffect)(() => {
|
|
8
8
|
const { current } = mediaRef;
|
|
@@ -27,6 +27,20 @@ const useRequestVideoCallbackTime = (mediaRef, mediaType) => {
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
const cb = videoTag.requestVideoFrameCallback((_, info) => {
|
|
30
|
+
if (currentTime.current !== null) {
|
|
31
|
+
const difference = Math.abs(currentTime.current - info.mediaTime);
|
|
32
|
+
const differenceToLastSeek = Math.abs(lastSeek.current === null
|
|
33
|
+
? Infinity
|
|
34
|
+
: info.mediaTime - lastSeek.current);
|
|
35
|
+
// If a video suddenly jumps to a position much further than previously
|
|
36
|
+
// and there was no relevant seek
|
|
37
|
+
// Case to be seen with 66a4a49b0862333a56c7d03c.mp4 and autoPlay and pauseWhenBuffering
|
|
38
|
+
if (difference > 0.5 &&
|
|
39
|
+
differenceToLastSeek > 0.5 &&
|
|
40
|
+
info.mediaTime > currentTime.current) {
|
|
41
|
+
onVariableFpsVideoDetected();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
30
44
|
currentTime.current = info.mediaTime;
|
|
31
45
|
request();
|
|
32
46
|
});
|
|
@@ -39,7 +53,7 @@ const useRequestVideoCallbackTime = (mediaRef, mediaType) => {
|
|
|
39
53
|
return () => {
|
|
40
54
|
cancel();
|
|
41
55
|
};
|
|
42
|
-
}, [mediaRef, mediaType]);
|
|
56
|
+
}, [lastSeek, mediaRef, mediaType, onVariableFpsVideoDetected]);
|
|
43
57
|
return currentTime;
|
|
44
58
|
};
|
|
45
59
|
exports.useRequestVideoCallbackTime = useRequestVideoCallbackTime;
|
package/dist/cjs/version.d.ts
CHANGED
package/dist/cjs/version.js
CHANGED
|
@@ -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, ...withoutTransparent } = 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, ...withoutTransparent }));
|
|
38
|
+
const { transparent, toneMapped, _remotionDebugSeeking, onAutoPlayError, ...withoutTransparent } = 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, ...withoutTransparent }));
|
|
40
40
|
};
|
|
41
41
|
exports.OffthreadVideo = OffthreadVideo;
|
|
@@ -130,10 +130,19 @@ const OffthreadVideoForRendering = ({ onError, volume: volumeProp, playbackRate,
|
|
|
130
130
|
const blob = await res.blob();
|
|
131
131
|
const url = URL.createObjectURL(blob);
|
|
132
132
|
cleanup.push(() => URL.revokeObjectURL(url));
|
|
133
|
-
setImageSrc(
|
|
134
|
-
|
|
133
|
+
setImageSrc({
|
|
134
|
+
src: url,
|
|
135
|
+
handle: newHandle,
|
|
136
|
+
});
|
|
135
137
|
}
|
|
136
138
|
catch (err) {
|
|
139
|
+
// If component is unmounted, we should not throw
|
|
140
|
+
if (err.message.includes('aborted')) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (controller.signal.aborted) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
137
146
|
if (onError) {
|
|
138
147
|
onError(err);
|
|
139
148
|
}
|
|
@@ -174,6 +183,7 @@ const OffthreadVideoForRendering = ({ onError, volume: volumeProp, playbackRate,
|
|
|
174
183
|
if (!imageSrc) {
|
|
175
184
|
return null;
|
|
176
185
|
}
|
|
177
|
-
|
|
186
|
+
(0, delay_render_js_1.continueRender)(imageSrc.handle);
|
|
187
|
+
return ((0, jsx_runtime_1.jsx)(Img_js_1.Img, { src: imageSrc.src, className: className, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, ...props, onError: onErr }));
|
|
178
188
|
};
|
|
179
189
|
exports.OffthreadVideoForRendering = OffthreadVideoForRendering;
|
|
@@ -17,6 +17,7 @@ export declare const Video: React.ForwardRefExoticComponent<Omit<Omit<React.Deta
|
|
|
17
17
|
loopVolumeCurveBehavior?: import("../audio/use-audio-frame.js").LoopVolumeCurveBehavior | undefined;
|
|
18
18
|
delayRenderRetries?: number | undefined;
|
|
19
19
|
onError?: ((err: Error) => void) | undefined;
|
|
20
|
+
onAutoPlayError?: (() => void) | undefined;
|
|
20
21
|
} & RemotionMainVideoProps & {
|
|
21
22
|
/**
|
|
22
23
|
* @deprecated For internal use only
|
package/dist/cjs/video/Video.js
CHANGED
|
@@ -19,7 +19,7 @@ const VideoForRendering_js_1 = require("./VideoForRendering.js");
|
|
|
19
19
|
const duration_state_js_1 = require("./duration-state.js");
|
|
20
20
|
const VideoForwardingFunction = (props, ref) => {
|
|
21
21
|
var _a, _b;
|
|
22
|
-
const { startFrom, endAt, name, pauseWhenBuffering, stack, _remotionInternalNativeLoopPassed, showInTimeline, ...otherProps } = props;
|
|
22
|
+
const { startFrom, endAt, name, pauseWhenBuffering, stack, _remotionInternalNativeLoopPassed, showInTimeline, onAutoPlayError, ...otherProps } = props;
|
|
23
23
|
const { loop, _remotionDebugSeeking, ...propsOtherThanLoop } = props;
|
|
24
24
|
const { fps } = (0, use_video_config_js_1.useVideoConfig)();
|
|
25
25
|
const environment = (0, get_remotion_environment_js_1.getRemotionEnvironment)();
|
|
@@ -56,7 +56,7 @@ const VideoForwardingFunction = (props, ref) => {
|
|
|
56
56
|
}
|
|
57
57
|
return ((0, jsx_runtime_1.jsx)(VideoForPreview_js_1.VideoForPreview, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref,
|
|
58
58
|
// Proposal: Make this default to true in v5
|
|
59
|
-
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 }));
|
|
59
|
+
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 }));
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* @description allows you to include a video file in your Remotion project. It wraps the native HTMLVideoElement.
|
|
@@ -19,7 +19,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
|
|
|
19
19
|
const videoRef = (0, react_1.useRef)(null);
|
|
20
20
|
const { volume, muted, playbackRate, onlyWarnForMediaSeekingError, src, onDuration,
|
|
21
21
|
// @ts-expect-error
|
|
22
|
-
acceptableTimeShift, acceptableTimeShiftInSeconds, toneFrequency, name, _remotionInternalNativeLoopPassed, _remotionInternalStack, _remotionDebugSeeking, style, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, onError, ...nativeProps } = props;
|
|
22
|
+
acceptableTimeShift, acceptableTimeShiftInSeconds, toneFrequency, name, _remotionInternalNativeLoopPassed, _remotionInternalStack, _remotionDebugSeeking, style, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, onError, onAutoPlayError, ...nativeProps } = props;
|
|
23
23
|
const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
|
|
24
24
|
const { fps, durationInFrames } = (0, use_video_config_js_1.useVideoConfig)();
|
|
25
25
|
const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
|
|
@@ -44,6 +44,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
|
|
|
44
44
|
stack: _remotionInternalStack,
|
|
45
45
|
showInTimeline,
|
|
46
46
|
premountDisplay: null,
|
|
47
|
+
onAutoPlayError: onAutoPlayError !== null && onAutoPlayError !== void 0 ? onAutoPlayError : null,
|
|
47
48
|
});
|
|
48
49
|
(0, use_sync_volume_with_media_tag_js_1.useSyncVolumeWithMediaTag)({
|
|
49
50
|
volumePropFrame,
|
|
@@ -62,6 +63,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
|
|
|
62
63
|
isPremounting: Boolean(parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.premounting),
|
|
63
64
|
pauseWhenBuffering,
|
|
64
65
|
debugSeeking: _remotionDebugSeeking,
|
|
66
|
+
onAutoPlayError: onAutoPlayError !== null && onAutoPlayError !== void 0 ? onAutoPlayError : null,
|
|
65
67
|
});
|
|
66
68
|
const actualFrom = parentSequence ? parentSequence.relativeFrom : 0;
|
|
67
69
|
const duration = parentSequence
|
|
@@ -13,6 +13,7 @@ export declare const VideoForRendering: ForwardRefExoticComponent<Omit<React.Det
|
|
|
13
13
|
loopVolumeCurveBehavior?: import("../audio/use-audio-frame.js").LoopVolumeCurveBehavior | undefined;
|
|
14
14
|
delayRenderRetries?: number | undefined;
|
|
15
15
|
onError?: ((err: Error) => void) | undefined;
|
|
16
|
+
onAutoPlayError?: (() => void) | undefined;
|
|
16
17
|
} & {
|
|
17
18
|
readonly onDuration: (src: string, durationInSeconds: number) => void;
|
|
18
19
|
} & RefAttributes<HTMLVideoElement>>;
|
|
@@ -23,6 +23,7 @@ export type RemotionVideoProps = Omit<React.DetailedHTMLProps<React.VideoHTMLAtt
|
|
|
23
23
|
loopVolumeCurveBehavior?: LoopVolumeCurveBehavior;
|
|
24
24
|
delayRenderRetries?: number;
|
|
25
25
|
onError?: (err: Error) => void;
|
|
26
|
+
onAutoPlayError?: () => void;
|
|
26
27
|
};
|
|
27
28
|
type DeprecatedOffthreadVideoProps = {
|
|
28
29
|
/**
|
|
@@ -54,5 +55,6 @@ export type OffthreadVideoProps = {
|
|
|
54
55
|
*/
|
|
55
56
|
stack?: string;
|
|
56
57
|
showInTimeline?: boolean;
|
|
58
|
+
onAutoPlayError?: null | (() => void);
|
|
57
59
|
} & RemotionMainVideoProps & DeprecatedOffthreadVideoProps;
|
|
58
60
|
export {};
|
package/dist/esm/index.mjs
CHANGED
|
@@ -138,7 +138,7 @@ function truthy(value) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
// src/version.ts
|
|
141
|
-
var VERSION = "4.0.
|
|
141
|
+
var VERSION = "4.0.188";
|
|
142
142
|
|
|
143
143
|
// src/multiple-versions-warning.ts
|
|
144
144
|
var checkMultipleRemotionVersions = () => {
|
|
@@ -300,46 +300,14 @@ var useNonce = () => {
|
|
|
300
300
|
// src/timeline-position-state.ts
|
|
301
301
|
var exports_timeline_position_state = {};
|
|
302
302
|
__export(exports_timeline_position_state, {
|
|
303
|
-
useTimelineSetFrame: () =>
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
usePlayingState: () => {
|
|
314
|
-
{
|
|
315
|
-
return usePlayingState;
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
|
-
persistCurrentFrame: () => {
|
|
319
|
-
{
|
|
320
|
-
return persistCurrentFrame;
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
getInitialFrameState: () => {
|
|
324
|
-
{
|
|
325
|
-
return getInitialFrameState;
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
getFrameForComposition: () => {
|
|
329
|
-
{
|
|
330
|
-
return getFrameForComposition;
|
|
331
|
-
}
|
|
332
|
-
},
|
|
333
|
-
TimelineContext: () => {
|
|
334
|
-
{
|
|
335
|
-
return TimelineContext;
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
SetTimelineContext: () => {
|
|
339
|
-
{
|
|
340
|
-
return SetTimelineContext;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
303
|
+
useTimelineSetFrame: () => useTimelineSetFrame,
|
|
304
|
+
useTimelinePosition: () => useTimelinePosition,
|
|
305
|
+
usePlayingState: () => usePlayingState,
|
|
306
|
+
persistCurrentFrame: () => persistCurrentFrame,
|
|
307
|
+
getInitialFrameState: () => getInitialFrameState,
|
|
308
|
+
getFrameForComposition: () => getFrameForComposition,
|
|
309
|
+
TimelineContext: () => TimelineContext,
|
|
310
|
+
SetTimelineContext: () => SetTimelineContext
|
|
343
311
|
});
|
|
344
312
|
import {createContext as createContext8, useContext as useContext7, useMemo as useMemo7} from "react";
|
|
345
313
|
|
|
@@ -2149,7 +2117,7 @@ var getAssetDisplayName = (filename) => {
|
|
|
2149
2117
|
};
|
|
2150
2118
|
|
|
2151
2119
|
// src/play-and-handle-not-allowed-error.ts
|
|
2152
|
-
var playAndHandleNotAllowedError = (mediaRef, mediaType) => {
|
|
2120
|
+
var playAndHandleNotAllowedError = (mediaRef, mediaType, onAutoPlayError) => {
|
|
2153
2121
|
const { current } = mediaRef;
|
|
2154
2122
|
if (!current) {
|
|
2155
2123
|
return;
|
|
@@ -2177,7 +2145,14 @@ var playAndHandleNotAllowedError = (mediaRef, mediaType) => {
|
|
|
2177
2145
|
}
|
|
2178
2146
|
console.log(`Could not play ${mediaType} due to following error: `, err);
|
|
2179
2147
|
if (!current.muted) {
|
|
2148
|
+
if (onAutoPlayError) {
|
|
2149
|
+
onAutoPlayError();
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2180
2152
|
console.log(`The video will be muted and we'll retry playing it.`);
|
|
2153
|
+
if (mediaType === "video" && getRemotionEnvironment().isPlayer) {
|
|
2154
|
+
console.log("Use onAutoPlayError() to handle this error yourself.");
|
|
2155
|
+
}
|
|
2181
2156
|
current.muted = true;
|
|
2182
2157
|
current.play();
|
|
2183
2158
|
}
|
|
@@ -2232,7 +2207,8 @@ var useMediaInTimeline = ({
|
|
|
2232
2207
|
id,
|
|
2233
2208
|
stack,
|
|
2234
2209
|
showInTimeline,
|
|
2235
|
-
premountDisplay
|
|
2210
|
+
premountDisplay,
|
|
2211
|
+
onAutoPlayError
|
|
2236
2212
|
}) => {
|
|
2237
2213
|
const videoConfig = useVideoConfig();
|
|
2238
2214
|
const { rootId, audioAndVideoTags } = useContext16(TimelineContext);
|
|
@@ -2327,14 +2303,14 @@ var useMediaInTimeline = ({
|
|
|
2327
2303
|
if (!playing) {
|
|
2328
2304
|
return;
|
|
2329
2305
|
}
|
|
2330
|
-
return playAndHandleNotAllowedError(mediaRef, mediaType);
|
|
2306
|
+
return playAndHandleNotAllowedError(mediaRef, mediaType, onAutoPlayError);
|
|
2331
2307
|
}
|
|
2332
2308
|
};
|
|
2333
2309
|
audioAndVideoTags.current.push(tag);
|
|
2334
2310
|
return () => {
|
|
2335
2311
|
audioAndVideoTags.current = audioAndVideoTags.current.filter((a) => a.id !== id);
|
|
2336
2312
|
};
|
|
2337
|
-
}, [audioAndVideoTags, id, mediaRef, mediaType, playing]);
|
|
2313
|
+
}, [audioAndVideoTags, id, mediaRef, mediaType, onAutoPlayError, playing]);
|
|
2338
2314
|
};
|
|
2339
2315
|
|
|
2340
2316
|
// src/use-media-playback.ts
|
|
@@ -2430,7 +2406,8 @@ var useBufferState = () => {
|
|
|
2430
2406
|
var useBufferUntilFirstFrame = ({
|
|
2431
2407
|
mediaRef,
|
|
2432
2408
|
mediaType,
|
|
2433
|
-
onVariableFpsVideoDetected
|
|
2409
|
+
onVariableFpsVideoDetected,
|
|
2410
|
+
pauseWhenBuffering
|
|
2434
2411
|
}) => {
|
|
2435
2412
|
const bufferingRef = useRef3(false);
|
|
2436
2413
|
const { delayPlayback } = useBufferState();
|
|
@@ -2438,6 +2415,9 @@ var useBufferUntilFirstFrame = ({
|
|
|
2438
2415
|
if (mediaType !== "video") {
|
|
2439
2416
|
return;
|
|
2440
2417
|
}
|
|
2418
|
+
if (!pauseWhenBuffering) {
|
|
2419
|
+
return;
|
|
2420
|
+
}
|
|
2441
2421
|
const current = mediaRef.current;
|
|
2442
2422
|
if (!current) {
|
|
2443
2423
|
return;
|
|
@@ -2471,7 +2451,13 @@ var useBufferUntilFirstFrame = ({
|
|
|
2471
2451
|
});
|
|
2472
2452
|
current.addEventListener("ended", onEndedOrPause, { once: true });
|
|
2473
2453
|
current.addEventListener("pause", onEndedOrPause, { once: true });
|
|
2474
|
-
}, [
|
|
2454
|
+
}, [
|
|
2455
|
+
delayPlayback,
|
|
2456
|
+
mediaRef,
|
|
2457
|
+
mediaType,
|
|
2458
|
+
onVariableFpsVideoDetected,
|
|
2459
|
+
pauseWhenBuffering
|
|
2460
|
+
]);
|
|
2475
2461
|
return useMemo17(() => {
|
|
2476
2462
|
return {
|
|
2477
2463
|
isBuffering: () => bufferingRef.current,
|
|
@@ -2556,7 +2542,12 @@ var useMediaBuffering = ({
|
|
|
2556
2542
|
|
|
2557
2543
|
// src/use-request-video-callback-time.ts
|
|
2558
2544
|
import {useEffect as useEffect11, useRef as useRef4} from "react";
|
|
2559
|
-
var useRequestVideoCallbackTime = (
|
|
2545
|
+
var useRequestVideoCallbackTime = ({
|
|
2546
|
+
mediaRef,
|
|
2547
|
+
mediaType,
|
|
2548
|
+
lastSeek,
|
|
2549
|
+
onVariableFpsVideoDetected
|
|
2550
|
+
}) => {
|
|
2560
2551
|
const currentTime = useRef4(null);
|
|
2561
2552
|
useEffect11(() => {
|
|
2562
2553
|
const { current } = mediaRef;
|
|
@@ -2582,6 +2573,13 @@ var useRequestVideoCallbackTime = (mediaRef, mediaType) => {
|
|
|
2582
2573
|
return;
|
|
2583
2574
|
}
|
|
2584
2575
|
const cb = videoTag.requestVideoFrameCallback((_, info) => {
|
|
2576
|
+
if (currentTime.current !== null) {
|
|
2577
|
+
const difference = Math.abs(currentTime.current - info.mediaTime);
|
|
2578
|
+
const differenceToLastSeek = Math.abs(lastSeek.current === null ? Infinity : info.mediaTime - lastSeek.current);
|
|
2579
|
+
if (difference > 0.5 && differenceToLastSeek > 0.5 && info.mediaTime > currentTime.current) {
|
|
2580
|
+
onVariableFpsVideoDetected();
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2585
2583
|
currentTime.current = info.mediaTime;
|
|
2586
2584
|
request();
|
|
2587
2585
|
});
|
|
@@ -2596,7 +2594,7 @@ var useRequestVideoCallbackTime = (mediaRef, mediaType) => {
|
|
|
2596
2594
|
return () => {
|
|
2597
2595
|
cancel();
|
|
2598
2596
|
};
|
|
2599
|
-
}, [mediaRef, mediaType]);
|
|
2597
|
+
}, [lastSeek, mediaRef, mediaType, onVariableFpsVideoDetected]);
|
|
2600
2598
|
return currentTime;
|
|
2601
2599
|
};
|
|
2602
2600
|
|
|
@@ -2855,7 +2853,8 @@ var useMediaPlayback = ({
|
|
|
2855
2853
|
acceptableTimeshift,
|
|
2856
2854
|
pauseWhenBuffering,
|
|
2857
2855
|
isPremounting,
|
|
2858
|
-
debugSeeking
|
|
2856
|
+
debugSeeking,
|
|
2857
|
+
onAutoPlayError
|
|
2859
2858
|
}) => {
|
|
2860
2859
|
const { playbackRate: globalPlaybackRate } = useContext18(TimelineContext);
|
|
2861
2860
|
const frame = useCurrentFrame();
|
|
@@ -2865,10 +2864,26 @@ var useMediaPlayback = ({
|
|
|
2865
2864
|
const { fps } = useVideoConfig();
|
|
2866
2865
|
const mediaStartsAt = useMediaStartsAt();
|
|
2867
2866
|
const lastSeekDueToShift = useRef6(null);
|
|
2867
|
+
const lastSeek = useRef6(null);
|
|
2868
2868
|
if (!buffering3) {
|
|
2869
2869
|
throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
|
|
2870
2870
|
}
|
|
2871
|
-
const
|
|
2871
|
+
const isVariableFpsVideoMap = useRef6({});
|
|
2872
|
+
const onVariableFpsVideoDetected = useCallback7(() => {
|
|
2873
|
+
if (!src) {
|
|
2874
|
+
return;
|
|
2875
|
+
}
|
|
2876
|
+
if (debugSeeking) {
|
|
2877
|
+
console.log(`Detected ${src} as a variable FPS video. Disabling buffering while seeking.`);
|
|
2878
|
+
}
|
|
2879
|
+
isVariableFpsVideoMap.current[src] = true;
|
|
2880
|
+
}, [debugSeeking, src]);
|
|
2881
|
+
const currentTime = useRequestVideoCallbackTime({
|
|
2882
|
+
mediaRef,
|
|
2883
|
+
mediaType,
|
|
2884
|
+
lastSeek,
|
|
2885
|
+
onVariableFpsVideoDetected
|
|
2886
|
+
});
|
|
2872
2887
|
const desiredUnclampedTime = getMediaTime({
|
|
2873
2888
|
frame,
|
|
2874
2889
|
playbackRate: localPlaybackRate,
|
|
@@ -2880,20 +2895,11 @@ var useMediaPlayback = ({
|
|
|
2880
2895
|
shouldBuffer: pauseWhenBuffering,
|
|
2881
2896
|
isPremounting
|
|
2882
2897
|
});
|
|
2883
|
-
const isVariableFpsVideoMap = useRef6({});
|
|
2884
|
-
const onVariableFpsVideoDetected = useCallback7(() => {
|
|
2885
|
-
if (!src) {
|
|
2886
|
-
return;
|
|
2887
|
-
}
|
|
2888
|
-
if (debugSeeking) {
|
|
2889
|
-
console.log(`Detected ${src} as a variable FPS video. Disabling buffering while seeking.`);
|
|
2890
|
-
}
|
|
2891
|
-
isVariableFpsVideoMap.current[src] = true;
|
|
2892
|
-
}, [debugSeeking, src]);
|
|
2893
2898
|
const { bufferUntilFirstFrame, isBuffering } = useBufferUntilFirstFrame({
|
|
2894
2899
|
mediaRef,
|
|
2895
2900
|
mediaType,
|
|
2896
|
-
onVariableFpsVideoDetected
|
|
2901
|
+
onVariableFpsVideoDetected,
|
|
2902
|
+
pauseWhenBuffering
|
|
2897
2903
|
});
|
|
2898
2904
|
const playbackRate = localPlaybackRate * globalPlaybackRate;
|
|
2899
2905
|
const acceptableTimeShiftButLessThanDuration = (() => {
|
|
@@ -2955,15 +2961,17 @@ var useMediaPlayback = ({
|
|
|
2955
2961
|
shouldBeTime,
|
|
2956
2962
|
isTime: mediaTagTime,
|
|
2957
2963
|
rvcTime,
|
|
2958
|
-
timeShift
|
|
2964
|
+
timeShift,
|
|
2965
|
+
isVariableFpsVideo
|
|
2959
2966
|
});
|
|
2960
2967
|
}
|
|
2961
2968
|
seek(mediaRef, shouldBeTime);
|
|
2969
|
+
lastSeek.current = shouldBeTime;
|
|
2962
2970
|
lastSeekDueToShift.current = shouldBeTime;
|
|
2963
2971
|
if (playing && !isVariableFpsVideo) {
|
|
2964
2972
|
bufferUntilFirstFrame(shouldBeTime);
|
|
2965
2973
|
if (mediaRef.current.paused) {
|
|
2966
|
-
playAndHandleNotAllowedError(mediaRef, mediaType);
|
|
2974
|
+
playAndHandleNotAllowedError(mediaRef, mediaType, onAutoPlayError);
|
|
2967
2975
|
}
|
|
2968
2976
|
}
|
|
2969
2977
|
if (!onlyWarnForMediaSeekingError) {
|
|
@@ -2978,14 +2986,16 @@ var useMediaPlayback = ({
|
|
|
2978
2986
|
if (!playing || isSomethingElseBuffering) {
|
|
2979
2987
|
if (makesSenseToSeek) {
|
|
2980
2988
|
seek(mediaRef, shouldBeTime);
|
|
2989
|
+
lastSeek.current = shouldBeTime;
|
|
2981
2990
|
}
|
|
2982
2991
|
return;
|
|
2983
2992
|
}
|
|
2984
2993
|
if (mediaRef.current.paused && !mediaRef.current.ended || absoluteFrame === 0) {
|
|
2985
2994
|
if (makesSenseToSeek) {
|
|
2986
2995
|
seek(mediaRef, shouldBeTime);
|
|
2996
|
+
lastSeek.current = shouldBeTime;
|
|
2987
2997
|
}
|
|
2988
|
-
playAndHandleNotAllowedError(mediaRef, mediaType);
|
|
2998
|
+
playAndHandleNotAllowedError(mediaRef, mediaType, onAutoPlayError);
|
|
2989
2999
|
if (!isVariableFpsVideo) {
|
|
2990
3000
|
bufferUntilFirstFrame(shouldBeTime);
|
|
2991
3001
|
}
|
|
@@ -3005,7 +3015,8 @@ var useMediaPlayback = ({
|
|
|
3005
3015
|
onlyWarnForMediaSeekingError,
|
|
3006
3016
|
playbackRate,
|
|
3007
3017
|
playing,
|
|
3008
|
-
src
|
|
3018
|
+
src,
|
|
3019
|
+
onAutoPlayError
|
|
3009
3020
|
]);
|
|
3010
3021
|
};
|
|
3011
3022
|
|
|
@@ -3231,7 +3242,7 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, component }) =>
|
|
|
3231
3242
|
}, [rerenderAudios]);
|
|
3232
3243
|
const playAllAudios = useCallback8(() => {
|
|
3233
3244
|
refs.forEach((ref) => {
|
|
3234
|
-
playAndHandleNotAllowedError(ref.ref, "audio");
|
|
3245
|
+
playAndHandleNotAllowedError(ref.ref, "audio", null);
|
|
3235
3246
|
});
|
|
3236
3247
|
}, [refs]);
|
|
3237
3248
|
const value = useMemo19(() => {
|
|
@@ -3394,7 +3405,8 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
3394
3405
|
id: timelineId,
|
|
3395
3406
|
stack: _remotionInternalStack,
|
|
3396
3407
|
showInTimeline,
|
|
3397
|
-
premountDisplay: null
|
|
3408
|
+
premountDisplay: null,
|
|
3409
|
+
onAutoPlayError: null
|
|
3398
3410
|
});
|
|
3399
3411
|
useMediaPlayback({
|
|
3400
3412
|
mediaRef: audioRef,
|
|
@@ -3405,7 +3417,8 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
|
|
|
3405
3417
|
acceptableTimeshift: acceptableTimeShiftInSeconds ?? DEFAULT_ACCEPTABLE_TIMESHIFT,
|
|
3406
3418
|
isPremounting: Boolean(sequenceContext?.premounting),
|
|
3407
3419
|
pauseWhenBuffering,
|
|
3408
|
-
debugSeeking: _remotionDebugSeeking
|
|
3420
|
+
debugSeeking: _remotionDebugSeeking,
|
|
3421
|
+
onAutoPlayError: null
|
|
3409
3422
|
});
|
|
3410
3423
|
useImperativeHandle3(ref, () => {
|
|
3411
3424
|
return audioRef.current;
|
|
@@ -4322,18 +4335,18 @@ class Easing {
|
|
|
4322
4335
|
return (t) => t * t * ((s + 1) * t - s);
|
|
4323
4336
|
}
|
|
4324
4337
|
static bounce(t) {
|
|
4325
|
-
if (t <
|
|
4338
|
+
if (t < 1 / 2.75) {
|
|
4326
4339
|
return 7.5625 * t * t;
|
|
4327
4340
|
}
|
|
4328
|
-
if (t <
|
|
4329
|
-
const t2_ = t -
|
|
4341
|
+
if (t < 2 / 2.75) {
|
|
4342
|
+
const t2_ = t - 1.5 / 2.75;
|
|
4330
4343
|
return 7.5625 * t2_ * t2_ + 0.75;
|
|
4331
4344
|
}
|
|
4332
|
-
if (t <
|
|
4333
|
-
const t2_ = t -
|
|
4345
|
+
if (t < 2.5 / 2.75) {
|
|
4346
|
+
const t2_ = t - 2.25 / 2.75;
|
|
4334
4347
|
return 7.5625 * t2_ * t2_ + 0.9375;
|
|
4335
4348
|
}
|
|
4336
|
-
const t2 = t -
|
|
4349
|
+
const t2 = t - 2.625 / 2.75;
|
|
4337
4350
|
return 7.5625 * t2 * t2 + 0.984375;
|
|
4338
4351
|
}
|
|
4339
4352
|
static bezier(x1, y1, x2, y2) {
|
|
@@ -4548,21 +4561,9 @@ var Img = forwardRef7(ImgRefForwarding);
|
|
|
4548
4561
|
// src/default-css.ts
|
|
4549
4562
|
var exports_default_css = {};
|
|
4550
4563
|
__export(exports_default_css, {
|
|
4551
|
-
makeDefaultPreviewCSS: () =>
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
}
|
|
4555
|
-
},
|
|
4556
|
-
injectCSS: () => {
|
|
4557
|
-
{
|
|
4558
|
-
return injectCSS;
|
|
4559
|
-
}
|
|
4560
|
-
},
|
|
4561
|
-
OFFTHREAD_VIDEO_CLASS_NAME: () => {
|
|
4562
|
-
{
|
|
4563
|
-
return OFFTHREAD_VIDEO_CLASS_NAME;
|
|
4564
|
-
}
|
|
4565
|
-
}
|
|
4564
|
+
makeDefaultPreviewCSS: () => makeDefaultPreviewCSS,
|
|
4565
|
+
injectCSS: () => injectCSS,
|
|
4566
|
+
OFFTHREAD_VIDEO_CLASS_NAME: () => OFFTHREAD_VIDEO_CLASS_NAME
|
|
4566
4567
|
});
|
|
4567
4568
|
var injected = {};
|
|
4568
4569
|
var injectCSS = (css) => {
|
|
@@ -5050,23 +5051,23 @@ var hue2rgb = function(p, q, t) {
|
|
|
5050
5051
|
if (t > 1) {
|
|
5051
5052
|
t -= 1;
|
|
5052
5053
|
}
|
|
5053
|
-
if (t <
|
|
5054
|
+
if (t < 1 / 6) {
|
|
5054
5055
|
return p + (q - p) * 6 * t;
|
|
5055
5056
|
}
|
|
5056
|
-
if (t <
|
|
5057
|
+
if (t < 1 / 2) {
|
|
5057
5058
|
return q;
|
|
5058
5059
|
}
|
|
5059
|
-
if (t <
|
|
5060
|
-
return p + (q - p) * (
|
|
5060
|
+
if (t < 2 / 3) {
|
|
5061
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
5061
5062
|
}
|
|
5062
5063
|
return p;
|
|
5063
5064
|
};
|
|
5064
5065
|
var hslToRgb = function(h, s, l) {
|
|
5065
5066
|
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
5066
5067
|
const p = 2 * l - q;
|
|
5067
|
-
const r = hue2rgb(p, q, h +
|
|
5068
|
+
const r = hue2rgb(p, q, h + 1 / 3);
|
|
5068
5069
|
const g = hue2rgb(p, q, h);
|
|
5069
|
-
const b2 = hue2rgb(p, q, h -
|
|
5070
|
+
const b2 = hue2rgb(p, q, h - 1 / 3);
|
|
5070
5071
|
return Math.round(r * 255) << 24 | Math.round(g * 255) << 16 | Math.round(b2 * 255) << 8;
|
|
5071
5072
|
};
|
|
5072
5073
|
var parse255 = function(str) {
|
|
@@ -5898,9 +5899,17 @@ var OffthreadVideoForRendering = ({
|
|
|
5898
5899
|
const blob = await res.blob();
|
|
5899
5900
|
const url = URL.createObjectURL(blob);
|
|
5900
5901
|
cleanup.push(() => URL.revokeObjectURL(url));
|
|
5901
|
-
setImageSrc(
|
|
5902
|
-
|
|
5902
|
+
setImageSrc({
|
|
5903
|
+
src: url,
|
|
5904
|
+
handle: newHandle
|
|
5905
|
+
});
|
|
5903
5906
|
} catch (err) {
|
|
5907
|
+
if (err.message.includes("aborted")) {
|
|
5908
|
+
return;
|
|
5909
|
+
}
|
|
5910
|
+
if (controller.signal.aborted) {
|
|
5911
|
+
return;
|
|
5912
|
+
}
|
|
5904
5913
|
if (onError) {
|
|
5905
5914
|
onError(err);
|
|
5906
5915
|
} else {
|
|
@@ -5937,8 +5946,9 @@ var OffthreadVideoForRendering = ({
|
|
|
5937
5946
|
if (!imageSrc) {
|
|
5938
5947
|
return null;
|
|
5939
5948
|
}
|
|
5949
|
+
continueRender(imageSrc.handle);
|
|
5940
5950
|
return jsx29(Img, {
|
|
5941
|
-
src: imageSrc,
|
|
5951
|
+
src: imageSrc.src,
|
|
5942
5952
|
className,
|
|
5943
5953
|
delayRenderRetries,
|
|
5944
5954
|
delayRenderTimeoutInMilliseconds,
|
|
@@ -5981,6 +5991,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
|
|
|
5981
5991
|
showInTimeline,
|
|
5982
5992
|
loopVolumeCurveBehavior,
|
|
5983
5993
|
onError,
|
|
5994
|
+
onAutoPlayError,
|
|
5984
5995
|
...nativeProps
|
|
5985
5996
|
} = props2;
|
|
5986
5997
|
const volumePropFrame = useFrameForVolumeProp(loopVolumeCurveBehavior ?? "repeat");
|
|
@@ -6006,7 +6017,8 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
|
|
|
6006
6017
|
id: timelineId,
|
|
6007
6018
|
stack: _remotionInternalStack,
|
|
6008
6019
|
showInTimeline,
|
|
6009
|
-
premountDisplay: null
|
|
6020
|
+
premountDisplay: null,
|
|
6021
|
+
onAutoPlayError: onAutoPlayError ?? null
|
|
6010
6022
|
});
|
|
6011
6023
|
useSyncVolumeWithMediaTag({
|
|
6012
6024
|
volumePropFrame,
|
|
@@ -6024,7 +6036,8 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
|
|
|
6024
6036
|
acceptableTimeshift: acceptableTimeShiftInSeconds ?? DEFAULT_ACCEPTABLE_TIMESHIFT,
|
|
6025
6037
|
isPremounting: Boolean(parentSequence?.premounting),
|
|
6026
6038
|
pauseWhenBuffering,
|
|
6027
|
-
debugSeeking: _remotionDebugSeeking
|
|
6039
|
+
debugSeeking: _remotionDebugSeeking,
|
|
6040
|
+
onAutoPlayError: onAutoPlayError ?? null
|
|
6028
6041
|
});
|
|
6029
6042
|
const actualFrom = parentSequence ? parentSequence.relativeFrom : 0;
|
|
6030
6043
|
const duration = parentSequence ? Math.min(parentSequence.durationInFrames, durationInFrames) : durationInFrames;
|
|
@@ -6164,6 +6177,7 @@ var OffthreadVideo = (props2) => {
|
|
|
6164
6177
|
transparent,
|
|
6165
6178
|
toneMapped,
|
|
6166
6179
|
_remotionDebugSeeking,
|
|
6180
|
+
onAutoPlayError,
|
|
6167
6181
|
...withoutTransparent
|
|
6168
6182
|
} = otherProps;
|
|
6169
6183
|
return jsx31(VideoForPreview, {
|
|
@@ -6174,6 +6188,7 @@ var OffthreadVideo = (props2) => {
|
|
|
6174
6188
|
onlyWarnForMediaSeekingError: true,
|
|
6175
6189
|
pauseWhenBuffering: pauseWhenBuffering ?? false,
|
|
6176
6190
|
showInTimeline: showInTimeline ?? true,
|
|
6191
|
+
onAutoPlayError: onAutoPlayError ?? undefined,
|
|
6177
6192
|
...withoutTransparent
|
|
6178
6193
|
});
|
|
6179
6194
|
};
|
|
@@ -6484,6 +6499,7 @@ var VideoForwardingFunction = (props2, ref) => {
|
|
|
6484
6499
|
stack,
|
|
6485
6500
|
_remotionInternalNativeLoopPassed,
|
|
6486
6501
|
showInTimeline,
|
|
6502
|
+
onAutoPlayError,
|
|
6487
6503
|
...otherProps
|
|
6488
6504
|
} = props2;
|
|
6489
6505
|
const { loop: loop4, _remotionDebugSeeking, ...propsOtherThanLoop } = props2;
|
|
@@ -6553,7 +6569,8 @@ var VideoForwardingFunction = (props2, ref) => {
|
|
|
6553
6569
|
_remotionInternalStack: stack ?? null,
|
|
6554
6570
|
_remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed ?? false,
|
|
6555
6571
|
_remotionDebugSeeking: _remotionDebugSeeking ?? false,
|
|
6556
|
-
showInTimeline: showInTimeline ?? true
|
|
6572
|
+
showInTimeline: showInTimeline ?? true,
|
|
6573
|
+
onAutoPlayError: onAutoPlayError ?? undefined
|
|
6557
6574
|
});
|
|
6558
6575
|
};
|
|
6559
6576
|
var Video = forwardRef11(VideoForwardingFunction);
|
package/dist/esm/no-react.mjs
CHANGED
|
@@ -318,23 +318,23 @@ var hue2rgb = function(p, q, t) {
|
|
|
318
318
|
if (t > 1) {
|
|
319
319
|
t -= 1;
|
|
320
320
|
}
|
|
321
|
-
if (t <
|
|
321
|
+
if (t < 1 / 6) {
|
|
322
322
|
return p + (q - p) * 6 * t;
|
|
323
323
|
}
|
|
324
|
-
if (t <
|
|
324
|
+
if (t < 1 / 2) {
|
|
325
325
|
return q;
|
|
326
326
|
}
|
|
327
|
-
if (t <
|
|
328
|
-
return p + (q - p) * (
|
|
327
|
+
if (t < 2 / 3) {
|
|
328
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
329
329
|
}
|
|
330
330
|
return p;
|
|
331
331
|
};
|
|
332
332
|
var hslToRgb = function(h, s, l) {
|
|
333
333
|
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
334
334
|
const p = 2 * l - q;
|
|
335
|
-
const r = hue2rgb(p, q, h +
|
|
335
|
+
const r = hue2rgb(p, q, h + 1 / 3);
|
|
336
336
|
const g = hue2rgb(p, q, h);
|
|
337
|
-
const b = hue2rgb(p, q, h -
|
|
337
|
+
const b = hue2rgb(p, q, h - 1 / 3);
|
|
338
338
|
return Math.round(r * 255) << 24 | Math.round(g * 255) << 16 | Math.round(b * 255) << 8;
|
|
339
339
|
};
|
|
340
340
|
var parse255 = function(str) {
|
package/dist/esm/version.mjs
CHANGED
package/package.json
CHANGED