@remotion/media 4.0.427 → 4.0.429
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/README.md +7 -7
- package/dist/audio/audio-preview-iterator.d.ts +8 -2
- package/dist/audio-iterator-manager.d.ts +11 -6
- package/dist/debug-overlay/preview-overlay.d.ts +9 -4
- package/dist/esm/index.mjs +13759 -202
- package/dist/use-media-in-timeline.d.ts +3 -2
- package/package.json +6 -6
- package/dist/audio/allow-wait.js +0 -15
- package/dist/audio/audio-for-preview.js +0 -304
- package/dist/audio/audio-for-rendering.js +0 -194
- package/dist/audio/audio-preview-iterator.js +0 -176
- package/dist/audio/audio.js +0 -20
- package/dist/audio/props.js +0 -1
- package/dist/audio-extraction/audio-cache.js +0 -66
- package/dist/audio-extraction/audio-iterator.js +0 -132
- package/dist/audio-extraction/audio-manager.js +0 -113
- package/dist/audio-extraction/extract-audio.js +0 -132
- package/dist/audio-iterator-manager.js +0 -228
- package/dist/browser-can-use-webgl2.js +0 -13
- package/dist/caches.js +0 -61
- package/dist/calculate-playbacktime.js +0 -4
- package/dist/convert-audiodata/apply-volume.js +0 -17
- package/dist/convert-audiodata/combine-audiodata.js +0 -23
- package/dist/convert-audiodata/convert-audiodata.js +0 -73
- package/dist/convert-audiodata/resample-audiodata.js +0 -94
- package/dist/debug-overlay/preview-overlay.js +0 -42
- package/dist/extract-frame-and-audio.js +0 -101
- package/dist/get-sink.js +0 -15
- package/dist/get-time-in-seconds.js +0 -40
- package/dist/helpers/round-to-4-digits.js +0 -4
- package/dist/index.js +0 -12
- package/dist/is-type-of-error.js +0 -20
- package/dist/looped-frame.js +0 -10
- package/dist/media-player.js +0 -431
- package/dist/nonce-manager.js +0 -13
- package/dist/prewarm-iterator-for-looping.js +0 -56
- package/dist/render-timestamp-range.js +0 -9
- package/dist/show-in-timeline.js +0 -31
- package/dist/use-media-in-timeline.js +0 -103
- package/dist/video/props.js +0 -1
- package/dist/video/video-for-preview.js +0 -331
- package/dist/video/video-for-rendering.js +0 -263
- package/dist/video/video-preview-iterator.js +0 -122
- package/dist/video/video.js +0 -35
- package/dist/video-extraction/add-broadcast-channel-listener.js +0 -125
- package/dist/video-extraction/extract-frame-via-broadcast-channel.js +0 -113
- package/dist/video-extraction/extract-frame.js +0 -85
- package/dist/video-extraction/get-allocation-size.js +0 -6
- package/dist/video-extraction/get-frames-since-keyframe.js +0 -108
- package/dist/video-extraction/keyframe-bank.js +0 -159
- package/dist/video-extraction/keyframe-manager.js +0 -206
- package/dist/video-extraction/remember-actual-matroska-timestamps.js +0 -19
- package/dist/video-extraction/rotate-frame.js +0 -34
- package/dist/video-iterator-manager.js +0 -109
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { useContext, useEffect, useState } from 'react';
|
|
2
|
-
import { Internals, useCurrentFrame } from 'remotion';
|
|
3
|
-
export const useMediaInTimeline = ({ volume, mediaVolume, src, mediaType, playbackRate, displayName, stack, showInTimeline, premountDisplay, postmountDisplay, loopDisplay, trimBefore, trimAfter, }) => {
|
|
4
|
-
const parentSequence = useContext(Internals.SequenceContext);
|
|
5
|
-
const startsAt = Internals.useMediaStartsAt();
|
|
6
|
-
const { registerSequence, unregisterSequence } = useContext(Internals.SequenceManager);
|
|
7
|
-
const [sequenceId] = useState(() => String(Math.random()));
|
|
8
|
-
const [mediaId] = useState(() => String(Math.random()));
|
|
9
|
-
const frame = useCurrentFrame();
|
|
10
|
-
const { volumes, duration, doesVolumeChange, nonce, rootId, isStudio, finalDisplayName, } = Internals.useBasicMediaInTimeline({
|
|
11
|
-
volume,
|
|
12
|
-
mediaVolume,
|
|
13
|
-
mediaType,
|
|
14
|
-
src,
|
|
15
|
-
displayName,
|
|
16
|
-
trimBefore,
|
|
17
|
-
trimAfter,
|
|
18
|
-
playbackRate,
|
|
19
|
-
});
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
if (!src) {
|
|
22
|
-
throw new Error('No src passed');
|
|
23
|
-
}
|
|
24
|
-
if (!isStudio && window.process?.env?.NODE_ENV !== 'test') {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (!showInTimeline) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
const loopIteration = loopDisplay
|
|
31
|
-
? Math.floor(frame / loopDisplay.durationInFrames)
|
|
32
|
-
: 0;
|
|
33
|
-
if (loopDisplay) {
|
|
34
|
-
registerSequence({
|
|
35
|
-
type: 'sequence',
|
|
36
|
-
premountDisplay,
|
|
37
|
-
postmountDisplay,
|
|
38
|
-
parent: parentSequence?.id ?? null,
|
|
39
|
-
displayName: finalDisplayName,
|
|
40
|
-
rootId,
|
|
41
|
-
showInTimeline: true,
|
|
42
|
-
nonce,
|
|
43
|
-
loopDisplay,
|
|
44
|
-
stack,
|
|
45
|
-
from: 0,
|
|
46
|
-
duration,
|
|
47
|
-
id: sequenceId,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
registerSequence({
|
|
51
|
-
type: mediaType,
|
|
52
|
-
src,
|
|
53
|
-
id: mediaId,
|
|
54
|
-
duration: loopDisplay?.durationInFrames ?? duration,
|
|
55
|
-
from: loopDisplay ? loopIteration * loopDisplay.durationInFrames : 0,
|
|
56
|
-
parent: loopDisplay ? sequenceId : (parentSequence?.id ?? null),
|
|
57
|
-
displayName: finalDisplayName,
|
|
58
|
-
rootId,
|
|
59
|
-
volume: volumes,
|
|
60
|
-
showInTimeline: true,
|
|
61
|
-
nonce,
|
|
62
|
-
startMediaFrom: 0 - startsAt,
|
|
63
|
-
doesVolumeChange,
|
|
64
|
-
loopDisplay: undefined,
|
|
65
|
-
playbackRate,
|
|
66
|
-
stack,
|
|
67
|
-
premountDisplay: null,
|
|
68
|
-
postmountDisplay: null,
|
|
69
|
-
});
|
|
70
|
-
return () => {
|
|
71
|
-
if (loopDisplay) {
|
|
72
|
-
unregisterSequence(sequenceId);
|
|
73
|
-
}
|
|
74
|
-
unregisterSequence(mediaId);
|
|
75
|
-
};
|
|
76
|
-
}, [
|
|
77
|
-
doesVolumeChange,
|
|
78
|
-
duration,
|
|
79
|
-
finalDisplayName,
|
|
80
|
-
isStudio,
|
|
81
|
-
loopDisplay,
|
|
82
|
-
mediaId,
|
|
83
|
-
mediaType,
|
|
84
|
-
nonce,
|
|
85
|
-
parentSequence?.id,
|
|
86
|
-
playbackRate,
|
|
87
|
-
postmountDisplay,
|
|
88
|
-
premountDisplay,
|
|
89
|
-
registerSequence,
|
|
90
|
-
rootId,
|
|
91
|
-
sequenceId,
|
|
92
|
-
showInTimeline,
|
|
93
|
-
src,
|
|
94
|
-
stack,
|
|
95
|
-
startsAt,
|
|
96
|
-
unregisterSequence,
|
|
97
|
-
volumes,
|
|
98
|
-
frame,
|
|
99
|
-
]);
|
|
100
|
-
return {
|
|
101
|
-
id: mediaId,
|
|
102
|
-
};
|
|
103
|
-
};
|
package/dist/video/props.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
-
import { Html5Video, Internals, useBufferState, useCurrentFrame, useVideoConfig, } from 'remotion';
|
|
4
|
-
import { getTimeInSeconds } from '../get-time-in-seconds';
|
|
5
|
-
import { MediaPlayer } from '../media-player';
|
|
6
|
-
import { useLoopDisplay } from '../show-in-timeline';
|
|
7
|
-
import { useMediaInTimeline } from '../use-media-in-timeline';
|
|
8
|
-
const { useUnsafeVideoConfig, Timeline, SharedAudioContext, useMediaMutedState, useMediaVolumeState, useFrameForVolumeProp, evaluateVolume, warnAboutTooHighVolume, usePreload, SequenceContext, SequenceVisibilityToggleContext, } = Internals;
|
|
9
|
-
const VideoForPreviewAssertedShowing = ({ src: unpreloadedSrc, style, playbackRate, logLevel, className, muted, volume, loopVolumeCurveBehavior, onVideoFrame, showInTimeline, loop, name, trimAfter, trimBefore, stack, disallowFallbackToOffthreadVideo, fallbackOffthreadVideoProps, audioStreamIndex, debugOverlay, headless, }) => {
|
|
10
|
-
const src = usePreload(unpreloadedSrc);
|
|
11
|
-
const canvasRef = useRef(null);
|
|
12
|
-
const videoConfig = useUnsafeVideoConfig();
|
|
13
|
-
const frame = useCurrentFrame();
|
|
14
|
-
const mediaPlayerRef = useRef(null);
|
|
15
|
-
const initialTrimBeforeRef = useRef(trimBefore);
|
|
16
|
-
const initialTrimAfterRef = useRef(trimAfter);
|
|
17
|
-
const initialOnVideoFrameRef = useRef(onVideoFrame);
|
|
18
|
-
const [mediaPlayerReady, setMediaPlayerReady] = useState(false);
|
|
19
|
-
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState(false);
|
|
20
|
-
const [playing] = Timeline.usePlayingState();
|
|
21
|
-
const timelineContext = useContext(Internals.TimelineContext);
|
|
22
|
-
const globalPlaybackRate = timelineContext.playbackRate;
|
|
23
|
-
const sharedAudioContext = useContext(SharedAudioContext);
|
|
24
|
-
const buffer = useBufferState();
|
|
25
|
-
const [mediaMuted] = useMediaMutedState();
|
|
26
|
-
const [mediaVolume] = useMediaVolumeState();
|
|
27
|
-
const [mediaDurationInSeconds, setMediaDurationInSeconds] = useState(null);
|
|
28
|
-
const { hidden } = useContext(SequenceVisibilityToggleContext);
|
|
29
|
-
const volumePropFrame = useFrameForVolumeProp(loopVolumeCurveBehavior);
|
|
30
|
-
const userPreferredVolume = evaluateVolume({
|
|
31
|
-
frame: volumePropFrame,
|
|
32
|
-
volume,
|
|
33
|
-
mediaVolume,
|
|
34
|
-
});
|
|
35
|
-
warnAboutTooHighVolume(userPreferredVolume);
|
|
36
|
-
const parentSequence = useContext(SequenceContext);
|
|
37
|
-
const isPremounting = Boolean(parentSequence?.premounting);
|
|
38
|
-
const isPostmounting = Boolean(parentSequence?.postmounting);
|
|
39
|
-
const loopDisplay = useLoopDisplay({
|
|
40
|
-
loop,
|
|
41
|
-
mediaDurationInSeconds,
|
|
42
|
-
playbackRate,
|
|
43
|
-
trimAfter,
|
|
44
|
-
trimBefore,
|
|
45
|
-
});
|
|
46
|
-
const { id: timelineId } = useMediaInTimeline({
|
|
47
|
-
volume,
|
|
48
|
-
mediaType: 'video',
|
|
49
|
-
src,
|
|
50
|
-
playbackRate,
|
|
51
|
-
displayName: name ?? null,
|
|
52
|
-
stack,
|
|
53
|
-
showInTimeline,
|
|
54
|
-
premountDisplay: parentSequence?.premountDisplay ?? null,
|
|
55
|
-
postmountDisplay: parentSequence?.postmountDisplay ?? null,
|
|
56
|
-
loopDisplay,
|
|
57
|
-
mediaVolume,
|
|
58
|
-
trimAfter,
|
|
59
|
-
trimBefore,
|
|
60
|
-
});
|
|
61
|
-
const isSequenceHidden = hidden[timelineId] ?? false;
|
|
62
|
-
if (!videoConfig) {
|
|
63
|
-
throw new Error('No video config found');
|
|
64
|
-
}
|
|
65
|
-
const currentTime = frame / videoConfig.fps;
|
|
66
|
-
const currentTimeRef = useRef(currentTime);
|
|
67
|
-
currentTimeRef.current = currentTime;
|
|
68
|
-
const preloadedSrc = usePreload(src);
|
|
69
|
-
const buffering = useContext(Internals.BufferingContextReact);
|
|
70
|
-
if (!buffering) {
|
|
71
|
-
throw new Error('useMediaPlayback must be used inside a <BufferingContext>');
|
|
72
|
-
}
|
|
73
|
-
const isPlayerBuffering = Internals.useIsPlayerBuffering(buffering);
|
|
74
|
-
const initialPlaying = useRef(playing && !isPlayerBuffering);
|
|
75
|
-
const initialIsPremounting = useRef(isPremounting);
|
|
76
|
-
const initialIsPostmounting = useRef(isPostmounting);
|
|
77
|
-
const initialGlobalPlaybackRate = useRef(globalPlaybackRate);
|
|
78
|
-
const initialPlaybackRate = useRef(playbackRate);
|
|
79
|
-
useEffect(() => {
|
|
80
|
-
if (!sharedAudioContext)
|
|
81
|
-
return;
|
|
82
|
-
if (!sharedAudioContext.audioContext)
|
|
83
|
-
return;
|
|
84
|
-
try {
|
|
85
|
-
const player = new MediaPlayer({
|
|
86
|
-
canvas: canvasRef.current,
|
|
87
|
-
src: preloadedSrc,
|
|
88
|
-
logLevel,
|
|
89
|
-
sharedAudioContext: sharedAudioContext.audioContext,
|
|
90
|
-
loop,
|
|
91
|
-
trimAfter: initialTrimAfterRef.current,
|
|
92
|
-
trimBefore: initialTrimBeforeRef.current,
|
|
93
|
-
fps: videoConfig.fps,
|
|
94
|
-
playbackRate: initialPlaybackRate.current,
|
|
95
|
-
audioStreamIndex,
|
|
96
|
-
debugOverlay,
|
|
97
|
-
bufferState: buffer,
|
|
98
|
-
isPremounting: initialIsPremounting.current,
|
|
99
|
-
isPostmounting: initialIsPostmounting.current,
|
|
100
|
-
globalPlaybackRate: initialGlobalPlaybackRate.current,
|
|
101
|
-
onVideoFrameCallback: initialOnVideoFrameRef.current ?? null,
|
|
102
|
-
playing: initialPlaying.current,
|
|
103
|
-
});
|
|
104
|
-
mediaPlayerRef.current = player;
|
|
105
|
-
player
|
|
106
|
-
.initialize(currentTimeRef.current)
|
|
107
|
-
.then((result) => {
|
|
108
|
-
if (result.type === 'disposed') {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
if (result.type === 'unknown-container-format') {
|
|
112
|
-
if (disallowFallbackToOffthreadVideo) {
|
|
113
|
-
throw new Error(`Unknown container format ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
114
|
-
}
|
|
115
|
-
Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <OffthreadVideo>`);
|
|
116
|
-
setShouldFallbackToNativeVideo(true);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if (result.type === 'network-error') {
|
|
120
|
-
if (disallowFallbackToOffthreadVideo) {
|
|
121
|
-
throw new Error(`Network error fetching ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
122
|
-
}
|
|
123
|
-
Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Network error fetching ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
124
|
-
setShouldFallbackToNativeVideo(true);
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (result.type === 'cannot-decode') {
|
|
128
|
-
if (disallowFallbackToOffthreadVideo) {
|
|
129
|
-
throw new Error(`Cannot decode ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
130
|
-
}
|
|
131
|
-
Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Cannot decode ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
132
|
-
setShouldFallbackToNativeVideo(true);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
if (result.type === 'no-tracks') {
|
|
136
|
-
if (disallowFallbackToOffthreadVideo) {
|
|
137
|
-
throw new Error(`No video or audio tracks found for ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
138
|
-
}
|
|
139
|
-
Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `No video or audio tracks found for ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
140
|
-
setShouldFallbackToNativeVideo(true);
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
if (result.type === 'success') {
|
|
144
|
-
setMediaPlayerReady(true);
|
|
145
|
-
setMediaDurationInSeconds(result.durationInSeconds);
|
|
146
|
-
}
|
|
147
|
-
})
|
|
148
|
-
.catch((error) => {
|
|
149
|
-
Internals.Log.error({ logLevel, tag: '@remotion/media' }, '[VideoForPreview] Failed to initialize MediaPlayer', error);
|
|
150
|
-
setShouldFallbackToNativeVideo(true);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
catch (error) {
|
|
154
|
-
Internals.Log.error({ logLevel, tag: '@remotion/media' }, '[VideoForPreview] MediaPlayer initialization failed', error);
|
|
155
|
-
setShouldFallbackToNativeVideo(true);
|
|
156
|
-
}
|
|
157
|
-
return () => {
|
|
158
|
-
if (mediaPlayerRef.current) {
|
|
159
|
-
Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[VideoForPreview] Disposing MediaPlayer`);
|
|
160
|
-
mediaPlayerRef.current.dispose();
|
|
161
|
-
mediaPlayerRef.current = null;
|
|
162
|
-
}
|
|
163
|
-
setMediaPlayerReady(false);
|
|
164
|
-
setShouldFallbackToNativeVideo(false);
|
|
165
|
-
};
|
|
166
|
-
}, [
|
|
167
|
-
audioStreamIndex,
|
|
168
|
-
buffer,
|
|
169
|
-
debugOverlay,
|
|
170
|
-
disallowFallbackToOffthreadVideo,
|
|
171
|
-
logLevel,
|
|
172
|
-
loop,
|
|
173
|
-
preloadedSrc,
|
|
174
|
-
sharedAudioContext,
|
|
175
|
-
videoConfig.fps,
|
|
176
|
-
]);
|
|
177
|
-
const classNameValue = useMemo(() => {
|
|
178
|
-
return [Internals.OBJECTFIT_CONTAIN_CLASS_NAME, className]
|
|
179
|
-
.filter(Internals.truthy)
|
|
180
|
-
.join(' ');
|
|
181
|
-
}, [className]);
|
|
182
|
-
useEffect(() => {
|
|
183
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
184
|
-
if (!mediaPlayer)
|
|
185
|
-
return;
|
|
186
|
-
if (playing && !isPlayerBuffering) {
|
|
187
|
-
mediaPlayer.play(currentTimeRef.current);
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
mediaPlayer.pause();
|
|
191
|
-
}
|
|
192
|
-
}, [isPlayerBuffering, playing, logLevel, mediaPlayerReady]);
|
|
193
|
-
useEffect(() => {
|
|
194
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
195
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
199
|
-
}, [trimBefore, mediaPlayerReady]);
|
|
200
|
-
useEffect(() => {
|
|
201
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
202
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
206
|
-
}, [trimAfter, mediaPlayerReady]);
|
|
207
|
-
const effectiveMuted = isSequenceHidden || muted || mediaMuted || userPreferredVolume <= 0;
|
|
208
|
-
useLayoutEffect(() => {
|
|
209
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
210
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
211
|
-
return;
|
|
212
|
-
mediaPlayer.setMuted(effectiveMuted);
|
|
213
|
-
}, [effectiveMuted, mediaPlayerReady]);
|
|
214
|
-
useLayoutEffect(() => {
|
|
215
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
216
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
mediaPlayer.setVolume(userPreferredVolume);
|
|
220
|
-
}, [userPreferredVolume, mediaPlayerReady]);
|
|
221
|
-
useLayoutEffect(() => {
|
|
222
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
223
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
mediaPlayer.setDebugOverlay(debugOverlay);
|
|
227
|
-
}, [debugOverlay, mediaPlayerReady]);
|
|
228
|
-
useLayoutEffect(() => {
|
|
229
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
230
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
mediaPlayer.setPlaybackRate(playbackRate);
|
|
234
|
-
}, [playbackRate, mediaPlayerReady]);
|
|
235
|
-
useLayoutEffect(() => {
|
|
236
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
237
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
mediaPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
241
|
-
}, [globalPlaybackRate, mediaPlayerReady]);
|
|
242
|
-
useLayoutEffect(() => {
|
|
243
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
244
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
mediaPlayer.setLoop(loop);
|
|
248
|
-
}, [loop, mediaPlayerReady]);
|
|
249
|
-
useLayoutEffect(() => {
|
|
250
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
251
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
mediaPlayer.setIsPremounting(isPremounting);
|
|
255
|
-
}, [isPremounting, mediaPlayerReady]);
|
|
256
|
-
useLayoutEffect(() => {
|
|
257
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
258
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
262
|
-
}, [isPostmounting, mediaPlayerReady]);
|
|
263
|
-
useLayoutEffect(() => {
|
|
264
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
265
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
mediaPlayer.setFps(videoConfig.fps);
|
|
269
|
-
}, [videoConfig.fps, mediaPlayerReady]);
|
|
270
|
-
useLayoutEffect(() => {
|
|
271
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
272
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
mediaPlayer.setVideoFrameCallback(onVideoFrame ?? null);
|
|
276
|
-
}, [onVideoFrame, mediaPlayerReady]);
|
|
277
|
-
useLayoutEffect(() => {
|
|
278
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
279
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
280
|
-
return;
|
|
281
|
-
mediaPlayer.seekTo(currentTime).catch(() => {
|
|
282
|
-
// Might be disposed
|
|
283
|
-
});
|
|
284
|
-
Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[VideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
285
|
-
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
286
|
-
const actualStyle = useMemo(() => {
|
|
287
|
-
return {
|
|
288
|
-
...style,
|
|
289
|
-
opacity: isSequenceHidden ? 0 : (style?.opacity ?? 1),
|
|
290
|
-
};
|
|
291
|
-
}, [isSequenceHidden, style]);
|
|
292
|
-
if (shouldFallbackToNativeVideo && !disallowFallbackToOffthreadVideo) {
|
|
293
|
-
// <Video> will fallback to <VideoForPreview> anyway
|
|
294
|
-
// not using <OffthreadVideo> because it does not support looping
|
|
295
|
-
return (_jsx(Html5Video, { src: src, style: actualStyle, className: className, muted: muted, volume: volume, trimAfter: trimAfter, trimBefore: trimBefore, playbackRate: playbackRate, loopVolumeCurveBehavior: loopVolumeCurveBehavior, name: name, loop: loop, showInTimeline: showInTimeline, stack: stack ?? undefined, ...fallbackOffthreadVideoProps }));
|
|
296
|
-
}
|
|
297
|
-
if (headless) {
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
return (_jsx("canvas", { ref: canvasRef, width: videoConfig.width, height: videoConfig.height, style: actualStyle, className: classNameValue }));
|
|
301
|
-
};
|
|
302
|
-
export const VideoForPreview = (props) => {
|
|
303
|
-
const frame = useCurrentFrame();
|
|
304
|
-
const videoConfig = useVideoConfig();
|
|
305
|
-
const currentTime = frame / videoConfig.fps;
|
|
306
|
-
const showShow = useMemo(() => {
|
|
307
|
-
return (getTimeInSeconds({
|
|
308
|
-
unloopedTimeInSeconds: currentTime,
|
|
309
|
-
playbackRate: props.playbackRate,
|
|
310
|
-
loop: props.loop,
|
|
311
|
-
trimBefore: props.trimBefore,
|
|
312
|
-
trimAfter: props.trimAfter,
|
|
313
|
-
mediaDurationInSeconds: Infinity,
|
|
314
|
-
fps: videoConfig.fps,
|
|
315
|
-
ifNoMediaDuration: 'infinity',
|
|
316
|
-
src: props.src,
|
|
317
|
-
}) !== null);
|
|
318
|
-
}, [
|
|
319
|
-
currentTime,
|
|
320
|
-
props.loop,
|
|
321
|
-
props.playbackRate,
|
|
322
|
-
props.src,
|
|
323
|
-
props.trimAfter,
|
|
324
|
-
props.trimBefore,
|
|
325
|
-
videoConfig.fps,
|
|
326
|
-
]);
|
|
327
|
-
if (!showShow) {
|
|
328
|
-
return null;
|
|
329
|
-
}
|
|
330
|
-
return _jsx(VideoForPreviewAssertedShowing, { ...props });
|
|
331
|
-
};
|