@remotion/media 4.0.430 → 4.0.432

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 (63) hide show
  1. package/dist/audio/audio-for-preview.d.ts +1 -0
  2. package/dist/audio/audio-preview-iterator.d.ts +16 -9
  3. package/dist/audio/props.d.ts +1 -0
  4. package/dist/audio-iterator-manager.d.ts +24 -13
  5. package/dist/debug-overlay/preview-overlay.d.ts +24 -14
  6. package/dist/esm/index.mjs +755 -537
  7. package/dist/make-iterator-with-priming.d.ts +6 -0
  8. package/dist/media-player.d.ts +12 -7
  9. package/dist/prewarm-iterator-for-looping.d.ts +3 -2
  10. package/dist/set-global-time-anchor.d.ts +11 -0
  11. package/dist/shared-audio-context-for-media-player.d.ts +8 -0
  12. package/dist/use-common-effects.d.ts +32 -0
  13. package/dist/video/props.d.ts +1 -0
  14. package/dist/video/video-for-preview.d.ts +1 -0
  15. package/package.json +4 -4
  16. package/dist/audio/allow-wait.d.ts +0 -6
  17. package/dist/audio/allow-wait.js +0 -15
  18. package/dist/audio/audio-for-preview.js +0 -304
  19. package/dist/audio/audio-for-rendering.js +0 -194
  20. package/dist/audio/audio-preview-iterator.js +0 -176
  21. package/dist/audio/audio.js +0 -20
  22. package/dist/audio/props.js +0 -1
  23. package/dist/audio-extraction/audio-cache.js +0 -66
  24. package/dist/audio-extraction/audio-iterator.js +0 -132
  25. package/dist/audio-extraction/audio-manager.js +0 -113
  26. package/dist/audio-extraction/extract-audio.js +0 -132
  27. package/dist/audio-iterator-manager.js +0 -228
  28. package/dist/browser-can-use-webgl2.js +0 -13
  29. package/dist/caches.js +0 -61
  30. package/dist/calculate-playbacktime.js +0 -4
  31. package/dist/convert-audiodata/apply-volume.js +0 -17
  32. package/dist/convert-audiodata/combine-audiodata.js +0 -23
  33. package/dist/convert-audiodata/convert-audiodata.js +0 -73
  34. package/dist/convert-audiodata/resample-audiodata.js +0 -94
  35. package/dist/debug-overlay/preview-overlay.js +0 -42
  36. package/dist/extract-frame-and-audio.js +0 -101
  37. package/dist/get-sink.js +0 -15
  38. package/dist/get-time-in-seconds.js +0 -40
  39. package/dist/helpers/round-to-4-digits.js +0 -4
  40. package/dist/index.js +0 -12
  41. package/dist/is-type-of-error.js +0 -20
  42. package/dist/looped-frame.js +0 -10
  43. package/dist/media-player.js +0 -431
  44. package/dist/nonce-manager.js +0 -13
  45. package/dist/prewarm-iterator-for-looping.js +0 -56
  46. package/dist/render-timestamp-range.js +0 -9
  47. package/dist/show-in-timeline.js +0 -31
  48. package/dist/use-media-in-timeline.js +0 -103
  49. package/dist/video/props.js +0 -1
  50. package/dist/video/video-for-preview.js +0 -331
  51. package/dist/video/video-for-rendering.js +0 -263
  52. package/dist/video/video-preview-iterator.js +0 -122
  53. package/dist/video/video.js +0 -35
  54. package/dist/video-extraction/add-broadcast-channel-listener.js +0 -125
  55. package/dist/video-extraction/extract-frame-via-broadcast-channel.js +0 -113
  56. package/dist/video-extraction/extract-frame.js +0 -85
  57. package/dist/video-extraction/get-allocation-size.js +0 -6
  58. package/dist/video-extraction/get-frames-since-keyframe.js +0 -108
  59. package/dist/video-extraction/keyframe-bank.js +0 -159
  60. package/dist/video-extraction/keyframe-manager.js +0 -206
  61. package/dist/video-extraction/remember-actual-matroska-timestamps.js +0 -19
  62. package/dist/video-extraction/rotate-frame.js +0 -34
  63. package/dist/video-iterator-manager.js +0 -109
