@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.
Files changed (54) hide show
  1. package/README.md +7 -7
  2. package/dist/audio/audio-preview-iterator.d.ts +8 -2
  3. package/dist/audio-iterator-manager.d.ts +11 -6
  4. package/dist/debug-overlay/preview-overlay.d.ts +9 -4
  5. package/dist/esm/index.mjs +13759 -202
  6. package/dist/use-media-in-timeline.d.ts +3 -2
  7. package/package.json +6 -6
  8. package/dist/audio/allow-wait.js +0 -15
  9. package/dist/audio/audio-for-preview.js +0 -304
  10. package/dist/audio/audio-for-rendering.js +0 -194
  11. package/dist/audio/audio-preview-iterator.js +0 -176
  12. package/dist/audio/audio.js +0 -20
  13. package/dist/audio/props.js +0 -1
  14. package/dist/audio-extraction/audio-cache.js +0 -66
  15. package/dist/audio-extraction/audio-iterator.js +0 -132
  16. package/dist/audio-extraction/audio-manager.js +0 -113
  17. package/dist/audio-extraction/extract-audio.js +0 -132
  18. package/dist/audio-iterator-manager.js +0 -228
  19. package/dist/browser-can-use-webgl2.js +0 -13
  20. package/dist/caches.js +0 -61
  21. package/dist/calculate-playbacktime.js +0 -4
  22. package/dist/convert-audiodata/apply-volume.js +0 -17
  23. package/dist/convert-audiodata/combine-audiodata.js +0 -23
  24. package/dist/convert-audiodata/convert-audiodata.js +0 -73
  25. package/dist/convert-audiodata/resample-audiodata.js +0 -94
  26. package/dist/debug-overlay/preview-overlay.js +0 -42
  27. package/dist/extract-frame-and-audio.js +0 -101
  28. package/dist/get-sink.js +0 -15
  29. package/dist/get-time-in-seconds.js +0 -40
  30. package/dist/helpers/round-to-4-digits.js +0 -4
  31. package/dist/index.js +0 -12
  32. package/dist/is-type-of-error.js +0 -20
  33. package/dist/looped-frame.js +0 -10
  34. package/dist/media-player.js +0 -431
  35. package/dist/nonce-manager.js +0 -13
  36. package/dist/prewarm-iterator-for-looping.js +0 -56
  37. package/dist/render-timestamp-range.js +0 -9
  38. package/dist/show-in-timeline.js +0 -31
  39. package/dist/use-media-in-timeline.js +0 -103
  40. package/dist/video/props.js +0 -1
  41. package/dist/video/video-for-preview.js +0 -331
  42. package/dist/video/video-for-rendering.js +0 -263
  43. package/dist/video/video-preview-iterator.js +0 -122
  44. package/dist/video/video.js +0 -35
  45. package/dist/video-extraction/add-broadcast-channel-listener.js +0 -125
  46. package/dist/video-extraction/extract-frame-via-broadcast-channel.js +0 -113
  47. package/dist/video-extraction/extract-frame.js +0 -85
  48. package/dist/video-extraction/get-allocation-size.js +0 -6
  49. package/dist/video-extraction/get-frames-since-keyframe.js +0 -108
  50. package/dist/video-extraction/keyframe-bank.js +0 -159
  51. package/dist/video-extraction/keyframe-manager.js +0 -206
  52. package/dist/video-extraction/remember-actual-matroska-timestamps.js +0 -19
  53. package/dist/video-extraction/rotate-frame.js +0 -34
  54. 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
- };
@@ -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
- };