@remotion/media 4.0.357 → 4.0.361
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.js +29 -13
- package/dist/audio/audio-for-rendering.js +8 -6
- package/dist/audio-extraction/extract-audio.js +1 -0
- package/dist/browser-can-use-webgl2.d.ts +1 -0
- package/dist/browser-can-use-webgl2.js +13 -0
- package/dist/caches.d.ts +1 -1
- package/dist/caches.js +3 -3
- package/dist/esm/index.mjs +568 -327
- package/dist/extract-frame-and-audio.js +6 -0
- package/dist/get-time-in-seconds.d.ts +2 -1
- package/dist/get-time-in-seconds.js +10 -10
- package/dist/show-in-timeline.d.ts +8 -0
- package/dist/show-in-timeline.js +31 -0
- package/dist/use-media-in-timeline.d.ts +19 -0
- package/dist/use-media-in-timeline.js +103 -0
- package/dist/video/media-player.d.ts +11 -5
- package/dist/video/media-player.js +74 -36
- package/dist/video/video-for-preview.d.ts +9 -9
- package/dist/video/video-for-preview.js +43 -20
- package/dist/video/video-for-rendering.js +21 -5
- package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +3 -0
- package/dist/video-extraction/extract-frame-via-broadcast-channel.js +17 -0
- package/dist/video-extraction/extract-frame.d.ts +3 -0
- package/dist/video-extraction/extract-frame.js +7 -0
- package/dist/video-extraction/keyframe-manager.d.ts +1 -1
- package/dist/video-extraction/keyframe-manager.js +5 -0
- package/package.json +54 -54
- package/LICENSE.md +0 -49
- package/dist/convert-audiodata/apply-tonefrequency.d.ts +0 -2
- package/dist/convert-audiodata/apply-tonefrequency.js +0 -43
- package/dist/convert-audiodata/wsola.d.ts +0 -13
- package/dist/convert-audiodata/wsola.js +0 -197
- package/dist/get-sink-weak.d.ts +0 -13
- package/dist/get-sink-weak.js +0 -15
- package/dist/log.d.ts +0 -10
- package/dist/log.js +0 -33
- package/dist/video/resolve-playback-time.d.ts +0 -8
- package/dist/video/resolve-playback-time.js +0 -22
package/dist/esm/index.mjs
CHANGED
|
@@ -1,15 +1,179 @@
|
|
|
1
1
|
// src/audio/audio.tsx
|
|
2
|
-
import { Internals as
|
|
2
|
+
import { Internals as Internals13, useRemotionEnvironment as useRemotionEnvironment2 } from "remotion";
|
|
3
3
|
|
|
4
4
|
// src/audio/audio-for-preview.tsx
|
|
5
|
-
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { useContext as useContext2, useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
|
|
6
6
|
import {
|
|
7
|
-
Internals as
|
|
7
|
+
Internals as Internals5,
|
|
8
8
|
Audio as RemotionAudio,
|
|
9
9
|
useBufferState,
|
|
10
|
-
useCurrentFrame
|
|
10
|
+
useCurrentFrame as useCurrentFrame2
|
|
11
11
|
} from "remotion";
|
|
12
12
|
|
|
13
|
+
// src/show-in-timeline.ts
|
|
14
|
+
import { useMemo } from "react";
|
|
15
|
+
import { Internals, useVideoConfig } from "remotion";
|
|
16
|
+
var useLoopDisplay = ({
|
|
17
|
+
loop,
|
|
18
|
+
mediaDurationInSeconds,
|
|
19
|
+
playbackRate,
|
|
20
|
+
trimAfter,
|
|
21
|
+
trimBefore
|
|
22
|
+
}) => {
|
|
23
|
+
const { durationInFrames: compDuration, fps } = useVideoConfig();
|
|
24
|
+
const loopDisplay = useMemo(() => {
|
|
25
|
+
if (!loop || !mediaDurationInSeconds) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const durationInFrames = Internals.calculateMediaDuration({
|
|
29
|
+
mediaDurationInFrames: mediaDurationInSeconds * fps,
|
|
30
|
+
playbackRate,
|
|
31
|
+
trimAfter,
|
|
32
|
+
trimBefore
|
|
33
|
+
});
|
|
34
|
+
const maxTimes = compDuration / durationInFrames;
|
|
35
|
+
return {
|
|
36
|
+
numberOfTimes: maxTimes,
|
|
37
|
+
startOffset: 0,
|
|
38
|
+
durationInFrames
|
|
39
|
+
};
|
|
40
|
+
}, [
|
|
41
|
+
compDuration,
|
|
42
|
+
fps,
|
|
43
|
+
loop,
|
|
44
|
+
mediaDurationInSeconds,
|
|
45
|
+
playbackRate,
|
|
46
|
+
trimAfter,
|
|
47
|
+
trimBefore
|
|
48
|
+
]);
|
|
49
|
+
return loopDisplay;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// src/use-media-in-timeline.ts
|
|
53
|
+
import { useContext, useEffect, useState } from "react";
|
|
54
|
+
import { Internals as Internals2, useCurrentFrame } from "remotion";
|
|
55
|
+
var useMediaInTimeline = ({
|
|
56
|
+
volume,
|
|
57
|
+
mediaVolume,
|
|
58
|
+
src,
|
|
59
|
+
mediaType,
|
|
60
|
+
playbackRate,
|
|
61
|
+
displayName,
|
|
62
|
+
stack,
|
|
63
|
+
showInTimeline,
|
|
64
|
+
premountDisplay,
|
|
65
|
+
postmountDisplay,
|
|
66
|
+
loopDisplay,
|
|
67
|
+
trimBefore,
|
|
68
|
+
trimAfter
|
|
69
|
+
}) => {
|
|
70
|
+
const parentSequence = useContext(Internals2.SequenceContext);
|
|
71
|
+
const startsAt = Internals2.useMediaStartsAt();
|
|
72
|
+
const { registerSequence, unregisterSequence } = useContext(Internals2.SequenceManager);
|
|
73
|
+
const [sequenceId] = useState(() => String(Math.random()));
|
|
74
|
+
const [mediaId] = useState(() => String(Math.random()));
|
|
75
|
+
const frame = useCurrentFrame();
|
|
76
|
+
const {
|
|
77
|
+
volumes,
|
|
78
|
+
duration,
|
|
79
|
+
doesVolumeChange,
|
|
80
|
+
nonce,
|
|
81
|
+
rootId,
|
|
82
|
+
isStudio,
|
|
83
|
+
finalDisplayName
|
|
84
|
+
} = Internals2.useBasicMediaInTimeline({
|
|
85
|
+
volume,
|
|
86
|
+
mediaVolume,
|
|
87
|
+
mediaType,
|
|
88
|
+
src,
|
|
89
|
+
displayName,
|
|
90
|
+
trimBefore,
|
|
91
|
+
trimAfter,
|
|
92
|
+
playbackRate
|
|
93
|
+
});
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
if (!src) {
|
|
96
|
+
throw new Error("No src passed");
|
|
97
|
+
}
|
|
98
|
+
if (!isStudio && window.process?.env?.NODE_ENV !== "test") {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (!showInTimeline) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const loopIteration = loopDisplay ? Math.floor(frame / loopDisplay.durationInFrames) : 0;
|
|
105
|
+
if (loopDisplay) {
|
|
106
|
+
registerSequence({
|
|
107
|
+
type: "sequence",
|
|
108
|
+
premountDisplay,
|
|
109
|
+
postmountDisplay,
|
|
110
|
+
parent: parentSequence?.id ?? null,
|
|
111
|
+
displayName: finalDisplayName,
|
|
112
|
+
rootId,
|
|
113
|
+
showInTimeline: true,
|
|
114
|
+
nonce,
|
|
115
|
+
loopDisplay,
|
|
116
|
+
stack,
|
|
117
|
+
from: 0,
|
|
118
|
+
duration,
|
|
119
|
+
id: sequenceId
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
registerSequence({
|
|
123
|
+
type: mediaType,
|
|
124
|
+
src,
|
|
125
|
+
id: mediaId,
|
|
126
|
+
duration: loopDisplay?.durationInFrames ?? duration,
|
|
127
|
+
from: loopDisplay ? loopIteration * loopDisplay.durationInFrames : 0,
|
|
128
|
+
parent: loopDisplay ? sequenceId : parentSequence?.id ?? null,
|
|
129
|
+
displayName: finalDisplayName,
|
|
130
|
+
rootId,
|
|
131
|
+
volume: volumes,
|
|
132
|
+
showInTimeline: true,
|
|
133
|
+
nonce,
|
|
134
|
+
startMediaFrom: 0 - startsAt,
|
|
135
|
+
doesVolumeChange,
|
|
136
|
+
loopDisplay: undefined,
|
|
137
|
+
playbackRate,
|
|
138
|
+
stack,
|
|
139
|
+
premountDisplay: null,
|
|
140
|
+
postmountDisplay: null
|
|
141
|
+
});
|
|
142
|
+
return () => {
|
|
143
|
+
if (loopDisplay) {
|
|
144
|
+
unregisterSequence(sequenceId);
|
|
145
|
+
}
|
|
146
|
+
unregisterSequence(mediaId);
|
|
147
|
+
};
|
|
148
|
+
}, [
|
|
149
|
+
doesVolumeChange,
|
|
150
|
+
duration,
|
|
151
|
+
finalDisplayName,
|
|
152
|
+
isStudio,
|
|
153
|
+
loopDisplay,
|
|
154
|
+
mediaId,
|
|
155
|
+
mediaType,
|
|
156
|
+
nonce,
|
|
157
|
+
parentSequence?.id,
|
|
158
|
+
playbackRate,
|
|
159
|
+
postmountDisplay,
|
|
160
|
+
premountDisplay,
|
|
161
|
+
registerSequence,
|
|
162
|
+
rootId,
|
|
163
|
+
sequenceId,
|
|
164
|
+
showInTimeline,
|
|
165
|
+
src,
|
|
166
|
+
stack,
|
|
167
|
+
startsAt,
|
|
168
|
+
unregisterSequence,
|
|
169
|
+
volumes,
|
|
170
|
+
frame
|
|
171
|
+
]);
|
|
172
|
+
return {
|
|
173
|
+
id: mediaId
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
|
|
13
177
|
// src/video/media-player.ts
|
|
14
178
|
import {
|
|
15
179
|
ALL_FORMATS,
|
|
@@ -18,7 +182,39 @@ import {
|
|
|
18
182
|
Input,
|
|
19
183
|
UrlSource
|
|
20
184
|
} from "mediabunny";
|
|
21
|
-
import { Internals } from "remotion";
|
|
185
|
+
import { Internals as Internals4 } from "remotion";
|
|
186
|
+
|
|
187
|
+
// src/get-time-in-seconds.ts
|
|
188
|
+
import { Internals as Internals3 } from "remotion";
|
|
189
|
+
var getTimeInSeconds = ({
|
|
190
|
+
loop,
|
|
191
|
+
mediaDurationInSeconds,
|
|
192
|
+
unloopedTimeInSeconds,
|
|
193
|
+
src,
|
|
194
|
+
trimAfter,
|
|
195
|
+
trimBefore,
|
|
196
|
+
fps,
|
|
197
|
+
playbackRate,
|
|
198
|
+
ifNoMediaDuration
|
|
199
|
+
}) => {
|
|
200
|
+
if (mediaDurationInSeconds === null && loop && ifNoMediaDuration === "fail") {
|
|
201
|
+
throw new Error(`Could not determine duration of ${src}, but "loop" was set.`);
|
|
202
|
+
}
|
|
203
|
+
const loopDuration = loop ? Internals3.calculateMediaDuration({
|
|
204
|
+
trimAfter,
|
|
205
|
+
mediaDurationInFrames: mediaDurationInSeconds ? mediaDurationInSeconds * fps : Infinity,
|
|
206
|
+
playbackRate: 1,
|
|
207
|
+
trimBefore
|
|
208
|
+
}) / fps : Infinity;
|
|
209
|
+
const timeInSeconds = unloopedTimeInSeconds * playbackRate % loopDuration;
|
|
210
|
+
if ((trimAfter ?? null) !== null && !loop) {
|
|
211
|
+
const time = (trimAfter - (trimBefore ?? 0)) / fps;
|
|
212
|
+
if (timeInSeconds >= time) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return timeInSeconds + (trimBefore ?? 0) / fps;
|
|
217
|
+
};
|
|
22
218
|
|
|
23
219
|
// src/is-network-error.ts
|
|
24
220
|
function isNetworkError(error) {
|
|
@@ -28,34 +224,6 @@ function isNetworkError(error) {
|
|
|
28
224
|
return false;
|
|
29
225
|
}
|
|
30
226
|
|
|
31
|
-
// src/video/resolve-playback-time.ts
|
|
32
|
-
var resolvePlaybackTime = ({
|
|
33
|
-
absolutePlaybackTimeInSeconds,
|
|
34
|
-
playbackRate,
|
|
35
|
-
loop,
|
|
36
|
-
trimBeforeInSeconds,
|
|
37
|
-
trimAfterInSeconds,
|
|
38
|
-
mediaDurationInSeconds
|
|
39
|
-
}) => {
|
|
40
|
-
const loopAfterPreliminary = loop ? Math.min(trimAfterInSeconds ?? Infinity, mediaDurationInSeconds ?? Infinity) : Infinity;
|
|
41
|
-
const loopAfterConsideringTrimBefore = loopAfterPreliminary - (trimBeforeInSeconds ?? 0);
|
|
42
|
-
const loopAfterConsideringPlaybackRate = loopAfterConsideringTrimBefore / playbackRate;
|
|
43
|
-
const timeConsideringLoop = absolutePlaybackTimeInSeconds % loopAfterConsideringPlaybackRate;
|
|
44
|
-
const time = timeConsideringLoop * playbackRate + (trimBeforeInSeconds ?? 0);
|
|
45
|
-
if (Number.isNaN(time)) {
|
|
46
|
-
console.log({
|
|
47
|
-
absolutePlaybackTimeInSeconds,
|
|
48
|
-
playbackRate,
|
|
49
|
-
loop,
|
|
50
|
-
trimBeforeInSeconds,
|
|
51
|
-
trimAfterInSeconds,
|
|
52
|
-
mediaDurationInSeconds
|
|
53
|
-
});
|
|
54
|
-
throw new Error("Time is NaN");
|
|
55
|
-
}
|
|
56
|
-
return time;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
227
|
// src/video/timeout-utils.ts
|
|
60
228
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
61
229
|
function withTimeout(promise, timeoutMs, errorMessage = "Operation timed out") {
|
|
@@ -93,13 +261,15 @@ class MediaPlayer {
|
|
|
93
261
|
audioBufferIterator = null;
|
|
94
262
|
queuedAudioNodes = new Set;
|
|
95
263
|
gainNode = null;
|
|
264
|
+
currentVolume = 1;
|
|
96
265
|
sharedAudioContext;
|
|
97
266
|
audioSyncAnchor = 0;
|
|
98
267
|
playing = false;
|
|
99
268
|
muted = false;
|
|
100
269
|
loop = false;
|
|
101
|
-
|
|
102
|
-
|
|
270
|
+
fps;
|
|
271
|
+
trimBefore;
|
|
272
|
+
trimAfter;
|
|
103
273
|
animationFrameId = null;
|
|
104
274
|
videoAsyncId = 0;
|
|
105
275
|
audioAsyncId = 0;
|
|
@@ -117,10 +287,11 @@ class MediaPlayer {
|
|
|
117
287
|
logLevel,
|
|
118
288
|
sharedAudioContext,
|
|
119
289
|
loop,
|
|
120
|
-
|
|
121
|
-
|
|
290
|
+
trimBefore,
|
|
291
|
+
trimAfter,
|
|
122
292
|
playbackRate,
|
|
123
|
-
audioStreamIndex
|
|
293
|
+
audioStreamIndex,
|
|
294
|
+
fps
|
|
124
295
|
}) {
|
|
125
296
|
this.canvas = canvas ?? null;
|
|
126
297
|
this.src = src;
|
|
@@ -128,12 +299,13 @@ class MediaPlayer {
|
|
|
128
299
|
this.sharedAudioContext = sharedAudioContext;
|
|
129
300
|
this.playbackRate = playbackRate;
|
|
130
301
|
this.loop = loop;
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
302
|
+
this.trimBefore = trimBefore;
|
|
303
|
+
this.trimAfter = trimAfter;
|
|
133
304
|
this.audioStreamIndex = audioStreamIndex ?? 0;
|
|
305
|
+
this.fps = fps;
|
|
134
306
|
if (canvas) {
|
|
135
307
|
const context = canvas.getContext("2d", {
|
|
136
|
-
alpha:
|
|
308
|
+
alpha: true,
|
|
137
309
|
desynchronized: true
|
|
138
310
|
});
|
|
139
311
|
if (!context) {
|
|
@@ -169,15 +341,15 @@ class MediaPlayer {
|
|
|
169
341
|
if (isNetworkError(err)) {
|
|
170
342
|
throw error;
|
|
171
343
|
}
|
|
172
|
-
|
|
344
|
+
Internals4.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Failed to recognize format for ${this.src}`, error);
|
|
173
345
|
return { type: "unknown-container-format" };
|
|
174
346
|
}
|
|
175
|
-
const [
|
|
347
|
+
const [durationInSeconds, videoTrack, audioTracks] = await Promise.all([
|
|
176
348
|
input.computeDuration(),
|
|
177
349
|
input.getPrimaryVideoTrack(),
|
|
178
350
|
input.getAudioTracks()
|
|
179
351
|
]);
|
|
180
|
-
this.totalDuration =
|
|
352
|
+
this.totalDuration = durationInSeconds;
|
|
181
353
|
const audioTrack = audioTracks[this.audioStreamIndex] ?? null;
|
|
182
354
|
if (!videoTrack && !audioTrack) {
|
|
183
355
|
return { type: "no-tracks" };
|
|
@@ -189,7 +361,8 @@ class MediaPlayer {
|
|
|
189
361
|
}
|
|
190
362
|
this.canvasSink = new CanvasSink(videoTrack, {
|
|
191
363
|
poolSize: 2,
|
|
192
|
-
fit: "contain"
|
|
364
|
+
fit: "contain",
|
|
365
|
+
alpha: true
|
|
193
366
|
});
|
|
194
367
|
this.canvas.width = videoTrack.displayWidth;
|
|
195
368
|
this.canvas.height = videoTrack.displayHeight;
|
|
@@ -199,14 +372,21 @@ class MediaPlayer {
|
|
|
199
372
|
this.gainNode = this.sharedAudioContext.createGain();
|
|
200
373
|
this.gainNode.connect(this.sharedAudioContext.destination);
|
|
201
374
|
}
|
|
202
|
-
const startTime =
|
|
203
|
-
|
|
375
|
+
const startTime = getTimeInSeconds({
|
|
376
|
+
unloopedTimeInSeconds: startTimeUnresolved,
|
|
204
377
|
playbackRate: this.playbackRate,
|
|
205
378
|
loop: this.loop,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
mediaDurationInSeconds: this.totalDuration
|
|
379
|
+
trimBefore: this.trimBefore,
|
|
380
|
+
trimAfter: this.trimAfter,
|
|
381
|
+
mediaDurationInSeconds: this.totalDuration,
|
|
382
|
+
fps: this.fps,
|
|
383
|
+
ifNoMediaDuration: "infinity",
|
|
384
|
+
src: this.src
|
|
209
385
|
});
|
|
386
|
+
if (startTime === null) {
|
|
387
|
+
this.clearCanvas();
|
|
388
|
+
return { type: "success", durationInSeconds: this.totalDuration };
|
|
389
|
+
}
|
|
210
390
|
if (this.sharedAudioContext) {
|
|
211
391
|
this.audioSyncAnchor = this.sharedAudioContext.currentTime - startTime;
|
|
212
392
|
}
|
|
@@ -216,17 +396,22 @@ class MediaPlayer {
|
|
|
216
396
|
this.startVideoIterator(startTime)
|
|
217
397
|
]);
|
|
218
398
|
this.startRenderLoop();
|
|
219
|
-
return { type: "success" };
|
|
399
|
+
return { type: "success", durationInSeconds };
|
|
220
400
|
} catch (error) {
|
|
221
401
|
const err = error;
|
|
222
402
|
if (isNetworkError(err)) {
|
|
223
|
-
|
|
403
|
+
Internals4.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Network/CORS error for ${this.src}`, err);
|
|
224
404
|
return { type: "network-error" };
|
|
225
405
|
}
|
|
226
|
-
|
|
406
|
+
Internals4.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to initialize", error);
|
|
227
407
|
throw error;
|
|
228
408
|
}
|
|
229
409
|
}
|
|
410
|
+
clearCanvas() {
|
|
411
|
+
if (this.context && this.canvas) {
|
|
412
|
+
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
230
415
|
cleanupAudioQueue() {
|
|
231
416
|
for (const node of this.queuedAudioNodes) {
|
|
232
417
|
node.stop();
|
|
@@ -243,16 +428,24 @@ class MediaPlayer {
|
|
|
243
428
|
async seekTo(time) {
|
|
244
429
|
if (!this.isReady())
|
|
245
430
|
return;
|
|
246
|
-
const newTime =
|
|
247
|
-
|
|
431
|
+
const newTime = getTimeInSeconds({
|
|
432
|
+
unloopedTimeInSeconds: time,
|
|
248
433
|
playbackRate: this.playbackRate,
|
|
249
434
|
loop: this.loop,
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
mediaDurationInSeconds: this.totalDuration
|
|
435
|
+
trimBefore: this.trimBefore,
|
|
436
|
+
trimAfter: this.trimAfter,
|
|
437
|
+
mediaDurationInSeconds: this.totalDuration ?? null,
|
|
438
|
+
fps: this.fps,
|
|
439
|
+
ifNoMediaDuration: "infinity",
|
|
440
|
+
src: this.src
|
|
253
441
|
});
|
|
442
|
+
if (newTime === null) {
|
|
443
|
+
this.clearCanvas();
|
|
444
|
+
await this.cleanAudioIteratorAndNodes();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
254
447
|
const currentPlaybackTime = this.getPlaybackTime();
|
|
255
|
-
const isSignificantSeek = Math.abs(newTime - currentPlaybackTime) > SEEK_THRESHOLD;
|
|
448
|
+
const isSignificantSeek = currentPlaybackTime === null || Math.abs(newTime - currentPlaybackTime) > SEEK_THRESHOLD;
|
|
256
449
|
if (isSignificantSeek) {
|
|
257
450
|
this.nextFrame = null;
|
|
258
451
|
this.audioSyncAnchor = this.sharedAudioContext.currentTime - newTime;
|
|
@@ -286,8 +479,8 @@ class MediaPlayer {
|
|
|
286
479
|
}
|
|
287
480
|
setMuted(muted) {
|
|
288
481
|
this.muted = muted;
|
|
289
|
-
if (
|
|
290
|
-
this.
|
|
482
|
+
if (this.gainNode) {
|
|
483
|
+
this.gainNode.gain.value = muted ? 0 : this.currentVolume;
|
|
291
484
|
}
|
|
292
485
|
}
|
|
293
486
|
setVolume(volume) {
|
|
@@ -295,11 +488,17 @@ class MediaPlayer {
|
|
|
295
488
|
return;
|
|
296
489
|
}
|
|
297
490
|
const appliedVolume = Math.max(0, volume);
|
|
298
|
-
this.
|
|
491
|
+
this.currentVolume = appliedVolume;
|
|
492
|
+
if (!this.muted) {
|
|
493
|
+
this.gainNode.gain.value = appliedVolume;
|
|
494
|
+
}
|
|
299
495
|
}
|
|
300
496
|
setPlaybackRate(rate) {
|
|
301
497
|
this.playbackRate = rate;
|
|
302
498
|
}
|
|
499
|
+
setFps(fps) {
|
|
500
|
+
this.fps = fps;
|
|
501
|
+
}
|
|
303
502
|
setLoop(loop) {
|
|
304
503
|
this.loop = loop;
|
|
305
504
|
}
|
|
@@ -311,15 +510,7 @@ class MediaPlayer {
|
|
|
311
510
|
this.videoAsyncId++;
|
|
312
511
|
}
|
|
313
512
|
getPlaybackTime() {
|
|
314
|
-
|
|
315
|
-
return resolvePlaybackTime({
|
|
316
|
-
absolutePlaybackTimeInSeconds: absoluteTime,
|
|
317
|
-
playbackRate: this.playbackRate,
|
|
318
|
-
loop: this.loop,
|
|
319
|
-
trimBeforeInSeconds: this.trimBeforeSeconds,
|
|
320
|
-
trimAfterInSeconds: this.trimAfterSeconds,
|
|
321
|
-
mediaDurationInSeconds: this.totalDuration
|
|
322
|
-
});
|
|
513
|
+
return this.sharedAudioContext.currentTime - this.audioSyncAnchor;
|
|
323
514
|
}
|
|
324
515
|
scheduleAudioChunk(buffer, mediaTimestamp) {
|
|
325
516
|
const targetTime = mediaTimestamp + this.audioSyncAnchor;
|
|
@@ -384,10 +575,15 @@ class MediaPlayer {
|
|
|
384
575
|
}
|
|
385
576
|
};
|
|
386
577
|
shouldRenderFrame() {
|
|
387
|
-
|
|
578
|
+
const playbackTime = this.getPlaybackTime();
|
|
579
|
+
if (playbackTime === null) {
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
return !this.isBuffering && this.canRenderVideo() && this.nextFrame !== null && this.nextFrame.timestamp <= playbackTime;
|
|
388
583
|
}
|
|
389
584
|
drawCurrentFrame() {
|
|
390
585
|
if (this.context && this.nextFrame) {
|
|
586
|
+
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
391
587
|
this.context.drawImage(this.nextFrame.canvas, 0, 0);
|
|
392
588
|
}
|
|
393
589
|
if (this.onVideoFrameCallback && this.canvas) {
|
|
@@ -408,7 +604,7 @@ class MediaPlayer {
|
|
|
408
604
|
this.audioBufferIterator = this.audioSink.buffers(startFromSecond);
|
|
409
605
|
this.runAudioIterator(startFromSecond, currentAsyncId);
|
|
410
606
|
} catch (error) {
|
|
411
|
-
|
|
607
|
+
Internals4.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to start audio iterator", error);
|
|
412
608
|
}
|
|
413
609
|
};
|
|
414
610
|
startVideoIterator = async (timeToSeek) => {
|
|
@@ -428,7 +624,7 @@ class MediaPlayer {
|
|
|
428
624
|
return;
|
|
429
625
|
}
|
|
430
626
|
if (firstFrame && this.context) {
|
|
431
|
-
|
|
627
|
+
Internals4.Log.trace({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Drew initial frame ${firstFrame.timestamp.toFixed(3)}s`);
|
|
432
628
|
this.context.drawImage(firstFrame.canvas, 0, 0);
|
|
433
629
|
if (this.onVideoFrameCallback && this.canvas) {
|
|
434
630
|
this.onVideoFrameCallback(this.canvas);
|
|
@@ -436,10 +632,10 @@ class MediaPlayer {
|
|
|
436
632
|
}
|
|
437
633
|
this.nextFrame = secondFrame ?? null;
|
|
438
634
|
if (secondFrame) {
|
|
439
|
-
|
|
635
|
+
Internals4.Log.trace({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Buffered next frame ${secondFrame.timestamp.toFixed(3)}s`);
|
|
440
636
|
}
|
|
441
637
|
} catch (error) {
|
|
442
|
-
|
|
638
|
+
Internals4.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to start video iterator", error);
|
|
443
639
|
}
|
|
444
640
|
};
|
|
445
641
|
updateNextFrame = async () => {
|
|
@@ -452,16 +648,20 @@ class MediaPlayer {
|
|
|
452
648
|
if (!newNextFrame) {
|
|
453
649
|
break;
|
|
454
650
|
}
|
|
455
|
-
|
|
651
|
+
const playbackTime = this.getPlaybackTime();
|
|
652
|
+
if (playbackTime === null) {
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
if (newNextFrame.timestamp <= playbackTime) {
|
|
456
656
|
continue;
|
|
457
657
|
} else {
|
|
458
658
|
this.nextFrame = newNextFrame;
|
|
459
|
-
|
|
659
|
+
Internals4.Log.trace({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Buffered next frame ${newNextFrame.timestamp.toFixed(3)}s`);
|
|
460
660
|
break;
|
|
461
661
|
}
|
|
462
662
|
}
|
|
463
663
|
} catch (error) {
|
|
464
|
-
|
|
664
|
+
Internals4.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to update next frame", error);
|
|
465
665
|
}
|
|
466
666
|
};
|
|
467
667
|
bufferingStartedAtMs = null;
|
|
@@ -486,7 +686,7 @@ class MediaPlayer {
|
|
|
486
686
|
const minTimeElapsed = bufferingDuration >= this.minBufferingTimeoutMs;
|
|
487
687
|
const bufferHealthy = currentBufferDuration >= this.HEALTHY_BUFER_THRESHOLD_SECONDS;
|
|
488
688
|
if (minTimeElapsed && bufferHealthy) {
|
|
489
|
-
|
|
689
|
+
Internals4.Log.trace({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Resuming from buffering after ${bufferingDuration}ms - buffer recovered`);
|
|
490
690
|
this.setBufferingState(false);
|
|
491
691
|
}
|
|
492
692
|
}
|
|
@@ -497,7 +697,7 @@ class MediaPlayer {
|
|
|
497
697
|
const bufferingDuration = now - this.bufferingStartedAtMs;
|
|
498
698
|
const forceTimeout = bufferingDuration > this.minBufferingTimeoutMs * 10;
|
|
499
699
|
if (forceTimeout) {
|
|
500
|
-
|
|
700
|
+
Internals4.Log.trace({ logLevel: this.logLevel, tag: "@remotion/media" }, `[MediaPlayer] Force resuming from buffering after ${bufferingDuration}ms`);
|
|
501
701
|
this.setBufferingState(false);
|
|
502
702
|
}
|
|
503
703
|
}
|
|
@@ -528,7 +728,7 @@ class MediaPlayer {
|
|
|
528
728
|
totalBufferDuration += duration;
|
|
529
729
|
this.audioBufferHealth = Math.max(0, totalBufferDuration / this.playbackRate);
|
|
530
730
|
this.maybeResumeFromBuffering(totalBufferDuration / this.playbackRate);
|
|
531
|
-
if (this.playing
|
|
731
|
+
if (this.playing) {
|
|
532
732
|
if (isFirstBuffer) {
|
|
533
733
|
this.audioSyncAnchor = this.sharedAudioContext.currentTime - timestamp;
|
|
534
734
|
isFirstBuffer = false;
|
|
@@ -538,10 +738,15 @@ class MediaPlayer {
|
|
|
538
738
|
}
|
|
539
739
|
this.scheduleAudioChunk(buffer, timestamp);
|
|
540
740
|
}
|
|
541
|
-
|
|
741
|
+
const playbackTime = this.getPlaybackTime();
|
|
742
|
+
if (playbackTime === null) {
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
if (timestamp - playbackTime >= 1) {
|
|
542
746
|
await new Promise((resolve) => {
|
|
543
747
|
const check = () => {
|
|
544
|
-
|
|
748
|
+
const currentPlaybackTime = this.getPlaybackTime();
|
|
749
|
+
if (currentPlaybackTime !== null && timestamp - currentPlaybackTime < 1) {
|
|
545
750
|
resolve();
|
|
546
751
|
} else {
|
|
547
752
|
requestAnimationFrame(check);
|
|
@@ -552,7 +757,7 @@ class MediaPlayer {
|
|
|
552
757
|
}
|
|
553
758
|
}
|
|
554
759
|
} catch (error) {
|
|
555
|
-
|
|
760
|
+
Internals4.Log.error({ logLevel: this.logLevel, tag: "@remotion/media" }, "[MediaPlayer] Failed to run audio iterator", error);
|
|
556
761
|
}
|
|
557
762
|
};
|
|
558
763
|
}
|
|
@@ -569,9 +774,8 @@ var {
|
|
|
569
774
|
evaluateVolume,
|
|
570
775
|
warnAboutTooHighVolume,
|
|
571
776
|
usePreload,
|
|
572
|
-
useMediaInTimeline,
|
|
573
777
|
SequenceContext
|
|
574
|
-
} =
|
|
778
|
+
} = Internals5;
|
|
575
779
|
var NewAudioForPreview = ({
|
|
576
780
|
src,
|
|
577
781
|
playbackRate,
|
|
@@ -591,14 +795,14 @@ var NewAudioForPreview = ({
|
|
|
591
795
|
fallbackHtml5AudioProps
|
|
592
796
|
}) => {
|
|
593
797
|
const videoConfig = useUnsafeVideoConfig();
|
|
594
|
-
const frame =
|
|
798
|
+
const frame = useCurrentFrame2();
|
|
595
799
|
const mediaPlayerRef = useRef(null);
|
|
596
|
-
const [mediaPlayerReady, setMediaPlayerReady] =
|
|
597
|
-
const [shouldFallbackToNativeAudio, setShouldFallbackToNativeAudio] =
|
|
800
|
+
const [mediaPlayerReady, setMediaPlayerReady] = useState2(false);
|
|
801
|
+
const [shouldFallbackToNativeAudio, setShouldFallbackToNativeAudio] = useState2(false);
|
|
598
802
|
const [playing] = Timeline.usePlayingState();
|
|
599
|
-
const timelineContext =
|
|
803
|
+
const timelineContext = useContext2(Timeline.TimelineContext);
|
|
600
804
|
const globalPlaybackRate = timelineContext.playbackRate;
|
|
601
|
-
const sharedAudioContext =
|
|
805
|
+
const sharedAudioContext = useContext2(SharedAudioContext);
|
|
602
806
|
const buffer = useBufferState();
|
|
603
807
|
const delayHandleRef = useRef(null);
|
|
604
808
|
const [mediaMuted] = useMediaMutedState();
|
|
@@ -620,8 +824,14 @@ var NewAudioForPreview = ({
|
|
|
620
824
|
const currentTimeRef = useRef(currentTime);
|
|
621
825
|
currentTimeRef.current = currentTime;
|
|
622
826
|
const preloadedSrc = usePreload(src);
|
|
623
|
-
const
|
|
624
|
-
const
|
|
827
|
+
const parentSequence = useContext2(SequenceContext);
|
|
828
|
+
const loopDisplay = useLoopDisplay({
|
|
829
|
+
loop,
|
|
830
|
+
mediaDurationInSeconds: videoConfig.durationInFrames,
|
|
831
|
+
playbackRate,
|
|
832
|
+
trimAfter,
|
|
833
|
+
trimBefore
|
|
834
|
+
});
|
|
625
835
|
useMediaInTimeline({
|
|
626
836
|
volume,
|
|
627
837
|
mediaVolume,
|
|
@@ -629,13 +839,15 @@ var NewAudioForPreview = ({
|
|
|
629
839
|
src,
|
|
630
840
|
playbackRate,
|
|
631
841
|
displayName: name ?? null,
|
|
632
|
-
id: timelineId,
|
|
633
842
|
stack,
|
|
634
843
|
showInTimeline,
|
|
635
844
|
premountDisplay: parentSequence?.premountDisplay ?? null,
|
|
636
|
-
postmountDisplay: parentSequence?.postmountDisplay ?? null
|
|
845
|
+
postmountDisplay: parentSequence?.postmountDisplay ?? null,
|
|
846
|
+
loopDisplay,
|
|
847
|
+
trimAfter,
|
|
848
|
+
trimBefore
|
|
637
849
|
});
|
|
638
|
-
|
|
850
|
+
useEffect2(() => {
|
|
639
851
|
if (!sharedAudioContext)
|
|
640
852
|
return;
|
|
641
853
|
if (!sharedAudioContext.audioContext)
|
|
@@ -646,8 +858,9 @@ var NewAudioForPreview = ({
|
|
|
646
858
|
logLevel,
|
|
647
859
|
sharedAudioContext: sharedAudioContext.audioContext,
|
|
648
860
|
loop,
|
|
649
|
-
|
|
650
|
-
|
|
861
|
+
trimAfter,
|
|
862
|
+
trimBefore,
|
|
863
|
+
fps: videoConfig.fps,
|
|
651
864
|
canvas: null,
|
|
652
865
|
playbackRate,
|
|
653
866
|
audioStreamIndex: audioStreamIndex ?? 0
|
|
@@ -658,7 +871,7 @@ var NewAudioForPreview = ({
|
|
|
658
871
|
if (disallowFallbackToHtml5Audio) {
|
|
659
872
|
throw new Error(`Unknown container format ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
|
|
660
873
|
}
|
|
661
|
-
|
|
874
|
+
Internals5.Log.warn({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Html5Audio>`);
|
|
662
875
|
setShouldFallbackToNativeAudio(true);
|
|
663
876
|
return;
|
|
664
877
|
}
|
|
@@ -666,7 +879,7 @@ var NewAudioForPreview = ({
|
|
|
666
879
|
if (disallowFallbackToHtml5Audio) {
|
|
667
880
|
throw new Error(`Network error fetching ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
|
|
668
881
|
}
|
|
669
|
-
|
|
882
|
+
Internals5.Log.warn({ logLevel, tag: "@remotion/media" }, `Network error fetching ${preloadedSrc}, falling back to <Html5Audio>`);
|
|
670
883
|
setShouldFallbackToNativeAudio(true);
|
|
671
884
|
return;
|
|
672
885
|
}
|
|
@@ -674,7 +887,7 @@ var NewAudioForPreview = ({
|
|
|
674
887
|
if (disallowFallbackToHtml5Audio) {
|
|
675
888
|
throw new Error(`Cannot decode ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
|
|
676
889
|
}
|
|
677
|
-
|
|
890
|
+
Internals5.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${preloadedSrc}, falling back to <Html5Audio>`);
|
|
678
891
|
setShouldFallbackToNativeAudio(true);
|
|
679
892
|
return;
|
|
680
893
|
}
|
|
@@ -682,20 +895,20 @@ var NewAudioForPreview = ({
|
|
|
682
895
|
if (disallowFallbackToHtml5Audio) {
|
|
683
896
|
throw new Error(`No video or audio tracks found for ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
|
|
684
897
|
}
|
|
685
|
-
|
|
898
|
+
Internals5.Log.warn({ logLevel, tag: "@remotion/media" }, `No video or audio tracks found for ${preloadedSrc}, falling back to <Html5Audio>`);
|
|
686
899
|
setShouldFallbackToNativeAudio(true);
|
|
687
900
|
return;
|
|
688
901
|
}
|
|
689
902
|
if (result.type === "success") {
|
|
690
903
|
setMediaPlayerReady(true);
|
|
691
|
-
|
|
904
|
+
Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, `[NewAudioForPreview] MediaPlayer initialized successfully`);
|
|
692
905
|
}
|
|
693
906
|
}).catch((error) => {
|
|
694
|
-
|
|
907
|
+
Internals5.Log.error({ logLevel, tag: "@remotion/media" }, "[NewAudioForPreview] Failed to initialize MediaPlayer", error);
|
|
695
908
|
setShouldFallbackToNativeAudio(true);
|
|
696
909
|
});
|
|
697
910
|
} catch (error) {
|
|
698
|
-
|
|
911
|
+
Internals5.Log.error({ logLevel, tag: "@remotion/media" }, "[NewAudioForPreview] MediaPlayer initialization failed", error);
|
|
699
912
|
setShouldFallbackToNativeAudio(true);
|
|
700
913
|
}
|
|
701
914
|
return () => {
|
|
@@ -704,7 +917,7 @@ var NewAudioForPreview = ({
|
|
|
704
917
|
delayHandleRef.current = null;
|
|
705
918
|
}
|
|
706
919
|
if (mediaPlayerRef.current) {
|
|
707
|
-
|
|
920
|
+
Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, `[NewAudioForPreview] Disposing MediaPlayer`);
|
|
708
921
|
mediaPlayerRef.current.dispose();
|
|
709
922
|
mediaPlayerRef.current = null;
|
|
710
923
|
}
|
|
@@ -724,62 +937,69 @@ var NewAudioForPreview = ({
|
|
|
724
937
|
audioStreamIndex,
|
|
725
938
|
disallowFallbackToHtml5Audio
|
|
726
939
|
]);
|
|
727
|
-
|
|
940
|
+
useEffect2(() => {
|
|
728
941
|
const audioPlayer = mediaPlayerRef.current;
|
|
729
942
|
if (!audioPlayer)
|
|
730
943
|
return;
|
|
731
944
|
if (playing) {
|
|
732
945
|
audioPlayer.play().catch((error) => {
|
|
733
|
-
|
|
946
|
+
Internals5.Log.error({ logLevel, tag: "@remotion/media" }, "[NewAudioForPreview] Failed to play", error);
|
|
734
947
|
});
|
|
735
948
|
} else {
|
|
736
949
|
audioPlayer.pause();
|
|
737
950
|
}
|
|
738
951
|
}, [playing, logLevel, mediaPlayerReady]);
|
|
739
|
-
|
|
952
|
+
useEffect2(() => {
|
|
740
953
|
const audioPlayer = mediaPlayerRef.current;
|
|
741
954
|
if (!audioPlayer || !mediaPlayerReady)
|
|
742
955
|
return;
|
|
743
956
|
audioPlayer.seekTo(currentTime);
|
|
744
|
-
|
|
957
|
+
Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, `[NewAudioForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
745
958
|
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
746
|
-
|
|
959
|
+
useEffect2(() => {
|
|
747
960
|
const audioPlayer = mediaPlayerRef.current;
|
|
748
961
|
if (!audioPlayer || !mediaPlayerReady)
|
|
749
962
|
return;
|
|
750
963
|
audioPlayer.onBufferingChange((newBufferingState) => {
|
|
751
964
|
if (newBufferingState && !delayHandleRef.current) {
|
|
752
965
|
delayHandleRef.current = buffer.delayPlayback();
|
|
753
|
-
|
|
966
|
+
Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, "[NewAudioForPreview] MediaPlayer buffering - blocking Remotion playback");
|
|
754
967
|
} else if (!newBufferingState && delayHandleRef.current) {
|
|
755
968
|
delayHandleRef.current.unblock();
|
|
756
969
|
delayHandleRef.current = null;
|
|
757
|
-
|
|
970
|
+
Internals5.Log.trace({ logLevel, tag: "@remotion/media" }, "[NewAudioForPreview] MediaPlayer unbuffering - unblocking Remotion playback");
|
|
758
971
|
}
|
|
759
972
|
});
|
|
760
973
|
}, [mediaPlayerReady, buffer, logLevel]);
|
|
761
974
|
const effectiveMuted = muted || mediaMuted || userPreferredVolume <= 0;
|
|
762
|
-
|
|
975
|
+
useEffect2(() => {
|
|
763
976
|
const audioPlayer = mediaPlayerRef.current;
|
|
764
977
|
if (!audioPlayer || !mediaPlayerReady)
|
|
765
978
|
return;
|
|
766
979
|
audioPlayer.setMuted(effectiveMuted);
|
|
767
980
|
}, [effectiveMuted, mediaPlayerReady]);
|
|
768
|
-
|
|
981
|
+
useEffect2(() => {
|
|
769
982
|
const audioPlayer = mediaPlayerRef.current;
|
|
770
983
|
if (!audioPlayer || !mediaPlayerReady) {
|
|
771
984
|
return;
|
|
772
985
|
}
|
|
773
986
|
audioPlayer.setVolume(userPreferredVolume);
|
|
774
|
-
}, [userPreferredVolume, mediaPlayerReady
|
|
775
|
-
const effectivePlaybackRate =
|
|
776
|
-
|
|
987
|
+
}, [userPreferredVolume, mediaPlayerReady]);
|
|
988
|
+
const effectivePlaybackRate = useMemo2(() => playbackRate * globalPlaybackRate, [playbackRate, globalPlaybackRate]);
|
|
989
|
+
useEffect2(() => {
|
|
777
990
|
const audioPlayer = mediaPlayerRef.current;
|
|
778
991
|
if (!audioPlayer || !mediaPlayerReady) {
|
|
779
992
|
return;
|
|
780
993
|
}
|
|
781
994
|
audioPlayer.setPlaybackRate(effectivePlaybackRate);
|
|
782
|
-
}, [effectivePlaybackRate, mediaPlayerReady
|
|
995
|
+
}, [effectivePlaybackRate, mediaPlayerReady]);
|
|
996
|
+
useEffect2(() => {
|
|
997
|
+
const audioPlayer = mediaPlayerRef.current;
|
|
998
|
+
if (!audioPlayer || !mediaPlayerReady) {
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
audioPlayer.setFps(videoConfig.fps);
|
|
1002
|
+
}, [videoConfig.fps, mediaPlayerReady]);
|
|
783
1003
|
if (shouldFallbackToNativeAudio && !disallowFallbackToHtml5Audio) {
|
|
784
1004
|
return /* @__PURE__ */ jsx(RemotionAudio, {
|
|
785
1005
|
src,
|
|
@@ -841,13 +1061,13 @@ var AudioForPreview = ({
|
|
|
841
1061
|
};
|
|
842
1062
|
|
|
843
1063
|
// src/audio/audio-for-rendering.tsx
|
|
844
|
-
import { useContext as
|
|
1064
|
+
import { useContext as useContext3, useLayoutEffect, useMemo as useMemo3, useState as useState3 } from "react";
|
|
845
1065
|
import {
|
|
846
|
-
Audio,
|
|
847
1066
|
cancelRender as cancelRender2,
|
|
848
|
-
|
|
1067
|
+
Html5Audio,
|
|
1068
|
+
Internals as Internals12,
|
|
849
1069
|
random,
|
|
850
|
-
useCurrentFrame as
|
|
1070
|
+
useCurrentFrame as useCurrentFrame3,
|
|
851
1071
|
useDelayRender,
|
|
852
1072
|
useRemotionEnvironment
|
|
853
1073
|
} from "remotion";
|
|
@@ -976,13 +1196,13 @@ var frameForVolumeProp = ({
|
|
|
976
1196
|
};
|
|
977
1197
|
|
|
978
1198
|
// src/caches.ts
|
|
979
|
-
import { cancelRender, Internals as
|
|
1199
|
+
import { cancelRender, Internals as Internals10 } from "remotion";
|
|
980
1200
|
|
|
981
1201
|
// src/audio-extraction/audio-manager.ts
|
|
982
|
-
import { Internals as
|
|
1202
|
+
import { Internals as Internals7 } from "remotion";
|
|
983
1203
|
|
|
984
1204
|
// src/audio-extraction/audio-iterator.ts
|
|
985
|
-
import { Internals as
|
|
1205
|
+
import { Internals as Internals6 } from "remotion";
|
|
986
1206
|
|
|
987
1207
|
// src/audio-extraction/audio-cache.ts
|
|
988
1208
|
var makeAudioCache = () => {
|
|
@@ -1060,7 +1280,7 @@ var warnAboutMatroskaOnce = (src, logLevel) => {
|
|
|
1060
1280
|
return;
|
|
1061
1281
|
}
|
|
1062
1282
|
warned[src] = true;
|
|
1063
|
-
|
|
1283
|
+
Internals6.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`);
|
|
1064
1284
|
};
|
|
1065
1285
|
var makeAudioIterator = ({
|
|
1066
1286
|
audioSampleSink,
|
|
@@ -1128,7 +1348,7 @@ var makeAudioIterator = ({
|
|
|
1128
1348
|
if (openTimestamps.length > 0) {
|
|
1129
1349
|
const first = openTimestamps[0];
|
|
1130
1350
|
const last = openTimestamps[openTimestamps.length - 1];
|
|
1131
|
-
|
|
1351
|
+
Internals6.Log.verbose({ logLevel, tag: "@remotion/media" }, "Open audio samples for src", src, `${first.toFixed(3)}...${last.toFixed(3)}`);
|
|
1132
1352
|
}
|
|
1133
1353
|
};
|
|
1134
1354
|
const getCacheStats = () => {
|
|
@@ -1225,7 +1445,7 @@ var makeAudioManager = () => {
|
|
|
1225
1445
|
if (seenKeys.has(key)) {
|
|
1226
1446
|
iterator.prepareForDeletion();
|
|
1227
1447
|
iterators.splice(iterators.indexOf(iterator), 1);
|
|
1228
|
-
|
|
1448
|
+
Internals7.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted duplicate iterator for ${iterator.src}`);
|
|
1229
1449
|
}
|
|
1230
1450
|
seenKeys.add(key);
|
|
1231
1451
|
}
|
|
@@ -1307,7 +1527,22 @@ var makeAudioManager = () => {
|
|
|
1307
1527
|
};
|
|
1308
1528
|
|
|
1309
1529
|
// src/video-extraction/keyframe-manager.ts
|
|
1310
|
-
import { Internals as
|
|
1530
|
+
import { Internals as Internals9 } from "remotion";
|
|
1531
|
+
|
|
1532
|
+
// src/browser-can-use-webgl2.ts
|
|
1533
|
+
var browserCanUseWebGl2 = null;
|
|
1534
|
+
var browserCanUseWebGl2Uncached = () => {
|
|
1535
|
+
const canvas = new OffscreenCanvas(1, 1);
|
|
1536
|
+
const context = canvas.getContext("webgl2");
|
|
1537
|
+
return context !== null;
|
|
1538
|
+
};
|
|
1539
|
+
var canBrowserUseWebGl2 = () => {
|
|
1540
|
+
if (browserCanUseWebGl2 !== null) {
|
|
1541
|
+
return browserCanUseWebGl2;
|
|
1542
|
+
}
|
|
1543
|
+
browserCanUseWebGl2 = browserCanUseWebGl2Uncached();
|
|
1544
|
+
return browserCanUseWebGl2;
|
|
1545
|
+
};
|
|
1311
1546
|
|
|
1312
1547
|
// src/render-timestamp-range.ts
|
|
1313
1548
|
var renderTimestampRange = (timestamps) => {
|
|
@@ -1333,7 +1568,7 @@ import {
|
|
|
1333
1568
|
} from "mediabunny";
|
|
1334
1569
|
|
|
1335
1570
|
// src/video-extraction/keyframe-bank.ts
|
|
1336
|
-
import { Internals as
|
|
1571
|
+
import { Internals as Internals8 } from "remotion";
|
|
1337
1572
|
var roundTo4Digits = (timestamp) => {
|
|
1338
1573
|
return Math.round(timestamp * 1000) / 1000;
|
|
1339
1574
|
};
|
|
@@ -1343,7 +1578,7 @@ var makeKeyframeBank = ({
|
|
|
1343
1578
|
sampleIterator,
|
|
1344
1579
|
logLevel: parentLogLevel
|
|
1345
1580
|
}) => {
|
|
1346
|
-
|
|
1581
|
+
Internals8.Log.verbose({ logLevel: parentLogLevel, tag: "@remotion/media" }, `Creating keyframe bank from ${startTimestampInSeconds}sec to ${endTimestampInSeconds}sec`);
|
|
1347
1582
|
const frames = {};
|
|
1348
1583
|
const frameTimestamps = [];
|
|
1349
1584
|
let lastUsed = Date.now();
|
|
@@ -1401,7 +1636,7 @@ var makeKeyframeBank = ({
|
|
|
1401
1636
|
return await getFrameFromTimestamp(timestamp) !== null;
|
|
1402
1637
|
};
|
|
1403
1638
|
const prepareForDeletion = (logLevel) => {
|
|
1404
|
-
|
|
1639
|
+
Internals8.Log.verbose({ logLevel, tag: "@remotion/media" }, `Preparing for deletion of keyframe bank from ${startTimestampInSeconds}sec to ${endTimestampInSeconds}sec`);
|
|
1405
1640
|
sampleIterator.return().then((result) => {
|
|
1406
1641
|
if (result.value) {
|
|
1407
1642
|
result.value.close();
|
|
@@ -1441,7 +1676,7 @@ var makeKeyframeBank = ({
|
|
|
1441
1676
|
}
|
|
1442
1677
|
}
|
|
1443
1678
|
if (deletedTimestamps.length > 0) {
|
|
1444
|
-
|
|
1679
|
+
Internals8.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)}`);
|
|
1445
1680
|
}
|
|
1446
1681
|
};
|
|
1447
1682
|
const getOpenFrameCount = () => {
|
|
@@ -1617,10 +1852,10 @@ var makeKeyframeManager = () => {
|
|
|
1617
1852
|
if (size === 0) {
|
|
1618
1853
|
continue;
|
|
1619
1854
|
}
|
|
1620
|
-
|
|
1855
|
+
Internals9.Log.verbose({ logLevel, tag: "@remotion/media" }, `Open frames for src ${src}: ${renderTimestampRange(timestamps)}`);
|
|
1621
1856
|
}
|
|
1622
1857
|
}
|
|
1623
|
-
|
|
1858
|
+
Internals9.Log.verbose({ logLevel, tag: "@remotion/media" }, `Video cache stats: ${count} open frames, ${totalSize} bytes`);
|
|
1624
1859
|
};
|
|
1625
1860
|
const getCacheStats = async () => {
|
|
1626
1861
|
let count = 0;
|
|
@@ -1661,7 +1896,7 @@ var makeKeyframeManager = () => {
|
|
|
1661
1896
|
if (mostInThePastBank) {
|
|
1662
1897
|
await mostInThePastBank.prepareForDeletion(logLevel);
|
|
1663
1898
|
delete sources[mostInThePastSrc][mostInThePastBank.startTimestampInSeconds];
|
|
1664
|
-
|
|
1899
|
+
Internals9.Log.verbose({ logLevel, tag: "@remotion/media" }, `Deleted frames for src ${mostInThePastSrc} from ${mostInThePastBank.startTimestampInSeconds}sec to ${mostInThePastBank.endTimestampInSeconds}sec to free up memory.`);
|
|
1665
1900
|
}
|
|
1666
1901
|
};
|
|
1667
1902
|
const ensureToStayUnderMaxCacheSize = async (logLevel) => {
|
|
@@ -1687,7 +1922,7 @@ var makeKeyframeManager = () => {
|
|
|
1687
1922
|
const { endTimestampInSeconds, startTimestampInSeconds } = bank;
|
|
1688
1923
|
if (endTimestampInSeconds < threshold) {
|
|
1689
1924
|
await bank.prepareForDeletion(logLevel);
|
|
1690
|
-
|
|
1925
|
+
Internals9.Log.verbose({ logLevel, tag: "@remotion/media" }, `[Video] Cleared frames for src ${src} from ${startTimestampInSeconds}sec to ${endTimestampInSeconds}sec`);
|
|
1691
1926
|
delete sources[src][startTimeInSeconds];
|
|
1692
1927
|
} else {
|
|
1693
1928
|
bank.deleteFramesBeforeTimestamp({
|
|
@@ -1709,6 +1944,10 @@ var makeKeyframeManager = () => {
|
|
|
1709
1944
|
const startPacket = await packetSink.getKeyPacket(timestamp, {
|
|
1710
1945
|
verifyKeyPackets: true
|
|
1711
1946
|
});
|
|
1947
|
+
const hasAlpha = startPacket?.sideData.alpha;
|
|
1948
|
+
if (hasAlpha && !canBrowserUseWebGl2()) {
|
|
1949
|
+
return "has-alpha";
|
|
1950
|
+
}
|
|
1712
1951
|
if (!startPacket) {
|
|
1713
1952
|
return null;
|
|
1714
1953
|
}
|
|
@@ -1727,7 +1966,7 @@ var makeKeyframeManager = () => {
|
|
|
1727
1966
|
if (await (await existingBank).hasTimestampInSecond(timestamp)) {
|
|
1728
1967
|
return existingBank;
|
|
1729
1968
|
}
|
|
1730
|
-
|
|
1969
|
+
Internals9.Log.verbose({ logLevel, tag: "@remotion/media" }, `Keyframe bank exists but frame at time ${timestamp} does not exist anymore.`);
|
|
1731
1970
|
await (await existingBank).prepareForDeletion(logLevel);
|
|
1732
1971
|
delete sources[src][startTimestampInSeconds];
|
|
1733
1972
|
const replacementKeybank = getFramesSinceKeyframe({
|
|
@@ -1815,20 +2054,20 @@ var getUncachedMaxCacheSize = (logLevel) => {
|
|
|
1815
2054
|
if (window.remotion_mediaCacheSizeInBytes > 20000 * 1024 * 1024) {
|
|
1816
2055
|
cancelRender(new Error(`The maximum value for the "mediaCacheSizeInBytes" prop is 20GB (${20000 * 1024 * 1024}), got: ${window.remotion_mediaCacheSizeInBytes}`));
|
|
1817
2056
|
}
|
|
1818
|
-
|
|
2057
|
+
Internals10.Log.verbose({ logLevel, tag: "@remotion/media" }, `Using cache size set using "mediaCacheSizeInBytes": ${(window.remotion_mediaCacheSizeInBytes / 1024 / 1024).toFixed(1)} MB`);
|
|
1819
2058
|
return window.remotion_mediaCacheSizeInBytes;
|
|
1820
2059
|
}
|
|
1821
2060
|
if (window.remotion_initialMemoryAvailable !== undefined && window.remotion_initialMemoryAvailable !== null) {
|
|
1822
2061
|
const value = window.remotion_initialMemoryAvailable / 2;
|
|
1823
|
-
if (value <
|
|
1824
|
-
|
|
1825
|
-
return
|
|
2062
|
+
if (value < 500 * 1024 * 1024) {
|
|
2063
|
+
Internals10.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!)`);
|
|
2064
|
+
return 500 * 1024 * 1024;
|
|
1826
2065
|
}
|
|
1827
2066
|
if (value > 20000 * 1024 * 1024) {
|
|
1828
|
-
|
|
2067
|
+
Internals10.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)`);
|
|
1829
2068
|
return 20000 * 1024 * 1024;
|
|
1830
2069
|
}
|
|
1831
|
-
|
|
2070
|
+
Internals10.Log.verbose({ logLevel, tag: "@remotion/media" }, `Using cache size set based on available memory (50% of available memory): ${(value / 1024 / 1024).toFixed(1)} MB`);
|
|
1832
2071
|
return value;
|
|
1833
2072
|
}
|
|
1834
2073
|
return 1000 * 1000 * 1000;
|
|
@@ -1915,12 +2154,12 @@ var convertAudioData = ({
|
|
|
1915
2154
|
};
|
|
1916
2155
|
|
|
1917
2156
|
// src/get-sink.ts
|
|
1918
|
-
import { Internals as
|
|
2157
|
+
import { Internals as Internals11 } from "remotion";
|
|
1919
2158
|
var sinkPromises = {};
|
|
1920
2159
|
var getSink = (src, logLevel) => {
|
|
1921
2160
|
let promise = sinkPromises[src];
|
|
1922
2161
|
if (!promise) {
|
|
1923
|
-
|
|
2162
|
+
Internals11.Log.verbose({
|
|
1924
2163
|
logLevel,
|
|
1925
2164
|
tag: "@remotion/media"
|
|
1926
2165
|
}, `Sink for ${src} was not found, creating new sink`);
|
|
@@ -1930,39 +2169,6 @@ var getSink = (src, logLevel) => {
|
|
|
1930
2169
|
return promise;
|
|
1931
2170
|
};
|
|
1932
2171
|
|
|
1933
|
-
// src/get-time-in-seconds.ts
|
|
1934
|
-
import { Internals as Internals9 } from "remotion";
|
|
1935
|
-
var getTimeInSeconds = ({
|
|
1936
|
-
loop,
|
|
1937
|
-
mediaDurationInSeconds,
|
|
1938
|
-
unloopedTimeInSeconds,
|
|
1939
|
-
src,
|
|
1940
|
-
trimAfter,
|
|
1941
|
-
trimBefore,
|
|
1942
|
-
fps,
|
|
1943
|
-
playbackRate
|
|
1944
|
-
}) => {
|
|
1945
|
-
if (mediaDurationInSeconds === null && loop) {
|
|
1946
|
-
throw new Error(`Could not determine duration of ${src}, but "loop" was set.`);
|
|
1947
|
-
}
|
|
1948
|
-
const loopDuration = loop ? Internals9.calculateLoopDuration({
|
|
1949
|
-
trimAfter,
|
|
1950
|
-
mediaDurationInFrames: mediaDurationInSeconds * fps,
|
|
1951
|
-
playbackRate: 1,
|
|
1952
|
-
trimBefore
|
|
1953
|
-
}) / fps : Infinity;
|
|
1954
|
-
const timeInSeconds = unloopedTimeInSeconds * playbackRate % loopDuration;
|
|
1955
|
-
if ((trimAfter ?? null) !== null) {
|
|
1956
|
-
if (!loop) {
|
|
1957
|
-
const time = (trimAfter - (trimBefore ?? 0)) / fps;
|
|
1958
|
-
if (timeInSeconds >= time) {
|
|
1959
|
-
return null;
|
|
1960
|
-
}
|
|
1961
|
-
}
|
|
1962
|
-
}
|
|
1963
|
-
return timeInSeconds + (trimBefore ?? 0) / fps;
|
|
1964
|
-
};
|
|
1965
|
-
|
|
1966
2172
|
// src/audio-extraction/extract-audio.ts
|
|
1967
2173
|
var extractAudioInternal = async ({
|
|
1968
2174
|
src,
|
|
@@ -1999,7 +2205,8 @@ var extractAudioInternal = async ({
|
|
|
1999
2205
|
trimAfter,
|
|
2000
2206
|
playbackRate,
|
|
2001
2207
|
trimBefore,
|
|
2002
|
-
fps
|
|
2208
|
+
fps,
|
|
2209
|
+
ifNoMediaDuration: "fail"
|
|
2003
2210
|
});
|
|
2004
2211
|
if (timeInSeconds === null) {
|
|
2005
2212
|
return { data: null, durationInSeconds: mediaDurationInSeconds };
|
|
@@ -2099,7 +2306,8 @@ var extractFrameInternal = async ({
|
|
|
2099
2306
|
trimAfter,
|
|
2100
2307
|
playbackRate,
|
|
2101
2308
|
trimBefore,
|
|
2102
|
-
fps
|
|
2309
|
+
fps,
|
|
2310
|
+
ifNoMediaDuration: "fail"
|
|
2103
2311
|
});
|
|
2104
2312
|
if (timeInSeconds === null) {
|
|
2105
2313
|
return {
|
|
@@ -2115,6 +2323,12 @@ var extractFrameInternal = async ({
|
|
|
2115
2323
|
src,
|
|
2116
2324
|
logLevel
|
|
2117
2325
|
});
|
|
2326
|
+
if (keyframeBank === "has-alpha") {
|
|
2327
|
+
return {
|
|
2328
|
+
type: "cannot-decode-alpha",
|
|
2329
|
+
durationInSeconds: await sink.getDuration()
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2118
2332
|
if (!keyframeBank) {
|
|
2119
2333
|
return {
|
|
2120
2334
|
type: "success",
|
|
@@ -2180,6 +2394,12 @@ var extractFrameAndAudio = async ({
|
|
|
2180
2394
|
if (frame?.type === "unknown-container-format") {
|
|
2181
2395
|
return { type: "unknown-container-format" };
|
|
2182
2396
|
}
|
|
2397
|
+
if (frame?.type === "cannot-decode-alpha") {
|
|
2398
|
+
return {
|
|
2399
|
+
type: "cannot-decode-alpha",
|
|
2400
|
+
durationInSeconds: frame.durationInSeconds
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2183
2403
|
if (audio === "unknown-container-format") {
|
|
2184
2404
|
if (frame !== null) {
|
|
2185
2405
|
frame?.frame?.close();
|
|
@@ -2239,6 +2459,15 @@ if (window.remotion_broadcastChannel && window.remotion_isMainTab) {
|
|
|
2239
2459
|
window.remotion_broadcastChannel.postMessage(cannotDecodeResponse);
|
|
2240
2460
|
return;
|
|
2241
2461
|
}
|
|
2462
|
+
if (result.type === "cannot-decode-alpha") {
|
|
2463
|
+
const cannotDecodeAlphaResponse = {
|
|
2464
|
+
type: "response-cannot-decode-alpha",
|
|
2465
|
+
id: data.id,
|
|
2466
|
+
durationInSeconds: result.durationInSeconds
|
|
2467
|
+
};
|
|
2468
|
+
window.remotion_broadcastChannel.postMessage(cannotDecodeAlphaResponse);
|
|
2469
|
+
return;
|
|
2470
|
+
}
|
|
2242
2471
|
if (result.type === "network-error") {
|
|
2243
2472
|
const networkErrorResponse = {
|
|
2244
2473
|
type: "response-network-error",
|
|
@@ -2357,6 +2586,14 @@ var extractFrameViaBroadcastChannel = ({
|
|
|
2357
2586
|
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
2358
2587
|
return;
|
|
2359
2588
|
}
|
|
2589
|
+
if (data.type === "response-cannot-decode-alpha") {
|
|
2590
|
+
resolve({
|
|
2591
|
+
type: "cannot-decode-alpha",
|
|
2592
|
+
durationInSeconds: data.durationInSeconds
|
|
2593
|
+
});
|
|
2594
|
+
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
2595
|
+
return;
|
|
2596
|
+
}
|
|
2360
2597
|
throw new Error(`Invalid message: ${JSON.stringify(data)}`);
|
|
2361
2598
|
};
|
|
2362
2599
|
window.remotion_broadcastChannel.addEventListener("message", onMessage);
|
|
@@ -2414,11 +2651,11 @@ var AudioForRendering = ({
|
|
|
2414
2651
|
trimAfter,
|
|
2415
2652
|
trimBefore
|
|
2416
2653
|
}) => {
|
|
2417
|
-
const frame =
|
|
2418
|
-
const absoluteFrame =
|
|
2419
|
-
const videoConfig =
|
|
2420
|
-
const { registerRenderAsset, unregisterRenderAsset } =
|
|
2421
|
-
const startsAt =
|
|
2654
|
+
const frame = useCurrentFrame3();
|
|
2655
|
+
const absoluteFrame = Internals12.useTimelinePosition();
|
|
2656
|
+
const videoConfig = Internals12.useUnsafeVideoConfig();
|
|
2657
|
+
const { registerRenderAsset, unregisterRenderAsset } = useContext3(Internals12.RenderAssetManager);
|
|
2658
|
+
const startsAt = Internals12.useMediaStartsAt();
|
|
2422
2659
|
const environment = useRemotionEnvironment();
|
|
2423
2660
|
if (!videoConfig) {
|
|
2424
2661
|
throw new Error("No video config found");
|
|
@@ -2428,9 +2665,9 @@ var AudioForRendering = ({
|
|
|
2428
2665
|
}
|
|
2429
2666
|
const { fps } = videoConfig;
|
|
2430
2667
|
const { delayRender, continueRender } = useDelayRender();
|
|
2431
|
-
const [replaceWithHtml5Audio, setReplaceWithHtml5Audio] =
|
|
2432
|
-
const sequenceContext =
|
|
2433
|
-
const id =
|
|
2668
|
+
const [replaceWithHtml5Audio, setReplaceWithHtml5Audio] = useState3(false);
|
|
2669
|
+
const sequenceContext = useContext3(Internals12.SequenceContext);
|
|
2670
|
+
const id = useMemo3(() => `media-video-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
2434
2671
|
src,
|
|
2435
2672
|
sequenceContext?.cumulatedFrom,
|
|
2436
2673
|
sequenceContext?.relativeFrom,
|
|
@@ -2474,7 +2711,7 @@ var AudioForRendering = ({
|
|
|
2474
2711
|
if (disallowFallbackToHtml5Audio) {
|
|
2475
2712
|
cancelRender2(new Error(`Unknown container format ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
2476
2713
|
}
|
|
2477
|
-
|
|
2714
|
+
Internals12.Log.warn({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${src} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Html5Audio>`);
|
|
2478
2715
|
setReplaceWithHtml5Audio(true);
|
|
2479
2716
|
return;
|
|
2480
2717
|
}
|
|
@@ -2482,15 +2719,18 @@ var AudioForRendering = ({
|
|
|
2482
2719
|
if (disallowFallbackToHtml5Audio) {
|
|
2483
2720
|
cancelRender2(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
2484
2721
|
}
|
|
2485
|
-
|
|
2722
|
+
Internals12.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${src}, falling back to <Html5Audio>`);
|
|
2486
2723
|
setReplaceWithHtml5Audio(true);
|
|
2487
2724
|
return;
|
|
2488
2725
|
}
|
|
2726
|
+
if (result.type === "cannot-decode-alpha") {
|
|
2727
|
+
throw new Error(`Cannot decode alpha component for ${src}, and 'disallowFallbackToHtml5Audio' was set. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
|
|
2728
|
+
}
|
|
2489
2729
|
if (result.type === "network-error") {
|
|
2490
2730
|
if (disallowFallbackToHtml5Audio) {
|
|
2491
2731
|
cancelRender2(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
2492
2732
|
}
|
|
2493
|
-
|
|
2733
|
+
Internals12.Log.warn({ logLevel, tag: "@remotion/media" }, `Network error fetching ${src}, falling back to <Html5Audio>`);
|
|
2494
2734
|
setReplaceWithHtml5Audio(true);
|
|
2495
2735
|
return;
|
|
2496
2736
|
}
|
|
@@ -2503,12 +2743,12 @@ var AudioForRendering = ({
|
|
|
2503
2743
|
frame,
|
|
2504
2744
|
startsAt
|
|
2505
2745
|
});
|
|
2506
|
-
const volume =
|
|
2746
|
+
const volume = Internals12.evaluateVolume({
|
|
2507
2747
|
volume: volumeProp,
|
|
2508
2748
|
frame: volumePropsFrame,
|
|
2509
2749
|
mediaVolume: 1
|
|
2510
2750
|
});
|
|
2511
|
-
|
|
2751
|
+
Internals12.warnAboutTooHighVolume(volume);
|
|
2512
2752
|
if (audio && volume > 0) {
|
|
2513
2753
|
applyVolume(audio.data, volume);
|
|
2514
2754
|
registerRenderAsset({
|
|
@@ -2557,7 +2797,7 @@ var AudioForRendering = ({
|
|
|
2557
2797
|
replaceWithHtml5Audio
|
|
2558
2798
|
]);
|
|
2559
2799
|
if (replaceWithHtml5Audio) {
|
|
2560
|
-
return /* @__PURE__ */ jsx2(
|
|
2800
|
+
return /* @__PURE__ */ jsx2(Html5Audio, {
|
|
2561
2801
|
src,
|
|
2562
2802
|
playbackRate,
|
|
2563
2803
|
muted,
|
|
@@ -2581,8 +2821,8 @@ var AudioForRendering = ({
|
|
|
2581
2821
|
|
|
2582
2822
|
// src/audio/audio.tsx
|
|
2583
2823
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
2584
|
-
var { validateMediaProps } =
|
|
2585
|
-
var
|
|
2824
|
+
var { validateMediaProps } = Internals13;
|
|
2825
|
+
var Audio = (props) => {
|
|
2586
2826
|
const { name, stack, showInTimeline, ...otherProps } = props;
|
|
2587
2827
|
const environment = useRemotionEnvironment2();
|
|
2588
2828
|
if (typeof props.src !== "string") {
|
|
@@ -2600,14 +2840,14 @@ var Audio2 = (props) => {
|
|
|
2600
2840
|
stack: stack ?? null
|
|
2601
2841
|
});
|
|
2602
2842
|
};
|
|
2603
|
-
|
|
2843
|
+
Internals13.addSequenceStackTraces(Audio);
|
|
2604
2844
|
|
|
2605
2845
|
// src/video/video.tsx
|
|
2606
|
-
import { Internals as
|
|
2846
|
+
import { Internals as Internals16, useRemotionEnvironment as useRemotionEnvironment4 } from "remotion";
|
|
2607
2847
|
|
|
2608
2848
|
// src/video/video-for-preview.tsx
|
|
2609
|
-
import { useContext as
|
|
2610
|
-
import { Internals as
|
|
2849
|
+
import { useContext as useContext4, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef2, useState as useState4 } from "react";
|
|
2850
|
+
import { Html5Video, Internals as Internals14, useBufferState as useBufferState2, useCurrentFrame as useCurrentFrame4 } from "remotion";
|
|
2611
2851
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
2612
2852
|
var {
|
|
2613
2853
|
useUnsafeVideoConfig: useUnsafeVideoConfig2,
|
|
@@ -2619,11 +2859,11 @@ var {
|
|
|
2619
2859
|
evaluateVolume: evaluateVolume2,
|
|
2620
2860
|
warnAboutTooHighVolume: warnAboutTooHighVolume2,
|
|
2621
2861
|
usePreload: usePreload2,
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
} =
|
|
2625
|
-
var
|
|
2626
|
-
src,
|
|
2862
|
+
SequenceContext: SequenceContext2,
|
|
2863
|
+
SequenceVisibilityToggleContext
|
|
2864
|
+
} = Internals14;
|
|
2865
|
+
var VideoForPreview = ({
|
|
2866
|
+
src: unpreloadedSrc,
|
|
2627
2867
|
style,
|
|
2628
2868
|
playbackRate,
|
|
2629
2869
|
logLevel,
|
|
@@ -2642,19 +2882,22 @@ var NewVideoForPreview = ({
|
|
|
2642
2882
|
fallbackOffthreadVideoProps,
|
|
2643
2883
|
audioStreamIndex
|
|
2644
2884
|
}) => {
|
|
2885
|
+
const src = usePreload2(unpreloadedSrc);
|
|
2645
2886
|
const canvasRef = useRef2(null);
|
|
2646
2887
|
const videoConfig = useUnsafeVideoConfig2();
|
|
2647
|
-
const frame =
|
|
2888
|
+
const frame = useCurrentFrame4();
|
|
2648
2889
|
const mediaPlayerRef = useRef2(null);
|
|
2649
|
-
const [mediaPlayerReady, setMediaPlayerReady] =
|
|
2650
|
-
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] =
|
|
2890
|
+
const [mediaPlayerReady, setMediaPlayerReady] = useState4(false);
|
|
2891
|
+
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState4(false);
|
|
2651
2892
|
const [playing] = Timeline2.usePlayingState();
|
|
2652
|
-
const timelineContext =
|
|
2893
|
+
const timelineContext = useContext4(Timeline2.TimelineContext);
|
|
2653
2894
|
const globalPlaybackRate = timelineContext.playbackRate;
|
|
2654
|
-
const sharedAudioContext =
|
|
2895
|
+
const sharedAudioContext = useContext4(SharedAudioContext2);
|
|
2655
2896
|
const buffer = useBufferState2();
|
|
2656
2897
|
const [mediaMuted] = useMediaMutedState2();
|
|
2657
2898
|
const [mediaVolume] = useMediaVolumeState2();
|
|
2899
|
+
const [mediaDurationInSeconds, setMediaDurationInSeconds] = useState4(null);
|
|
2900
|
+
const { hidden } = useContext4(SequenceVisibilityToggleContext);
|
|
2658
2901
|
const volumePropFrame = useFrameForVolumeProp2(loopVolumeCurveBehavior);
|
|
2659
2902
|
const userPreferredVolume = evaluateVolume2({
|
|
2660
2903
|
frame: volumePropFrame,
|
|
@@ -2662,21 +2905,30 @@ var NewVideoForPreview = ({
|
|
|
2662
2905
|
mediaVolume
|
|
2663
2906
|
});
|
|
2664
2907
|
warnAboutTooHighVolume2(userPreferredVolume);
|
|
2665
|
-
const
|
|
2666
|
-
const
|
|
2667
|
-
|
|
2908
|
+
const parentSequence = useContext4(SequenceContext2);
|
|
2909
|
+
const loopDisplay = useLoopDisplay({
|
|
2910
|
+
loop,
|
|
2911
|
+
mediaDurationInSeconds,
|
|
2912
|
+
playbackRate,
|
|
2913
|
+
trimAfter,
|
|
2914
|
+
trimBefore
|
|
2915
|
+
});
|
|
2916
|
+
const { id: timelineId } = useMediaInTimeline({
|
|
2668
2917
|
volume,
|
|
2669
|
-
mediaVolume,
|
|
2670
2918
|
mediaType: "video",
|
|
2671
2919
|
src,
|
|
2672
2920
|
playbackRate,
|
|
2673
2921
|
displayName: name ?? null,
|
|
2674
|
-
id: timelineId,
|
|
2675
2922
|
stack,
|
|
2676
2923
|
showInTimeline,
|
|
2677
2924
|
premountDisplay: parentSequence?.premountDisplay ?? null,
|
|
2678
|
-
postmountDisplay: parentSequence?.postmountDisplay ?? null
|
|
2925
|
+
postmountDisplay: parentSequence?.postmountDisplay ?? null,
|
|
2926
|
+
loopDisplay,
|
|
2927
|
+
mediaVolume,
|
|
2928
|
+
trimAfter,
|
|
2929
|
+
trimBefore
|
|
2679
2930
|
});
|
|
2931
|
+
const isSequenceHidden = hidden[timelineId] ?? false;
|
|
2680
2932
|
if (!videoConfig) {
|
|
2681
2933
|
throw new Error("No video config found");
|
|
2682
2934
|
}
|
|
@@ -2687,7 +2939,7 @@ var NewVideoForPreview = ({
|
|
|
2687
2939
|
const currentTimeRef = useRef2(currentTime);
|
|
2688
2940
|
currentTimeRef.current = currentTime;
|
|
2689
2941
|
const preloadedSrc = usePreload2(src);
|
|
2690
|
-
|
|
2942
|
+
useEffect3(() => {
|
|
2691
2943
|
if (!canvasRef.current)
|
|
2692
2944
|
return;
|
|
2693
2945
|
if (!sharedAudioContext)
|
|
@@ -2701,8 +2953,9 @@ var NewVideoForPreview = ({
|
|
|
2701
2953
|
logLevel,
|
|
2702
2954
|
sharedAudioContext: sharedAudioContext.audioContext,
|
|
2703
2955
|
loop,
|
|
2704
|
-
|
|
2705
|
-
|
|
2956
|
+
trimAfter,
|
|
2957
|
+
trimBefore,
|
|
2958
|
+
fps: videoConfig.fps,
|
|
2706
2959
|
playbackRate,
|
|
2707
2960
|
audioStreamIndex
|
|
2708
2961
|
});
|
|
@@ -2712,7 +2965,7 @@ var NewVideoForPreview = ({
|
|
|
2712
2965
|
if (disallowFallbackToOffthreadVideo) {
|
|
2713
2966
|
throw new Error(`Unknown container format ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
2714
2967
|
}
|
|
2715
|
-
|
|
2968
|
+
Internals14.Log.warn({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <OffthreadVideo>`);
|
|
2716
2969
|
setShouldFallbackToNativeVideo(true);
|
|
2717
2970
|
return;
|
|
2718
2971
|
}
|
|
@@ -2720,7 +2973,7 @@ var NewVideoForPreview = ({
|
|
|
2720
2973
|
if (disallowFallbackToOffthreadVideo) {
|
|
2721
2974
|
throw new Error(`Network error fetching ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
2722
2975
|
}
|
|
2723
|
-
|
|
2976
|
+
Internals14.Log.warn({ logLevel, tag: "@remotion/media" }, `Network error fetching ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
2724
2977
|
setShouldFallbackToNativeVideo(true);
|
|
2725
2978
|
return;
|
|
2726
2979
|
}
|
|
@@ -2728,7 +2981,7 @@ var NewVideoForPreview = ({
|
|
|
2728
2981
|
if (disallowFallbackToOffthreadVideo) {
|
|
2729
2982
|
throw new Error(`Cannot decode ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
2730
2983
|
}
|
|
2731
|
-
|
|
2984
|
+
Internals14.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
2732
2985
|
setShouldFallbackToNativeVideo(true);
|
|
2733
2986
|
return;
|
|
2734
2987
|
}
|
|
@@ -2736,24 +2989,25 @@ var NewVideoForPreview = ({
|
|
|
2736
2989
|
if (disallowFallbackToOffthreadVideo) {
|
|
2737
2990
|
throw new Error(`No video or audio tracks found for ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
2738
2991
|
}
|
|
2739
|
-
|
|
2992
|
+
Internals14.Log.warn({ logLevel, tag: "@remotion/media" }, `No video or audio tracks found for ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
2740
2993
|
setShouldFallbackToNativeVideo(true);
|
|
2741
2994
|
return;
|
|
2742
2995
|
}
|
|
2743
2996
|
if (result.type === "success") {
|
|
2744
2997
|
setMediaPlayerReady(true);
|
|
2998
|
+
setMediaDurationInSeconds(result.durationInSeconds);
|
|
2745
2999
|
}
|
|
2746
3000
|
}).catch((error) => {
|
|
2747
|
-
|
|
3001
|
+
Internals14.Log.error({ logLevel, tag: "@remotion/media" }, "[NewVideoForPreview] Failed to initialize MediaPlayer", error);
|
|
2748
3002
|
setShouldFallbackToNativeVideo(true);
|
|
2749
3003
|
});
|
|
2750
3004
|
} catch (error) {
|
|
2751
|
-
|
|
3005
|
+
Internals14.Log.error({ logLevel, tag: "@remotion/media" }, "[NewVideoForPreview] MediaPlayer initialization failed", error);
|
|
2752
3006
|
setShouldFallbackToNativeVideo(true);
|
|
2753
3007
|
}
|
|
2754
3008
|
return () => {
|
|
2755
3009
|
if (mediaPlayerRef.current) {
|
|
2756
|
-
|
|
3010
|
+
Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, `[NewVideoForPreview] Disposing MediaPlayer`);
|
|
2757
3011
|
mediaPlayerRef.current.dispose();
|
|
2758
3012
|
mediaPlayerRef.current = null;
|
|
2759
3013
|
}
|
|
@@ -2772,29 +3026,29 @@ var NewVideoForPreview = ({
|
|
|
2772
3026
|
disallowFallbackToOffthreadVideo,
|
|
2773
3027
|
audioStreamIndex
|
|
2774
3028
|
]);
|
|
2775
|
-
const classNameValue =
|
|
2776
|
-
return [
|
|
3029
|
+
const classNameValue = useMemo4(() => {
|
|
3030
|
+
return [Internals14.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals14.truthy).join(" ");
|
|
2777
3031
|
}, [className]);
|
|
2778
|
-
|
|
3032
|
+
useEffect3(() => {
|
|
2779
3033
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2780
3034
|
if (!mediaPlayer)
|
|
2781
3035
|
return;
|
|
2782
3036
|
if (playing) {
|
|
2783
3037
|
mediaPlayer.play().catch((error) => {
|
|
2784
|
-
|
|
3038
|
+
Internals14.Log.error({ logLevel, tag: "@remotion/media" }, "[NewVideoForPreview] Failed to play", error);
|
|
2785
3039
|
});
|
|
2786
3040
|
} else {
|
|
2787
3041
|
mediaPlayer.pause();
|
|
2788
3042
|
}
|
|
2789
3043
|
}, [playing, logLevel, mediaPlayerReady]);
|
|
2790
|
-
|
|
3044
|
+
useEffect3(() => {
|
|
2791
3045
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2792
3046
|
if (!mediaPlayer || !mediaPlayerReady)
|
|
2793
3047
|
return;
|
|
2794
3048
|
mediaPlayer.seekTo(currentTime);
|
|
2795
|
-
|
|
3049
|
+
Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, `[NewVideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
2796
3050
|
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
2797
|
-
|
|
3051
|
+
useEffect3(() => {
|
|
2798
3052
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2799
3053
|
if (!mediaPlayer || !mediaPlayerReady)
|
|
2800
3054
|
return;
|
|
@@ -2802,11 +3056,11 @@ var NewVideoForPreview = ({
|
|
|
2802
3056
|
const unsubscribe = mediaPlayer.onBufferingChange((newBufferingState) => {
|
|
2803
3057
|
if (newBufferingState && !currentBlock) {
|
|
2804
3058
|
currentBlock = buffer.delayPlayback();
|
|
2805
|
-
|
|
3059
|
+
Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, "[NewVideoForPreview] MediaPlayer buffering - blocking Remotion playback");
|
|
2806
3060
|
} else if (!newBufferingState && currentBlock) {
|
|
2807
3061
|
currentBlock.unblock();
|
|
2808
3062
|
currentBlock = null;
|
|
2809
|
-
|
|
3063
|
+
Internals14.Log.trace({ logLevel, tag: "@remotion/media" }, "[NewVideoForPreview] MediaPlayer unbuffering - unblocking Remotion playback");
|
|
2810
3064
|
}
|
|
2811
3065
|
});
|
|
2812
3066
|
return () => {
|
|
@@ -2817,36 +3071,43 @@ var NewVideoForPreview = ({
|
|
|
2817
3071
|
}
|
|
2818
3072
|
};
|
|
2819
3073
|
}, [mediaPlayerReady, buffer, logLevel]);
|
|
2820
|
-
const effectiveMuted = muted || mediaMuted || userPreferredVolume <= 0;
|
|
2821
|
-
|
|
3074
|
+
const effectiveMuted = isSequenceHidden || muted || mediaMuted || userPreferredVolume <= 0;
|
|
3075
|
+
useEffect3(() => {
|
|
2822
3076
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2823
3077
|
if (!mediaPlayer || !mediaPlayerReady)
|
|
2824
3078
|
return;
|
|
2825
3079
|
mediaPlayer.setMuted(effectiveMuted);
|
|
2826
3080
|
}, [effectiveMuted, mediaPlayerReady]);
|
|
2827
|
-
|
|
3081
|
+
useEffect3(() => {
|
|
2828
3082
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2829
3083
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
2830
3084
|
return;
|
|
2831
3085
|
}
|
|
2832
3086
|
mediaPlayer.setVolume(userPreferredVolume);
|
|
2833
|
-
}, [userPreferredVolume, mediaPlayerReady
|
|
2834
|
-
const effectivePlaybackRate =
|
|
2835
|
-
|
|
3087
|
+
}, [userPreferredVolume, mediaPlayerReady]);
|
|
3088
|
+
const effectivePlaybackRate = useMemo4(() => playbackRate * globalPlaybackRate, [playbackRate, globalPlaybackRate]);
|
|
3089
|
+
useEffect3(() => {
|
|
2836
3090
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2837
3091
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
2838
3092
|
return;
|
|
2839
3093
|
}
|
|
2840
3094
|
mediaPlayer.setPlaybackRate(effectivePlaybackRate);
|
|
2841
|
-
}, [effectivePlaybackRate, mediaPlayerReady
|
|
2842
|
-
|
|
3095
|
+
}, [effectivePlaybackRate, mediaPlayerReady]);
|
|
3096
|
+
useEffect3(() => {
|
|
2843
3097
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2844
3098
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
2845
3099
|
return;
|
|
2846
3100
|
}
|
|
2847
3101
|
mediaPlayer.setLoop(loop);
|
|
2848
3102
|
}, [loop, mediaPlayerReady]);
|
|
2849
|
-
|
|
3103
|
+
useEffect3(() => {
|
|
3104
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
3105
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3106
|
+
return;
|
|
3107
|
+
}
|
|
3108
|
+
mediaPlayer.setFps(videoConfig.fps);
|
|
3109
|
+
}, [videoConfig.fps, mediaPlayerReady]);
|
|
3110
|
+
useEffect3(() => {
|
|
2850
3111
|
const mediaPlayer = mediaPlayerRef.current;
|
|
2851
3112
|
if (!mediaPlayer || !mediaPlayerReady || !onVideoFrame) {
|
|
2852
3113
|
return;
|
|
@@ -2856,10 +3117,16 @@ var NewVideoForPreview = ({
|
|
|
2856
3117
|
unsubscribe();
|
|
2857
3118
|
};
|
|
2858
3119
|
}, [onVideoFrame, mediaPlayerReady]);
|
|
3120
|
+
const actualStyle = useMemo4(() => {
|
|
3121
|
+
return {
|
|
3122
|
+
...style,
|
|
3123
|
+
opacity: isSequenceHidden ? 0 : style?.opacity ?? 1
|
|
3124
|
+
};
|
|
3125
|
+
}, [isSequenceHidden, style]);
|
|
2859
3126
|
if (shouldFallbackToNativeVideo && !disallowFallbackToOffthreadVideo) {
|
|
2860
|
-
return /* @__PURE__ */ jsx4(
|
|
3127
|
+
return /* @__PURE__ */ jsx4(Html5Video, {
|
|
2861
3128
|
src,
|
|
2862
|
-
style,
|
|
3129
|
+
style: actualStyle,
|
|
2863
3130
|
className,
|
|
2864
3131
|
muted,
|
|
2865
3132
|
volume,
|
|
@@ -2878,74 +3145,32 @@ var NewVideoForPreview = ({
|
|
|
2878
3145
|
ref: canvasRef,
|
|
2879
3146
|
width: videoConfig.width,
|
|
2880
3147
|
height: videoConfig.height,
|
|
2881
|
-
style,
|
|
3148
|
+
style: actualStyle,
|
|
2882
3149
|
className: classNameValue
|
|
2883
3150
|
});
|
|
2884
3151
|
};
|
|
2885
|
-
var VideoForPreview = ({
|
|
2886
|
-
className,
|
|
2887
|
-
loop,
|
|
2888
|
-
src,
|
|
2889
|
-
logLevel,
|
|
2890
|
-
muted,
|
|
2891
|
-
name,
|
|
2892
|
-
volume,
|
|
2893
|
-
loopVolumeCurveBehavior,
|
|
2894
|
-
onVideoFrame,
|
|
2895
|
-
playbackRate,
|
|
2896
|
-
style,
|
|
2897
|
-
showInTimeline,
|
|
2898
|
-
trimAfter,
|
|
2899
|
-
trimBefore,
|
|
2900
|
-
stack,
|
|
2901
|
-
disallowFallbackToOffthreadVideo,
|
|
2902
|
-
fallbackOffthreadVideoProps,
|
|
2903
|
-
audioStreamIndex
|
|
2904
|
-
}) => {
|
|
2905
|
-
const preloadedSrc = usePreload2(src);
|
|
2906
|
-
return /* @__PURE__ */ jsx4(NewVideoForPreview, {
|
|
2907
|
-
className,
|
|
2908
|
-
logLevel,
|
|
2909
|
-
muted,
|
|
2910
|
-
onVideoFrame,
|
|
2911
|
-
playbackRate,
|
|
2912
|
-
src: preloadedSrc,
|
|
2913
|
-
style,
|
|
2914
|
-
volume,
|
|
2915
|
-
name,
|
|
2916
|
-
trimAfter,
|
|
2917
|
-
trimBefore,
|
|
2918
|
-
loop,
|
|
2919
|
-
loopVolumeCurveBehavior,
|
|
2920
|
-
showInTimeline,
|
|
2921
|
-
stack,
|
|
2922
|
-
disallowFallbackToOffthreadVideo,
|
|
2923
|
-
fallbackOffthreadVideoProps,
|
|
2924
|
-
audioStreamIndex
|
|
2925
|
-
});
|
|
2926
|
-
};
|
|
2927
3152
|
|
|
2928
3153
|
// src/video/video-for-rendering.tsx
|
|
2929
3154
|
import {
|
|
2930
|
-
useContext as
|
|
3155
|
+
useContext as useContext5,
|
|
2931
3156
|
useLayoutEffect as useLayoutEffect2,
|
|
2932
|
-
useMemo as
|
|
3157
|
+
useMemo as useMemo5,
|
|
2933
3158
|
useRef as useRef3,
|
|
2934
|
-
useState as
|
|
3159
|
+
useState as useState5
|
|
2935
3160
|
} from "react";
|
|
2936
3161
|
import {
|
|
2937
3162
|
cancelRender as cancelRender3,
|
|
2938
|
-
Internals as
|
|
3163
|
+
Internals as Internals15,
|
|
2939
3164
|
Loop,
|
|
2940
3165
|
random as random2,
|
|
2941
|
-
useCurrentFrame as
|
|
3166
|
+
useCurrentFrame as useCurrentFrame5,
|
|
2942
3167
|
useDelayRender as useDelayRender2,
|
|
2943
3168
|
useRemotionEnvironment as useRemotionEnvironment3,
|
|
2944
|
-
useVideoConfig
|
|
3169
|
+
useVideoConfig as useVideoConfig2
|
|
2945
3170
|
} from "remotion";
|
|
2946
3171
|
|
|
2947
|
-
// ../core/src/calculate-
|
|
2948
|
-
var
|
|
3172
|
+
// ../core/src/calculate-media-duration.ts
|
|
3173
|
+
var calculateMediaDuration = ({
|
|
2949
3174
|
trimAfter,
|
|
2950
3175
|
mediaDurationInFrames,
|
|
2951
3176
|
playbackRate,
|
|
@@ -2989,13 +3214,13 @@ var VideoForRendering = ({
|
|
|
2989
3214
|
if (!src) {
|
|
2990
3215
|
throw new TypeError("No `src` was passed to <Video>.");
|
|
2991
3216
|
}
|
|
2992
|
-
const frame =
|
|
2993
|
-
const absoluteFrame =
|
|
2994
|
-
const { fps } =
|
|
2995
|
-
const { registerRenderAsset, unregisterRenderAsset } =
|
|
2996
|
-
const startsAt =
|
|
2997
|
-
const sequenceContext =
|
|
2998
|
-
const id =
|
|
3217
|
+
const frame = useCurrentFrame5();
|
|
3218
|
+
const absoluteFrame = Internals15.useTimelinePosition();
|
|
3219
|
+
const { fps } = useVideoConfig2();
|
|
3220
|
+
const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals15.RenderAssetManager);
|
|
3221
|
+
const startsAt = Internals15.useMediaStartsAt();
|
|
3222
|
+
const sequenceContext = useContext5(Internals15.SequenceContext);
|
|
3223
|
+
const id = useMemo5(() => `media-video-${random2(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
2999
3224
|
src,
|
|
3000
3225
|
sequenceContext?.cumulatedFrom,
|
|
3001
3226
|
sequenceContext?.relativeFrom,
|
|
@@ -3004,7 +3229,7 @@ var VideoForRendering = ({
|
|
|
3004
3229
|
const environment = useRemotionEnvironment3();
|
|
3005
3230
|
const { delayRender, continueRender } = useDelayRender2();
|
|
3006
3231
|
const canvasRef = useRef3(null);
|
|
3007
|
-
const [replaceWithOffthreadVideo, setReplaceWithOffthreadVideo] =
|
|
3232
|
+
const [replaceWithOffthreadVideo, setReplaceWithOffthreadVideo] = useState5(false);
|
|
3008
3233
|
useLayoutEffect2(() => {
|
|
3009
3234
|
if (!canvasRef.current) {
|
|
3010
3235
|
return;
|
|
@@ -3047,7 +3272,7 @@ var VideoForRendering = ({
|
|
|
3047
3272
|
cancelRender3(new Error(`Unknown container format ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
3048
3273
|
}
|
|
3049
3274
|
if (window.remotion_isMainTab) {
|
|
3050
|
-
|
|
3275
|
+
Internals15.Log.info({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${src} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <OffthreadVideo>`);
|
|
3051
3276
|
}
|
|
3052
3277
|
setReplaceWithOffthreadVideo({ durationInSeconds: null });
|
|
3053
3278
|
return;
|
|
@@ -3057,7 +3282,19 @@ var VideoForRendering = ({
|
|
|
3057
3282
|
cancelRender3(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
3058
3283
|
}
|
|
3059
3284
|
if (window.remotion_isMainTab) {
|
|
3060
|
-
|
|
3285
|
+
Internals15.Log.info({ logLevel, tag: "@remotion/media" }, `Cannot decode ${src}, falling back to <OffthreadVideo>`);
|
|
3286
|
+
}
|
|
3287
|
+
setReplaceWithOffthreadVideo({
|
|
3288
|
+
durationInSeconds: result.durationInSeconds
|
|
3289
|
+
});
|
|
3290
|
+
return;
|
|
3291
|
+
}
|
|
3292
|
+
if (result.type === "cannot-decode-alpha") {
|
|
3293
|
+
if (disallowFallbackToOffthreadVideo) {
|
|
3294
|
+
cancelRender3(new Error(`Cannot decode alpha component for ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
3295
|
+
}
|
|
3296
|
+
if (window.remotion_isMainTab) {
|
|
3297
|
+
Internals15.Log.info({ logLevel, tag: "@remotion/media" }, `Cannot decode alpha component for ${src}, falling back to <OffthreadVideo>`);
|
|
3061
3298
|
}
|
|
3062
3299
|
setReplaceWithOffthreadVideo({
|
|
3063
3300
|
durationInSeconds: result.durationInSeconds
|
|
@@ -3069,7 +3306,7 @@ var VideoForRendering = ({
|
|
|
3069
3306
|
cancelRender3(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
3070
3307
|
}
|
|
3071
3308
|
if (window.remotion_isMainTab) {
|
|
3072
|
-
|
|
3309
|
+
Internals15.Log.info({ logLevel, tag: "@remotion/media" }, `Network error fetching ${src}, falling back to <OffthreadVideo>`);
|
|
3073
3310
|
}
|
|
3074
3311
|
setReplaceWithOffthreadVideo({ durationInSeconds: null });
|
|
3075
3312
|
return;
|
|
@@ -3081,7 +3318,9 @@ var VideoForRendering = ({
|
|
|
3081
3318
|
} = result;
|
|
3082
3319
|
if (imageBitmap) {
|
|
3083
3320
|
onVideoFrame?.(imageBitmap);
|
|
3084
|
-
const context = canvasRef.current?.getContext("2d"
|
|
3321
|
+
const context = canvasRef.current?.getContext("2d", {
|
|
3322
|
+
alpha: true
|
|
3323
|
+
});
|
|
3085
3324
|
if (!context) {
|
|
3086
3325
|
return;
|
|
3087
3326
|
}
|
|
@@ -3091,7 +3330,9 @@ var VideoForRendering = ({
|
|
|
3091
3330
|
context.drawImage(imageBitmap, 0, 0);
|
|
3092
3331
|
imageBitmap.close();
|
|
3093
3332
|
} else if (window.remotion_videoEnabled) {
|
|
3094
|
-
const context = canvasRef.current?.getContext("2d"
|
|
3333
|
+
const context = canvasRef.current?.getContext("2d", {
|
|
3334
|
+
alpha: true
|
|
3335
|
+
});
|
|
3095
3336
|
if (context) {
|
|
3096
3337
|
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
|
|
3097
3338
|
}
|
|
@@ -3104,12 +3345,12 @@ var VideoForRendering = ({
|
|
|
3104
3345
|
frame,
|
|
3105
3346
|
startsAt
|
|
3106
3347
|
});
|
|
3107
|
-
const volume =
|
|
3348
|
+
const volume = Internals15.evaluateVolume({
|
|
3108
3349
|
volume: volumeProp,
|
|
3109
3350
|
frame: volumePropsFrame,
|
|
3110
3351
|
mediaVolume: 1
|
|
3111
3352
|
});
|
|
3112
|
-
|
|
3353
|
+
Internals15.warnAboutTooHighVolume(volume);
|
|
3113
3354
|
if (audio && volume > 0) {
|
|
3114
3355
|
applyVolume(audio.data, volume);
|
|
3115
3356
|
registerRenderAsset({
|
|
@@ -3158,11 +3399,11 @@ var VideoForRendering = ({
|
|
|
3158
3399
|
trimAfterValue,
|
|
3159
3400
|
trimBeforeValue
|
|
3160
3401
|
]);
|
|
3161
|
-
const classNameValue =
|
|
3162
|
-
return [
|
|
3402
|
+
const classNameValue = useMemo5(() => {
|
|
3403
|
+
return [Internals15.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals15.truthy).join(" ");
|
|
3163
3404
|
}, [className]);
|
|
3164
3405
|
if (replaceWithOffthreadVideo) {
|
|
3165
|
-
const fallback = /* @__PURE__ */ jsx5(
|
|
3406
|
+
const fallback = /* @__PURE__ */ jsx5(Internals15.InnerOffthreadVideo, {
|
|
3166
3407
|
src,
|
|
3167
3408
|
playbackRate: playbackRate ?? 1,
|
|
3168
3409
|
muted: muted ?? false,
|
|
@@ -3172,7 +3413,7 @@ var VideoForRendering = ({
|
|
|
3172
3413
|
delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined,
|
|
3173
3414
|
style,
|
|
3174
3415
|
allowAmplificationDuringRender: true,
|
|
3175
|
-
transparent: fallbackOffthreadVideoProps?.transparent ??
|
|
3416
|
+
transparent: fallbackOffthreadVideoProps?.transparent ?? true,
|
|
3176
3417
|
toneMapped: fallbackOffthreadVideoProps?.toneMapped ?? true,
|
|
3177
3418
|
audioStreamIndex: audioStreamIndex ?? 0,
|
|
3178
3419
|
name,
|
|
@@ -3202,7 +3443,7 @@ var VideoForRendering = ({
|
|
|
3202
3443
|
}
|
|
3203
3444
|
return /* @__PURE__ */ jsx5(Loop, {
|
|
3204
3445
|
layout: "none",
|
|
3205
|
-
durationInFrames:
|
|
3446
|
+
durationInFrames: calculateMediaDuration({
|
|
3206
3447
|
trimAfter: trimAfterValue,
|
|
3207
3448
|
mediaDurationInFrames: replaceWithOffthreadVideo.durationInSeconds * fps,
|
|
3208
3449
|
playbackRate,
|
|
@@ -3222,7 +3463,7 @@ var VideoForRendering = ({
|
|
|
3222
3463
|
|
|
3223
3464
|
// src/video/video.tsx
|
|
3224
3465
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
3225
|
-
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } =
|
|
3466
|
+
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } = Internals16;
|
|
3226
3467
|
var InnerVideo = ({
|
|
3227
3468
|
src,
|
|
3228
3469
|
audioStreamIndex,
|
|
@@ -3308,7 +3549,7 @@ var InnerVideo = ({
|
|
|
3308
3549
|
fallbackOffthreadVideoProps
|
|
3309
3550
|
});
|
|
3310
3551
|
};
|
|
3311
|
-
var
|
|
3552
|
+
var Video = ({
|
|
3312
3553
|
src,
|
|
3313
3554
|
audioStreamIndex,
|
|
3314
3555
|
className,
|
|
@@ -3355,14 +3596,14 @@ var Video2 = ({
|
|
|
3355
3596
|
stack
|
|
3356
3597
|
});
|
|
3357
3598
|
};
|
|
3358
|
-
|
|
3599
|
+
Internals16.addSequenceStackTraces(Video);
|
|
3359
3600
|
// src/index.ts
|
|
3360
|
-
var experimental_Audio =
|
|
3361
|
-
var experimental_Video =
|
|
3601
|
+
var experimental_Audio = Audio;
|
|
3602
|
+
var experimental_Video = Video;
|
|
3362
3603
|
export {
|
|
3363
3604
|
experimental_Video,
|
|
3364
3605
|
experimental_Audio,
|
|
3365
|
-
|
|
3606
|
+
Video,
|
|
3366
3607
|
AudioForPreview,
|
|
3367
|
-
|
|
3608
|
+
Audio
|
|
3368
3609
|
};
|