@@ -1,431 +0,0 @@
1
- import { ALL_FORMATS, Input, UrlSource } from 'mediabunny';
2
- import { Internals } from 'remotion';
3
- import { audioIteratorManager, } from './audio-iterator-manager';
4
- import { calculatePlaybackTime } from './calculate-playbacktime';
5
- import { drawPreviewOverlay } from './debug-overlay/preview-overlay';
6
- import { calculateEndTime, getTimeInSeconds } from './get-time-in-seconds';
7
- import { isNetworkError } from './is-type-of-error';
8
- import { makeNonceManager } from './nonce-manager';
9
- import { videoIteratorManager } from './video-iterator-manager';
10
- export class MediaPlayer {
11
- constructor({ canvas, src, logLevel, sharedAudioContext, loop, trimBefore, trimAfter, playbackRate, globalPlaybackRate, audioStreamIndex, fps, debugOverlay, bufferState, isPremounting, isPostmounting, onVideoFrameCallback, playing, }) {
12
- this.audioIteratorManager = null;
13
- this.videoIteratorManager = null;
14
- // this is the time difference between Web Audio timeline
15
- // and media file timeline
16
- this.audioSyncAnchor = 0;
17
- this.playing = false;
18
- this.loop = false;
19
- this.debugOverlay = false;
20
- this.onVideoFrameCallback = null;
21
- this.initializationPromise = null;
22
- this.seekPromiseChain = Promise.resolve();
23
- this.delayPlaybackHandleIfNotPremounting = () => {
24
- if (this.isPremounting || this.isPostmounting) {
25
- return {
26
- unblock: () => { },
27
- };
28
- }
29
- return this.bufferState.delayPlayback();
30
- };
31
- this.scheduleAudioNode = (node, mediaTimestamp) => {
32
- const currentTime = this.getPlaybackTime();
33
- const delayWithoutPlaybackRate = mediaTimestamp - currentTime;
34
- const delay = delayWithoutPlaybackRate / (this.playbackRate * this.globalPlaybackRate);
35
- if (delay >= 0) {
36
- node.start(this.sharedAudioContext.currentTime + delay);
37
- }
38
- else {
39
- node.start(this.sharedAudioContext.currentTime, -delay);
40
- }
41
- };
42
- this.drawDebugOverlay = () => {
43
- if (!this.debugOverlay)
44
- return;
45
- if (this.context && this.canvas) {
46
- drawPreviewOverlay({
47
- context: this.context,
48
- audioTime: this.sharedAudioContext.currentTime,
49
- audioContextState: this.sharedAudioContext.state,
50
- audioSyncAnchor: this.audioSyncAnchor,
51
- audioIteratorManager: this.audioIteratorManager,
52
- playing: this.playing,
53
- videoIteratorManager: this.videoIteratorManager,
54
- });
55
- }
56
- };
57
- this.canvas = canvas ?? null;
58
- this.src = src;
59
- this.logLevel = logLevel ?? window.remotion_logLevel;
60
- this.sharedAudioContext = sharedAudioContext;
61
- this.playbackRate = playbackRate;
62
- this.globalPlaybackRate = globalPlaybackRate;
63
- this.loop = loop;
64
- this.trimBefore = trimBefore;
65
- this.trimAfter = trimAfter;
66
- this.audioStreamIndex = audioStreamIndex ?? 0;
67
- this.fps = fps;
68
- this.debugOverlay = debugOverlay;
69
- this.bufferState = bufferState;
70
- this.isPremounting = isPremounting;
71
- this.isPostmounting = isPostmounting;
72
- this.nonceManager = makeNonceManager();
73
- this.onVideoFrameCallback = onVideoFrameCallback;
74
- this.playing = playing;
75
- this.input = new Input({
76
- source: new UrlSource(this.src),
77
- formats: ALL_FORMATS,
78
- });
79
- if (canvas) {
80
- const context = canvas.getContext('2d', {
81
- alpha: true,
82
- desynchronized: true,
83
- });
84
- if (!context) {
85
- throw new Error('Could not get 2D context from canvas');
86
- }
87
- this.context = context;
88
- }
89
- else {
90
- this.context = null;
91
- }
92
- }
93
- isDisposalError() {
94
- return this.input.disposed === true;
95
- }
96
- initialize(startTimeUnresolved) {
97
- const promise = this._initialize(startTimeUnresolved);
98
- this.initializationPromise = promise;
99
- this.seekPromiseChain = promise;
100
- return promise;
101
- }
102
- getStartTime() {
103
- return (this.trimBefore ?? 0) / this.fps;
104
- }
105
- getEndTime() {
106
- return calculateEndTime({
107
- mediaDurationInSeconds: this.totalDuration,
108
- ifNoMediaDuration: 'fail',
109
- src: this.src,
110
- trimAfter: this.trimAfter,
111
- trimBefore: this.trimBefore,
112
- fps: this.fps,
113
- });
114
- }
115
- async _initialize(startTimeUnresolved) {
116
- const delayHandle = this.delayPlaybackHandleIfNotPremounting();
117
- try {
118
- if (this.input.disposed) {
119
- return { type: 'disposed' };
120
- }
121
- try {
122
- await this.input.getFormat();
123
- }
124
- catch (error) {
125
- if (this.isDisposalError()) {
126
- return { type: 'disposed' };
127
- }
128
- const err = error;
129
- if (isNetworkError(err)) {
130
- throw error;
131
- }
132
- Internals.Log.error({ logLevel: this.logLevel, tag: '@remotion/media' }, `[MediaPlayer] Failed to recognize format for ${this.src}`, error);
133
- return { type: 'unknown-container-format' };
134
- }
135
- const [durationInSeconds, videoTrack, audioTracks] = await Promise.all([
136
- this.input.computeDuration(),
137
- this.input.getPrimaryVideoTrack(),
138
- this.input.getAudioTracks(),
139
- ]);
140
- if (this.input.disposed) {
141
- return { type: 'disposed' };
142
- }
143
- this.totalDuration = durationInSeconds;
144
- const audioTrack = audioTracks[this.audioStreamIndex] ?? null;
145
- if (!videoTrack && !audioTrack) {
146
- return { type: 'no-tracks' };
147
- }
148
- if (videoTrack) {
149
- const canDecode = await videoTrack.canDecode();
150
- if (!canDecode) {
151
- return { type: 'cannot-decode' };
152
- }
153
- if (this.input.disposed) {
154
- return { type: 'disposed' };
155
- }
156
- this.videoIteratorManager = videoIteratorManager({
157
- videoTrack,
158
- delayPlaybackHandleIfNotPremounting: this.delayPlaybackHandleIfNotPremounting,
159
- context: this.context,
160
- canvas: this.canvas,
161
- getOnVideoFrameCallback: () => this.onVideoFrameCallback,
162
- logLevel: this.logLevel,
163
- drawDebugOverlay: this.drawDebugOverlay,
164
- getEndTime: () => this.getEndTime(),
165
- getStartTime: () => this.getStartTime(),
166
- getIsLooping: () => this.loop,
167
- });
168
- }
169
- const startTime = getTimeInSeconds({
170
- unloopedTimeInSeconds: startTimeUnresolved,
171
- playbackRate: this.playbackRate,
172
- loop: this.loop,
173
- trimBefore: this.trimBefore,
174
- trimAfter: this.trimAfter,
175
- mediaDurationInSeconds: this.totalDuration,
176
- fps: this.fps,
177
- ifNoMediaDuration: 'infinity',
178
- src: this.src,
179
- });
180
- if (startTime === null) {
181
- throw new Error(`should have asserted that the time is not null`);
182
- }
183
- this.setPlaybackTime(startTime, this.playbackRate * this.globalPlaybackRate);
184
- if (audioTrack) {
185
- this.audioIteratorManager = audioIteratorManager({
186
- audioTrack,
187
- delayPlaybackHandleIfNotPremounting: this.delayPlaybackHandleIfNotPremounting,
188
- sharedAudioContext: this.sharedAudioContext,
189
- getIsLooping: () => this.loop,
190
- getEndTime: () => this.getEndTime(),
191
- getStartTime: () => this.getStartTime(),
192
- updatePlaybackTime: (time) => this.setPlaybackTime(time, this.playbackRate * this.globalPlaybackRate),
193
- });
194
- }
195
- const nonce = this.nonceManager.createAsyncOperation();
196
- try {
197
- await Promise.all([
198
- this.audioIteratorManager
199
- ? this.audioIteratorManager.startAudioIterator({
200
- nonce,
201
- playbackRate: this.playbackRate * this.globalPlaybackRate,
202
- startFromSecond: startTime,
203
- getIsPlaying: () => this.playing,
204
- scheduleAudioNode: this.scheduleAudioNode,
205
- })
206
- : Promise.resolve(),
207
- this.videoIteratorManager
208
- ? this.videoIteratorManager.startVideoIterator(startTime, nonce)
209
- : Promise.resolve(),
210
- ]);
211
- }
212
- catch (error) {
213
- if (this.isDisposalError()) {
214
- return { type: 'disposed' };
215
- }
216
- Internals.Log.error({ logLevel: this.logLevel, tag: '@remotion/media' }, '[MediaPlayer] Failed to start audio and video iterators', error);
217
- }
218
- return { type: 'success', durationInSeconds };
219
- }
220
- catch (error) {
221
- const err = error;
222
- if (isNetworkError(err)) {
223
- Internals.Log.error({ logLevel: this.logLevel, tag: '@remotion/media' }, `[MediaPlayer] Network/CORS error for ${this.src}`, err);
224
- return { type: 'network-error' };
225
- }
226
- Internals.Log.error({ logLevel: this.logLevel, tag: '@remotion/media' }, '[MediaPlayer] Failed to initialize', error);
227
- throw error;
228
- }
229
- finally {
230
- delayHandle.unblock();
231
- }
232
- }
233
- async seekTo(time) {
234
- const newTime = getTimeInSeconds({
235
- unloopedTimeInSeconds: time,
236
- playbackRate: this.playbackRate,
237
- loop: this.loop,
238
- trimBefore: this.trimBefore,
239
- trimAfter: this.trimAfter,
240
- mediaDurationInSeconds: this.totalDuration ?? null,
241
- fps: this.fps,
242
- ifNoMediaDuration: 'infinity',
243
- src: this.src,
244
- });
245
- if (newTime === null) {
246
- throw new Error(`should have asserted that the time is not null`);
247
- }
248
- const nonce = this.nonceManager.createAsyncOperation();
249
- await this.seekPromiseChain;
250
- this.seekPromiseChain = this.seekToDoNotCallDirectly(newTime, nonce);
251
- await this.seekPromiseChain;
252
- }
253
- async seekToDoNotCallDirectly(newTime, nonce) {
254
- if (nonce.isStale()) {
255
- return;
256
- }
257
- const currentPlaybackTime = this.getPlaybackTime();
258
- if (currentPlaybackTime === newTime) {
259
- return;
260
- }
261
- await Promise.all([
262
- this.videoIteratorManager?.seek({
263
- newTime,
264
- nonce,
265
- }),
266
- this.audioIteratorManager?.seek({
267
- newTime,
268
- nonce,
269
- fps: this.fps,
270
- playbackRate: this.playbackRate * this.globalPlaybackRate,
271
- getIsPlaying: () => this.playing,
272
- scheduleAudioNode: this.scheduleAudioNode,
273
- bufferState: this.bufferState,
274
- }),
275
- ]);
276
- }
277
- async play(time) {
278
- if (this.playing) {
279
- return;
280
- }
281
- const newTime = getTimeInSeconds({
282
- unloopedTimeInSeconds: time,
283
- playbackRate: this.playbackRate,
284
- loop: this.loop,
285
- trimBefore: this.trimBefore,
286
- trimAfter: this.trimAfter,
287
- mediaDurationInSeconds: this.totalDuration ?? null,
288
- fps: this.fps,
289
- ifNoMediaDuration: 'infinity',
290
- src: this.src,
291
- });
292
- if (newTime === null) {
293
- throw new Error(`should have asserted that the time is not null`);
294
- }
295
- this.setPlaybackTime(newTime, this.playbackRate * this.globalPlaybackRate);
296
- this.playing = true;
297
- if (this.audioIteratorManager) {
298
- this.audioIteratorManager.resumeScheduledAudioChunks({
299
- playbackRate: this.playbackRate * this.globalPlaybackRate,
300
- scheduleAudioNode: this.scheduleAudioNode,
301
- });
302
- }
303
- if (this.sharedAudioContext.state === 'suspended') {
304
- await this.sharedAudioContext.resume();
305
- }
306
- this.drawDebugOverlay();
307
- }
308
- pause() {
309
- if (!this.playing) {
310
- return;
311
- }
312
- this.playing = false;
313
- this.audioIteratorManager?.pausePlayback();
314
- this.drawDebugOverlay();
315
- }
316
- setMuted(muted) {
317
- this.audioIteratorManager?.setMuted(muted);
318
- }
319
- setVolume(volume) {
320
- if (!this.audioIteratorManager) {
321
- return;
322
- }
323
- this.audioIteratorManager.setVolume(volume);
324
- }
325
- updateAfterTrimChange(unloopedTimeInSeconds) {
326
- if (!this.audioIteratorManager && !this.videoIteratorManager) {
327
- return;
328
- }
329
- const newMediaTime = getTimeInSeconds({
330
- unloopedTimeInSeconds,
331
- playbackRate: this.playbackRate,
332
- loop: this.loop,
333
- trimBefore: this.trimBefore,
334
- trimAfter: this.trimAfter,
335
- mediaDurationInSeconds: this.totalDuration ?? null,
336
- fps: this.fps,
337
- ifNoMediaDuration: 'infinity',
338
- src: this.src,
339
- });
340
- if (newMediaTime !== null) {
341
- this.setPlaybackTime(newMediaTime, this.playbackRate * this.globalPlaybackRate);
342
- }
343
- // audio iterator will be re-created on next play/seek
344
- // video iterator doesn't need to be re-created
345
- this.audioIteratorManager?.destroyIterator();
346
- }
347
- setTrimBefore(trimBefore, unloopedTimeInSeconds) {
348
- if (this.trimBefore !== trimBefore) {
349
- this.trimBefore = trimBefore;
350
- this.updateAfterTrimChange(unloopedTimeInSeconds);
351
- }
352
- }
353
- setTrimAfter(trimAfter, unloopedTimeInSeconds) {
354
- if (this.trimAfter !== trimAfter) {
355
- this.trimAfter = trimAfter;
356
- this.updateAfterTrimChange(unloopedTimeInSeconds);
357
- }
358
- }
359
- setDebugOverlay(debugOverlay) {
360
- this.debugOverlay = debugOverlay;
361
- }
362
- updateAfterPlaybackRateChange() {
363
- if (!this.audioIteratorManager) {
364
- return;
365
- }
366
- this.setPlaybackTime(this.getPlaybackTime(), this.playbackRate * this.globalPlaybackRate);
367
- const iterator = this.audioIteratorManager.getAudioBufferIterator();
368
- if (!iterator) {
369
- return;
370
- }
371
- iterator.moveQueuedChunksToPauseQueue();
372
- if (this.playing) {
373
- this.audioIteratorManager.resumeScheduledAudioChunks({
374
- playbackRate: this.playbackRate * this.globalPlaybackRate,
375
- scheduleAudioNode: this.scheduleAudioNode,
376
- });
377
- }
378
- }
379
- setPlaybackRate(rate) {
380
- this.playbackRate = rate;
381
- this.updateAfterPlaybackRateChange();
382
- }
383
- setGlobalPlaybackRate(rate) {
384
- this.globalPlaybackRate = rate;
385
- this.updateAfterPlaybackRateChange();
386
- }
387
- setFps(fps) {
388
- this.fps = fps;
389
- }
390
- setIsPremounting(isPremounting) {
391
- this.isPremounting = isPremounting;
392
- }
393
- setIsPostmounting(isPostmounting) {
394
- this.isPostmounting = isPostmounting;
395
- }
396
- setLoop(loop) {
397
- this.loop = loop;
398
- }
399
- async dispose() {
400
- if (this.initializationPromise) {
401
- try {
402
- // wait for the init to finished
403
- // otherwise we might get errors like:
404
- // Error: Response stream reader stopped unexpectedly before all requested data was read. from UrlSource
405
- await this.initializationPromise;
406
- }
407
- catch {
408
- // Ignore initialization errors during disposal
409
- }
410
- }
411
- // Mark all async operations as stale
412
- this.nonceManager.createAsyncOperation();
413
- this.videoIteratorManager?.destroy();
414
- this.audioIteratorManager?.destroyIterator();
415
- this.input.dispose();
416
- }
417
- getPlaybackTime() {
418
- return calculatePlaybackTime({
419
- audioSyncAnchor: this.audioSyncAnchor,
420
- currentTime: this.sharedAudioContext.currentTime,
421
- playbackRate: this.playbackRate * this.globalPlaybackRate,
422
- });
423
- }
424
- setPlaybackTime(time, playbackRate) {
425
- this.audioSyncAnchor =
426
- this.sharedAudioContext.currentTime - time / playbackRate;
427
- }
428
- setVideoFrameCallback(callback) {
429
- this.onVideoFrameCallback = callback;
430
- }
431
- }
@@ -1,13 +0,0 @@
1
- export const makeNonceManager = () => {
2
- let nonce = 0;
3
- const createAsyncOperation = () => {
4
- nonce++;
5
- const currentNonce = nonce;
6
- return {
7
- isStale: () => nonce !== currentNonce,
8
- };
9
- };
10
- return {
11
- createAsyncOperation,
12
- };
13
- };
@@ -1,56 +0,0 @@
1
- export const makePrewarmedVideoIteratorCache = (videoSink) => {
2
- const prewarmedVideoIterators = new Map();
3
- const prewarmIteratorForLooping = ({ timeToSeek }) => {
4
- if (!prewarmedVideoIterators.has(timeToSeek)) {
5
- prewarmedVideoIterators.set(timeToSeek, videoSink.canvases(timeToSeek));
6
- }
7
- };
8
- const makeIteratorOrUsePrewarmed = (timeToSeek) => {
9
- const prewarmedIterator = prewarmedVideoIterators.get(timeToSeek);
10
- if (prewarmedIterator) {
11
- prewarmedVideoIterators.delete(timeToSeek);
12
- return prewarmedIterator;
13
- }
14
- const iterator = videoSink.canvases(timeToSeek);
15
- return iterator;
16
- };
17
- const destroy = () => {
18
- for (const iterator of prewarmedVideoIterators.values()) {
19
- iterator.return();
20
- }
21
- prewarmedVideoIterators.clear();
22
- };
23
- return {
24
- prewarmIteratorForLooping,
25
- makeIteratorOrUsePrewarmed,
26
- destroy,
27
- };
28
- };
29
- export const makePrewarmedAudioIteratorCache = (audioSink) => {
30
- const prewarmedAudioIterators = new Map();
31
- const prewarmIteratorForLooping = ({ timeToSeek }) => {
32
- if (!prewarmedAudioIterators.has(timeToSeek)) {
33
- prewarmedAudioIterators.set(timeToSeek, audioSink.buffers(timeToSeek));
34
- }
35
- };
36
- const makeIteratorOrUsePrewarmed = (timeToSeek) => {
37
- const prewarmedIterator = prewarmedAudioIterators.get(timeToSeek);
38
- if (prewarmedIterator) {
39
- prewarmedAudioIterators.delete(timeToSeek);
40
- return prewarmedIterator;
41
- }
42
- const iterator = audioSink.buffers(timeToSeek);
43
- return iterator;
44
- };
45
- const destroy = () => {
46
- for (const iterator of prewarmedAudioIterators.values()) {
47
- iterator.return();
48
- }
49
- prewarmedAudioIterators.clear();
50
- };
51
- return {
52
- prewarmIteratorForLooping,
53
- makeIteratorOrUsePrewarmed,
54
- destroy,
55
- };
56
- };
@@ -1,9 +0,0 @@
1
- export const renderTimestampRange = (timestamps) => {
2
- if (timestamps.length === 0) {
3
- return '(none)';
4
- }
5
- if (timestamps.length === 1) {
6
- return timestamps[0].toFixed(3);
7
- }
8
- return `${timestamps[0].toFixed(3)}...${timestamps[timestamps.length - 1].toFixed(3)}`;
9
- };
@@ -1,31 +0,0 @@
1
- import { useMemo } from 'react';
2
- import { Internals, useVideoConfig } from 'remotion';
3
- export const useLoopDisplay = ({ loop, mediaDurationInSeconds, playbackRate, trimAfter, trimBefore, }) => {
4
- const { durationInFrames: compDuration, fps } = useVideoConfig();
5
- const loopDisplay = useMemo(() => {
6
- if (!loop || !mediaDurationInSeconds) {
7
- return undefined;
8
- }
9
- const durationInFrames = Internals.calculateMediaDuration({
10
- mediaDurationInFrames: mediaDurationInSeconds * fps,
11
- playbackRate,
12
- trimAfter,
13
- trimBefore,
14
- });
15
- const maxTimes = compDuration / durationInFrames;
16
- return {
17
- numberOfTimes: maxTimes,
18
- startOffset: 0,
19
- durationInFrames,
20
- };
21
- }, [
22
- compDuration,
23
- fps,
24
- loop,
25
- mediaDurationInSeconds,
26
- playbackRate,
27
- trimAfter,
28
- trimBefore,
29
- ]);
30
- return loopDisplay;
31
- };
@@ -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 {};