@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.
- package/dist/audio/audio-for-preview.d.ts +1 -0
- package/dist/audio/audio-preview-iterator.d.ts +16 -9
- package/dist/audio/props.d.ts +1 -0
- package/dist/audio-iterator-manager.d.ts +24 -13
- package/dist/debug-overlay/preview-overlay.d.ts +24 -14
- package/dist/esm/index.mjs +755 -537
- package/dist/make-iterator-with-priming.d.ts +6 -0
- package/dist/media-player.d.ts +12 -7
- package/dist/prewarm-iterator-for-looping.d.ts +3 -2
- package/dist/set-global-time-anchor.d.ts +11 -0
- package/dist/shared-audio-context-for-media-player.d.ts +8 -0
- package/dist/use-common-effects.d.ts +32 -0
- package/dist/video/props.d.ts +1 -0
- package/dist/video/video-for-preview.d.ts +1 -0
- package/package.json +4 -4
- package/dist/audio/allow-wait.d.ts +0 -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
package/dist/esm/index.mjs
CHANGED
|
@@ -37,19 +37,12 @@ var __callDispose = (stack, error, hasError) => {
|
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
// src/audio/audio.tsx
|
|
40
|
-
import { Internals as
|
|
40
|
+
import { Internals as Internals19, useRemotionEnvironment as useRemotionEnvironment2 } from "remotion";
|
|
41
41
|
|
|
42
42
|
// src/audio/audio-for-preview.tsx
|
|
43
|
+
import { useContext as useContext3, useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
|
|
43
44
|
import {
|
|
44
|
-
|
|
45
|
-
useEffect as useEffect2,
|
|
46
|
-
useLayoutEffect,
|
|
47
|
-
useMemo as useMemo2,
|
|
48
|
-
useRef,
|
|
49
|
-
useState as useState2
|
|
50
|
-
} from "react";
|
|
51
|
-
import {
|
|
52
|
-
Internals as Internals6,
|
|
45
|
+
Internals as Internals10,
|
|
53
46
|
Audio as RemotionAudio,
|
|
54
47
|
useBufferState,
|
|
55
48
|
useCurrentFrame as useCurrentFrame2,
|
|
@@ -109,27 +102,65 @@ var calculateEndTime = ({
|
|
|
109
102
|
|
|
110
103
|
// src/media-player.ts
|
|
111
104
|
import { ALL_FORMATS, Input, UrlSource } from "mediabunny";
|
|
112
|
-
import { Internals as
|
|
105
|
+
import { Internals as Internals6 } from "remotion";
|
|
113
106
|
|
|
114
107
|
// src/audio-iterator-manager.ts
|
|
115
108
|
import { AudioBufferSink, InputDisposedError } from "mediabunny";
|
|
109
|
+
import { Internals as Internals4 } from "remotion";
|
|
110
|
+
|
|
111
|
+
// src/audio/audio-preview-iterator.ts
|
|
112
|
+
import { Internals as Internals3 } from "remotion";
|
|
116
113
|
|
|
117
114
|
// src/helpers/round-to-4-digits.ts
|
|
118
115
|
var roundTo4Digits = (timestamp) => {
|
|
119
116
|
return Math.round(timestamp * 1000) / 1000;
|
|
120
117
|
};
|
|
121
118
|
|
|
119
|
+
// src/set-global-time-anchor.ts
|
|
120
|
+
import { Internals as Internals2 } from "remotion";
|
|
121
|
+
var ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
|
|
122
|
+
var setGlobalTimeAnchor = ({
|
|
123
|
+
audioContext,
|
|
124
|
+
audioSyncAnchor,
|
|
125
|
+
absoluteTimeInSeconds,
|
|
126
|
+
globalPlaybackRate,
|
|
127
|
+
debugAudioScheduling,
|
|
128
|
+
logLevel
|
|
129
|
+
}) => {
|
|
130
|
+
const newAnchor = audioContext.currentTime - absoluteTimeInSeconds / globalPlaybackRate;
|
|
131
|
+
const shift = (newAnchor - audioSyncAnchor.value) * globalPlaybackRate;
|
|
132
|
+
if (Math.abs(shift) < ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (debugAudioScheduling) {
|
|
136
|
+
Internals2.Log.info({ logLevel, tag: "audio-scheduling" }, "Anchor changed from %s to %s with shift %s", audioSyncAnchor.value, newAnchor, shift);
|
|
137
|
+
}
|
|
138
|
+
audioSyncAnchor.value = newAnchor;
|
|
139
|
+
};
|
|
140
|
+
|
|
122
141
|
// src/audio/audio-preview-iterator.ts
|
|
123
|
-
var makeAudioIterator = (startFromSecond, cache) => {
|
|
142
|
+
var makeAudioIterator = (startFromSecond, maximumTimestamp, cache, debugAudioScheduling) => {
|
|
124
143
|
let destroyed = false;
|
|
125
|
-
const iterator = cache.makeIteratorOrUsePrewarmed(startFromSecond);
|
|
144
|
+
const iterator = cache.makeIteratorOrUsePrewarmed(startFromSecond, maximumTimestamp);
|
|
126
145
|
const queuedAudioNodes = [];
|
|
127
146
|
const audioChunksForAfterResuming = [];
|
|
128
147
|
let mostRecentTimestamp = -Infinity;
|
|
129
148
|
let pendingNext = null;
|
|
130
|
-
const cleanupAudioQueue = () => {
|
|
149
|
+
const cleanupAudioQueue = (audioContext) => {
|
|
131
150
|
for (const node of queuedAudioNodes) {
|
|
132
|
-
|
|
151
|
+
try {
|
|
152
|
+
const currentlyHearing = audioContext.getOutputTimestamp().contextTime;
|
|
153
|
+
const nodeEndTime = node.scheduledTime + node.buffer.duration / node.playbackRate;
|
|
154
|
+
const isAlreadyPlaying = node.scheduledTime - ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT < audioContext.currentTime;
|
|
155
|
+
const shouldKeep = isAlreadyPlaying;
|
|
156
|
+
if (shouldKeep) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (debugAudioScheduling) {
|
|
160
|
+
Internals3.Log.info({ logLevel: "trace", tag: "audio-scheduling" }, `Stopping node ${node.timestamp.toFixed(3)}, currently hearing = ${currentlyHearing.toFixed(3)} currentTime = ${audioContext.currentTime.toFixed(3)} nodeEndTime = ${nodeEndTime.toFixed(3)} scheduledTime = ${node.scheduledTime.toFixed(3)}`);
|
|
161
|
+
}
|
|
162
|
+
node.node.stop();
|
|
163
|
+
} catch {}
|
|
133
164
|
}
|
|
134
165
|
queuedAudioNodes.length = 0;
|
|
135
166
|
};
|
|
@@ -238,26 +269,34 @@ var makeAudioIterator = (startFromSecond, cache) => {
|
|
|
238
269
|
const removeAndReturnAllQueuedAudioNodes = () => {
|
|
239
270
|
const nodes = queuedAudioNodes.slice();
|
|
240
271
|
for (const node of nodes) {
|
|
241
|
-
|
|
272
|
+
try {
|
|
273
|
+
node.node.stop();
|
|
274
|
+
} catch {}
|
|
242
275
|
}
|
|
243
276
|
queuedAudioNodes.length = 0;
|
|
244
277
|
return nodes;
|
|
245
278
|
};
|
|
246
|
-
const addChunkForAfterResuming = (buffer, timestamp
|
|
247
|
-
audioChunksForAfterResuming.push({
|
|
279
|
+
const addChunkForAfterResuming = (buffer, timestamp) => {
|
|
280
|
+
audioChunksForAfterResuming.push({
|
|
281
|
+
buffer,
|
|
282
|
+
timestamp
|
|
283
|
+
});
|
|
248
284
|
};
|
|
249
285
|
const moveQueuedChunksToPauseQueue = () => {
|
|
250
286
|
const toQueue = removeAndReturnAllQueuedAudioNodes();
|
|
251
287
|
for (const chunk of toQueue) {
|
|
252
|
-
addChunkForAfterResuming(chunk.buffer, chunk.timestamp
|
|
288
|
+
addChunkForAfterResuming(chunk.buffer, chunk.timestamp);
|
|
289
|
+
}
|
|
290
|
+
if (debugAudioScheduling && toQueue.length > 0) {
|
|
291
|
+
Internals3.Log.trace({ logLevel: "trace", tag: "audio-scheduling" }, `Moved ${toQueue.length} ${toQueue.length === 1 ? "chunk" : "chunks"} to pause queue (${toQueue[0].timestamp.toFixed(3)}-${toQueue[toQueue.length - 1].timestamp + toQueue[toQueue.length - 1].buffer.duration.toFixed(3)})`);
|
|
253
292
|
}
|
|
254
293
|
};
|
|
255
294
|
const getNumberOfChunksAfterResuming = () => {
|
|
256
295
|
return audioChunksForAfterResuming.length;
|
|
257
296
|
};
|
|
258
297
|
return {
|
|
259
|
-
destroy: () => {
|
|
260
|
-
cleanupAudioQueue();
|
|
298
|
+
destroy: (audioContext) => {
|
|
299
|
+
cleanupAudioQueue(audioContext);
|
|
261
300
|
destroyed = true;
|
|
262
301
|
iterator.return().catch(() => {
|
|
263
302
|
return;
|
|
@@ -274,8 +313,20 @@ var makeAudioIterator = (startFromSecond, cache) => {
|
|
|
274
313
|
isDestroyed: () => {
|
|
275
314
|
return destroyed;
|
|
276
315
|
},
|
|
277
|
-
addQueuedAudioNode: (
|
|
278
|
-
|
|
316
|
+
addQueuedAudioNode: ({
|
|
317
|
+
node,
|
|
318
|
+
timestamp,
|
|
319
|
+
buffer,
|
|
320
|
+
scheduledTime,
|
|
321
|
+
playbackRate
|
|
322
|
+
}) => {
|
|
323
|
+
queuedAudioNodes.push({
|
|
324
|
+
node,
|
|
325
|
+
timestamp,
|
|
326
|
+
buffer,
|
|
327
|
+
scheduledTime,
|
|
328
|
+
playbackRate
|
|
329
|
+
});
|
|
279
330
|
},
|
|
280
331
|
removeQueuedAudioNode: (node) => {
|
|
281
332
|
const index = queuedAudioNodes.findIndex((n) => n.node === node);
|
|
@@ -321,6 +372,121 @@ var isAlreadyQueued = (time, queuedPeriod) => {
|
|
|
321
372
|
return time >= queuedPeriod.from && time < queuedPeriod.until;
|
|
322
373
|
};
|
|
323
374
|
|
|
375
|
+
// src/make-iterator-with-priming.ts
|
|
376
|
+
var AUDIO_PRIMING_SECONDS = 0.5;
|
|
377
|
+
var PREDECODE_AHEAD_SECONDS = 8;
|
|
378
|
+
function makePredecodingIterator(inner) {
|
|
379
|
+
const buffer = [];
|
|
380
|
+
let consumerEndTime = 0;
|
|
381
|
+
let innerDone = false;
|
|
382
|
+
let returned = false;
|
|
383
|
+
let fetching = false;
|
|
384
|
+
let waiter = null;
|
|
385
|
+
const prefetch = () => {
|
|
386
|
+
if (fetching || returned || innerDone) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const lastBuffered = buffer.length > 0 ? buffer[buffer.length - 1] : null;
|
|
390
|
+
const bufferedEndTime = lastBuffered ? lastBuffered.timestamp + lastBuffered.duration : consumerEndTime;
|
|
391
|
+
if (bufferedEndTime >= consumerEndTime + PREDECODE_AHEAD_SECONDS) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
fetching = true;
|
|
395
|
+
inner.next().then((result) => {
|
|
396
|
+
fetching = false;
|
|
397
|
+
if (returned) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (result.done) {
|
|
401
|
+
innerDone = true;
|
|
402
|
+
if (waiter) {
|
|
403
|
+
const w = waiter;
|
|
404
|
+
waiter = null;
|
|
405
|
+
w({ value: undefined, done: true });
|
|
406
|
+
}
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (waiter) {
|
|
410
|
+
const w = waiter;
|
|
411
|
+
waiter = null;
|
|
412
|
+
const buf = result.value;
|
|
413
|
+
consumerEndTime = buf.timestamp + buf.duration;
|
|
414
|
+
w({ value: buf, done: false });
|
|
415
|
+
prefetch();
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
buffer.push(result.value);
|
|
419
|
+
prefetch();
|
|
420
|
+
}, () => {
|
|
421
|
+
fetching = false;
|
|
422
|
+
innerDone = true;
|
|
423
|
+
if (waiter) {
|
|
424
|
+
const w = waiter;
|
|
425
|
+
waiter = null;
|
|
426
|
+
w({ value: undefined, done: true });
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
};
|
|
430
|
+
prefetch();
|
|
431
|
+
const iterator = {
|
|
432
|
+
next() {
|
|
433
|
+
if (buffer.length > 0) {
|
|
434
|
+
const buf = buffer.shift();
|
|
435
|
+
consumerEndTime = buf.timestamp + buf.duration;
|
|
436
|
+
prefetch();
|
|
437
|
+
return Promise.resolve({ value: buf, done: false });
|
|
438
|
+
}
|
|
439
|
+
if (innerDone) {
|
|
440
|
+
return Promise.resolve({
|
|
441
|
+
value: undefined,
|
|
442
|
+
done: true
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
return new Promise((resolve) => {
|
|
446
|
+
waiter = resolve;
|
|
447
|
+
prefetch();
|
|
448
|
+
});
|
|
449
|
+
},
|
|
450
|
+
return() {
|
|
451
|
+
returned = true;
|
|
452
|
+
buffer.length = 0;
|
|
453
|
+
if (waiter) {
|
|
454
|
+
const w = waiter;
|
|
455
|
+
waiter = null;
|
|
456
|
+
w({ value: undefined, done: true });
|
|
457
|
+
}
|
|
458
|
+
inner.return(undefined);
|
|
459
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
460
|
+
},
|
|
461
|
+
throw(e) {
|
|
462
|
+
returned = true;
|
|
463
|
+
buffer.length = 0;
|
|
464
|
+
return inner.throw(e);
|
|
465
|
+
},
|
|
466
|
+
[Symbol.asyncIterator]() {
|
|
467
|
+
return iterator;
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
return iterator;
|
|
471
|
+
}
|
|
472
|
+
async function* makeIteratorWithPrimingInner(audioSink, timeToSeek, maximumTimestamp) {
|
|
473
|
+
const primingStart = Math.max(0, timeToSeek - AUDIO_PRIMING_SECONDS);
|
|
474
|
+
const iterator = audioSink.buffers(primingStart, maximumTimestamp);
|
|
475
|
+
for await (const buffer of iterator) {
|
|
476
|
+
if (buffer.timestamp + buffer.duration <= timeToSeek) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
yield buffer;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
var makeIteratorWithPriming = ({
|
|
483
|
+
audioSink,
|
|
484
|
+
timeToSeek,
|
|
485
|
+
maximumTimestamp
|
|
486
|
+
}) => {
|
|
487
|
+
return makePredecodingIterator(makeIteratorWithPrimingInner(audioSink, timeToSeek, maximumTimestamp));
|
|
488
|
+
};
|
|
489
|
+
|
|
324
490
|
// src/prewarm-iterator-for-looping.ts
|
|
325
491
|
var makePrewarmedVideoIteratorCache = (videoSink) => {
|
|
326
492
|
const prewarmedVideoIterators = new Map;
|
|
@@ -350,20 +516,30 @@ var makePrewarmedVideoIteratorCache = (videoSink) => {
|
|
|
350
516
|
destroy
|
|
351
517
|
};
|
|
352
518
|
};
|
|
519
|
+
var makeKey = (timeToSeek, maximumTimestamp) => {
|
|
520
|
+
return `${timeToSeek}-${maximumTimestamp}`;
|
|
521
|
+
};
|
|
353
522
|
var makePrewarmedAudioIteratorCache = (audioSink) => {
|
|
354
523
|
const prewarmedAudioIterators = new Map;
|
|
355
|
-
const prewarmIteratorForLooping = ({
|
|
356
|
-
|
|
357
|
-
|
|
524
|
+
const prewarmIteratorForLooping = ({
|
|
525
|
+
timeToSeek,
|
|
526
|
+
maximumTimestamp
|
|
527
|
+
}) => {
|
|
528
|
+
if (!prewarmedAudioIterators.has(makeKey(timeToSeek, maximumTimestamp))) {
|
|
529
|
+
prewarmedAudioIterators.set(makeKey(timeToSeek, maximumTimestamp), makeIteratorWithPriming({ audioSink, timeToSeek, maximumTimestamp }));
|
|
358
530
|
}
|
|
359
531
|
};
|
|
360
|
-
const makeIteratorOrUsePrewarmed = (timeToSeek) => {
|
|
361
|
-
const prewarmedIterator = prewarmedAudioIterators.get(timeToSeek);
|
|
532
|
+
const makeIteratorOrUsePrewarmed = (timeToSeek, maximumTimestamp) => {
|
|
533
|
+
const prewarmedIterator = prewarmedAudioIterators.get(makeKey(timeToSeek, maximumTimestamp));
|
|
362
534
|
if (prewarmedIterator) {
|
|
363
|
-
prewarmedAudioIterators.delete(timeToSeek);
|
|
535
|
+
prewarmedAudioIterators.delete(makeKey(timeToSeek, maximumTimestamp));
|
|
364
536
|
return prewarmedIterator;
|
|
365
537
|
}
|
|
366
|
-
const iterator =
|
|
538
|
+
const iterator = makeIteratorWithPriming({
|
|
539
|
+
audioSink,
|
|
540
|
+
timeToSeek,
|
|
541
|
+
maximumTimestamp
|
|
542
|
+
});
|
|
367
543
|
return iterator;
|
|
368
544
|
};
|
|
369
545
|
const destroy = () => {
|
|
@@ -405,11 +581,14 @@ var audioIteratorManager = ({
|
|
|
405
581
|
mediaTimestamp,
|
|
406
582
|
playbackRate,
|
|
407
583
|
scheduleAudioNode,
|
|
408
|
-
|
|
584
|
+
debugAudioScheduling
|
|
409
585
|
}) => {
|
|
410
586
|
if (!audioBufferIterator) {
|
|
411
587
|
throw new Error("Audio buffer iterator not found");
|
|
412
588
|
}
|
|
589
|
+
if (sharedAudioContext.state !== "running") {
|
|
590
|
+
throw new Error("Tried to schedule node while audio context is not running");
|
|
591
|
+
}
|
|
413
592
|
if (muted) {
|
|
414
593
|
return;
|
|
415
594
|
}
|
|
@@ -417,42 +596,88 @@ var audioIteratorManager = ({
|
|
|
417
596
|
node.buffer = buffer;
|
|
418
597
|
node.playbackRate.value = playbackRate;
|
|
419
598
|
node.connect(gainNode);
|
|
420
|
-
scheduleAudioNode(node, mediaTimestamp
|
|
599
|
+
const started = scheduleAudioNode(node, mediaTimestamp);
|
|
600
|
+
if (started.type === "not-started") {
|
|
601
|
+
if (debugAudioScheduling) {
|
|
602
|
+
Internals4.Log.info({ logLevel: "trace", tag: "audio-scheduling" }, "not started, disconnected: %s %s", mediaTimestamp.toFixed(3), buffer.duration.toFixed(3));
|
|
603
|
+
}
|
|
604
|
+
node.disconnect();
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
421
607
|
const iterator = audioBufferIterator;
|
|
422
|
-
iterator.addQueuedAudioNode(
|
|
608
|
+
iterator.addQueuedAudioNode({
|
|
609
|
+
node,
|
|
610
|
+
timestamp: mediaTimestamp,
|
|
611
|
+
buffer,
|
|
612
|
+
scheduledTime: started.scheduledTime,
|
|
613
|
+
playbackRate
|
|
614
|
+
});
|
|
423
615
|
node.onended = () => {
|
|
424
616
|
setTimeout(() => {
|
|
425
617
|
iterator.removeQueuedAudioNode(node);
|
|
426
618
|
}, 30);
|
|
427
619
|
};
|
|
428
620
|
};
|
|
621
|
+
const resumeScheduledAudioChunks = ({
|
|
622
|
+
playbackRate,
|
|
623
|
+
scheduleAudioNode,
|
|
624
|
+
debugAudioScheduling
|
|
625
|
+
}) => {
|
|
626
|
+
if (muted) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
if (!audioBufferIterator) {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
for (const chunk of audioBufferIterator.getAndClearAudioChunksForAfterResuming()) {
|
|
633
|
+
scheduleAudioChunk({
|
|
634
|
+
buffer: chunk.buffer,
|
|
635
|
+
mediaTimestamp: chunk.timestamp,
|
|
636
|
+
playbackRate,
|
|
637
|
+
scheduleAudioNode,
|
|
638
|
+
debugAudioScheduling
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
};
|
|
429
642
|
const onAudioChunk = ({
|
|
430
643
|
getIsPlaying,
|
|
431
644
|
buffer,
|
|
432
645
|
playbackRate,
|
|
433
|
-
scheduleAudioNode
|
|
646
|
+
scheduleAudioNode,
|
|
647
|
+
debugAudioScheduling
|
|
434
648
|
}) => {
|
|
435
649
|
if (muted) {
|
|
436
650
|
return;
|
|
437
651
|
}
|
|
652
|
+
const startTime = getStartTime();
|
|
438
653
|
const endTime = getEndTime();
|
|
654
|
+
if (buffer.timestamp + buffer.duration <= startTime) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
439
657
|
if (buffer.timestamp >= endTime) {
|
|
440
658
|
return;
|
|
441
659
|
}
|
|
442
|
-
|
|
443
|
-
|
|
660
|
+
if (getIsPlaying() && sharedAudioContext.state === "running" && (sharedAudioContext.getOutputTimestamp().contextTime ?? 0) > 0) {
|
|
661
|
+
resumeScheduledAudioChunks({
|
|
662
|
+
playbackRate,
|
|
663
|
+
scheduleAudioNode,
|
|
664
|
+
debugAudioScheduling
|
|
665
|
+
});
|
|
444
666
|
scheduleAudioChunk({
|
|
445
667
|
buffer: buffer.buffer,
|
|
446
668
|
mediaTimestamp: buffer.timestamp,
|
|
447
669
|
playbackRate,
|
|
448
670
|
scheduleAudioNode,
|
|
449
|
-
|
|
671
|
+
debugAudioScheduling
|
|
450
672
|
});
|
|
451
673
|
} else {
|
|
452
674
|
if (!audioBufferIterator) {
|
|
453
675
|
throw new Error("Audio buffer iterator not found");
|
|
454
676
|
}
|
|
455
|
-
|
|
677
|
+
if (debugAudioScheduling) {
|
|
678
|
+
Internals4.Log.info({ logLevel: "trace", tag: "audio-scheduling" }, "not ready, added to queue: %s %s", buffer.timestamp.toFixed(3), buffer.duration.toFixed(3));
|
|
679
|
+
}
|
|
680
|
+
audioBufferIterator.addChunkForAfterResuming(buffer.buffer, buffer.timestamp);
|
|
456
681
|
}
|
|
457
682
|
drawDebugOverlay();
|
|
458
683
|
};
|
|
@@ -461,17 +686,18 @@ var audioIteratorManager = ({
|
|
|
461
686
|
playbackRate,
|
|
462
687
|
startFromSecond,
|
|
463
688
|
getIsPlaying,
|
|
464
|
-
scheduleAudioNode
|
|
689
|
+
scheduleAudioNode,
|
|
690
|
+
debugAudioScheduling
|
|
465
691
|
}) => {
|
|
466
692
|
let __stack = [];
|
|
467
693
|
try {
|
|
468
694
|
if (muted) {
|
|
469
695
|
return;
|
|
470
696
|
}
|
|
471
|
-
audioBufferIterator?.destroy();
|
|
697
|
+
audioBufferIterator?.destroy(sharedAudioContext);
|
|
472
698
|
const delayHandle = __using(__stack, delayPlaybackHandleIfNotPremounting(), 0);
|
|
473
699
|
currentDelayHandle = delayHandle;
|
|
474
|
-
const iterator = makeAudioIterator(startFromSecond, prewarmedAudioIteratorCache);
|
|
700
|
+
const iterator = makeAudioIterator(startFromSecond, getEndTime(), prewarmedAudioIteratorCache, debugAudioScheduling);
|
|
475
701
|
audioIteratorsCreated++;
|
|
476
702
|
audioBufferIterator = iterator;
|
|
477
703
|
try {
|
|
@@ -490,7 +716,8 @@ var audioIteratorManager = ({
|
|
|
490
716
|
getIsPlaying,
|
|
491
717
|
buffer: result.value,
|
|
492
718
|
playbackRate,
|
|
493
|
-
scheduleAudioNode
|
|
719
|
+
scheduleAudioNode,
|
|
720
|
+
debugAudioScheduling
|
|
494
721
|
});
|
|
495
722
|
}
|
|
496
723
|
await iterator.bufferAsFarAsPossible((buffer) => {
|
|
@@ -499,7 +726,8 @@ var audioIteratorManager = ({
|
|
|
499
726
|
getIsPlaying,
|
|
500
727
|
buffer,
|
|
501
728
|
playbackRate,
|
|
502
|
-
scheduleAudioNode
|
|
729
|
+
scheduleAudioNode,
|
|
730
|
+
debugAudioScheduling
|
|
503
731
|
});
|
|
504
732
|
}
|
|
505
733
|
}, Math.min(startFromSecond + MAX_BUFFER_AHEAD_SECONDS, getEndTime()));
|
|
@@ -526,7 +754,8 @@ var audioIteratorManager = ({
|
|
|
526
754
|
nonce,
|
|
527
755
|
playbackRate,
|
|
528
756
|
getIsPlaying,
|
|
529
|
-
scheduleAudioNode
|
|
757
|
+
scheduleAudioNode,
|
|
758
|
+
debugAudioScheduling
|
|
530
759
|
}) => {
|
|
531
760
|
if (muted) {
|
|
532
761
|
return;
|
|
@@ -534,7 +763,8 @@ var audioIteratorManager = ({
|
|
|
534
763
|
if (getIsLooping()) {
|
|
535
764
|
if (getEndTime() - newTime < 1) {
|
|
536
765
|
prewarmedAudioIteratorCache.prewarmIteratorForLooping({
|
|
537
|
-
timeToSeek: getStartTime()
|
|
766
|
+
timeToSeek: getStartTime(),
|
|
767
|
+
maximumTimestamp: getEndTime()
|
|
538
768
|
});
|
|
539
769
|
}
|
|
540
770
|
}
|
|
@@ -544,7 +774,8 @@ var audioIteratorManager = ({
|
|
|
544
774
|
playbackRate,
|
|
545
775
|
startFromSecond: newTime,
|
|
546
776
|
getIsPlaying,
|
|
547
|
-
scheduleAudioNode
|
|
777
|
+
scheduleAudioNode,
|
|
778
|
+
debugAudioScheduling
|
|
548
779
|
});
|
|
549
780
|
return;
|
|
550
781
|
}
|
|
@@ -557,7 +788,8 @@ var audioIteratorManager = ({
|
|
|
557
788
|
getIsPlaying,
|
|
558
789
|
buffer,
|
|
559
790
|
playbackRate,
|
|
560
|
-
scheduleAudioNode
|
|
791
|
+
scheduleAudioNode,
|
|
792
|
+
debugAudioScheduling
|
|
561
793
|
});
|
|
562
794
|
}
|
|
563
795
|
});
|
|
@@ -573,7 +805,8 @@ var audioIteratorManager = ({
|
|
|
573
805
|
playbackRate,
|
|
574
806
|
startFromSecond: newTime,
|
|
575
807
|
getIsPlaying,
|
|
576
|
-
scheduleAudioNode
|
|
808
|
+
scheduleAudioNode,
|
|
809
|
+
debugAudioScheduling
|
|
577
810
|
});
|
|
578
811
|
return;
|
|
579
812
|
}
|
|
@@ -585,31 +818,12 @@ var audioIteratorManager = ({
|
|
|
585
818
|
getIsPlaying,
|
|
586
819
|
buffer,
|
|
587
820
|
playbackRate,
|
|
588
|
-
scheduleAudioNode
|
|
821
|
+
scheduleAudioNode,
|
|
822
|
+
debugAudioScheduling
|
|
589
823
|
});
|
|
590
824
|
}
|
|
591
825
|
}, Math.min(newTime + MAX_BUFFER_AHEAD_SECONDS, getEndTime()));
|
|
592
826
|
};
|
|
593
|
-
const resumeScheduledAudioChunks = ({
|
|
594
|
-
playbackRate,
|
|
595
|
-
scheduleAudioNode
|
|
596
|
-
}) => {
|
|
597
|
-
if (muted) {
|
|
598
|
-
return;
|
|
599
|
-
}
|
|
600
|
-
if (!audioBufferIterator) {
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
for (const chunk of audioBufferIterator.getAndClearAudioChunksForAfterResuming()) {
|
|
604
|
-
scheduleAudioChunk({
|
|
605
|
-
buffer: chunk.buffer,
|
|
606
|
-
mediaTimestamp: chunk.timestamp,
|
|
607
|
-
playbackRate,
|
|
608
|
-
scheduleAudioNode,
|
|
609
|
-
maxDuration: chunk.maxDuration
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
};
|
|
613
827
|
return {
|
|
614
828
|
startAudioIterator,
|
|
615
829
|
resumeScheduledAudioChunks,
|
|
@@ -617,7 +831,7 @@ var audioIteratorManager = ({
|
|
|
617
831
|
getAudioBufferIterator: () => audioBufferIterator,
|
|
618
832
|
destroyIterator: () => {
|
|
619
833
|
prewarmedAudioIteratorCache.destroy();
|
|
620
|
-
audioBufferIterator?.destroy();
|
|
834
|
+
audioBufferIterator?.destroy(sharedAudioContext);
|
|
621
835
|
audioBufferIterator = null;
|
|
622
836
|
if (currentDelayHandle) {
|
|
623
837
|
currentDelayHandle.unblock();
|
|
@@ -638,16 +852,6 @@ var audioIteratorManager = ({
|
|
|
638
852
|
};
|
|
639
853
|
};
|
|
640
854
|
|
|
641
|
-
// src/calculate-playbacktime.ts
|
|
642
|
-
var calculatePlaybackTime = ({
|
|
643
|
-
audioSyncAnchor,
|
|
644
|
-
currentTime,
|
|
645
|
-
playbackRate
|
|
646
|
-
}) => {
|
|
647
|
-
const timeSinceAnchor = currentTime - audioSyncAnchor;
|
|
648
|
-
return timeSinceAnchor * playbackRate;
|
|
649
|
-
};
|
|
650
|
-
|
|
651
855
|
// src/debug-overlay/preview-overlay.ts
|
|
652
856
|
var drawPreviewOverlay = ({
|
|
653
857
|
context,
|
|
@@ -659,18 +863,19 @@ var drawPreviewOverlay = ({
|
|
|
659
863
|
videoIteratorManager,
|
|
660
864
|
playbackRate
|
|
661
865
|
}) => {
|
|
866
|
+
const anchorValue = audioSyncAnchor?.value ?? 0;
|
|
662
867
|
const lines = [
|
|
663
868
|
"Debug overlay",
|
|
664
869
|
`Video iterators created: ${videoIteratorManager?.getVideoIteratorsCreated()}`,
|
|
665
870
|
`Audio iterators created: ${audioIteratorManager2?.getAudioIteratorsCreated()}`,
|
|
666
871
|
`Frames rendered: ${videoIteratorManager?.getFramesRendered()}`,
|
|
667
872
|
`Audio context state: ${audioContextState}`,
|
|
668
|
-
audioTime ? `Audio time: ${((audioTime -
|
|
873
|
+
audioTime ? `Audio time: ${((audioTime - anchorValue) * playbackRate).toFixed(3)}s` : null
|
|
669
874
|
].filter(Boolean);
|
|
670
875
|
if (audioIteratorManager2) {
|
|
671
876
|
const queuedPeriod = audioIteratorManager2.getAudioBufferIterator()?.getQueuedPeriod();
|
|
672
877
|
if (queuedPeriod) {
|
|
673
|
-
const aheadText = audioTime ? ` (${(queuedPeriod.until - (audioTime -
|
|
878
|
+
const aheadText = audioTime ? ` (${(queuedPeriod.until - (audioTime - anchorValue) * playbackRate).toFixed(3)}s ahead)` : "";
|
|
674
879
|
lines.push(`Audio queued until ${queuedPeriod.until.toFixed(3)}s${aheadText}`);
|
|
675
880
|
}
|
|
676
881
|
lines.push(`Playing: ${playing}`);
|
|
@@ -720,7 +925,7 @@ var makeNonceManager = () => {
|
|
|
720
925
|
|
|
721
926
|
// src/video-iterator-manager.ts
|
|
722
927
|
import { CanvasSink } from "mediabunny";
|
|
723
|
-
import { Internals as
|
|
928
|
+
import { Internals as Internals5 } from "remotion";
|
|
724
929
|
|
|
725
930
|
// src/video/video-preview-iterator.ts
|
|
726
931
|
var createVideoIterator = async (timeToSeek, cache) => {
|
|
@@ -890,7 +1095,7 @@ var videoIteratorManager = ({
|
|
|
890
1095
|
if (callback) {
|
|
891
1096
|
callback(frame.canvas);
|
|
892
1097
|
}
|
|
893
|
-
|
|
1098
|
+
Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, `[MediaPlayer] Drew frame ${frame.timestamp.toFixed(3)}s`);
|
|
894
1099
|
};
|
|
895
1100
|
const startVideoIterator = async (timeToSeek, nonce) => {
|
|
896
1101
|
let __stack = [];
|
|
@@ -975,7 +1180,7 @@ class MediaPlayer {
|
|
|
975
1180
|
sharedAudioContext;
|
|
976
1181
|
audioIteratorManager = null;
|
|
977
1182
|
videoIteratorManager = null;
|
|
978
|
-
|
|
1183
|
+
sequenceOffset;
|
|
979
1184
|
playing = false;
|
|
980
1185
|
loop = false;
|
|
981
1186
|
fps;
|
|
@@ -984,6 +1189,7 @@ class MediaPlayer {
|
|
|
984
1189
|
durationInFrames;
|
|
985
1190
|
totalDuration;
|
|
986
1191
|
debugOverlay = false;
|
|
1192
|
+
debugAudioScheduling = false;
|
|
987
1193
|
nonceManager;
|
|
988
1194
|
onVideoFrameCallback = null;
|
|
989
1195
|
initializationPromise = null;
|
|
@@ -1004,12 +1210,14 @@ class MediaPlayer {
|
|
|
1004
1210
|
audioStreamIndex,
|
|
1005
1211
|
fps,
|
|
1006
1212
|
debugOverlay,
|
|
1213
|
+
debugAudioScheduling,
|
|
1007
1214
|
bufferState,
|
|
1008
1215
|
isPremounting,
|
|
1009
1216
|
isPostmounting,
|
|
1010
1217
|
durationInFrames,
|
|
1011
1218
|
onVideoFrameCallback,
|
|
1012
|
-
playing
|
|
1219
|
+
playing,
|
|
1220
|
+
sequenceOffset
|
|
1013
1221
|
}) {
|
|
1014
1222
|
this.canvas = canvas ?? null;
|
|
1015
1223
|
this.src = src;
|
|
@@ -1023,6 +1231,7 @@ class MediaPlayer {
|
|
|
1023
1231
|
this.audioStreamIndex = audioStreamIndex ?? 0;
|
|
1024
1232
|
this.fps = fps;
|
|
1025
1233
|
this.debugOverlay = debugOverlay;
|
|
1234
|
+
this.debugAudioScheduling = debugAudioScheduling;
|
|
1026
1235
|
this.bufferState = bufferState;
|
|
1027
1236
|
this.isPremounting = isPremounting;
|
|
1028
1237
|
this.isPostmounting = isPostmounting;
|
|
@@ -1030,6 +1239,7 @@ class MediaPlayer {
|
|
|
1030
1239
|
this.nonceManager = makeNonceManager();
|
|
1031
1240
|
this.onVideoFrameCallback = onVideoFrameCallback;
|
|
1032
1241
|
this.playing = playing;
|
|
1242
|
+
this.sequenceOffset = sequenceOffset;
|
|
1033
1243
|
this.input = new Input({
|
|
1034
1244
|
source: new UrlSource(this.src),
|
|
1035
1245
|
formats: ALL_FORMATS
|
|
@@ -1093,7 +1303,7 @@ class MediaPlayer {
|
|
|
1093
1303
|
if (isNetworkError(err)) {
|
|
1094
1304
|
throw error;
|
|
1095
1305
|
}
|
|
1096
|
-
|
|
1306
|
+
Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Failed to recognize format for ${this.src}`, error);
|
|
1097
1307
|
return { type: "unknown-container-format" };
|
|
1098
1308
|
}
|
|
1099
1309
|
const [durationInSeconds, videoTrack, audioTracks] = await Promise.all([
|
|
@@ -1134,7 +1344,6 @@ class MediaPlayer {
|
|
|
1134
1344
|
if (startTime === null) {
|
|
1135
1345
|
throw new Error(`should have asserted that the time is not null`);
|
|
1136
1346
|
}
|
|
1137
|
-
this.setAudioPlaybackTime(startTime);
|
|
1138
1347
|
if (audioTrack && this.sharedAudioContext) {
|
|
1139
1348
|
const canDecode = await audioTrack.canDecode();
|
|
1140
1349
|
if (!canDecode) {
|
|
@@ -1146,7 +1355,7 @@ class MediaPlayer {
|
|
|
1146
1355
|
this.audioIteratorManager = audioIteratorManager({
|
|
1147
1356
|
audioTrack,
|
|
1148
1357
|
delayPlaybackHandleIfNotPremounting: this.delayPlaybackHandleIfNotPremounting,
|
|
1149
|
-
sharedAudioContext: this.sharedAudioContext,
|
|
1358
|
+
sharedAudioContext: this.sharedAudioContext.audioContext,
|
|
1150
1359
|
getIsLooping: () => this.loop,
|
|
1151
1360
|
getEndTime: () => this.getEndTime(),
|
|
1152
1361
|
getStartTime: () => this.getStartTime(),
|
|
@@ -1162,7 +1371,8 @@ class MediaPlayer {
|
|
|
1162
1371
|
playbackRate: this.playbackRate * this.globalPlaybackRate,
|
|
1163
1372
|
startFromSecond: startTime,
|
|
1164
1373
|
getIsPlaying: () => this.playing,
|
|
1165
|
-
scheduleAudioNode: this.scheduleAudioNode
|
|
1374
|
+
scheduleAudioNode: this.scheduleAudioNode,
|
|
1375
|
+
debugAudioScheduling: this.debugAudioScheduling
|
|
1166
1376
|
}) : Promise.resolve(),
|
|
1167
1377
|
this.videoIteratorManager ? this.videoIteratorManager.startVideoIterator(startTime, nonce) : Promise.resolve()
|
|
1168
1378
|
]);
|
|
@@ -1170,16 +1380,16 @@ class MediaPlayer {
|
|
|
1170
1380
|
if (this.isDisposalError()) {
|
|
1171
1381
|
return { type: "disposed" };
|
|
1172
1382
|
}
|
|
1173
|
-
|
|
1383
|
+
Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to start audio and video iterators", error);
|
|
1174
1384
|
}
|
|
1175
1385
|
return { type: "success", durationInSeconds };
|
|
1176
1386
|
} catch (error) {
|
|
1177
1387
|
const err = error;
|
|
1178
1388
|
if (isNetworkError(err)) {
|
|
1179
|
-
|
|
1389
|
+
Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Network/CORS error for ${this.src}`, err);
|
|
1180
1390
|
return { type: "network-error" };
|
|
1181
1391
|
}
|
|
1182
|
-
|
|
1392
|
+
Internals6.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to initialize", error);
|
|
1183
1393
|
throw error;
|
|
1184
1394
|
}
|
|
1185
1395
|
} catch (_catch) {
|
|
@@ -1205,46 +1415,44 @@ class MediaPlayer {
|
|
|
1205
1415
|
if (nonce.isStale()) {
|
|
1206
1416
|
return;
|
|
1207
1417
|
}
|
|
1208
|
-
const shouldSeekAudio = this.audioIteratorManager && this.sharedAudioContext
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
throw new Error(`should have asserted that the time is not null`);
|
|
1418
|
+
const shouldSeekAudio = this.audioIteratorManager && this.getAudioPlaybackTime(this.sharedAudioContext?.audioContext.currentTime ?? 0) !== newTime;
|
|
1419
|
+
try {
|
|
1420
|
+
await Promise.all([
|
|
1421
|
+
this.videoIteratorManager?.seek({
|
|
1422
|
+
newTime,
|
|
1423
|
+
nonce
|
|
1424
|
+
}),
|
|
1425
|
+
shouldSeekAudio ? this.audioIteratorManager?.seek({
|
|
1426
|
+
newTime,
|
|
1427
|
+
nonce,
|
|
1428
|
+
playbackRate: this.playbackRate * this.globalPlaybackRate,
|
|
1429
|
+
getIsPlaying: () => this.playing,
|
|
1430
|
+
scheduleAudioNode: this.scheduleAudioNode,
|
|
1431
|
+
debugAudioScheduling: this.debugAudioScheduling
|
|
1432
|
+
}) : null
|
|
1433
|
+
]);
|
|
1434
|
+
} catch (error) {
|
|
1435
|
+
if (this.isDisposalError()) {
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
throw error;
|
|
1230
1439
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1440
|
+
}
|
|
1441
|
+
playAudio() {
|
|
1442
|
+
if (this.audioIteratorManager && this.sharedAudioContext?.audioContext.state === "running" && (this.sharedAudioContext?.audioContext?.getOutputTimestamp().contextTime ?? 0) > 0) {
|
|
1233
1443
|
this.audioIteratorManager.resumeScheduledAudioChunks({
|
|
1234
1444
|
playbackRate: this.playbackRate * this.globalPlaybackRate,
|
|
1235
|
-
scheduleAudioNode: this.scheduleAudioNode
|
|
1445
|
+
scheduleAudioNode: this.scheduleAudioNode,
|
|
1446
|
+
debugAudioScheduling: this.debugAudioScheduling
|
|
1236
1447
|
});
|
|
1237
1448
|
}
|
|
1238
|
-
if (this.sharedAudioContext && this.sharedAudioContext.state === "suspended") {
|
|
1239
|
-
await this.sharedAudioContext.resume();
|
|
1240
|
-
}
|
|
1241
1449
|
}
|
|
1242
|
-
|
|
1450
|
+
play() {
|
|
1451
|
+
this.playAudio();
|
|
1243
1452
|
if (this.playing) {
|
|
1244
1453
|
return;
|
|
1245
1454
|
}
|
|
1246
1455
|
this.playing = true;
|
|
1247
|
-
await this.playAudio(time);
|
|
1248
1456
|
this.drawDebugOverlay();
|
|
1249
1457
|
}
|
|
1250
1458
|
delayPlaybackHandleIfNotPremounting = () => {
|
|
@@ -1299,7 +1507,6 @@ class MediaPlayer {
|
|
|
1299
1507
|
const newMediaTime = this.getTrimmedTime(unloopedTimeInSeconds);
|
|
1300
1508
|
this.audioIteratorManager?.destroyIterator();
|
|
1301
1509
|
if (newMediaTime !== null) {
|
|
1302
|
-
this.setAudioPlaybackTime(newMediaTime);
|
|
1303
1510
|
if (!this.playing && this.videoIteratorManager) {
|
|
1304
1511
|
await this.seekToWithQueue(newMediaTime);
|
|
1305
1512
|
}
|
|
@@ -1320,39 +1527,43 @@ class MediaPlayer {
|
|
|
1320
1527
|
setDebugOverlay(debugOverlay) {
|
|
1321
1528
|
this.debugOverlay = debugOverlay;
|
|
1322
1529
|
}
|
|
1323
|
-
|
|
1530
|
+
setDebugAudioScheduling(debugAudioScheduling) {
|
|
1531
|
+
this.debugAudioScheduling = debugAudioScheduling;
|
|
1532
|
+
}
|
|
1533
|
+
rescheduleAudioChunks() {
|
|
1324
1534
|
if (!this.audioIteratorManager) {
|
|
1325
1535
|
return;
|
|
1326
1536
|
}
|
|
1327
1537
|
if (!this.sharedAudioContext) {
|
|
1328
1538
|
return;
|
|
1329
1539
|
}
|
|
1330
|
-
this.setAudioPlaybackTime(mediaTimeBeforeChange);
|
|
1331
1540
|
const iterator = this.audioIteratorManager.getAudioBufferIterator();
|
|
1332
1541
|
if (!iterator) {
|
|
1333
1542
|
return;
|
|
1334
1543
|
}
|
|
1335
1544
|
iterator.moveQueuedChunksToPauseQueue();
|
|
1336
|
-
if (this.playing) {
|
|
1545
|
+
if (this.playing && this.sharedAudioContext.audioContext.state === "running" && (this.sharedAudioContext.audioContext?.getOutputTimestamp().contextTime ?? 0) > 0) {
|
|
1337
1546
|
this.audioIteratorManager.resumeScheduledAudioChunks({
|
|
1338
1547
|
playbackRate: this.playbackRate * this.globalPlaybackRate,
|
|
1339
|
-
scheduleAudioNode: this.scheduleAudioNode
|
|
1548
|
+
scheduleAudioNode: this.scheduleAudioNode,
|
|
1549
|
+
debugAudioScheduling: this.debugAudioScheduling
|
|
1340
1550
|
});
|
|
1341
1551
|
}
|
|
1342
1552
|
}
|
|
1343
1553
|
async setPlaybackRate(rate, unloopedTimeInSeconds) {
|
|
1344
1554
|
const previousRate = this.playbackRate;
|
|
1345
|
-
const mediaTime = this.sharedAudioContext ? this.getAudioPlaybackTime() : 0;
|
|
1346
|
-
this.playbackRate = rate;
|
|
1347
|
-
this.updateAudioTimeAfterPlaybackRateChange(mediaTime);
|
|
1348
1555
|
if (previousRate !== rate) {
|
|
1556
|
+
this.playbackRate = rate;
|
|
1557
|
+
this.rescheduleAudioChunks();
|
|
1349
1558
|
await this.seekTo(unloopedTimeInSeconds);
|
|
1350
1559
|
}
|
|
1351
1560
|
}
|
|
1352
1561
|
setGlobalPlaybackRate(rate) {
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1562
|
+
const previousRate = this.globalPlaybackRate;
|
|
1563
|
+
if (previousRate !== rate) {
|
|
1564
|
+
this.globalPlaybackRate = rate;
|
|
1565
|
+
this.rescheduleAudioChunks();
|
|
1566
|
+
}
|
|
1356
1567
|
}
|
|
1357
1568
|
setFps(fps) {
|
|
1358
1569
|
this.fps = fps;
|
|
@@ -1366,6 +1577,9 @@ class MediaPlayer {
|
|
|
1366
1577
|
setLoop(loop) {
|
|
1367
1578
|
this.loop = loop;
|
|
1368
1579
|
}
|
|
1580
|
+
setSequenceOffset(offset) {
|
|
1581
|
+
this.sequenceOffset = offset;
|
|
1582
|
+
}
|
|
1369
1583
|
setDurationInFrames(durationInFrames) {
|
|
1370
1584
|
this.durationInFrames = durationInFrames;
|
|
1371
1585
|
}
|
|
@@ -1380,41 +1594,40 @@ class MediaPlayer {
|
|
|
1380
1594
|
this.audioIteratorManager?.destroyIterator();
|
|
1381
1595
|
this.input.dispose();
|
|
1382
1596
|
}
|
|
1383
|
-
scheduleAudioNode = (node, mediaTimestamp
|
|
1384
|
-
const currentTime = this.getAudioPlaybackTime();
|
|
1385
|
-
const delayWithoutPlaybackRate = mediaTimestamp - currentTime;
|
|
1386
|
-
const delay = delayWithoutPlaybackRate / (this.playbackRate * this.globalPlaybackRate);
|
|
1597
|
+
scheduleAudioNode = (node, mediaTimestamp) => {
|
|
1387
1598
|
if (!this.sharedAudioContext) {
|
|
1388
1599
|
throw new Error("Shared audio context not found");
|
|
1389
1600
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1601
|
+
const { audioContext } = this.sharedAudioContext;
|
|
1602
|
+
const { currentTime } = audioContext;
|
|
1603
|
+
const globalTime = (currentTime - this.sharedAudioContext.audioSyncAnchor.value) * this.globalPlaybackRate;
|
|
1604
|
+
const timeInSeconds = globalTime - this.sequenceOffset;
|
|
1605
|
+
const localTime = this.getTrimmedTime(timeInSeconds);
|
|
1606
|
+
if (localTime === null) {
|
|
1607
|
+
throw new Error("hmm, should not render!");
|
|
1608
|
+
}
|
|
1609
|
+
const targetTime = (mediaTimestamp - localTime) / (this.playbackRate * this.globalPlaybackRate);
|
|
1610
|
+
return this.sharedAudioContext.scheduleAudioNode({
|
|
1611
|
+
node,
|
|
1612
|
+
mediaTimestamp,
|
|
1613
|
+
targetTime,
|
|
1614
|
+
currentTime,
|
|
1615
|
+
sequenceEndTime: this.getEndTime(),
|
|
1616
|
+
sequenceStartTime: this.getStartTime(),
|
|
1617
|
+
debugAudioScheduling: this.debugAudioScheduling
|
|
1618
|
+
});
|
|
1396
1619
|
};
|
|
1397
|
-
getAudioPlaybackTime() {
|
|
1620
|
+
getAudioPlaybackTime(currentTime) {
|
|
1398
1621
|
if (!this.sharedAudioContext) {
|
|
1399
1622
|
throw new Error("Shared audio context not found");
|
|
1400
1623
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
}
|
|
1407
|
-
setAudioPlaybackTime(time) {
|
|
1408
|
-
if (!this.sharedAudioContext) {
|
|
1409
|
-
return;
|
|
1624
|
+
const globalTime = (currentTime - this.sharedAudioContext.audioSyncAnchor.value) * this.globalPlaybackRate;
|
|
1625
|
+
const localTime = globalTime - this.sequenceOffset;
|
|
1626
|
+
const trimmedTime = this.getTrimmedTime(localTime);
|
|
1627
|
+
if (trimmedTime !== null) {
|
|
1628
|
+
return trimmedTime;
|
|
1410
1629
|
}
|
|
1411
|
-
|
|
1412
|
-
const newAnchor = this.sharedAudioContext.currentTime - time / playbackRate;
|
|
1413
|
-
const shift = Math.abs(newAnchor - this.audioSyncAnchor) * playbackRate;
|
|
1414
|
-
if (shift < 0.05) {
|
|
1415
|
-
return;
|
|
1416
|
-
}
|
|
1417
|
-
this.audioSyncAnchor = newAnchor;
|
|
1630
|
+
return localTime * this.playbackRate + (this.trimBefore ?? 0) / this.fps;
|
|
1418
1631
|
}
|
|
1419
1632
|
setVideoFrameCallback(callback) {
|
|
1420
1633
|
this.onVideoFrameCallback = callback;
|
|
@@ -1425,9 +1638,9 @@ class MediaPlayer {
|
|
|
1425
1638
|
if (this.context && this.canvas) {
|
|
1426
1639
|
drawPreviewOverlay({
|
|
1427
1640
|
context: this.context,
|
|
1428
|
-
audioTime: this.sharedAudioContext?.currentTime ?? null,
|
|
1429
|
-
audioContextState: this.sharedAudioContext?.state ?? null,
|
|
1430
|
-
audioSyncAnchor: this.audioSyncAnchor,
|
|
1641
|
+
audioTime: this.sharedAudioContext?.audioContext.currentTime ?? null,
|
|
1642
|
+
audioContextState: this.sharedAudioContext?.audioContext.state ?? null,
|
|
1643
|
+
audioSyncAnchor: this.sharedAudioContext?.audioSyncAnchor ?? null,
|
|
1431
1644
|
audioIteratorManager: this.audioIteratorManager,
|
|
1432
1645
|
playing: this.playing,
|
|
1433
1646
|
videoIteratorManager: this.videoIteratorManager,
|
|
@@ -1460,7 +1673,7 @@ var callOnErrorAndResolve = ({
|
|
|
1460
1673
|
|
|
1461
1674
|
// src/show-in-timeline.ts
|
|
1462
1675
|
import { useMemo } from "react";
|
|
1463
|
-
import { Internals as
|
|
1676
|
+
import { Internals as Internals7, useVideoConfig } from "remotion";
|
|
1464
1677
|
var useLoopDisplay = ({
|
|
1465
1678
|
loop,
|
|
1466
1679
|
mediaDurationInSeconds,
|
|
@@ -1473,7 +1686,7 @@ var useLoopDisplay = ({
|
|
|
1473
1686
|
if (!loop || !mediaDurationInSeconds) {
|
|
1474
1687
|
return;
|
|
1475
1688
|
}
|
|
1476
|
-
const durationInFrames =
|
|
1689
|
+
const durationInFrames = Internals7.calculateMediaDuration({
|
|
1477
1690
|
mediaDurationInFrames: mediaDurationInSeconds * fps,
|
|
1478
1691
|
playbackRate,
|
|
1479
1692
|
trimAfter,
|
|
@@ -1497,9 +1710,177 @@ var useLoopDisplay = ({
|
|
|
1497
1710
|
return loopDisplay;
|
|
1498
1711
|
};
|
|
1499
1712
|
|
|
1713
|
+
// src/use-common-effects.ts
|
|
1714
|
+
import { useContext, useLayoutEffect } from "react";
|
|
1715
|
+
import { Internals as Internals8 } from "remotion";
|
|
1716
|
+
var useCommonEffects = ({
|
|
1717
|
+
mediaPlayerRef,
|
|
1718
|
+
mediaPlayerReady,
|
|
1719
|
+
currentTimeRef,
|
|
1720
|
+
playing,
|
|
1721
|
+
isPlayerBuffering,
|
|
1722
|
+
frame,
|
|
1723
|
+
trimBefore,
|
|
1724
|
+
trimAfter,
|
|
1725
|
+
effectiveMuted,
|
|
1726
|
+
userPreferredVolume,
|
|
1727
|
+
playbackRate,
|
|
1728
|
+
globalPlaybackRate,
|
|
1729
|
+
fps,
|
|
1730
|
+
sequenceOffset,
|
|
1731
|
+
loop,
|
|
1732
|
+
debugAudioScheduling,
|
|
1733
|
+
durationInFrames,
|
|
1734
|
+
isPremounting,
|
|
1735
|
+
isPostmounting,
|
|
1736
|
+
currentTime,
|
|
1737
|
+
logLevel,
|
|
1738
|
+
sharedAudioContext,
|
|
1739
|
+
label
|
|
1740
|
+
}) => {
|
|
1741
|
+
const absoluteTime = Internals8.useAbsoluteTimelinePosition();
|
|
1742
|
+
const { playing: playingWhilePremounting } = useContext(Internals8.PremountContext);
|
|
1743
|
+
useLayoutEffect(() => {
|
|
1744
|
+
if (sharedAudioContext?.audioContext && sharedAudioContext.audioSyncAnchor) {
|
|
1745
|
+
setGlobalTimeAnchor({
|
|
1746
|
+
audioContext: sharedAudioContext.audioContext,
|
|
1747
|
+
audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
|
|
1748
|
+
absoluteTimeInSeconds: absoluteTime / fps,
|
|
1749
|
+
globalPlaybackRate,
|
|
1750
|
+
debugAudioScheduling,
|
|
1751
|
+
logLevel
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
}, [
|
|
1755
|
+
absoluteTime,
|
|
1756
|
+
globalPlaybackRate,
|
|
1757
|
+
sharedAudioContext,
|
|
1758
|
+
fps,
|
|
1759
|
+
debugAudioScheduling,
|
|
1760
|
+
logLevel
|
|
1761
|
+
]);
|
|
1762
|
+
if (playingWhilePremounting) {
|
|
1763
|
+
mediaPlayerRef.current?.playAudio();
|
|
1764
|
+
}
|
|
1765
|
+
useLayoutEffect(() => {
|
|
1766
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1767
|
+
if (!mediaPlayer)
|
|
1768
|
+
return;
|
|
1769
|
+
if (playing && !isPlayerBuffering) {
|
|
1770
|
+
mediaPlayer.play();
|
|
1771
|
+
} else {
|
|
1772
|
+
mediaPlayer.pause();
|
|
1773
|
+
}
|
|
1774
|
+
}, [
|
|
1775
|
+
isPlayerBuffering,
|
|
1776
|
+
playing,
|
|
1777
|
+
logLevel,
|
|
1778
|
+
mediaPlayerReady,
|
|
1779
|
+
frame,
|
|
1780
|
+
mediaPlayerRef
|
|
1781
|
+
]);
|
|
1782
|
+
useLayoutEffect(() => {
|
|
1783
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1784
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1785
|
+
return;
|
|
1786
|
+
}
|
|
1787
|
+
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
1788
|
+
}, [trimBefore, mediaPlayerReady, mediaPlayerRef, currentTimeRef]);
|
|
1789
|
+
useLayoutEffect(() => {
|
|
1790
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1791
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
1795
|
+
}, [trimAfter, mediaPlayerReady, mediaPlayerRef, currentTimeRef]);
|
|
1796
|
+
useLayoutEffect(() => {
|
|
1797
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1798
|
+
if (!mediaPlayer || !mediaPlayerReady)
|
|
1799
|
+
return;
|
|
1800
|
+
mediaPlayer.setMuted(effectiveMuted);
|
|
1801
|
+
}, [effectiveMuted, mediaPlayerReady, mediaPlayerRef]);
|
|
1802
|
+
useLayoutEffect(() => {
|
|
1803
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1804
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1807
|
+
mediaPlayer.setVolume(userPreferredVolume);
|
|
1808
|
+
}, [userPreferredVolume, mediaPlayerReady, mediaPlayerRef]);
|
|
1809
|
+
useLayoutEffect(() => {
|
|
1810
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1811
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
mediaPlayer.setPlaybackRate(playbackRate, currentTimeRef.current);
|
|
1815
|
+
}, [playbackRate, mediaPlayerReady, mediaPlayerRef, currentTimeRef]);
|
|
1816
|
+
useLayoutEffect(() => {
|
|
1817
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1818
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1819
|
+
return;
|
|
1820
|
+
}
|
|
1821
|
+
mediaPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
1822
|
+
}, [globalPlaybackRate, mediaPlayerReady, mediaPlayerRef]);
|
|
1823
|
+
useLayoutEffect(() => {
|
|
1824
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1825
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1828
|
+
mediaPlayer.setLoop(loop);
|
|
1829
|
+
}, [loop, mediaPlayerReady, mediaPlayerRef]);
|
|
1830
|
+
useLayoutEffect(() => {
|
|
1831
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1832
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1835
|
+
mediaPlayer.setDurationInFrames(durationInFrames);
|
|
1836
|
+
}, [durationInFrames, mediaPlayerReady, mediaPlayerRef]);
|
|
1837
|
+
useLayoutEffect(() => {
|
|
1838
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1839
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
mediaPlayer.setIsPremounting(isPremounting);
|
|
1843
|
+
}, [isPremounting, mediaPlayerReady, mediaPlayerRef]);
|
|
1844
|
+
useLayoutEffect(() => {
|
|
1845
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1846
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
1850
|
+
}, [isPostmounting, mediaPlayerReady, mediaPlayerRef]);
|
|
1851
|
+
useLayoutEffect(() => {
|
|
1852
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1853
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
mediaPlayer.setFps(fps);
|
|
1857
|
+
}, [fps, mediaPlayerReady, mediaPlayerRef]);
|
|
1858
|
+
useLayoutEffect(() => {
|
|
1859
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1860
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1863
|
+
mediaPlayer.setSequenceOffset(sequenceOffset);
|
|
1864
|
+
}, [sequenceOffset, mediaPlayerReady, mediaPlayerRef]);
|
|
1865
|
+
useLayoutEffect(() => {
|
|
1866
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1867
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
mediaPlayer.setDebugAudioScheduling(debugAudioScheduling);
|
|
1871
|
+
}, [debugAudioScheduling, mediaPlayerReady, mediaPlayerRef]);
|
|
1872
|
+
useLayoutEffect(() => {
|
|
1873
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1874
|
+
if (!mediaPlayer || !mediaPlayerReady)
|
|
1875
|
+
return;
|
|
1876
|
+
mediaPlayer.seekTo(currentTime).catch(() => {});
|
|
1877
|
+
Internals8.Log.trace({ logLevel, tag: "@remotion/media" }, `[${label}] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
1878
|
+
}, [currentTime, logLevel, mediaPlayerReady, label, mediaPlayerRef]);
|
|
1879
|
+
};
|
|
1880
|
+
|
|
1500
1881
|
// src/use-media-in-timeline.ts
|
|
1501
|
-
import { useContext, useEffect, useState } from "react";
|
|
1502
|
-
import { Internals as
|
|
1882
|
+
import { useContext as useContext2, useEffect, useState } from "react";
|
|
1883
|
+
import { Internals as Internals9, useCurrentFrame } from "remotion";
|
|
1503
1884
|
var useMediaInTimeline = ({
|
|
1504
1885
|
volume,
|
|
1505
1886
|
mediaVolume,
|
|
@@ -1516,9 +1897,9 @@ var useMediaInTimeline = ({
|
|
|
1516
1897
|
trimAfter,
|
|
1517
1898
|
controls
|
|
1518
1899
|
}) => {
|
|
1519
|
-
const parentSequence =
|
|
1520
|
-
const startsAt =
|
|
1521
|
-
const { registerSequence, unregisterSequence } =
|
|
1900
|
+
const parentSequence = useContext2(Internals9.SequenceContext);
|
|
1901
|
+
const startsAt = Internals9.useMediaStartsAt();
|
|
1902
|
+
const { registerSequence, unregisterSequence } = useContext2(Internals9.SequenceManager);
|
|
1522
1903
|
const [sequenceId] = useState(() => String(Math.random()));
|
|
1523
1904
|
const [mediaId] = useState(() => String(Math.random()));
|
|
1524
1905
|
const frame = useCurrentFrame();
|
|
@@ -1530,7 +1911,7 @@ var useMediaInTimeline = ({
|
|
|
1530
1911
|
rootId,
|
|
1531
1912
|
isStudio,
|
|
1532
1913
|
finalDisplayName
|
|
1533
|
-
} =
|
|
1914
|
+
} = Internals9.useBasicMediaInTimeline({
|
|
1534
1915
|
volume,
|
|
1535
1916
|
mediaVolume,
|
|
1536
1917
|
mediaType,
|
|
@@ -1640,7 +2021,7 @@ var {
|
|
|
1640
2021
|
warnAboutTooHighVolume,
|
|
1641
2022
|
usePreload,
|
|
1642
2023
|
SequenceContext
|
|
1643
|
-
} =
|
|
2024
|
+
} = Internals10;
|
|
1644
2025
|
var AudioForPreviewAssertedShowing = ({
|
|
1645
2026
|
src,
|
|
1646
2027
|
playbackRate,
|
|
@@ -1658,6 +2039,7 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1658
2039
|
toneFrequency,
|
|
1659
2040
|
audioStreamIndex,
|
|
1660
2041
|
fallbackHtml5AudioProps,
|
|
2042
|
+
debugAudioScheduling,
|
|
1661
2043
|
onError,
|
|
1662
2044
|
controls
|
|
1663
2045
|
}) => {
|
|
@@ -1669,9 +2051,9 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1669
2051
|
const [mediaPlayerReady, setMediaPlayerReady] = useState2(false);
|
|
1670
2052
|
const [shouldFallbackToNativeAudio, setShouldFallbackToNativeAudio] = useState2(false);
|
|
1671
2053
|
const [playing] = Timeline.usePlayingState();
|
|
1672
|
-
const timelineContext =
|
|
2054
|
+
const timelineContext = useContext3(Internals10.TimelineContext);
|
|
1673
2055
|
const globalPlaybackRate = timelineContext.playbackRate;
|
|
1674
|
-
const sharedAudioContext =
|
|
2056
|
+
const sharedAudioContext = useContext3(SharedAudioContext);
|
|
1675
2057
|
const buffer = useBufferState();
|
|
1676
2058
|
const [mediaMuted] = useMediaMutedState();
|
|
1677
2059
|
const [mediaVolume] = useMediaVolumeState();
|
|
@@ -1693,9 +2075,10 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1693
2075
|
const currentTimeRef = useRef(currentTime);
|
|
1694
2076
|
currentTimeRef.current = currentTime;
|
|
1695
2077
|
const preloadedSrc = usePreload(src);
|
|
1696
|
-
const parentSequence =
|
|
2078
|
+
const parentSequence = useContext3(SequenceContext);
|
|
1697
2079
|
const isPremounting = Boolean(parentSequence?.premounting);
|
|
1698
2080
|
const isPostmounting = Boolean(parentSequence?.postmounting);
|
|
2081
|
+
const sequenceOffset = ((parentSequence?.cumulatedFrom ?? 0) + (parentSequence?.relativeFrom ?? 0)) / videoConfig.fps;
|
|
1699
2082
|
const loopDisplay = useLoopDisplay({
|
|
1700
2083
|
loop,
|
|
1701
2084
|
mediaDurationInSeconds,
|
|
@@ -1719,28 +2102,55 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1719
2102
|
trimBefore,
|
|
1720
2103
|
controls
|
|
1721
2104
|
});
|
|
1722
|
-
const bufferingContext =
|
|
2105
|
+
const bufferingContext = useContext3(Internals10.BufferingContextReact);
|
|
1723
2106
|
if (!bufferingContext) {
|
|
1724
2107
|
throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
|
|
1725
2108
|
}
|
|
1726
2109
|
const effectiveMuted = muted || mediaMuted || userPreferredVolume <= 0;
|
|
1727
|
-
const isPlayerBuffering =
|
|
2110
|
+
const isPlayerBuffering = Internals10.useIsPlayerBuffering(bufferingContext);
|
|
1728
2111
|
const initialPlaying = useRef(playing && !isPlayerBuffering);
|
|
1729
2112
|
const initialIsPremounting = useRef(isPremounting);
|
|
1730
2113
|
const initialIsPostmounting = useRef(isPostmounting);
|
|
1731
2114
|
const initialGlobalPlaybackRate = useRef(globalPlaybackRate);
|
|
1732
2115
|
const initialPlaybackRate = useRef(playbackRate);
|
|
1733
2116
|
const initialMuted = useRef(effectiveMuted);
|
|
2117
|
+
const initialSequenceOffset = useRef(sequenceOffset);
|
|
2118
|
+
useCommonEffects({
|
|
2119
|
+
mediaPlayerRef,
|
|
2120
|
+
mediaPlayerReady,
|
|
2121
|
+
currentTimeRef,
|
|
2122
|
+
playing,
|
|
2123
|
+
isPlayerBuffering,
|
|
2124
|
+
frame,
|
|
2125
|
+
trimBefore,
|
|
2126
|
+
trimAfter,
|
|
2127
|
+
effectiveMuted,
|
|
2128
|
+
userPreferredVolume,
|
|
2129
|
+
playbackRate,
|
|
2130
|
+
globalPlaybackRate,
|
|
2131
|
+
fps: videoConfig.fps,
|
|
2132
|
+
sequenceOffset,
|
|
2133
|
+
loop,
|
|
2134
|
+
debugAudioScheduling,
|
|
2135
|
+
durationInFrames: videoConfig.durationInFrames,
|
|
2136
|
+
isPremounting,
|
|
2137
|
+
isPostmounting,
|
|
2138
|
+
currentTime,
|
|
2139
|
+
logLevel,
|
|
2140
|
+
sharedAudioContext,
|
|
2141
|
+
label: "AudioForPreview"
|
|
2142
|
+
});
|
|
1734
2143
|
useEffect2(() => {
|
|
1735
2144
|
if (!sharedAudioContext)
|
|
1736
2145
|
return;
|
|
1737
2146
|
if (!sharedAudioContext.audioContext)
|
|
1738
2147
|
return;
|
|
2148
|
+
const { audioContext, audioSyncAnchor, scheduleAudioNode } = sharedAudioContext;
|
|
1739
2149
|
try {
|
|
1740
2150
|
const player = new MediaPlayer({
|
|
1741
2151
|
src: preloadedSrc,
|
|
1742
2152
|
logLevel,
|
|
1743
|
-
sharedAudioContext:
|
|
2153
|
+
sharedAudioContext: { audioContext, audioSyncAnchor, scheduleAudioNode },
|
|
1744
2154
|
loop,
|
|
1745
2155
|
trimAfter: initialTrimAfterRef.current,
|
|
1746
2156
|
trimBefore: initialTrimBeforeRef.current,
|
|
@@ -1749,13 +2159,15 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1749
2159
|
playbackRate: initialPlaybackRate.current,
|
|
1750
2160
|
audioStreamIndex: audioStreamIndex ?? 0,
|
|
1751
2161
|
debugOverlay: false,
|
|
2162
|
+
debugAudioScheduling,
|
|
1752
2163
|
bufferState: buffer,
|
|
1753
2164
|
isPostmounting: initialIsPostmounting.current,
|
|
1754
2165
|
isPremounting: initialIsPremounting.current,
|
|
1755
2166
|
globalPlaybackRate: initialGlobalPlaybackRate.current,
|
|
1756
2167
|
durationInFrames: videoConfig.durationInFrames,
|
|
1757
2168
|
onVideoFrameCallback: null,
|
|
1758
|
-
playing: initialPlaying.current
|
|
2169
|
+
playing: initialPlaying.current,
|
|
2170
|
+
sequenceOffset: initialSequenceOffset.current
|
|
1759
2171
|
});
|
|
1760
2172
|
mediaPlayerRef.current = player;
|
|
1761
2173
|
player.initialize(currentTimeRef.current, initialMuted.current).then((result) => {
|
|
@@ -1773,7 +2185,7 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1773
2185
|
if (action === "fail") {
|
|
1774
2186
|
throw errorToUse;
|
|
1775
2187
|
} else {
|
|
1776
|
-
|
|
2188
|
+
Internals10.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
|
|
1777
2189
|
setShouldFallbackToNativeAudio(true);
|
|
1778
2190
|
}
|
|
1779
2191
|
};
|
|
@@ -1796,7 +2208,7 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1796
2208
|
if (result.type === "success") {
|
|
1797
2209
|
setMediaPlayerReady(true);
|
|
1798
2210
|
setMediaDurationInSeconds(result.durationInSeconds);
|
|
1799
|
-
|
|
2211
|
+
Internals10.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] MediaPlayer initialized successfully`);
|
|
1800
2212
|
}
|
|
1801
2213
|
}).catch((error) => {
|
|
1802
2214
|
const [action, errorToUse] = callOnErrorAndResolve({
|
|
@@ -1809,7 +2221,7 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1809
2221
|
if (action === "fail") {
|
|
1810
2222
|
throw errorToUse;
|
|
1811
2223
|
} else {
|
|
1812
|
-
|
|
2224
|
+
Internals10.Log.error({ logLevel, tag: "@remotion/media" }, "[AudioForPreview] Failed to initialize MediaPlayer", error);
|
|
1813
2225
|
setShouldFallbackToNativeAudio(true);
|
|
1814
2226
|
}
|
|
1815
2227
|
});
|
|
@@ -1824,12 +2236,12 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1824
2236
|
if (action === "fail") {
|
|
1825
2237
|
throw errorToUse;
|
|
1826
2238
|
}
|
|
1827
|
-
|
|
2239
|
+
Internals10.Log.error({ logLevel, tag: "@remotion/media" }, "[AudioForPreview] MediaPlayer initialization failed", errorToUse);
|
|
1828
2240
|
setShouldFallbackToNativeAudio(true);
|
|
1829
2241
|
}
|
|
1830
2242
|
return () => {
|
|
1831
2243
|
if (mediaPlayerRef.current) {
|
|
1832
|
-
|
|
2244
|
+
Internals10.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] Disposing MediaPlayer`);
|
|
1833
2245
|
mediaPlayerRef.current.dispose();
|
|
1834
2246
|
mediaPlayerRef.current = null;
|
|
1835
2247
|
}
|
|
@@ -1840,108 +2252,15 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1840
2252
|
preloadedSrc,
|
|
1841
2253
|
logLevel,
|
|
1842
2254
|
sharedAudioContext,
|
|
1843
|
-
currentTimeRef,
|
|
1844
2255
|
loop,
|
|
1845
2256
|
videoConfig.fps,
|
|
1846
2257
|
audioStreamIndex,
|
|
1847
2258
|
disallowFallbackToHtml5Audio,
|
|
2259
|
+
debugAudioScheduling,
|
|
1848
2260
|
buffer,
|
|
1849
2261
|
onError,
|
|
1850
2262
|
videoConfig.durationInFrames
|
|
1851
2263
|
]);
|
|
1852
|
-
useLayoutEffect(() => {
|
|
1853
|
-
const audioPlayer = mediaPlayerRef.current;
|
|
1854
|
-
if (!audioPlayer)
|
|
1855
|
-
return;
|
|
1856
|
-
if (playing && !isPlayerBuffering) {
|
|
1857
|
-
audioPlayer.play(currentTimeRef.current);
|
|
1858
|
-
} else {
|
|
1859
|
-
audioPlayer.pause();
|
|
1860
|
-
}
|
|
1861
|
-
}, [isPlayerBuffering, logLevel, playing]);
|
|
1862
|
-
useLayoutEffect(() => {
|
|
1863
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1864
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1865
|
-
return;
|
|
1866
|
-
}
|
|
1867
|
-
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
1868
|
-
}, [trimBefore, mediaPlayerReady]);
|
|
1869
|
-
useLayoutEffect(() => {
|
|
1870
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1871
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1872
|
-
return;
|
|
1873
|
-
}
|
|
1874
|
-
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
1875
|
-
}, [trimAfter, mediaPlayerReady]);
|
|
1876
|
-
useLayoutEffect(() => {
|
|
1877
|
-
const audioPlayer = mediaPlayerRef.current;
|
|
1878
|
-
if (!audioPlayer || !mediaPlayerReady)
|
|
1879
|
-
return;
|
|
1880
|
-
audioPlayer.setMuted(effectiveMuted);
|
|
1881
|
-
}, [effectiveMuted, mediaPlayerReady]);
|
|
1882
|
-
useEffect2(() => {
|
|
1883
|
-
const audioPlayer = mediaPlayerRef.current;
|
|
1884
|
-
if (!audioPlayer || !mediaPlayerReady) {
|
|
1885
|
-
return;
|
|
1886
|
-
}
|
|
1887
|
-
audioPlayer.setVolume(userPreferredVolume);
|
|
1888
|
-
}, [userPreferredVolume, mediaPlayerReady]);
|
|
1889
|
-
useEffect2(() => {
|
|
1890
|
-
const audioPlayer = mediaPlayerRef.current;
|
|
1891
|
-
if (!audioPlayer || !mediaPlayerReady) {
|
|
1892
|
-
return;
|
|
1893
|
-
}
|
|
1894
|
-
audioPlayer.setPlaybackRate(playbackRate, currentTimeRef.current);
|
|
1895
|
-
}, [playbackRate, mediaPlayerReady]);
|
|
1896
|
-
useLayoutEffect(() => {
|
|
1897
|
-
const audioPlayer = mediaPlayerRef.current;
|
|
1898
|
-
if (!audioPlayer || !mediaPlayerReady) {
|
|
1899
|
-
return;
|
|
1900
|
-
}
|
|
1901
|
-
audioPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
1902
|
-
}, [globalPlaybackRate, mediaPlayerReady]);
|
|
1903
|
-
useLayoutEffect(() => {
|
|
1904
|
-
const audioPlayer = mediaPlayerRef.current;
|
|
1905
|
-
if (!audioPlayer || !mediaPlayerReady) {
|
|
1906
|
-
return;
|
|
1907
|
-
}
|
|
1908
|
-
audioPlayer.setFps(videoConfig.fps);
|
|
1909
|
-
}, [videoConfig.fps, mediaPlayerReady]);
|
|
1910
|
-
useLayoutEffect(() => {
|
|
1911
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1912
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1913
|
-
return;
|
|
1914
|
-
}
|
|
1915
|
-
mediaPlayer.setLoop(loop);
|
|
1916
|
-
}, [loop, mediaPlayerReady]);
|
|
1917
|
-
useLayoutEffect(() => {
|
|
1918
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1919
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1920
|
-
return;
|
|
1921
|
-
}
|
|
1922
|
-
mediaPlayer.setDurationInFrames(videoConfig.durationInFrames);
|
|
1923
|
-
}, [videoConfig.durationInFrames, mediaPlayerReady]);
|
|
1924
|
-
useLayoutEffect(() => {
|
|
1925
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1926
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1927
|
-
return;
|
|
1928
|
-
}
|
|
1929
|
-
mediaPlayer.setIsPremounting(isPremounting);
|
|
1930
|
-
}, [isPremounting, mediaPlayerReady]);
|
|
1931
|
-
useLayoutEffect(() => {
|
|
1932
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1933
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1934
|
-
return;
|
|
1935
|
-
}
|
|
1936
|
-
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
1937
|
-
}, [isPostmounting, mediaPlayerReady]);
|
|
1938
|
-
useLayoutEffect(() => {
|
|
1939
|
-
const audioPlayer = mediaPlayerRef.current;
|
|
1940
|
-
if (!audioPlayer || !mediaPlayerReady)
|
|
1941
|
-
return;
|
|
1942
|
-
audioPlayer.seekTo(currentTime).catch(() => {});
|
|
1943
|
-
Internals6.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
1944
|
-
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
1945
2264
|
if (shouldFallbackToNativeAudio && !disallowFallbackToHtml5Audio) {
|
|
1946
2265
|
return /* @__PURE__ */ jsx(RemotionAudio, {
|
|
1947
2266
|
src,
|
|
@@ -1975,61 +2294,54 @@ var audioSchema = {
|
|
|
1975
2294
|
},
|
|
1976
2295
|
playbackRate: {
|
|
1977
2296
|
type: "number",
|
|
1978
|
-
min: 0,
|
|
2297
|
+
min: 0.1,
|
|
1979
2298
|
step: 0.01,
|
|
1980
2299
|
default: 1,
|
|
1981
2300
|
description: "Playback Rate"
|
|
1982
2301
|
},
|
|
1983
|
-
|
|
1984
|
-
trimAfter: { type: "number", min: 0, default: 0 }
|
|
2302
|
+
loop: { type: "boolean", default: false, description: "Loop" }
|
|
1985
2303
|
};
|
|
1986
2304
|
var AudioForPreview = ({
|
|
1987
|
-
loop,
|
|
2305
|
+
loop: loopProp = false,
|
|
1988
2306
|
src,
|
|
1989
2307
|
logLevel,
|
|
1990
2308
|
muted,
|
|
1991
2309
|
name,
|
|
1992
2310
|
volume: volumeProp,
|
|
1993
2311
|
loopVolumeCurveBehavior,
|
|
1994
|
-
playbackRate: playbackRateProp,
|
|
1995
|
-
trimAfter
|
|
1996
|
-
trimBefore
|
|
2312
|
+
playbackRate: playbackRateProp = 1,
|
|
2313
|
+
trimAfter,
|
|
2314
|
+
trimBefore,
|
|
1997
2315
|
showInTimeline,
|
|
1998
2316
|
stack,
|
|
1999
2317
|
disallowFallbackToHtml5Audio,
|
|
2000
2318
|
toneFrequency,
|
|
2001
2319
|
audioStreamIndex,
|
|
2002
2320
|
fallbackHtml5AudioProps,
|
|
2321
|
+
debugAudioScheduling,
|
|
2003
2322
|
onError
|
|
2004
2323
|
}) => {
|
|
2005
2324
|
const schemaInput = useMemo2(() => {
|
|
2006
|
-
if (typeof volumeProp !== "number") {
|
|
2007
|
-
return null;
|
|
2008
|
-
}
|
|
2009
2325
|
return {
|
|
2010
2326
|
volume: volumeProp,
|
|
2011
2327
|
playbackRate: playbackRateProp,
|
|
2012
|
-
|
|
2013
|
-
trimAfter: trimAfterProp,
|
|
2014
|
-
loop: loop ?? false
|
|
2328
|
+
loop: loopProp
|
|
2015
2329
|
};
|
|
2016
|
-
}, [volumeProp, playbackRateProp,
|
|
2017
|
-
const {
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
const trimAfter = schemaInput !== null ? values.trimAfter : trimAfterProp;
|
|
2022
|
-
const effectiveLoop = schemaInput !== null ? values.loop : loop ?? false;
|
|
2330
|
+
}, [volumeProp, playbackRateProp, loopProp]);
|
|
2331
|
+
const {
|
|
2332
|
+
controls,
|
|
2333
|
+
values: { volume, playbackRate, loop }
|
|
2334
|
+
} = Internals10.useSchema(audioSchema, schemaInput);
|
|
2023
2335
|
const preloadedSrc = usePreload(src);
|
|
2024
|
-
const defaultLogLevel =
|
|
2336
|
+
const defaultLogLevel = Internals10.useLogLevel();
|
|
2025
2337
|
const frame = useCurrentFrame2();
|
|
2026
2338
|
const videoConfig = useVideoConfig2();
|
|
2027
2339
|
const currentTime = frame / videoConfig.fps;
|
|
2028
2340
|
const showShow = useMemo2(() => {
|
|
2029
2341
|
return getTimeInSeconds({
|
|
2030
2342
|
unloopedTimeInSeconds: currentTime,
|
|
2031
|
-
playbackRate
|
|
2032
|
-
loop
|
|
2343
|
+
playbackRate,
|
|
2344
|
+
loop,
|
|
2033
2345
|
trimBefore,
|
|
2034
2346
|
trimAfter,
|
|
2035
2347
|
mediaDurationInSeconds: Infinity,
|
|
@@ -2039,12 +2351,12 @@ var AudioForPreview = ({
|
|
|
2039
2351
|
}) !== null;
|
|
2040
2352
|
}, [
|
|
2041
2353
|
currentTime,
|
|
2042
|
-
effectiveLoop,
|
|
2043
2354
|
playbackRate,
|
|
2044
2355
|
src,
|
|
2045
2356
|
trimAfter,
|
|
2046
2357
|
trimBefore,
|
|
2047
|
-
videoConfig.fps
|
|
2358
|
+
videoConfig.fps,
|
|
2359
|
+
loop
|
|
2048
2360
|
]);
|
|
2049
2361
|
if (!showShow) {
|
|
2050
2362
|
return null;
|
|
@@ -2052,12 +2364,12 @@ var AudioForPreview = ({
|
|
|
2052
2364
|
return /* @__PURE__ */ jsx(AudioForPreviewAssertedShowing, {
|
|
2053
2365
|
audioStreamIndex: audioStreamIndex ?? 0,
|
|
2054
2366
|
src: preloadedSrc,
|
|
2055
|
-
playbackRate
|
|
2367
|
+
playbackRate,
|
|
2056
2368
|
logLevel: logLevel ?? defaultLogLevel,
|
|
2057
2369
|
muted: muted ?? false,
|
|
2058
2370
|
volume: volume ?? 1,
|
|
2059
2371
|
loopVolumeCurveBehavior: loopVolumeCurveBehavior ?? "repeat",
|
|
2060
|
-
loop
|
|
2372
|
+
loop,
|
|
2061
2373
|
trimAfter,
|
|
2062
2374
|
trimBefore,
|
|
2063
2375
|
name,
|
|
@@ -2065,6 +2377,7 @@ var AudioForPreview = ({
|
|
|
2065
2377
|
stack,
|
|
2066
2378
|
disallowFallbackToHtml5Audio: disallowFallbackToHtml5Audio ?? false,
|
|
2067
2379
|
toneFrequency,
|
|
2380
|
+
debugAudioScheduling: debugAudioScheduling ?? false,
|
|
2068
2381
|
onError,
|
|
2069
2382
|
fallbackHtml5AudioProps,
|
|
2070
2383
|
controls
|
|
@@ -2072,11 +2385,11 @@ var AudioForPreview = ({
|
|
|
2072
2385
|
};
|
|
2073
2386
|
|
|
2074
2387
|
// src/audio/audio-for-rendering.tsx
|
|
2075
|
-
import { useContext as
|
|
2388
|
+
import { useContext as useContext4, useLayoutEffect as useLayoutEffect2, useMemo as useMemo3, useState as useState3 } from "react";
|
|
2076
2389
|
import {
|
|
2077
2390
|
cancelRender as cancelRender2,
|
|
2078
2391
|
Html5Audio,
|
|
2079
|
-
Internals as
|
|
2392
|
+
Internals as Internals18,
|
|
2080
2393
|
random,
|
|
2081
2394
|
useCurrentFrame as useCurrentFrame3,
|
|
2082
2395
|
useDelayRender,
|
|
@@ -2085,13 +2398,13 @@ import {
|
|
|
2085
2398
|
|
|
2086
2399
|
// src/caches.ts
|
|
2087
2400
|
import React2 from "react";
|
|
2088
|
-
import { cancelRender, Internals as
|
|
2401
|
+
import { cancelRender, Internals as Internals15 } from "remotion";
|
|
2089
2402
|
|
|
2090
2403
|
// src/audio-extraction/audio-manager.ts
|
|
2091
|
-
import { Internals as
|
|
2404
|
+
import { Internals as Internals12 } from "remotion";
|
|
2092
2405
|
|
|
2093
2406
|
// src/audio-extraction/audio-iterator.ts
|
|
2094
|
-
import { Internals as
|
|
2407
|
+
import { Internals as Internals11 } from "remotion";
|
|
2095
2408
|
|
|
2096
2409
|
// src/audio-extraction/audio-cache.ts
|
|
2097
2410
|
var makeAudioCache = () => {
|
|
@@ -2162,7 +2475,7 @@ var makeAudioCache = () => {
|
|
|
2162
2475
|
};
|
|
2163
2476
|
|
|
2164
2477
|
// src/audio-extraction/audio-iterator.ts
|
|
2165
|
-
var
|
|
2478
|
+
var EXTRA_THRESHOLD_IN_SECONDS = 1.5;
|
|
2166
2479
|
var safetyOutOfOrderThreshold = 0.2;
|
|
2167
2480
|
var warned = {};
|
|
2168
2481
|
var warnAboutMatroskaOnce = (src, logLevel) => {
|
|
@@ -2170,7 +2483,7 @@ var warnAboutMatroskaOnce = (src, logLevel) => {
|
|
|
2170
2483
|
return;
|
|
2171
2484
|
}
|
|
2172
2485
|
warned[src] = true;
|
|
2173
|
-
|
|
2486
|
+
Internals11.Log.warn({ logLevel, tag: "@remotion/media" }, `Audio from ${src} will need to be read from the beginning. https://www.remotion.dev/docs/media/support#matroska-limitation`);
|
|
2174
2487
|
};
|
|
2175
2488
|
var makeAudioIterator2 = ({
|
|
2176
2489
|
audioSampleSink,
|
|
@@ -2180,7 +2493,7 @@ var makeAudioIterator2 = ({
|
|
|
2180
2493
|
actualMatroskaTimestamps,
|
|
2181
2494
|
logLevel
|
|
2182
2495
|
}) => {
|
|
2183
|
-
const sampleIterator = audioSampleSink.samples(isMatroska ? 0 : Math.max(0, startTimestamp -
|
|
2496
|
+
const sampleIterator = audioSampleSink.samples(isMatroska ? 0 : Math.max(0, startTimestamp - EXTRA_THRESHOLD_IN_SECONDS));
|
|
2184
2497
|
if (isMatroska) {
|
|
2185
2498
|
warnAboutMatroskaOnce(src, logLevel);
|
|
2186
2499
|
}
|
|
@@ -2238,7 +2551,7 @@ var makeAudioIterator2 = ({
|
|
|
2238
2551
|
if (openTimestamps.length > 0) {
|
|
2239
2552
|
const first = openTimestamps[0];
|
|
2240
2553
|
const last = openTimestamps[openTimestamps.length - 1];
|
|
2241
|
-
|
|
2554
|
+
Internals11.Log.verbose({ logLevel, tag: "@remotion/media" }, "Open audio samples for src", src, `${first.toFixed(3)}...${last.toFixed(3)}`);
|
|
2242
2555
|
}
|
|
2243
2556
|
};
|
|
2244
2557
|
const getCacheStats = () => {
|
|
@@ -2335,7 +2648,7 @@ var makeAudioManager = () => {
|
|
|
2335
2648
|
if (seenKeys.has(key)) {
|
|
2336
2649
|
iterator.prepareForDeletion();
|
|
2337
2650
|
iterators.splice(iterators.indexOf(iterator), 1);
|
|
2338
|
-
|
|
2651
|
+
Internals12.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted duplicate iterator for ${iterator.src}`);
|
|
2339
2652
|
}
|
|
2340
2653
|
seenKeys.add(key);
|
|
2341
2654
|
}
|
|
@@ -2356,7 +2669,7 @@ var makeAudioManager = () => {
|
|
|
2356
2669
|
attempts++;
|
|
2357
2670
|
}
|
|
2358
2671
|
if ((await getTotalCacheStats()).totalSize > maxCacheSize && attempts >= maxAttempts) {
|
|
2359
|
-
|
|
2672
|
+
Internals12.Log.warn({ logLevel, tag: "@remotion/media" }, `Audio cache: Exceeded max cache size after ${maxAttempts} attempts. Still ${(await getTotalCacheStats()).totalSize} bytes used, target was ${maxCacheSize} bytes.`);
|
|
2360
2673
|
}
|
|
2361
2674
|
for (const iterator of iterators) {
|
|
2362
2675
|
if (iterator.src === src && await iterator.waitForCompletion() && iterator.canSatisfyRequestedTime(timeInSeconds)) {
|
|
@@ -2425,7 +2738,7 @@ var makeAudioManager = () => {
|
|
|
2425
2738
|
};
|
|
2426
2739
|
|
|
2427
2740
|
// src/video-extraction/keyframe-manager.ts
|
|
2428
|
-
import { Internals as
|
|
2741
|
+
import { Internals as Internals14 } from "remotion";
|
|
2429
2742
|
|
|
2430
2743
|
// src/render-timestamp-range.ts
|
|
2431
2744
|
var renderTimestampRange = (timestamps) => {
|
|
@@ -2439,7 +2752,7 @@ var renderTimestampRange = (timestamps) => {
|
|
|
2439
2752
|
};
|
|
2440
2753
|
|
|
2441
2754
|
// src/video-extraction/keyframe-bank.ts
|
|
2442
|
-
import { Internals as
|
|
2755
|
+
import { Internals as Internals13 } from "remotion";
|
|
2443
2756
|
|
|
2444
2757
|
// src/video-extraction/get-allocation-size.ts
|
|
2445
2758
|
var getAllocationSize = (sample) => {
|
|
@@ -2502,7 +2815,7 @@ var makeKeyframeBank = async ({
|
|
|
2502
2815
|
}
|
|
2503
2816
|
}
|
|
2504
2817
|
if (deletedTimestamps.length > 0) {
|
|
2505
|
-
|
|
2818
|
+
Internals13.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted ${deletedTimestamps.length} frame${deletedTimestamps.length === 1 ? "" : "s"} ${renderTimestampRange(deletedTimestamps)} for src ${src} because it is lower than ${timestampInSeconds}. Remaining: ${renderTimestampRange(frameTimestamps)}`);
|
|
2506
2819
|
}
|
|
2507
2820
|
};
|
|
2508
2821
|
const hasDecodedEnoughForTimestamp = (timestamp) => {
|
|
@@ -2525,7 +2838,7 @@ var makeKeyframeBank = async ({
|
|
|
2525
2838
|
frameTimestamps.push(frame.timestamp);
|
|
2526
2839
|
allocationSize += getAllocationSize(frame);
|
|
2527
2840
|
lastUsed = Date.now();
|
|
2528
|
-
|
|
2841
|
+
Internals13.Log.trace({ logLevel, tag: "@remotion/media" }, `Added frame at ${frame.timestamp}sec to bank`);
|
|
2529
2842
|
};
|
|
2530
2843
|
const ensureEnoughFramesForTimestamp = async (timestampInSeconds, logLevel, fps) => {
|
|
2531
2844
|
while (!hasDecodedEnoughForTimestamp(timestampInSeconds)) {
|
|
@@ -2580,7 +2893,7 @@ var makeKeyframeBank = async ({
|
|
|
2580
2893
|
throw new Error("No first frame found");
|
|
2581
2894
|
}
|
|
2582
2895
|
const startTimestampInSeconds = firstFrame.value.timestamp;
|
|
2583
|
-
|
|
2896
|
+
Internals13.Log.verbose({ logLevel: parentLogLevel, tag: "@remotion/media" }, `Creating keyframe bank from ${startTimestampInSeconds}sec`);
|
|
2584
2897
|
addFrame(firstFrame.value, parentLogLevel);
|
|
2585
2898
|
const getRangeOfTimestamps = () => {
|
|
2586
2899
|
if (frameTimestamps.length === 0) {
|
|
@@ -2598,7 +2911,7 @@ var makeKeyframeBank = async ({
|
|
|
2598
2911
|
const prepareForDeletion = (logLevel, reason) => {
|
|
2599
2912
|
const range = getRangeOfTimestamps();
|
|
2600
2913
|
if (range) {
|
|
2601
|
-
|
|
2914
|
+
Internals13.Log.verbose({ logLevel, tag: "@remotion/media" }, `Preparing for deletion (${reason}) of keyframe bank from ${range?.firstTimestamp}sec to ${range?.lastTimestamp}sec`);
|
|
2602
2915
|
}
|
|
2603
2916
|
let framesDeleted = 0;
|
|
2604
2917
|
for (const frameTimestamp of frameTimestamps.slice()) {
|
|
@@ -2671,10 +2984,10 @@ var makeKeyframeManager = () => {
|
|
|
2671
2984
|
if (size === 0) {
|
|
2672
2985
|
continue;
|
|
2673
2986
|
}
|
|
2674
|
-
|
|
2987
|
+
Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Open frames for src ${src}: ${renderTimestampRange(timestamps)}`);
|
|
2675
2988
|
}
|
|
2676
2989
|
}
|
|
2677
|
-
|
|
2990
|
+
Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Video cache stats: ${count} open frames, ${totalSize} bytes`);
|
|
2678
2991
|
};
|
|
2679
2992
|
const getCacheStats = () => {
|
|
2680
2993
|
let count = 0;
|
|
@@ -2728,7 +3041,7 @@ var makeKeyframeManager = () => {
|
|
|
2728
3041
|
const { framesDeleted } = mostInThePastBank.prepareForDeletion(logLevel, "deleted oldest keyframe bank to stay under max cache size");
|
|
2729
3042
|
sources[mostInThePastSrc].splice(mostInThePastIndex, 1);
|
|
2730
3043
|
if (range) {
|
|
2731
|
-
|
|
3044
|
+
Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted ${framesDeleted} frames for src ${mostInThePastSrc} from ${range?.firstTimestamp}sec to ${range?.lastTimestamp}sec to free up memory.`);
|
|
2732
3045
|
}
|
|
2733
3046
|
}
|
|
2734
3047
|
return { finish: false };
|
|
@@ -2742,12 +3055,12 @@ var makeKeyframeManager = () => {
|
|
|
2742
3055
|
if (finish) {
|
|
2743
3056
|
break;
|
|
2744
3057
|
}
|
|
2745
|
-
|
|
3058
|
+
Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, "Deleted oldest keyframe bank to stay under max cache size", (cacheStats.totalSize / 1024 / 1024).toFixed(1), "out of", (maxCacheSize / 1024 / 1024).toFixed(1));
|
|
2746
3059
|
cacheStats = getTotalCacheStats();
|
|
2747
3060
|
attempts++;
|
|
2748
3061
|
}
|
|
2749
3062
|
if (cacheStats.totalSize > maxCacheSize && attempts >= maxAttempts) {
|
|
2750
|
-
|
|
3063
|
+
Internals14.Log.warn({ logLevel, tag: "@remotion/media" }, `Exceeded max cache size after ${maxAttempts} attempts. Remaining cache size: ${(cacheStats.totalSize / 1024 / 1024).toFixed(1)} MB, target was ${(maxCacheSize / 1024 / 1024).toFixed(1)} MB.`);
|
|
2751
3064
|
}
|
|
2752
3065
|
};
|
|
2753
3066
|
const clearKeyframeBanksBeforeTime = ({
|
|
@@ -2768,7 +3081,7 @@ var makeKeyframeManager = () => {
|
|
|
2768
3081
|
}
|
|
2769
3082
|
if (range.lastTimestamp < threshold) {
|
|
2770
3083
|
bank.prepareForDeletion(logLevel, "cleared before threshold " + threshold);
|
|
2771
|
-
|
|
3084
|
+
Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `[Video] Cleared frames for src ${src} from ${range.firstTimestamp}sec to ${range.lastTimestamp}sec`);
|
|
2772
3085
|
const bankIndex = banks.indexOf(bank);
|
|
2773
3086
|
delete sources[src][bankIndex];
|
|
2774
3087
|
} else {
|
|
@@ -2790,7 +3103,7 @@ var makeKeyframeManager = () => {
|
|
|
2790
3103
|
const existingBanks = sources[src] ?? [];
|
|
2791
3104
|
const existingBank = existingBanks?.find((bank) => bank.canSatisfyTimestamp(timestamp));
|
|
2792
3105
|
if (!existingBank) {
|
|
2793
|
-
|
|
3106
|
+
Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, `Creating new keyframe bank for src ${src} at timestamp ${timestamp}`);
|
|
2794
3107
|
const newKeyframeBank = await makeKeyframeBank({
|
|
2795
3108
|
videoSampleSink,
|
|
2796
3109
|
logLevel,
|
|
@@ -2801,10 +3114,10 @@ var makeKeyframeManager = () => {
|
|
|
2801
3114
|
return newKeyframeBank;
|
|
2802
3115
|
}
|
|
2803
3116
|
if (existingBank.canSatisfyTimestamp(timestamp)) {
|
|
2804
|
-
|
|
3117
|
+
Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, `Keyframe bank exists and satisfies timestamp ${timestamp}`);
|
|
2805
3118
|
return existingBank;
|
|
2806
3119
|
}
|
|
2807
|
-
|
|
3120
|
+
Internals14.Log.verbose({ logLevel, tag: "@remotion/media" }, `Keyframe bank exists but frame at time ${timestamp} does not exist anymore.`);
|
|
2808
3121
|
existingBank.prepareForDeletion(logLevel, "already existed but evicted");
|
|
2809
3122
|
sources[src] = sources[src].filter((bank) => bank !== existingBank);
|
|
2810
3123
|
const replacementKeybank = await makeKeyframeBank({
|
|
@@ -2895,20 +3208,20 @@ var getUncachedMaxCacheSize = (logLevel) => {
|
|
|
2895
3208
|
if (window.remotion_mediaCacheSizeInBytes > 20000 * 1024 * 1024) {
|
|
2896
3209
|
cancelRender(new Error(`The maximum value for the "mediaCacheSizeInBytes" prop is 20GB (${20000 * 1024 * 1024}), got: ${window.remotion_mediaCacheSizeInBytes}`));
|
|
2897
3210
|
}
|
|
2898
|
-
|
|
3211
|
+
Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Using cache size set using "mediaCacheSizeInBytes": ${(window.remotion_mediaCacheSizeInBytes / 1024 / 1024).toFixed(1)} MB`);
|
|
2899
3212
|
return window.remotion_mediaCacheSizeInBytes;
|
|
2900
3213
|
}
|
|
2901
3214
|
if (typeof window !== "undefined" && window.remotion_initialMemoryAvailable !== undefined && window.remotion_initialMemoryAvailable !== null) {
|
|
2902
3215
|
const value = window.remotion_initialMemoryAvailable / 2;
|
|
2903
3216
|
if (value < 500 * 1024 * 1024) {
|
|
2904
|
-
|
|
3217
|
+
Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Using cache size set based on minimum value of 500MB (which is more than half of the available system memory!)`);
|
|
2905
3218
|
return 500 * 1024 * 1024;
|
|
2906
3219
|
}
|
|
2907
3220
|
if (value > 20000 * 1024 * 1024) {
|
|
2908
|
-
|
|
3221
|
+
Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Using cache size set based on maximum value of 20GB (which is less than half of the available system memory)`);
|
|
2909
3222
|
return 20000 * 1024 * 1024;
|
|
2910
3223
|
}
|
|
2911
|
-
|
|
3224
|
+
Internals15.Log.verbose({ logLevel, tag: "@remotion/media" }, `Using cache size set based on available memory (50% of available memory): ${(value / 1024 / 1024).toFixed(1)} MB`);
|
|
2912
3225
|
return value;
|
|
2913
3226
|
}
|
|
2914
3227
|
return 1000 * 1000 * 1000;
|
|
@@ -2922,7 +3235,7 @@ var getMaxVideoCacheSize = (logLevel) => {
|
|
|
2922
3235
|
return cachedMaxCacheSize;
|
|
2923
3236
|
};
|
|
2924
3237
|
var useMaxMediaCacheSize = (logLevel) => {
|
|
2925
|
-
const context = React2.useContext(
|
|
3238
|
+
const context = React2.useContext(Internals15.MaxMediaCacheSizeContext);
|
|
2926
3239
|
if (context === null) {
|
|
2927
3240
|
return getMaxVideoCacheSize(logLevel);
|
|
2928
3241
|
}
|
|
@@ -3171,7 +3484,7 @@ var combineAudioDataAndClosePrevious = (audioDataArray) => {
|
|
|
3171
3484
|
};
|
|
3172
3485
|
|
|
3173
3486
|
// src/get-sink.ts
|
|
3174
|
-
import { Internals as
|
|
3487
|
+
import { Internals as Internals16 } from "remotion";
|
|
3175
3488
|
|
|
3176
3489
|
// src/video-extraction/get-frames-since-keyframe.ts
|
|
3177
3490
|
import {
|
|
@@ -3324,7 +3637,7 @@ var sinkPromises = {};
|
|
|
3324
3637
|
var getSink = (src, logLevel) => {
|
|
3325
3638
|
let promise = sinkPromises[src];
|
|
3326
3639
|
if (!promise) {
|
|
3327
|
-
|
|
3640
|
+
Internals16.Log.verbose({
|
|
3328
3641
|
logLevel,
|
|
3329
3642
|
tag: "@remotion/media"
|
|
3330
3643
|
}, `Sink for ${src} was not found, creating new sink`);
|
|
@@ -3464,7 +3777,7 @@ var extractAudio = (params) => {
|
|
|
3464
3777
|
};
|
|
3465
3778
|
|
|
3466
3779
|
// src/video-extraction/extract-frame.ts
|
|
3467
|
-
import { Internals as
|
|
3780
|
+
import { Internals as Internals17 } from "remotion";
|
|
3468
3781
|
var extractFrameInternal = async ({
|
|
3469
3782
|
src,
|
|
3470
3783
|
timeInSeconds: unloopedTimeInSeconds,
|
|
@@ -3545,7 +3858,7 @@ var extractFrameInternal = async ({
|
|
|
3545
3858
|
durationInSeconds: await sink.getDuration()
|
|
3546
3859
|
};
|
|
3547
3860
|
} catch (err) {
|
|
3548
|
-
|
|
3861
|
+
Internals17.Log.info({ logLevel, tag: "@remotion/media" }, `Error decoding ${src} at time ${timeInSeconds}: ${err}`, err);
|
|
3549
3862
|
return { type: "cannot-decode", durationInSeconds: mediaDurationInSeconds };
|
|
3550
3863
|
}
|
|
3551
3864
|
};
|
|
@@ -3941,13 +4254,13 @@ var AudioForRendering = ({
|
|
|
3941
4254
|
trimBefore,
|
|
3942
4255
|
onError
|
|
3943
4256
|
}) => {
|
|
3944
|
-
const defaultLogLevel =
|
|
4257
|
+
const defaultLogLevel = Internals18.useLogLevel();
|
|
3945
4258
|
const logLevel = overriddenLogLevel ?? defaultLogLevel;
|
|
3946
4259
|
const frame = useCurrentFrame3();
|
|
3947
|
-
const absoluteFrame =
|
|
3948
|
-
const videoConfig =
|
|
3949
|
-
const { registerRenderAsset, unregisterRenderAsset } =
|
|
3950
|
-
const startsAt =
|
|
4260
|
+
const absoluteFrame = Internals18.useTimelinePosition();
|
|
4261
|
+
const videoConfig = Internals18.useUnsafeVideoConfig();
|
|
4262
|
+
const { registerRenderAsset, unregisterRenderAsset } = useContext4(Internals18.RenderAssetManager);
|
|
4263
|
+
const startsAt = Internals18.useMediaStartsAt();
|
|
3951
4264
|
const environment = useRemotionEnvironment();
|
|
3952
4265
|
if (!videoConfig) {
|
|
3953
4266
|
throw new Error("No video config found");
|
|
@@ -3958,7 +4271,7 @@ var AudioForRendering = ({
|
|
|
3958
4271
|
const { fps } = videoConfig;
|
|
3959
4272
|
const { delayRender, continueRender } = useDelayRender();
|
|
3960
4273
|
const [replaceWithHtml5Audio, setReplaceWithHtml5Audio] = useState3(false);
|
|
3961
|
-
const sequenceContext =
|
|
4274
|
+
const sequenceContext = useContext4(Internals18.SequenceContext);
|
|
3962
4275
|
const id = useMemo3(() => `media-audio-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
3963
4276
|
src,
|
|
3964
4277
|
sequenceContext?.cumulatedFrom,
|
|
@@ -3966,7 +4279,7 @@ var AudioForRendering = ({
|
|
|
3966
4279
|
sequenceContext?.durationInFrames
|
|
3967
4280
|
]);
|
|
3968
4281
|
const maxCacheSize = useMaxMediaCacheSize(logLevel);
|
|
3969
|
-
const audioEnabled =
|
|
4282
|
+
const audioEnabled = Internals18.useAudioEnabled();
|
|
3970
4283
|
useLayoutEffect2(() => {
|
|
3971
4284
|
const timestamp = frame / fps;
|
|
3972
4285
|
const durationInSeconds = 1 / fps;
|
|
@@ -4016,7 +4329,7 @@ var AudioForRendering = ({
|
|
|
4016
4329
|
if (action === "fail") {
|
|
4017
4330
|
cancelRender2(errorToUse);
|
|
4018
4331
|
}
|
|
4019
|
-
|
|
4332
|
+
Internals18.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
|
|
4020
4333
|
setReplaceWithHtml5Audio(true);
|
|
4021
4334
|
};
|
|
4022
4335
|
if (result.type === "unknown-container-format") {
|
|
@@ -4043,12 +4356,12 @@ var AudioForRendering = ({
|
|
|
4043
4356
|
frame,
|
|
4044
4357
|
startsAt
|
|
4045
4358
|
});
|
|
4046
|
-
const volume =
|
|
4359
|
+
const volume = Internals18.evaluateVolume({
|
|
4047
4360
|
volume: volumeProp,
|
|
4048
4361
|
frame: volumePropsFrame,
|
|
4049
4362
|
mediaVolume: 1
|
|
4050
4363
|
});
|
|
4051
|
-
|
|
4364
|
+
Internals18.warnAboutTooHighVolume(volume);
|
|
4052
4365
|
if (audio && volume > 0) {
|
|
4053
4366
|
applyVolume(audio.data, volume);
|
|
4054
4367
|
registerRenderAsset({
|
|
@@ -4124,7 +4437,7 @@ var AudioForRendering = ({
|
|
|
4124
4437
|
|
|
4125
4438
|
// src/audio/audio.tsx
|
|
4126
4439
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
4127
|
-
var { validateMediaProps } =
|
|
4440
|
+
var { validateMediaProps } = Internals19;
|
|
4128
4441
|
var Audio = (props) => {
|
|
4129
4442
|
const { name, stack, showInTimeline, ...otherProps } = props;
|
|
4130
4443
|
const environment = useRemotionEnvironment2();
|
|
@@ -4143,14 +4456,14 @@ var Audio = (props) => {
|
|
|
4143
4456
|
stack: stack ?? null
|
|
4144
4457
|
});
|
|
4145
4458
|
};
|
|
4146
|
-
|
|
4459
|
+
Internals19.addSequenceStackTraces(Audio);
|
|
4147
4460
|
|
|
4148
4461
|
// src/video/video.tsx
|
|
4149
|
-
import { Internals as
|
|
4462
|
+
import { Internals as Internals22, useRemotionEnvironment as useRemotionEnvironment4 } from "remotion";
|
|
4150
4463
|
|
|
4151
4464
|
// src/video/video-for-preview.tsx
|
|
4152
4465
|
import {
|
|
4153
|
-
useContext as
|
|
4466
|
+
useContext as useContext5,
|
|
4154
4467
|
useEffect as useEffect3,
|
|
4155
4468
|
useLayoutEffect as useLayoutEffect3,
|
|
4156
4469
|
useMemo as useMemo4,
|
|
@@ -4159,7 +4472,7 @@ import {
|
|
|
4159
4472
|
} from "react";
|
|
4160
4473
|
import {
|
|
4161
4474
|
Html5Video,
|
|
4162
|
-
Internals as
|
|
4475
|
+
Internals as Internals20,
|
|
4163
4476
|
useBufferState as useBufferState2,
|
|
4164
4477
|
useCurrentFrame as useCurrentFrame4,
|
|
4165
4478
|
useVideoConfig as useVideoConfig3
|
|
@@ -4177,7 +4490,7 @@ var {
|
|
|
4177
4490
|
usePreload: usePreload2,
|
|
4178
4491
|
SequenceContext: SequenceContext2,
|
|
4179
4492
|
SequenceVisibilityToggleContext
|
|
4180
|
-
} =
|
|
4493
|
+
} = Internals20;
|
|
4181
4494
|
var VideoForPreviewAssertedShowing = ({
|
|
4182
4495
|
src: unpreloadedSrc,
|
|
4183
4496
|
style,
|
|
@@ -4198,6 +4511,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4198
4511
|
fallbackOffthreadVideoProps,
|
|
4199
4512
|
audioStreamIndex,
|
|
4200
4513
|
debugOverlay,
|
|
4514
|
+
debugAudioScheduling,
|
|
4201
4515
|
headless,
|
|
4202
4516
|
onError,
|
|
4203
4517
|
controls
|
|
@@ -4213,26 +4527,28 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4213
4527
|
const [mediaPlayerReady, setMediaPlayerReady] = useState4(false);
|
|
4214
4528
|
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState4(false);
|
|
4215
4529
|
const [playing] = Timeline2.usePlayingState();
|
|
4216
|
-
const timelineContext =
|
|
4530
|
+
const timelineContext = useContext5(Internals20.TimelineContext);
|
|
4217
4531
|
const globalPlaybackRate = timelineContext.playbackRate;
|
|
4218
|
-
const sharedAudioContext =
|
|
4532
|
+
const sharedAudioContext = useContext5(SharedAudioContext2);
|
|
4219
4533
|
const buffer = useBufferState2();
|
|
4220
4534
|
const [mediaMuted] = useMediaMutedState2();
|
|
4221
4535
|
const [mediaVolume] = useMediaVolumeState2();
|
|
4222
4536
|
const [mediaDurationInSeconds, setMediaDurationInSeconds] = useState4(null);
|
|
4223
|
-
const { hidden } =
|
|
4537
|
+
const { hidden } = useContext5(SequenceVisibilityToggleContext);
|
|
4224
4538
|
const volumePropFrame = useFrameForVolumeProp2(loopVolumeCurveBehavior);
|
|
4225
4539
|
const userPreferredVolume = evaluateVolume2({
|
|
4226
4540
|
frame: volumePropFrame,
|
|
4227
4541
|
volume,
|
|
4228
4542
|
mediaVolume
|
|
4229
4543
|
});
|
|
4544
|
+
if (!videoConfig) {
|
|
4545
|
+
throw new Error("No video config found");
|
|
4546
|
+
}
|
|
4230
4547
|
warnAboutTooHighVolume2(userPreferredVolume);
|
|
4231
|
-
const parentSequence =
|
|
4548
|
+
const parentSequence = useContext5(SequenceContext2);
|
|
4232
4549
|
const isPremounting = Boolean(parentSequence?.premounting);
|
|
4233
4550
|
const isPostmounting = Boolean(parentSequence?.postmounting);
|
|
4234
|
-
const
|
|
4235
|
-
const isNextFrameGoingToPlay = playingWhilePremounting && premountFramesRemaining > 0 && premountFramesRemaining <= 1.000000001;
|
|
4551
|
+
const sequenceOffset = ((parentSequence?.cumulatedFrom ?? 0) + (parentSequence?.relativeFrom ?? 0)) / videoConfig.fps;
|
|
4236
4552
|
const loopDisplay = useLoopDisplay({
|
|
4237
4553
|
loop,
|
|
4238
4554
|
mediaDurationInSeconds,
|
|
@@ -4257,34 +4573,35 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4257
4573
|
controls
|
|
4258
4574
|
});
|
|
4259
4575
|
const isSequenceHidden = hidden[timelineId] ?? false;
|
|
4260
|
-
if (!videoConfig) {
|
|
4261
|
-
throw new Error("No video config found");
|
|
4262
|
-
}
|
|
4263
4576
|
const currentTime = frame / videoConfig.fps;
|
|
4264
4577
|
const currentTimeRef = useRef2(currentTime);
|
|
4265
4578
|
currentTimeRef.current = currentTime;
|
|
4266
4579
|
const preloadedSrc = usePreload2(src);
|
|
4267
|
-
const buffering =
|
|
4580
|
+
const buffering = useContext5(Internals20.BufferingContextReact);
|
|
4268
4581
|
if (!buffering) {
|
|
4269
4582
|
throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
|
|
4270
4583
|
}
|
|
4271
4584
|
const effectiveMuted = isSequenceHidden || muted || mediaMuted || userPreferredVolume <= 0;
|
|
4272
|
-
const isPlayerBuffering =
|
|
4585
|
+
const isPlayerBuffering = Internals20.useIsPlayerBuffering(buffering);
|
|
4273
4586
|
const initialPlaying = useRef2(playing && !isPlayerBuffering);
|
|
4274
4587
|
const initialIsPremounting = useRef2(isPremounting);
|
|
4275
4588
|
const initialIsPostmounting = useRef2(isPostmounting);
|
|
4276
4589
|
const initialGlobalPlaybackRate = useRef2(globalPlaybackRate);
|
|
4277
4590
|
const initialPlaybackRate = useRef2(playbackRate);
|
|
4278
4591
|
const initialMuted = useRef2(effectiveMuted);
|
|
4592
|
+
const initialSequenceOffset = useRef2(sequenceOffset);
|
|
4279
4593
|
useEffect3(() => {
|
|
4280
4594
|
if (!sharedAudioContext)
|
|
4281
4595
|
return;
|
|
4596
|
+
if (!sharedAudioContext.audioContext)
|
|
4597
|
+
return;
|
|
4598
|
+
const { audioContext, audioSyncAnchor, scheduleAudioNode } = sharedAudioContext;
|
|
4282
4599
|
try {
|
|
4283
4600
|
const player = new MediaPlayer({
|
|
4284
4601
|
canvas: canvasRef.current,
|
|
4285
4602
|
src: preloadedSrc,
|
|
4286
4603
|
logLevel,
|
|
4287
|
-
sharedAudioContext:
|
|
4604
|
+
sharedAudioContext: { audioContext, audioSyncAnchor, scheduleAudioNode },
|
|
4288
4605
|
loop,
|
|
4289
4606
|
trimAfter: initialTrimAfterRef.current,
|
|
4290
4607
|
trimBefore: initialTrimBeforeRef.current,
|
|
@@ -4292,13 +4609,15 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4292
4609
|
playbackRate: initialPlaybackRate.current,
|
|
4293
4610
|
audioStreamIndex,
|
|
4294
4611
|
debugOverlay,
|
|
4612
|
+
debugAudioScheduling,
|
|
4295
4613
|
bufferState: buffer,
|
|
4296
4614
|
isPremounting: initialIsPremounting.current,
|
|
4297
4615
|
isPostmounting: initialIsPostmounting.current,
|
|
4298
4616
|
globalPlaybackRate: initialGlobalPlaybackRate.current,
|
|
4299
4617
|
durationInFrames: videoConfig.durationInFrames,
|
|
4300
4618
|
onVideoFrameCallback: initialOnVideoFrameRef.current ?? null,
|
|
4301
|
-
playing: initialPlaying.current
|
|
4619
|
+
playing: initialPlaying.current,
|
|
4620
|
+
sequenceOffset: initialSequenceOffset.current
|
|
4302
4621
|
});
|
|
4303
4622
|
mediaPlayerRef.current = player;
|
|
4304
4623
|
player.initialize(currentTimeRef.current, initialMuted.current).then((result) => {
|
|
@@ -4316,7 +4635,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4316
4635
|
if (action === "fail") {
|
|
4317
4636
|
throw errorToUse;
|
|
4318
4637
|
}
|
|
4319
|
-
|
|
4638
|
+
Internals20.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
|
|
4320
4639
|
setShouldFallbackToNativeVideo(true);
|
|
4321
4640
|
};
|
|
4322
4641
|
if (result.type === "unknown-container-format") {
|
|
@@ -4350,7 +4669,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4350
4669
|
if (action === "fail") {
|
|
4351
4670
|
throw errorToUse;
|
|
4352
4671
|
}
|
|
4353
|
-
|
|
4672
|
+
Internals20.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", errorToUse);
|
|
4354
4673
|
setShouldFallbackToNativeVideo(true);
|
|
4355
4674
|
});
|
|
4356
4675
|
} catch (error) {
|
|
@@ -4364,12 +4683,12 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4364
4683
|
if (action === "fail") {
|
|
4365
4684
|
throw errorToUse;
|
|
4366
4685
|
}
|
|
4367
|
-
|
|
4686
|
+
Internals20.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", errorToUse);
|
|
4368
4687
|
setShouldFallbackToNativeVideo(true);
|
|
4369
4688
|
}
|
|
4370
4689
|
return () => {
|
|
4371
4690
|
if (mediaPlayerRef.current) {
|
|
4372
|
-
|
|
4691
|
+
Internals20.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
|
|
4373
4692
|
mediaPlayerRef.current.dispose();
|
|
4374
4693
|
mediaPlayerRef.current = null;
|
|
4375
4694
|
}
|
|
@@ -4380,6 +4699,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4380
4699
|
audioStreamIndex,
|
|
4381
4700
|
buffer,
|
|
4382
4701
|
debugOverlay,
|
|
4702
|
+
debugAudioScheduling,
|
|
4383
4703
|
disallowFallbackToOffthreadVideo,
|
|
4384
4704
|
logLevel,
|
|
4385
4705
|
loop,
|
|
@@ -4390,65 +4710,33 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4390
4710
|
videoConfig.durationInFrames
|
|
4391
4711
|
]);
|
|
4392
4712
|
const classNameValue = useMemo4(() => {
|
|
4393
|
-
return [
|
|
4713
|
+
return [Internals20.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals20.truthy).join(" ");
|
|
4394
4714
|
}, [className]);
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
if (isNextFrameGoingToPlay) {
|
|
4400
|
-
const currentTimeUntilZero = premountFramesRemaining / videoConfig.fps / globalPlaybackRate;
|
|
4401
|
-
mediaPlayer.playAudio(currentTimeRef.current - currentTimeUntilZero);
|
|
4402
|
-
}
|
|
4403
|
-
}, [
|
|
4404
|
-
isNextFrameGoingToPlay,
|
|
4405
|
-
premountFramesRemaining,
|
|
4406
|
-
videoConfig.fps,
|
|
4407
|
-
globalPlaybackRate
|
|
4408
|
-
]);
|
|
4409
|
-
useEffect3(() => {
|
|
4410
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4411
|
-
if (!mediaPlayer)
|
|
4412
|
-
return;
|
|
4413
|
-
if (playing && !isPlayerBuffering && !isNextFrameGoingToPlay) {
|
|
4414
|
-
mediaPlayer.play(currentTimeRef.current);
|
|
4415
|
-
} else {
|
|
4416
|
-
mediaPlayer.pause();
|
|
4417
|
-
}
|
|
4418
|
-
}, [
|
|
4419
|
-
isPlayerBuffering,
|
|
4715
|
+
useCommonEffects({
|
|
4716
|
+
mediaPlayerRef,
|
|
4717
|
+
mediaPlayerReady,
|
|
4718
|
+
currentTimeRef,
|
|
4420
4719
|
playing,
|
|
4720
|
+
isPlayerBuffering,
|
|
4721
|
+
frame,
|
|
4722
|
+
trimBefore,
|
|
4723
|
+
trimAfter,
|
|
4724
|
+
effectiveMuted,
|
|
4725
|
+
userPreferredVolume,
|
|
4726
|
+
playbackRate,
|
|
4727
|
+
globalPlaybackRate,
|
|
4728
|
+
fps: videoConfig.fps,
|
|
4729
|
+
sequenceOffset,
|
|
4730
|
+
loop,
|
|
4731
|
+
debugAudioScheduling,
|
|
4732
|
+
durationInFrames: videoConfig.durationInFrames,
|
|
4733
|
+
isPremounting,
|
|
4734
|
+
isPostmounting,
|
|
4735
|
+
currentTime,
|
|
4421
4736
|
logLevel,
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
useEffect3(() => {
|
|
4426
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4427
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4428
|
-
return;
|
|
4429
|
-
}
|
|
4430
|
-
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
4431
|
-
}, [trimBefore, mediaPlayerReady]);
|
|
4432
|
-
useEffect3(() => {
|
|
4433
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4434
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4435
|
-
return;
|
|
4436
|
-
}
|
|
4437
|
-
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
4438
|
-
}, [trimAfter, mediaPlayerReady]);
|
|
4439
|
-
useLayoutEffect3(() => {
|
|
4440
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4441
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
4442
|
-
return;
|
|
4443
|
-
mediaPlayer.setMuted(effectiveMuted);
|
|
4444
|
-
}, [effectiveMuted, mediaPlayerReady]);
|
|
4445
|
-
useLayoutEffect3(() => {
|
|
4446
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4447
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4448
|
-
return;
|
|
4449
|
-
}
|
|
4450
|
-
mediaPlayer.setVolume(userPreferredVolume);
|
|
4451
|
-
}, [userPreferredVolume, mediaPlayerReady]);
|
|
4737
|
+
sharedAudioContext,
|
|
4738
|
+
label: "VideoForPreview"
|
|
4739
|
+
});
|
|
4452
4740
|
useLayoutEffect3(() => {
|
|
4453
4741
|
const mediaPlayer = mediaPlayerRef.current;
|
|
4454
4742
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
@@ -4456,55 +4744,6 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4456
4744
|
}
|
|
4457
4745
|
mediaPlayer.setDebugOverlay(debugOverlay);
|
|
4458
4746
|
}, [debugOverlay, mediaPlayerReady]);
|
|
4459
|
-
useLayoutEffect3(() => {
|
|
4460
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4461
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4462
|
-
return;
|
|
4463
|
-
}
|
|
4464
|
-
mediaPlayer.setPlaybackRate(playbackRate, currentTimeRef.current);
|
|
4465
|
-
}, [playbackRate, mediaPlayerReady]);
|
|
4466
|
-
useLayoutEffect3(() => {
|
|
4467
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4468
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4469
|
-
return;
|
|
4470
|
-
}
|
|
4471
|
-
mediaPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
4472
|
-
}, [globalPlaybackRate, mediaPlayerReady]);
|
|
4473
|
-
useLayoutEffect3(() => {
|
|
4474
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4475
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4476
|
-
return;
|
|
4477
|
-
}
|
|
4478
|
-
mediaPlayer.setLoop(loop);
|
|
4479
|
-
}, [loop, mediaPlayerReady]);
|
|
4480
|
-
useLayoutEffect3(() => {
|
|
4481
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4482
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4483
|
-
return;
|
|
4484
|
-
}
|
|
4485
|
-
mediaPlayer.setDurationInFrames(videoConfig.durationInFrames);
|
|
4486
|
-
}, [videoConfig.durationInFrames, mediaPlayerReady]);
|
|
4487
|
-
useLayoutEffect3(() => {
|
|
4488
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4489
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4490
|
-
return;
|
|
4491
|
-
}
|
|
4492
|
-
mediaPlayer.setIsPremounting(isPremounting);
|
|
4493
|
-
}, [isPremounting, mediaPlayerReady]);
|
|
4494
|
-
useLayoutEffect3(() => {
|
|
4495
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4496
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4497
|
-
return;
|
|
4498
|
-
}
|
|
4499
|
-
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
4500
|
-
}, [isPostmounting, mediaPlayerReady]);
|
|
4501
|
-
useLayoutEffect3(() => {
|
|
4502
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4503
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
4504
|
-
return;
|
|
4505
|
-
}
|
|
4506
|
-
mediaPlayer.setFps(videoConfig.fps);
|
|
4507
|
-
}, [videoConfig.fps, mediaPlayerReady]);
|
|
4508
4747
|
useLayoutEffect3(() => {
|
|
4509
4748
|
const mediaPlayer = mediaPlayerRef.current;
|
|
4510
4749
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
@@ -4512,13 +4751,6 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4512
4751
|
}
|
|
4513
4752
|
mediaPlayer.setVideoFrameCallback(onVideoFrame ?? null);
|
|
4514
4753
|
}, [onVideoFrame, mediaPlayerReady]);
|
|
4515
|
-
useLayoutEffect3(() => {
|
|
4516
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
4517
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
4518
|
-
return;
|
|
4519
|
-
mediaPlayer.seekTo(currentTime).catch(() => {});
|
|
4520
|
-
Internals16.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
4521
|
-
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
4522
4754
|
const actualStyle = useMemo4(() => {
|
|
4523
4755
|
return {
|
|
4524
4756
|
...style,
|
|
@@ -4548,8 +4780,6 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4548
4780
|
}
|
|
4549
4781
|
return /* @__PURE__ */ jsx4("canvas", {
|
|
4550
4782
|
ref: canvasRef,
|
|
4551
|
-
width: videoConfig.width,
|
|
4552
|
-
height: videoConfig.height,
|
|
4553
4783
|
style: actualStyle,
|
|
4554
4784
|
className: classNameValue
|
|
4555
4785
|
});
|
|
@@ -4565,39 +4795,25 @@ var videoSchema = {
|
|
|
4565
4795
|
},
|
|
4566
4796
|
playbackRate: {
|
|
4567
4797
|
type: "number",
|
|
4568
|
-
min: 0,
|
|
4798
|
+
min: 0.1,
|
|
4569
4799
|
step: 0.01,
|
|
4570
4800
|
default: 1,
|
|
4571
4801
|
description: "Playback Rate"
|
|
4572
4802
|
},
|
|
4573
|
-
|
|
4574
|
-
trimAfter: { type: "number", min: 0, default: 0 }
|
|
4803
|
+
loop: { type: "boolean", default: false, description: "Loop" }
|
|
4575
4804
|
};
|
|
4576
4805
|
var VideoForPreview = (props) => {
|
|
4577
4806
|
const schemaInput = useMemo4(() => {
|
|
4578
|
-
if (typeof props.volume !== "number") {
|
|
4579
|
-
return null;
|
|
4580
|
-
}
|
|
4581
4807
|
return {
|
|
4582
4808
|
volume: props.volume,
|
|
4583
4809
|
playbackRate: props.playbackRate,
|
|
4584
|
-
trimBefore: props.trimBefore,
|
|
4585
|
-
trimAfter: props.trimAfter,
|
|
4586
4810
|
loop: props.loop
|
|
4587
4811
|
};
|
|
4588
|
-
}, [
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
props.loop
|
|
4594
|
-
]);
|
|
4595
|
-
const { controls, values } = Internals16.useSchema(schemaInput ? videoSchema : null, schemaInput);
|
|
4596
|
-
const volume = schemaInput !== null ? values.volume : props.volume;
|
|
4597
|
-
const playbackRate = schemaInput !== null ? values.playbackRate : props.playbackRate;
|
|
4598
|
-
const trimBefore = schemaInput !== null ? values.trimBefore : props.trimBefore;
|
|
4599
|
-
const trimAfter = schemaInput !== null ? values.trimAfter : props.trimAfter;
|
|
4600
|
-
const effectiveLoop = schemaInput !== null ? values.loop : props.loop;
|
|
4812
|
+
}, [props.volume, props.playbackRate, props.loop]);
|
|
4813
|
+
const {
|
|
4814
|
+
controls,
|
|
4815
|
+
values: { loop, playbackRate, volume }
|
|
4816
|
+
} = Internals20.useSchema(videoSchema, schemaInput);
|
|
4601
4817
|
const frame = useCurrentFrame4();
|
|
4602
4818
|
const videoConfig = useVideoConfig3();
|
|
4603
4819
|
const currentTime = frame / videoConfig.fps;
|
|
@@ -4605,9 +4821,9 @@ var VideoForPreview = (props) => {
|
|
|
4605
4821
|
return getTimeInSeconds({
|
|
4606
4822
|
unloopedTimeInSeconds: currentTime,
|
|
4607
4823
|
playbackRate,
|
|
4608
|
-
loop
|
|
4609
|
-
trimBefore,
|
|
4610
|
-
trimAfter,
|
|
4824
|
+
loop,
|
|
4825
|
+
trimBefore: props.trimBefore,
|
|
4826
|
+
trimAfter: props.trimAfter,
|
|
4611
4827
|
mediaDurationInSeconds: Infinity,
|
|
4612
4828
|
fps: videoConfig.fps,
|
|
4613
4829
|
ifNoMediaDuration: "infinity",
|
|
@@ -4615,37 +4831,35 @@ var VideoForPreview = (props) => {
|
|
|
4615
4831
|
}) !== null;
|
|
4616
4832
|
}, [
|
|
4617
4833
|
currentTime,
|
|
4618
|
-
|
|
4834
|
+
loop,
|
|
4619
4835
|
playbackRate,
|
|
4620
4836
|
props.src,
|
|
4621
|
-
|
|
4622
|
-
trimBefore,
|
|
4623
|
-
|
|
4837
|
+
videoConfig.fps,
|
|
4838
|
+
props.trimBefore,
|
|
4839
|
+
props.trimAfter
|
|
4624
4840
|
]);
|
|
4625
4841
|
if (!showShow) {
|
|
4626
4842
|
return null;
|
|
4627
4843
|
}
|
|
4628
4844
|
return /* @__PURE__ */ jsx4(VideoForPreviewAssertedShowing, {
|
|
4629
4845
|
...props,
|
|
4630
|
-
volume,
|
|
4846
|
+
volume: volume ?? 1,
|
|
4631
4847
|
playbackRate,
|
|
4632
|
-
loop
|
|
4633
|
-
trimBefore,
|
|
4634
|
-
trimAfter,
|
|
4848
|
+
loop,
|
|
4635
4849
|
controls
|
|
4636
4850
|
});
|
|
4637
4851
|
};
|
|
4638
4852
|
|
|
4639
4853
|
// src/video/video-for-rendering.tsx
|
|
4640
4854
|
import {
|
|
4641
|
-
useContext as
|
|
4855
|
+
useContext as useContext6,
|
|
4642
4856
|
useLayoutEffect as useLayoutEffect4,
|
|
4643
4857
|
useMemo as useMemo5,
|
|
4644
4858
|
useRef as useRef3,
|
|
4645
4859
|
useState as useState5
|
|
4646
4860
|
} from "react";
|
|
4647
4861
|
import {
|
|
4648
|
-
Internals as
|
|
4862
|
+
Internals as Internals21,
|
|
4649
4863
|
Loop,
|
|
4650
4864
|
random as random2,
|
|
4651
4865
|
useCurrentFrame as useCurrentFrame5,
|
|
@@ -4682,11 +4896,11 @@ var VideoForRendering = ({
|
|
|
4682
4896
|
throw new TypeError("No `src` was passed to <Video>.");
|
|
4683
4897
|
}
|
|
4684
4898
|
const frame = useCurrentFrame5();
|
|
4685
|
-
const absoluteFrame =
|
|
4899
|
+
const absoluteFrame = Internals21.useTimelinePosition();
|
|
4686
4900
|
const { fps } = useVideoConfig4();
|
|
4687
|
-
const { registerRenderAsset, unregisterRenderAsset } =
|
|
4688
|
-
const startsAt =
|
|
4689
|
-
const sequenceContext =
|
|
4901
|
+
const { registerRenderAsset, unregisterRenderAsset } = useContext6(Internals21.RenderAssetManager);
|
|
4902
|
+
const startsAt = Internals21.useMediaStartsAt();
|
|
4903
|
+
const sequenceContext = useContext6(Internals21.SequenceContext);
|
|
4690
4904
|
const id = useMemo5(() => `media-video-${random2(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
4691
4905
|
src,
|
|
4692
4906
|
sequenceContext?.cumulatedFrom,
|
|
@@ -4697,8 +4911,8 @@ var VideoForRendering = ({
|
|
|
4697
4911
|
const { delayRender, continueRender, cancelRender: cancelRender3 } = useDelayRender2();
|
|
4698
4912
|
const canvasRef = useRef3(null);
|
|
4699
4913
|
const [replaceWithOffthreadVideo, setReplaceWithOffthreadVideo] = useState5(false);
|
|
4700
|
-
const audioEnabled =
|
|
4701
|
-
const videoEnabled =
|
|
4914
|
+
const audioEnabled = Internals21.useAudioEnabled();
|
|
4915
|
+
const videoEnabled = Internals21.useVideoEnabled();
|
|
4702
4916
|
const maxCacheSize = useMaxMediaCacheSize(logLevel);
|
|
4703
4917
|
const [error, setError] = useState5(null);
|
|
4704
4918
|
if (error) {
|
|
@@ -4762,7 +4976,7 @@ var VideoForRendering = ({
|
|
|
4762
4976
|
return;
|
|
4763
4977
|
}
|
|
4764
4978
|
if (window.remotion_isMainTab) {
|
|
4765
|
-
|
|
4979
|
+
Internals21.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
|
|
4766
4980
|
}
|
|
4767
4981
|
setReplaceWithOffthreadVideo({
|
|
4768
4982
|
durationInSeconds: mediaDurationInSeconds
|
|
@@ -4817,12 +5031,12 @@ var VideoForRendering = ({
|
|
|
4817
5031
|
frame,
|
|
4818
5032
|
startsAt
|
|
4819
5033
|
});
|
|
4820
|
-
const volume =
|
|
5034
|
+
const volume = Internals21.evaluateVolume({
|
|
4821
5035
|
volume: volumeProp,
|
|
4822
5036
|
frame: volumePropsFrame,
|
|
4823
5037
|
mediaVolume: 1
|
|
4824
5038
|
});
|
|
4825
|
-
|
|
5039
|
+
Internals21.warnAboutTooHighVolume(volume);
|
|
4826
5040
|
if (audio && volume > 0) {
|
|
4827
5041
|
applyVolume(audio.data, volume);
|
|
4828
5042
|
registerRenderAsset({
|
|
@@ -4878,10 +5092,10 @@ var VideoForRendering = ({
|
|
|
4878
5092
|
onError
|
|
4879
5093
|
]);
|
|
4880
5094
|
const classNameValue = useMemo5(() => {
|
|
4881
|
-
return [
|
|
5095
|
+
return [Internals21.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals21.truthy).join(" ");
|
|
4882
5096
|
}, [className]);
|
|
4883
5097
|
if (replaceWithOffthreadVideo) {
|
|
4884
|
-
const fallback = /* @__PURE__ */ jsx5(
|
|
5098
|
+
const fallback = /* @__PURE__ */ jsx5(Internals21.InnerOffthreadVideo, {
|
|
4885
5099
|
src,
|
|
4886
5100
|
playbackRate: playbackRate ?? 1,
|
|
4887
5101
|
muted: muted ?? false,
|
|
@@ -4921,7 +5135,7 @@ var VideoForRendering = ({
|
|
|
4921
5135
|
}
|
|
4922
5136
|
return /* @__PURE__ */ jsx5(Loop, {
|
|
4923
5137
|
layout: "none",
|
|
4924
|
-
durationInFrames:
|
|
5138
|
+
durationInFrames: Internals21.calculateMediaDuration({
|
|
4925
5139
|
trimAfter: trimAfterValue,
|
|
4926
5140
|
mediaDurationInFrames: replaceWithOffthreadVideo.durationInSeconds * fps,
|
|
4927
5141
|
playbackRate,
|
|
@@ -4944,7 +5158,7 @@ var VideoForRendering = ({
|
|
|
4944
5158
|
|
|
4945
5159
|
// src/video/video.tsx
|
|
4946
5160
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
4947
|
-
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } =
|
|
5161
|
+
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } = Internals22;
|
|
4948
5162
|
var InnerVideo = ({
|
|
4949
5163
|
src,
|
|
4950
5164
|
audioStreamIndex,
|
|
@@ -4968,6 +5182,7 @@ var InnerVideo = ({
|
|
|
4968
5182
|
toneFrequency,
|
|
4969
5183
|
showInTimeline,
|
|
4970
5184
|
debugOverlay,
|
|
5185
|
+
debugAudioScheduling,
|
|
4971
5186
|
headless,
|
|
4972
5187
|
onError
|
|
4973
5188
|
}) => {
|
|
@@ -5034,6 +5249,7 @@ var InnerVideo = ({
|
|
|
5034
5249
|
disallowFallbackToOffthreadVideo,
|
|
5035
5250
|
fallbackOffthreadVideoProps,
|
|
5036
5251
|
debugOverlay: debugOverlay ?? false,
|
|
5252
|
+
debugAudioScheduling: debugAudioScheduling ?? false,
|
|
5037
5253
|
headless: headless ?? false,
|
|
5038
5254
|
onError
|
|
5039
5255
|
});
|
|
@@ -5061,10 +5277,11 @@ var Video = ({
|
|
|
5061
5277
|
stack,
|
|
5062
5278
|
toneFrequency,
|
|
5063
5279
|
debugOverlay,
|
|
5280
|
+
debugAudioScheduling,
|
|
5064
5281
|
headless,
|
|
5065
5282
|
onError
|
|
5066
5283
|
}) => {
|
|
5067
|
-
const fallbackLogLevel =
|
|
5284
|
+
const fallbackLogLevel = Internals22.useLogLevel();
|
|
5068
5285
|
return /* @__PURE__ */ jsx6(InnerVideo, {
|
|
5069
5286
|
audioStreamIndex: audioStreamIndex ?? 0,
|
|
5070
5287
|
className,
|
|
@@ -5088,11 +5305,12 @@ var Video = ({
|
|
|
5088
5305
|
toneFrequency: toneFrequency ?? 1,
|
|
5089
5306
|
stack,
|
|
5090
5307
|
debugOverlay: debugOverlay ?? false,
|
|
5308
|
+
debugAudioScheduling: debugAudioScheduling ?? false,
|
|
5091
5309
|
headless: headless ?? false,
|
|
5092
5310
|
onError
|
|
5093
5311
|
});
|
|
5094
5312
|
};
|
|
5095
|
-
|
|
5313
|
+
Internals22.addSequenceStackTraces(Video);
|
|
5096
5314
|
|
|
5097
5315
|
// src/index.ts
|
|
5098
5316
|
var experimental_Audio = Audio;
|