@remotion/media 4.0.358 → 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-rendering.js +3 -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 +76 -7
- package/dist/extract-frame-and-audio.js +6 -0
- package/dist/video/media-player.js +2 -0
- package/dist/video/video-for-rendering.js +19 -3
- 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 +6 -0
- package/dist/video-extraction/keyframe-manager.d.ts +1 -1
- package/dist/video-extraction/keyframe-manager.js +5 -0
- package/package.json +3 -3
|
@@ -81,6 +81,9 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
81
81
|
setReplaceWithHtml5Audio(true);
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
|
+
if (result.type === 'cannot-decode-alpha') {
|
|
85
|
+
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.`);
|
|
86
|
+
}
|
|
84
87
|
if (result.type === 'network-error') {
|
|
85
88
|
if (disallowFallbackToHtml5Audio) {
|
|
86
89
|
cancelRender(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const canBrowserUseWebGl2: () => boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
let browserCanUseWebGl2 = null;
|
|
2
|
+
const browserCanUseWebGl2Uncached = () => {
|
|
3
|
+
const canvas = new OffscreenCanvas(1, 1);
|
|
4
|
+
const context = canvas.getContext('webgl2');
|
|
5
|
+
return context !== null;
|
|
6
|
+
};
|
|
7
|
+
export const canBrowserUseWebGl2 = () => {
|
|
8
|
+
if (browserCanUseWebGl2 !== null) {
|
|
9
|
+
return browserCanUseWebGl2;
|
|
10
|
+
}
|
|
11
|
+
browserCanUseWebGl2 = browserCanUseWebGl2Uncached();
|
|
12
|
+
return browserCanUseWebGl2;
|
|
13
|
+
};
|
package/dist/caches.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare const keyframeManager: {
|
|
|
7
7
|
videoSampleSink: import("mediabunny").VideoSampleSink;
|
|
8
8
|
src: string;
|
|
9
9
|
logLevel: LogLevel;
|
|
10
|
-
}) => Promise<import("./video-extraction/keyframe-bank").KeyframeBank | null>;
|
|
10
|
+
}) => Promise<import("./video-extraction/keyframe-bank").KeyframeBank | "has-alpha" | null>;
|
|
11
11
|
getCacheStats: () => Promise<{
|
|
12
12
|
count: number;
|
|
13
13
|
totalSize: number;
|
package/dist/caches.js
CHANGED
|
@@ -28,9 +28,9 @@ const getUncachedMaxCacheSize = (logLevel) => {
|
|
|
28
28
|
if (window.remotion_initialMemoryAvailable !== undefined &&
|
|
29
29
|
window.remotion_initialMemoryAvailable !== null) {
|
|
30
30
|
const value = window.remotion_initialMemoryAvailable / 2;
|
|
31
|
-
if (value <
|
|
32
|
-
Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set based on minimum value of
|
|
33
|
-
return
|
|
31
|
+
if (value < 500 * 1024 * 1024) {
|
|
32
|
+
Internals.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!)`);
|
|
33
|
+
return 500 * 1024 * 1024;
|
|
34
34
|
}
|
|
35
35
|
if (value > 20000 * 1024 * 1024) {
|
|
36
36
|
Internals.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)`);
|
package/dist/esm/index.mjs
CHANGED
|
@@ -361,7 +361,8 @@ class MediaPlayer {
|
|
|
361
361
|
}
|
|
362
362
|
this.canvasSink = new CanvasSink(videoTrack, {
|
|
363
363
|
poolSize: 2,
|
|
364
|
-
fit: "contain"
|
|
364
|
+
fit: "contain",
|
|
365
|
+
alpha: true
|
|
365
366
|
});
|
|
366
367
|
this.canvas.width = videoTrack.displayWidth;
|
|
367
368
|
this.canvas.height = videoTrack.displayHeight;
|
|
@@ -582,6 +583,7 @@ class MediaPlayer {
|
|
|
582
583
|
}
|
|
583
584
|
drawCurrentFrame() {
|
|
584
585
|
if (this.context && this.nextFrame) {
|
|
586
|
+
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
585
587
|
this.context.drawImage(this.nextFrame.canvas, 0, 0);
|
|
586
588
|
}
|
|
587
589
|
if (this.onVideoFrameCallback && this.canvas) {
|
|
@@ -1527,6 +1529,21 @@ var makeAudioManager = () => {
|
|
|
1527
1529
|
// src/video-extraction/keyframe-manager.ts
|
|
1528
1530
|
import { Internals as Internals9 } from "remotion";
|
|
1529
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
|
+
};
|
|
1546
|
+
|
|
1530
1547
|
// src/render-timestamp-range.ts
|
|
1531
1548
|
var renderTimestampRange = (timestamps) => {
|
|
1532
1549
|
if (timestamps.length === 0) {
|
|
@@ -1927,6 +1944,10 @@ var makeKeyframeManager = () => {
|
|
|
1927
1944
|
const startPacket = await packetSink.getKeyPacket(timestamp, {
|
|
1928
1945
|
verifyKeyPackets: true
|
|
1929
1946
|
});
|
|
1947
|
+
const hasAlpha = startPacket?.sideData.alpha;
|
|
1948
|
+
if (hasAlpha && !canBrowserUseWebGl2()) {
|
|
1949
|
+
return "has-alpha";
|
|
1950
|
+
}
|
|
1930
1951
|
if (!startPacket) {
|
|
1931
1952
|
return null;
|
|
1932
1953
|
}
|
|
@@ -2038,9 +2059,9 @@ var getUncachedMaxCacheSize = (logLevel) => {
|
|
|
2038
2059
|
}
|
|
2039
2060
|
if (window.remotion_initialMemoryAvailable !== undefined && window.remotion_initialMemoryAvailable !== null) {
|
|
2040
2061
|
const value = window.remotion_initialMemoryAvailable / 2;
|
|
2041
|
-
if (value <
|
|
2042
|
-
Internals10.Log.verbose({ logLevel, tag: "@remotion/media" }, `Using cache size set based on minimum value of
|
|
2043
|
-
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;
|
|
2044
2065
|
}
|
|
2045
2066
|
if (value > 20000 * 1024 * 1024) {
|
|
2046
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)`);
|
|
@@ -2302,6 +2323,12 @@ var extractFrameInternal = async ({
|
|
|
2302
2323
|
src,
|
|
2303
2324
|
logLevel
|
|
2304
2325
|
});
|
|
2326
|
+
if (keyframeBank === "has-alpha") {
|
|
2327
|
+
return {
|
|
2328
|
+
type: "cannot-decode-alpha",
|
|
2329
|
+
durationInSeconds: await sink.getDuration()
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2305
2332
|
if (!keyframeBank) {
|
|
2306
2333
|
return {
|
|
2307
2334
|
type: "success",
|
|
@@ -2367,6 +2394,12 @@ var extractFrameAndAudio = async ({
|
|
|
2367
2394
|
if (frame?.type === "unknown-container-format") {
|
|
2368
2395
|
return { type: "unknown-container-format" };
|
|
2369
2396
|
}
|
|
2397
|
+
if (frame?.type === "cannot-decode-alpha") {
|
|
2398
|
+
return {
|
|
2399
|
+
type: "cannot-decode-alpha",
|
|
2400
|
+
durationInSeconds: frame.durationInSeconds
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2370
2403
|
if (audio === "unknown-container-format") {
|
|
2371
2404
|
if (frame !== null) {
|
|
2372
2405
|
frame?.frame?.close();
|
|
@@ -2426,6 +2459,15 @@ if (window.remotion_broadcastChannel && window.remotion_isMainTab) {
|
|
|
2426
2459
|
window.remotion_broadcastChannel.postMessage(cannotDecodeResponse);
|
|
2427
2460
|
return;
|
|
2428
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
|
+
}
|
|
2429
2471
|
if (result.type === "network-error") {
|
|
2430
2472
|
const networkErrorResponse = {
|
|
2431
2473
|
type: "response-network-error",
|
|
@@ -2544,6 +2586,14 @@ var extractFrameViaBroadcastChannel = ({
|
|
|
2544
2586
|
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
2545
2587
|
return;
|
|
2546
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
|
+
}
|
|
2547
2597
|
throw new Error(`Invalid message: ${JSON.stringify(data)}`);
|
|
2548
2598
|
};
|
|
2549
2599
|
window.remotion_broadcastChannel.addEventListener("message", onMessage);
|
|
@@ -2673,6 +2723,9 @@ var AudioForRendering = ({
|
|
|
2673
2723
|
setReplaceWithHtml5Audio(true);
|
|
2674
2724
|
return;
|
|
2675
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
|
+
}
|
|
2676
2729
|
if (result.type === "network-error") {
|
|
2677
2730
|
if (disallowFallbackToHtml5Audio) {
|
|
2678
2731
|
cancelRender2(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
@@ -3236,6 +3289,18 @@ var VideoForRendering = ({
|
|
|
3236
3289
|
});
|
|
3237
3290
|
return;
|
|
3238
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>`);
|
|
3298
|
+
}
|
|
3299
|
+
setReplaceWithOffthreadVideo({
|
|
3300
|
+
durationInSeconds: result.durationInSeconds
|
|
3301
|
+
});
|
|
3302
|
+
return;
|
|
3303
|
+
}
|
|
3239
3304
|
if (result.type === "network-error") {
|
|
3240
3305
|
if (disallowFallbackToOffthreadVideo) {
|
|
3241
3306
|
cancelRender3(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
@@ -3253,7 +3318,9 @@ var VideoForRendering = ({
|
|
|
3253
3318
|
} = result;
|
|
3254
3319
|
if (imageBitmap) {
|
|
3255
3320
|
onVideoFrame?.(imageBitmap);
|
|
3256
|
-
const context = canvasRef.current?.getContext("2d"
|
|
3321
|
+
const context = canvasRef.current?.getContext("2d", {
|
|
3322
|
+
alpha: true
|
|
3323
|
+
});
|
|
3257
3324
|
if (!context) {
|
|
3258
3325
|
return;
|
|
3259
3326
|
}
|
|
@@ -3263,7 +3330,9 @@ var VideoForRendering = ({
|
|
|
3263
3330
|
context.drawImage(imageBitmap, 0, 0);
|
|
3264
3331
|
imageBitmap.close();
|
|
3265
3332
|
} else if (window.remotion_videoEnabled) {
|
|
3266
|
-
const context = canvasRef.current?.getContext("2d"
|
|
3333
|
+
const context = canvasRef.current?.getContext("2d", {
|
|
3334
|
+
alpha: true
|
|
3335
|
+
});
|
|
3267
3336
|
if (context) {
|
|
3268
3337
|
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
|
|
3269
3338
|
}
|
|
@@ -3344,7 +3413,7 @@ var VideoForRendering = ({
|
|
|
3344
3413
|
delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined,
|
|
3345
3414
|
style,
|
|
3346
3415
|
allowAmplificationDuringRender: true,
|
|
3347
|
-
transparent: fallbackOffthreadVideoProps?.transparent ??
|
|
3416
|
+
transparent: fallbackOffthreadVideoProps?.transparent ?? true,
|
|
3348
3417
|
toneMapped: fallbackOffthreadVideoProps?.toneMapped ?? true,
|
|
3349
3418
|
audioStreamIndex: audioStreamIndex ?? 0,
|
|
3350
3419
|
name,
|
|
@@ -40,6 +40,12 @@ export const extractFrameAndAudio = async ({ src, timeInSeconds, logLevel, durat
|
|
|
40
40
|
if (frame?.type === 'unknown-container-format') {
|
|
41
41
|
return { type: 'unknown-container-format' };
|
|
42
42
|
}
|
|
43
|
+
if (frame?.type === 'cannot-decode-alpha') {
|
|
44
|
+
return {
|
|
45
|
+
type: 'cannot-decode-alpha',
|
|
46
|
+
durationInSeconds: frame.durationInSeconds,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
43
49
|
if (audio === 'unknown-container-format') {
|
|
44
50
|
if (frame !== null) {
|
|
45
51
|
frame?.frame?.close();
|
|
@@ -258,6 +258,7 @@ export class MediaPlayer {
|
|
|
258
258
|
this.canvasSink = new CanvasSink(videoTrack, {
|
|
259
259
|
poolSize: 2,
|
|
260
260
|
fit: 'contain',
|
|
261
|
+
alpha: true,
|
|
261
262
|
});
|
|
262
263
|
this.canvas.width = videoTrack.displayWidth;
|
|
263
264
|
this.canvas.height = videoTrack.displayHeight;
|
|
@@ -473,6 +474,7 @@ export class MediaPlayer {
|
|
|
473
474
|
}
|
|
474
475
|
drawCurrentFrame() {
|
|
475
476
|
if (this.context && this.nextFrame) {
|
|
477
|
+
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
476
478
|
this.context.drawImage(this.nextFrame.canvas, 0, 0);
|
|
477
479
|
}
|
|
478
480
|
if (this.onVideoFrameCallback && this.canvas) {
|
|
@@ -88,6 +88,18 @@ export const VideoForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
88
88
|
});
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
|
+
if (result.type === 'cannot-decode-alpha') {
|
|
92
|
+
if (disallowFallbackToOffthreadVideo) {
|
|
93
|
+
cancelRender(new Error(`Cannot decode alpha component for ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
94
|
+
}
|
|
95
|
+
if (window.remotion_isMainTab) {
|
|
96
|
+
Internals.Log.info({ logLevel, tag: '@remotion/media' }, `Cannot decode alpha component for ${src}, falling back to <OffthreadVideo>`);
|
|
97
|
+
}
|
|
98
|
+
setReplaceWithOffthreadVideo({
|
|
99
|
+
durationInSeconds: result.durationInSeconds,
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
91
103
|
if (result.type === 'network-error') {
|
|
92
104
|
if (disallowFallbackToOffthreadVideo) {
|
|
93
105
|
cancelRender(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
@@ -101,7 +113,9 @@ export const VideoForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
101
113
|
const { frame: imageBitmap, audio, durationInSeconds: assetDurationInSeconds, } = result;
|
|
102
114
|
if (imageBitmap) {
|
|
103
115
|
onVideoFrame?.(imageBitmap);
|
|
104
|
-
const context = canvasRef.current?.getContext('2d'
|
|
116
|
+
const context = canvasRef.current?.getContext('2d', {
|
|
117
|
+
alpha: true,
|
|
118
|
+
});
|
|
105
119
|
if (!context) {
|
|
106
120
|
return;
|
|
107
121
|
}
|
|
@@ -121,7 +135,9 @@ export const VideoForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
121
135
|
// In the case of https://discord.com/channels/809501355504959528/809501355504959531/1424400511070765086
|
|
122
136
|
// A video that only starts at time 0.033sec
|
|
123
137
|
// we shall not crash here but clear the canvas
|
|
124
|
-
const context = canvasRef.current?.getContext('2d'
|
|
138
|
+
const context = canvasRef.current?.getContext('2d', {
|
|
139
|
+
alpha: true,
|
|
140
|
+
});
|
|
125
141
|
if (context) {
|
|
126
142
|
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
|
|
127
143
|
}
|
|
@@ -195,7 +211,7 @@ export const VideoForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
195
211
|
.join(' ');
|
|
196
212
|
}, [className]);
|
|
197
213
|
if (replaceWithOffthreadVideo) {
|
|
198
|
-
const fallback = (_jsx(Internals.InnerOffthreadVideo, { src: src, playbackRate: playbackRate ?? 1, muted: muted ?? false, acceptableTimeShiftInSeconds: fallbackOffthreadVideoProps?.acceptableTimeShiftInSeconds, loopVolumeCurveBehavior: loopVolumeCurveBehavior ?? 'repeat', delayRenderRetries: delayRenderRetries ?? undefined, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined, style: style, allowAmplificationDuringRender: true, transparent: fallbackOffthreadVideoProps?.transparent ??
|
|
214
|
+
const fallback = (_jsx(Internals.InnerOffthreadVideo, { src: src, playbackRate: playbackRate ?? 1, muted: muted ?? false, acceptableTimeShiftInSeconds: fallbackOffthreadVideoProps?.acceptableTimeShiftInSeconds, loopVolumeCurveBehavior: loopVolumeCurveBehavior ?? 'repeat', delayRenderRetries: delayRenderRetries ?? undefined, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined, style: style, allowAmplificationDuringRender: true, transparent: fallbackOffthreadVideoProps?.transparent ?? true, toneMapped: fallbackOffthreadVideoProps?.toneMapped ?? true, audioStreamIndex: audioStreamIndex ?? 0, name: name, className: className, onVideoFrame: onVideoFrame, volume: volumeProp, id: id, onError: fallbackOffthreadVideoProps?.onError, toneFrequency: fallbackOffthreadVideoProps?.toneFrequency ?? 1,
|
|
199
215
|
// these shouldn't matter during rendering / should not appear at all
|
|
200
216
|
showInTimeline: false, crossOrigin: undefined, onAutoPlayError: () => undefined, pauseWhenBuffering: false, trimAfter: undefined, trimBefore: undefined, useWebAudioApi: false, startFrom: undefined, endAt: undefined, stack: stack, _remotionInternalNativeLoopPassed: false }));
|
|
201
217
|
if (loop) {
|
|
@@ -28,6 +28,15 @@ if (window.remotion_broadcastChannel && window.remotion_isMainTab) {
|
|
|
28
28
|
window.remotion_broadcastChannel.postMessage(cannotDecodeResponse);
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
|
+
if (result.type === 'cannot-decode-alpha') {
|
|
32
|
+
const cannotDecodeAlphaResponse = {
|
|
33
|
+
type: 'response-cannot-decode-alpha',
|
|
34
|
+
id: data.id,
|
|
35
|
+
durationInSeconds: result.durationInSeconds,
|
|
36
|
+
};
|
|
37
|
+
window.remotion_broadcastChannel.postMessage(cannotDecodeAlphaResponse);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
31
40
|
if (result.type === 'network-error') {
|
|
32
41
|
const networkErrorResponse = {
|
|
33
42
|
type: 'response-network-error',
|
|
@@ -138,6 +147,14 @@ export const extractFrameViaBroadcastChannel = ({ src, timeInSeconds, logLevel,
|
|
|
138
147
|
window.remotion_broadcastChannel.removeEventListener('message', onMessage);
|
|
139
148
|
return;
|
|
140
149
|
}
|
|
150
|
+
if (data.type === 'response-cannot-decode-alpha') {
|
|
151
|
+
resolve({
|
|
152
|
+
type: 'cannot-decode-alpha',
|
|
153
|
+
durationInSeconds: data.durationInSeconds,
|
|
154
|
+
});
|
|
155
|
+
window.remotion_broadcastChannel.removeEventListener('message', onMessage);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
141
158
|
throw new Error(`Invalid message: ${JSON.stringify(data)}`);
|
|
142
159
|
};
|
|
143
160
|
window.remotion_broadcastChannel.addEventListener('message', onMessage);
|
|
@@ -42,6 +42,12 @@ const extractFrameInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds,
|
|
|
42
42
|
src,
|
|
43
43
|
logLevel,
|
|
44
44
|
});
|
|
45
|
+
if (keyframeBank === 'has-alpha') {
|
|
46
|
+
return {
|
|
47
|
+
type: 'cannot-decode-alpha',
|
|
48
|
+
durationInSeconds: await sink.getDuration(),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
45
51
|
if (!keyframeBank) {
|
|
46
52
|
return {
|
|
47
53
|
type: 'success',
|
|
@@ -8,7 +8,7 @@ export declare const makeKeyframeManager: () => {
|
|
|
8
8
|
videoSampleSink: VideoSampleSink;
|
|
9
9
|
src: string;
|
|
10
10
|
logLevel: LogLevel;
|
|
11
|
-
}) => Promise<KeyframeBank | null>;
|
|
11
|
+
}) => Promise<KeyframeBank | "has-alpha" | null>;
|
|
12
12
|
getCacheStats: () => Promise<{
|
|
13
13
|
count: number;
|
|
14
14
|
totalSize: number;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Internals } from 'remotion';
|
|
2
|
+
import { canBrowserUseWebGl2 } from '../browser-can-use-webgl2';
|
|
2
3
|
import { getMaxVideoCacheSize, getTotalCacheStats, SAFE_BACK_WINDOW_IN_SECONDS, } from '../caches';
|
|
3
4
|
import { renderTimestampRange } from '../render-timestamp-range';
|
|
4
5
|
import { getFramesSinceKeyframe } from './get-frames-since-keyframe';
|
|
@@ -104,6 +105,10 @@ export const makeKeyframeManager = () => {
|
|
|
104
105
|
const startPacket = await packetSink.getKeyPacket(timestamp, {
|
|
105
106
|
verifyKeyPackets: true,
|
|
106
107
|
});
|
|
108
|
+
const hasAlpha = startPacket?.sideData.alpha;
|
|
109
|
+
if (hasAlpha && !canBrowserUseWebGl2()) {
|
|
110
|
+
return 'has-alpha';
|
|
111
|
+
}
|
|
107
112
|
if (!startPacket) {
|
|
108
113
|
// e.g. https://discord.com/channels/809501355504959528/809501355504959531/1424400511070765086
|
|
109
114
|
// The video has an offset and the first frame is at time 0.033sec
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.361",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"mediabunny": "1.23.0",
|
|
25
|
-
"remotion": "4.0.
|
|
25
|
+
"remotion": "4.0.361",
|
|
26
26
|
"webdriverio": "9.19.2"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"react-dom": ">=16.8.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
33
|
+
"@remotion/eslint-config-internal": "4.0.361",
|
|
34
34
|
"@vitest/browser": "^3.2.4",
|
|
35
35
|
"eslint": "9.19.0",
|
|
36
36
|
"react": "19.0.0",
|