@remotion/media 4.0.453 → 4.0.455
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-extraction/extract-audio.d.ts +1 -1
- package/dist/debug-overlay/preview-overlay.d.ts +1 -1
- package/dist/esm/index.mjs +150 -37
- package/dist/extract-frame-and-audio.d.ts +1 -1
- package/dist/get-duration-or-compute.d.ts +2 -0
- package/dist/get-sink.d.ts +1 -1
- package/dist/helpers/resolve-audio-track.d.ts +6 -0
- package/dist/index.d.ts +1 -0
- package/dist/media-player.d.ts +10 -2
- package/dist/use-media-in-timeline.d.ts +3 -2
- package/dist/video/props.d.ts +2 -0
- package/dist/video/video-for-preview.d.ts +2 -1
- package/dist/video/video.d.ts +1 -0
- package/dist/video-extraction/add-broadcast-channel-listener.d.ts +1 -1
- package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +1 -1
- package/dist/video-extraction/get-frames-since-keyframe.d.ts +1 -1
- package/dist/video-iterator-manager.d.ts +9 -5
- package/package.json +4 -4
|
@@ -86,7 +86,7 @@ export declare const drawPreviewOverlay: ({ context, audioTime, audioContextStat
|
|
|
86
86
|
frame: import("mediabunny").WrappedCanvas;
|
|
87
87
|
};
|
|
88
88
|
} | null;
|
|
89
|
-
drawFrame: (frame: import("mediabunny").WrappedCanvas) => void
|
|
89
|
+
drawFrame: (frame: import("mediabunny").WrappedCanvas) => Promise<void>;
|
|
90
90
|
getFramesRendered: () => number;
|
|
91
91
|
} | null;
|
|
92
92
|
playbackRate: number;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -758,6 +758,28 @@ var drawPreviewOverlay = ({
|
|
|
758
758
|
}
|
|
759
759
|
};
|
|
760
760
|
|
|
761
|
+
// src/get-duration-or-compute.ts
|
|
762
|
+
var getDurationOrCompute = async (input) => {
|
|
763
|
+
return await input.getDurationFromMetadata(undefined, {
|
|
764
|
+
skipLiveWait: true
|
|
765
|
+
}) ?? input.computeDuration(undefined, { skipLiveWait: true });
|
|
766
|
+
};
|
|
767
|
+
|
|
768
|
+
// src/helpers/resolve-audio-track.ts
|
|
769
|
+
var resolveAudioTrack = async ({
|
|
770
|
+
videoTrack,
|
|
771
|
+
audioTracks,
|
|
772
|
+
audioStreamIndex
|
|
773
|
+
}) => {
|
|
774
|
+
if (audioStreamIndex !== null) {
|
|
775
|
+
return audioTracks[audioStreamIndex] ?? null;
|
|
776
|
+
}
|
|
777
|
+
if (videoTrack) {
|
|
778
|
+
return await videoTrack.getPrimaryPairableAudioTrack() ?? null;
|
|
779
|
+
}
|
|
780
|
+
return audioTracks[0] ?? null;
|
|
781
|
+
};
|
|
782
|
+
|
|
761
783
|
// src/is-type-of-error.ts
|
|
762
784
|
function isNetworkError(error) {
|
|
763
785
|
if (error.message.includes("Failed to fetch") || error.message.includes("Load failed") || error.message.includes("NetworkError when attempting to fetch resource")) {
|
|
@@ -1013,7 +1035,8 @@ var createVideoIterator = async (timeToSeek, cache) => {
|
|
|
1013
1035
|
};
|
|
1014
1036
|
|
|
1015
1037
|
// src/video-iterator-manager.ts
|
|
1016
|
-
var
|
|
1038
|
+
var { runEffectChain } = Internals3;
|
|
1039
|
+
var videoIteratorManager = async ({
|
|
1017
1040
|
delayPlaybackHandleIfNotPremounting,
|
|
1018
1041
|
canvas,
|
|
1019
1042
|
context,
|
|
@@ -1023,16 +1046,21 @@ var videoIteratorManager = ({
|
|
|
1023
1046
|
videoTrack,
|
|
1024
1047
|
getLoopSegmentMediaEndTimestamp,
|
|
1025
1048
|
getStartTime,
|
|
1026
|
-
getIsLooping
|
|
1049
|
+
getIsLooping,
|
|
1050
|
+
getEffects,
|
|
1051
|
+
getEffectChainState,
|
|
1052
|
+
getCurrentFrame
|
|
1027
1053
|
}) => {
|
|
1028
1054
|
let videoIteratorsCreated = 0;
|
|
1029
1055
|
let videoFrameIterator = null;
|
|
1030
1056
|
let framesRendered = 0;
|
|
1031
1057
|
let currentDelayHandle = null;
|
|
1032
1058
|
if (canvas) {
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1059
|
+
const displayWidth = await videoTrack.getDisplayWidth();
|
|
1060
|
+
const displayHeight = await videoTrack.getDisplayHeight();
|
|
1061
|
+
if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
|
|
1062
|
+
canvas.width = displayWidth;
|
|
1063
|
+
canvas.height = displayHeight;
|
|
1036
1064
|
}
|
|
1037
1065
|
}
|
|
1038
1066
|
const canvasSink = new CanvasSink(videoTrack, {
|
|
@@ -1041,10 +1069,24 @@ var videoIteratorManager = ({
|
|
|
1041
1069
|
alpha: true
|
|
1042
1070
|
});
|
|
1043
1071
|
const prewarmedVideoIteratorCache = makePrewarmedVideoIteratorCache(canvasSink);
|
|
1044
|
-
const drawFrame = (frame) => {
|
|
1072
|
+
const drawFrame = async (frame) => {
|
|
1045
1073
|
if (context && canvas) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1074
|
+
const effects = getEffects();
|
|
1075
|
+
const chainState = getEffectChainState(canvas.width, canvas.height);
|
|
1076
|
+
if (effects.length > 0 && chainState && canvas instanceof HTMLCanvasElement) {
|
|
1077
|
+
await runEffectChain({
|
|
1078
|
+
state: chainState,
|
|
1079
|
+
source: frame.canvas,
|
|
1080
|
+
effects,
|
|
1081
|
+
output: canvas,
|
|
1082
|
+
frame: getCurrentFrame(),
|
|
1083
|
+
width: canvas.width,
|
|
1084
|
+
height: canvas.height
|
|
1085
|
+
});
|
|
1086
|
+
} else {
|
|
1087
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
1088
|
+
context.drawImage(frame.canvas, 0, 0);
|
|
1089
|
+
}
|
|
1048
1090
|
}
|
|
1049
1091
|
framesRendered++;
|
|
1050
1092
|
drawDebugOverlay();
|
|
@@ -1075,7 +1117,7 @@ var videoIteratorManager = ({
|
|
|
1075
1117
|
if (!iterator.initialFrame) {
|
|
1076
1118
|
return;
|
|
1077
1119
|
}
|
|
1078
|
-
drawFrame(iterator.initialFrame);
|
|
1120
|
+
await drawFrame(iterator.initialFrame);
|
|
1079
1121
|
} catch (_catch) {
|
|
1080
1122
|
var _err = _catch, _hasErr = 1;
|
|
1081
1123
|
} finally {
|
|
@@ -1095,7 +1137,7 @@ var videoIteratorManager = ({
|
|
|
1095
1137
|
}
|
|
1096
1138
|
const videoSatisfyResult = videoFrameIterator.tryToSatisfySeek(newTime);
|
|
1097
1139
|
if (videoSatisfyResult.type === "satisfied") {
|
|
1098
|
-
drawFrame(videoSatisfyResult.frame);
|
|
1140
|
+
await drawFrame(videoSatisfyResult.frame);
|
|
1099
1141
|
return;
|
|
1100
1142
|
}
|
|
1101
1143
|
if (nonce.isStale()) {
|
|
@@ -1149,6 +1191,9 @@ class MediaPlayer {
|
|
|
1149
1191
|
debugOverlay = false;
|
|
1150
1192
|
nonceManager;
|
|
1151
1193
|
onVideoFrameCallback = null;
|
|
1194
|
+
getEffects;
|
|
1195
|
+
getEffectChainState;
|
|
1196
|
+
getCurrentFrame;
|
|
1152
1197
|
initializationPromise = null;
|
|
1153
1198
|
bufferState;
|
|
1154
1199
|
isPremounting;
|
|
@@ -1175,7 +1220,10 @@ class MediaPlayer {
|
|
|
1175
1220
|
playing,
|
|
1176
1221
|
sequenceOffset,
|
|
1177
1222
|
credentials,
|
|
1178
|
-
tagType
|
|
1223
|
+
tagType,
|
|
1224
|
+
getEffects,
|
|
1225
|
+
getEffectChainState,
|
|
1226
|
+
getCurrentFrame
|
|
1179
1227
|
}) {
|
|
1180
1228
|
this.canvas = canvas ?? null;
|
|
1181
1229
|
this.src = src;
|
|
@@ -1186,7 +1234,7 @@ class MediaPlayer {
|
|
|
1186
1234
|
this.loop = loop;
|
|
1187
1235
|
this.trimBefore = trimBefore;
|
|
1188
1236
|
this.trimAfter = trimAfter;
|
|
1189
|
-
this.audioStreamIndex = audioStreamIndex
|
|
1237
|
+
this.audioStreamIndex = audioStreamIndex;
|
|
1190
1238
|
this.fps = fps;
|
|
1191
1239
|
this.debugOverlay = debugOverlay;
|
|
1192
1240
|
this.bufferState = bufferState;
|
|
@@ -1204,6 +1252,9 @@ class MediaPlayer {
|
|
|
1204
1252
|
formats: ALL_FORMATS
|
|
1205
1253
|
});
|
|
1206
1254
|
this.tagType = tagType;
|
|
1255
|
+
this.getEffects = getEffects;
|
|
1256
|
+
this.getEffectChainState = getEffectChainState;
|
|
1257
|
+
this.getCurrentFrame = getCurrentFrame;
|
|
1207
1258
|
if (canvas) {
|
|
1208
1259
|
const context = canvas.getContext("2d", {
|
|
1209
1260
|
alpha: true,
|
|
@@ -1271,7 +1322,7 @@ class MediaPlayer {
|
|
|
1271
1322
|
return { type: "unknown-container-format" };
|
|
1272
1323
|
}
|
|
1273
1324
|
const [durationInSeconds, videoTrack, audioTracks] = await Promise.all([
|
|
1274
|
-
this.input
|
|
1325
|
+
getDurationOrCompute(this.input),
|
|
1275
1326
|
this.input.getPrimaryVideoTrack(),
|
|
1276
1327
|
this.input.getAudioTracks()
|
|
1277
1328
|
]);
|
|
@@ -1279,11 +1330,21 @@ class MediaPlayer {
|
|
|
1279
1330
|
return { type: "disposed" };
|
|
1280
1331
|
}
|
|
1281
1332
|
this.totalDuration = durationInSeconds;
|
|
1282
|
-
const audioTrack =
|
|
1333
|
+
const audioTrack = await resolveAudioTrack({
|
|
1334
|
+
videoTrack,
|
|
1335
|
+
audioTracks,
|
|
1336
|
+
audioStreamIndex: this.audioStreamIndex
|
|
1337
|
+
});
|
|
1283
1338
|
if (!videoTrack && !audioTrack) {
|
|
1284
1339
|
return { type: "no-tracks" };
|
|
1285
1340
|
}
|
|
1286
1341
|
if (videoTrack && this.tagType === "video") {
|
|
1342
|
+
if (await videoTrack.isLive()) {
|
|
1343
|
+
throw new Error("Live streams are not currently supported by Remotion. Sorry! Source: " + this.src);
|
|
1344
|
+
}
|
|
1345
|
+
if (await videoTrack.isRelativeToUnixEpoch()) {
|
|
1346
|
+
throw new Error("Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: " + this.src);
|
|
1347
|
+
}
|
|
1287
1348
|
const canDecode = await videoTrack.canDecode();
|
|
1288
1349
|
if (!canDecode) {
|
|
1289
1350
|
return { type: "cannot-decode" };
|
|
@@ -1291,7 +1352,7 @@ class MediaPlayer {
|
|
|
1291
1352
|
if (this.input.disposed) {
|
|
1292
1353
|
return { type: "disposed" };
|
|
1293
1354
|
}
|
|
1294
|
-
this.videoIteratorManager = videoIteratorManager({
|
|
1355
|
+
this.videoIteratorManager = await videoIteratorManager({
|
|
1295
1356
|
videoTrack,
|
|
1296
1357
|
delayPlaybackHandleIfNotPremounting: this.delayPlaybackHandleIfNotPremounting,
|
|
1297
1358
|
context: this.context,
|
|
@@ -1301,7 +1362,10 @@ class MediaPlayer {
|
|
|
1301
1362
|
drawDebugOverlay: this.drawDebugOverlay,
|
|
1302
1363
|
getLoopSegmentMediaEndTimestamp: () => this.getLoopSegmentMediaEndTimestamp(),
|
|
1303
1364
|
getStartTime: () => this.getStartTime(),
|
|
1304
|
-
getIsLooping: () => this.loop
|
|
1365
|
+
getIsLooping: () => this.loop,
|
|
1366
|
+
getEffects: this.getEffects,
|
|
1367
|
+
getEffectChainState: this.getEffectChainState,
|
|
1368
|
+
getCurrentFrame: this.getCurrentFrame
|
|
1305
1369
|
});
|
|
1306
1370
|
}
|
|
1307
1371
|
const startTime = this.getTrimmedTime(startTimeUnresolved);
|
|
@@ -1309,6 +1373,12 @@ class MediaPlayer {
|
|
|
1309
1373
|
throw new Error(`should have asserted that the time is not null`);
|
|
1310
1374
|
}
|
|
1311
1375
|
if (audioTrack && this.sharedAudioContext) {
|
|
1376
|
+
if (await audioTrack.isLive()) {
|
|
1377
|
+
throw new Error("Live streams are not currently supported by Remotion. Sorry! Source: " + this.src);
|
|
1378
|
+
}
|
|
1379
|
+
if (await audioTrack.isRelativeToUnixEpoch()) {
|
|
1380
|
+
throw new Error("Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: " + this.src);
|
|
1381
|
+
}
|
|
1312
1382
|
const canDecode = await audioTrack.canDecode();
|
|
1313
1383
|
if (!canDecode) {
|
|
1314
1384
|
return { type: "cannot-decode" };
|
|
@@ -1856,7 +1926,8 @@ var useMediaInTimeline = ({
|
|
|
1856
1926
|
loopDisplay,
|
|
1857
1927
|
trimBefore,
|
|
1858
1928
|
trimAfter,
|
|
1859
|
-
controls
|
|
1929
|
+
controls,
|
|
1930
|
+
_experimentalEffects
|
|
1860
1931
|
}) => {
|
|
1861
1932
|
const parentSequence = useContext2(Internals7.SequenceContext);
|
|
1862
1933
|
const startsAt = Internals7.useMediaStartsAt();
|
|
@@ -1909,7 +1980,8 @@ var useMediaInTimeline = ({
|
|
|
1909
1980
|
stack,
|
|
1910
1981
|
premountDisplay,
|
|
1911
1982
|
postmountDisplay,
|
|
1912
|
-
controls: controls ?? null
|
|
1983
|
+
controls: controls ?? null,
|
|
1984
|
+
effects: _experimentalEffects
|
|
1913
1985
|
});
|
|
1914
1986
|
return () => {
|
|
1915
1987
|
unregisterSequence(mediaId);
|
|
@@ -1936,7 +2008,8 @@ var useMediaInTimeline = ({
|
|
|
1936
2008
|
startsAt,
|
|
1937
2009
|
unregisterSequence,
|
|
1938
2010
|
volumes,
|
|
1939
|
-
trimBefore
|
|
2011
|
+
trimBefore,
|
|
2012
|
+
_experimentalEffects
|
|
1940
2013
|
]);
|
|
1941
2014
|
return {
|
|
1942
2015
|
id: mediaId
|
|
@@ -2021,6 +2094,9 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
2021
2094
|
trimAfter,
|
|
2022
2095
|
trimBefore
|
|
2023
2096
|
});
|
|
2097
|
+
const effects = useMemo2(() => {
|
|
2098
|
+
return [];
|
|
2099
|
+
}, []);
|
|
2024
2100
|
useMediaInTimeline({
|
|
2025
2101
|
volume,
|
|
2026
2102
|
mediaVolume,
|
|
@@ -2035,7 +2111,8 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
2035
2111
|
loopDisplay,
|
|
2036
2112
|
trimAfter,
|
|
2037
2113
|
trimBefore,
|
|
2038
|
-
controls
|
|
2114
|
+
controls,
|
|
2115
|
+
_experimentalEffects: effects
|
|
2039
2116
|
});
|
|
2040
2117
|
const bufferingContext = useContext3(Internals8.BufferingContextReact);
|
|
2041
2118
|
if (!bufferingContext) {
|
|
@@ -2106,7 +2183,7 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
2106
2183
|
fps: videoConfig.fps,
|
|
2107
2184
|
canvas: null,
|
|
2108
2185
|
playbackRate: initialPlaybackRate.current,
|
|
2109
|
-
audioStreamIndex: audioStreamIndex ??
|
|
2186
|
+
audioStreamIndex: audioStreamIndex ?? null,
|
|
2110
2187
|
debugOverlay: false,
|
|
2111
2188
|
bufferState: buffer,
|
|
2112
2189
|
isPostmounting: initialIsPostmounting.current,
|
|
@@ -2117,7 +2194,10 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
2117
2194
|
playing: initialPlaying.current,
|
|
2118
2195
|
sequenceOffset: initialSequenceOffset.current,
|
|
2119
2196
|
credentials,
|
|
2120
|
-
tagType: "audio"
|
|
2197
|
+
tagType: "audio",
|
|
2198
|
+
getEffects: () => [],
|
|
2199
|
+
getEffectChainState: () => null,
|
|
2200
|
+
getCurrentFrame: () => 0
|
|
2121
2201
|
});
|
|
2122
2202
|
mediaPlayerRef.current = player;
|
|
2123
2203
|
player.initialize(currentTimeRef.current, initialMuted.current).then((result) => {
|
|
@@ -2283,7 +2363,7 @@ var AudioForPreview = ({
|
|
|
2283
2363
|
return null;
|
|
2284
2364
|
}
|
|
2285
2365
|
return /* @__PURE__ */ jsx(AudioForPreviewAssertedShowing, {
|
|
2286
|
-
audioStreamIndex
|
|
2366
|
+
audioStreamIndex,
|
|
2287
2367
|
src: preloadedSrc,
|
|
2288
2368
|
playbackRate,
|
|
2289
2369
|
logLevel: logLevel ?? defaultLogLevel,
|
|
@@ -3495,6 +3575,12 @@ var getSinks = async (src, credentials) => {
|
|
|
3495
3575
|
if (!videoTrack) {
|
|
3496
3576
|
return "no-video-track";
|
|
3497
3577
|
}
|
|
3578
|
+
if (await videoTrack.isLive()) {
|
|
3579
|
+
throw new Error("Live streams are not currently supported by Remotion. Sorry! Source: " + src);
|
|
3580
|
+
}
|
|
3581
|
+
if (await videoTrack.isRelativeToUnixEpoch()) {
|
|
3582
|
+
throw new Error("Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: " + src);
|
|
3583
|
+
}
|
|
3498
3584
|
const canDecode = await videoTrack.canDecode();
|
|
3499
3585
|
if (!canDecode) {
|
|
3500
3586
|
return "cannot-decode";
|
|
@@ -3528,8 +3614,15 @@ var getSinks = async (src, credentials) => {
|
|
|
3528
3614
|
if (format === "network-error") {
|
|
3529
3615
|
return "network-error";
|
|
3530
3616
|
}
|
|
3531
|
-
const audioTracks = await
|
|
3532
|
-
|
|
3617
|
+
const [videoTrack, audioTracks] = await Promise.all([
|
|
3618
|
+
input.getPrimaryVideoTrack(),
|
|
3619
|
+
input.getAudioTracks()
|
|
3620
|
+
]);
|
|
3621
|
+
const audioTrack = await resolveAudioTrack({
|
|
3622
|
+
videoTrack,
|
|
3623
|
+
audioTracks,
|
|
3624
|
+
audioStreamIndex: index
|
|
3625
|
+
});
|
|
3533
3626
|
if (!audioTrack) {
|
|
3534
3627
|
return "no-audio-track";
|
|
3535
3628
|
}
|
|
@@ -3542,11 +3635,12 @@ var getSinks = async (src, credentials) => {
|
|
|
3542
3635
|
};
|
|
3543
3636
|
};
|
|
3544
3637
|
const getAudioSinksPromise = (index) => {
|
|
3545
|
-
|
|
3546
|
-
|
|
3638
|
+
const keyIndex = index === null ? -1 : index;
|
|
3639
|
+
if (audioSinksPromise[keyIndex]) {
|
|
3640
|
+
return audioSinksPromise[keyIndex];
|
|
3547
3641
|
}
|
|
3548
|
-
audioSinksPromise[
|
|
3549
|
-
return audioSinksPromise[
|
|
3642
|
+
audioSinksPromise[keyIndex] = getAudioSinks(index);
|
|
3643
|
+
return audioSinksPromise[keyIndex];
|
|
3550
3644
|
};
|
|
3551
3645
|
return {
|
|
3552
3646
|
getVideo: () => getVideoSinksPromise(),
|
|
@@ -3554,7 +3648,7 @@ var getSinks = async (src, credentials) => {
|
|
|
3554
3648
|
actualMatroskaTimestamps: rememberActualMatroskaTimestamps(isMatroska),
|
|
3555
3649
|
isMatroska,
|
|
3556
3650
|
getDuration: () => {
|
|
3557
|
-
return input
|
|
3651
|
+
return getDurationOrCompute(input);
|
|
3558
3652
|
}
|
|
3559
3653
|
};
|
|
3560
3654
|
};
|
|
@@ -4250,7 +4344,7 @@ var AudioForRendering = ({
|
|
|
4250
4344
|
includeVideo: false,
|
|
4251
4345
|
isClientSideRendering: environment.isClientSideRendering,
|
|
4252
4346
|
loop: loop ?? false,
|
|
4253
|
-
audioStreamIndex: audioStreamIndex ??
|
|
4347
|
+
audioStreamIndex: audioStreamIndex ?? null,
|
|
4254
4348
|
trimAfter,
|
|
4255
4349
|
trimBefore,
|
|
4256
4350
|
fps,
|
|
@@ -4505,7 +4599,9 @@ var {
|
|
|
4505
4599
|
warnAboutTooHighVolume: warnAboutTooHighVolume2,
|
|
4506
4600
|
usePreload: usePreload2,
|
|
4507
4601
|
SequenceContext: SequenceContext2,
|
|
4508
|
-
SequenceVisibilityToggleContext
|
|
4602
|
+
SequenceVisibilityToggleContext,
|
|
4603
|
+
useEffectChainState,
|
|
4604
|
+
useMemoizedEffects
|
|
4509
4605
|
} = Internals19;
|
|
4510
4606
|
var VideoForPreviewAssertedShowing = ({
|
|
4511
4607
|
src: unpreloadedSrc,
|
|
@@ -4532,7 +4628,8 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4532
4628
|
credentials,
|
|
4533
4629
|
controls,
|
|
4534
4630
|
objectFit: objectFitProp,
|
|
4535
|
-
_experimentalInitiallyDrawCachedFrame
|
|
4631
|
+
_experimentalInitiallyDrawCachedFrame,
|
|
4632
|
+
_experimentalEffects
|
|
4536
4633
|
}) => {
|
|
4537
4634
|
const src = usePreload2(unpreloadedSrc);
|
|
4538
4635
|
const canvasRef = useRef2(null);
|
|
@@ -4563,6 +4660,14 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4563
4660
|
throw new Error("No video config found");
|
|
4564
4661
|
}
|
|
4565
4662
|
warnAboutTooHighVolume2(userPreferredVolume);
|
|
4663
|
+
const effectChainState = useEffectChainState();
|
|
4664
|
+
const experimentalEffectsRef = useRef2(_experimentalEffects);
|
|
4665
|
+
experimentalEffectsRef.current = _experimentalEffects;
|
|
4666
|
+
const memoizedEffects = useMemoizedEffects(_experimentalEffects.flat());
|
|
4667
|
+
const effectChainStateRef = useRef2(effectChainState);
|
|
4668
|
+
effectChainStateRef.current = effectChainState;
|
|
4669
|
+
const frameRef = useRef2(frame);
|
|
4670
|
+
frameRef.current = frame;
|
|
4566
4671
|
const parentSequence = useContext5(SequenceContext2);
|
|
4567
4672
|
const isPremounting = Boolean(parentSequence?.premounting);
|
|
4568
4673
|
const isPostmounting = Boolean(parentSequence?.postmounting);
|
|
@@ -4588,7 +4693,8 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4588
4693
|
mediaVolume,
|
|
4589
4694
|
trimAfter,
|
|
4590
4695
|
trimBefore,
|
|
4591
|
-
controls
|
|
4696
|
+
controls,
|
|
4697
|
+
_experimentalEffects: memoizedEffects
|
|
4592
4698
|
});
|
|
4593
4699
|
const isSequenceHidden = hidden[timelineId] ?? false;
|
|
4594
4700
|
const currentTime = frame / videoConfig.fps;
|
|
@@ -4690,7 +4796,10 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4690
4796
|
playing: initialPlaying.current,
|
|
4691
4797
|
sequenceOffset: initialSequenceOffset.current,
|
|
4692
4798
|
credentials,
|
|
4693
|
-
tagType: "video"
|
|
4799
|
+
tagType: "video",
|
|
4800
|
+
getEffects: () => experimentalEffectsRef.current,
|
|
4801
|
+
getEffectChainState: (width, height) => effectChainStateRef.current?.get(width, height),
|
|
4802
|
+
getCurrentFrame: () => frameRef.current
|
|
4694
4803
|
});
|
|
4695
4804
|
mediaPlayerRef.current = player;
|
|
4696
4805
|
player.initialize(currentTimeRef.current, initialMuted.current).then((result) => {
|
|
@@ -5286,7 +5395,8 @@ var InnerVideo = ({
|
|
|
5286
5395
|
credentials,
|
|
5287
5396
|
controls,
|
|
5288
5397
|
objectFit,
|
|
5289
|
-
_experimentalInitiallyDrawCachedFrame
|
|
5398
|
+
_experimentalInitiallyDrawCachedFrame,
|
|
5399
|
+
_experimentalEffects
|
|
5290
5400
|
}) => {
|
|
5291
5401
|
const environment = useRemotionEnvironment4();
|
|
5292
5402
|
if (typeof src !== "string") {
|
|
@@ -5358,6 +5468,7 @@ var InnerVideo = ({
|
|
|
5358
5468
|
credentials,
|
|
5359
5469
|
controls,
|
|
5360
5470
|
objectFit,
|
|
5471
|
+
_experimentalEffects,
|
|
5361
5472
|
_experimentalInitiallyDrawCachedFrame
|
|
5362
5473
|
});
|
|
5363
5474
|
};
|
|
@@ -5390,6 +5501,7 @@ var VideoInner = ({
|
|
|
5390
5501
|
controls,
|
|
5391
5502
|
objectFit,
|
|
5392
5503
|
_experimentalInitiallyDrawCachedFrame,
|
|
5504
|
+
_experimentalEffects,
|
|
5393
5505
|
from,
|
|
5394
5506
|
durationInFrames
|
|
5395
5507
|
}) => {
|
|
@@ -5427,7 +5539,8 @@ var VideoInner = ({
|
|
|
5427
5539
|
credentials,
|
|
5428
5540
|
controls,
|
|
5429
5541
|
objectFit: objectFit ?? "contain",
|
|
5430
|
-
_experimentalInitiallyDrawCachedFrame: _experimentalInitiallyDrawCachedFrame ?? false
|
|
5542
|
+
_experimentalInitiallyDrawCachedFrame: _experimentalInitiallyDrawCachedFrame ?? false,
|
|
5543
|
+
_experimentalEffects: _experimentalEffects ?? []
|
|
5431
5544
|
})
|
|
5432
5545
|
});
|
|
5433
5546
|
};
|
|
@@ -8,7 +8,7 @@ export declare const extractFrameAndAudio: ({ src, timeInSeconds, logLevel, dura
|
|
|
8
8
|
includeAudio: boolean;
|
|
9
9
|
includeVideo: boolean;
|
|
10
10
|
loop: boolean;
|
|
11
|
-
audioStreamIndex: number;
|
|
11
|
+
audioStreamIndex: number | null;
|
|
12
12
|
trimAfter: number | undefined;
|
|
13
13
|
trimBefore: number | undefined;
|
|
14
14
|
fps: number;
|
package/dist/get-sink.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { GetSink } from './video-extraction/get-frames-since-keyframe';
|
|
|
2
2
|
export declare const sinkPromises: Record<string, Promise<GetSink>>;
|
|
3
3
|
export declare const getSink: (src: string, logLevel: "error" | "info" | "trace" | "verbose" | "warn", credentials: RequestCredentials | undefined) => Promise<{
|
|
4
4
|
getVideo: () => Promise<import("./video-extraction/get-frames-since-keyframe").VideoSinkResult>;
|
|
5
|
-
getAudio: (index: number) => Promise<import("./video-extraction/get-frames-since-keyframe").AudioSinkResult>;
|
|
5
|
+
getAudio: (index: number | null) => Promise<import("./video-extraction/get-frames-since-keyframe").AudioSinkResult>;
|
|
6
6
|
actualMatroskaTimestamps: {
|
|
7
7
|
observeTimestamp: (startTime: number) => void;
|
|
8
8
|
getRealTimestamp: (observedTimestamp: number) => number | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { InputAudioTrack, InputVideoTrack } from 'mediabunny';
|
|
2
|
+
export declare const resolveAudioTrack: ({ videoTrack, audioTracks, audioStreamIndex, }: {
|
|
3
|
+
videoTrack: InputVideoTrack | null;
|
|
4
|
+
audioTracks: InputAudioTrack[];
|
|
5
|
+
audioStreamIndex: number | null;
|
|
6
|
+
}) => Promise<InputAudioTrack | null>;
|
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export declare const experimental_Video: import("react").ComponentType<{
|
|
|
39
39
|
credentials: RequestCredentials | undefined;
|
|
40
40
|
objectFit: import(".").VideoObjectFit;
|
|
41
41
|
_experimentalInitiallyDrawCachedFrame: boolean;
|
|
42
|
+
_experimentalEffects: import("remotion").EffectsProp;
|
|
42
43
|
}> & {
|
|
43
44
|
from?: number | undefined;
|
|
44
45
|
durationInFrames?: number | undefined;
|
package/dist/media-player.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { LogLevel, useBufferState } from 'remotion';
|
|
2
|
+
import type { EffectChainState } from 'remotion';
|
|
3
|
+
import type { EffectsProp } from 'remotion';
|
|
2
4
|
import { type AudioIteratorManager } from './audio-iterator-manager';
|
|
3
5
|
import type { SharedAudioContextForMediaPlayer } from './shared-audio-context-for-media-player';
|
|
4
6
|
import type { VideoIteratorManager } from './video-iterator-manager';
|
|
@@ -39,12 +41,15 @@ export declare class MediaPlayer {
|
|
|
39
41
|
private debugOverlay;
|
|
40
42
|
private nonceManager;
|
|
41
43
|
private onVideoFrameCallback;
|
|
44
|
+
private getEffects;
|
|
45
|
+
private getEffectChainState;
|
|
46
|
+
private getCurrentFrame;
|
|
42
47
|
private initializationPromise;
|
|
43
48
|
private bufferState;
|
|
44
49
|
private isPremounting;
|
|
45
50
|
private isPostmounting;
|
|
46
51
|
private seekPromiseChain;
|
|
47
|
-
constructor({ canvas, src, logLevel, sharedAudioContext, loop, trimBefore, trimAfter, playbackRate, globalPlaybackRate, audioStreamIndex, fps, debugOverlay, bufferState, isPremounting, isPostmounting, durationInFrames, onVideoFrameCallback, playing, sequenceOffset, credentials, tagType }: {
|
|
52
|
+
constructor({ canvas, src, logLevel, sharedAudioContext, loop, trimBefore, trimAfter, playbackRate, globalPlaybackRate, audioStreamIndex, fps, debugOverlay, bufferState, isPremounting, isPostmounting, durationInFrames, onVideoFrameCallback, playing, sequenceOffset, credentials, tagType, getEffects, getEffectChainState, getCurrentFrame }: {
|
|
48
53
|
canvas: HTMLCanvasElement | OffscreenCanvas | null;
|
|
49
54
|
src: string;
|
|
50
55
|
logLevel: LogLevel;
|
|
@@ -54,7 +59,7 @@ export declare class MediaPlayer {
|
|
|
54
59
|
trimAfter: number | undefined;
|
|
55
60
|
playbackRate: number;
|
|
56
61
|
globalPlaybackRate: number;
|
|
57
|
-
audioStreamIndex: number;
|
|
62
|
+
audioStreamIndex: number | null;
|
|
58
63
|
fps: number;
|
|
59
64
|
debugOverlay: boolean;
|
|
60
65
|
bufferState: ReturnType<typeof useBufferState>;
|
|
@@ -66,6 +71,9 @@ export declare class MediaPlayer {
|
|
|
66
71
|
sequenceOffset: number;
|
|
67
72
|
credentials: RequestCredentials | undefined;
|
|
68
73
|
tagType: 'audio' | 'video';
|
|
74
|
+
getEffects: () => EffectsProp;
|
|
75
|
+
getEffectChainState: (width: number, height: number) => EffectChainState | null;
|
|
76
|
+
getCurrentFrame: () => number;
|
|
69
77
|
});
|
|
70
78
|
private input;
|
|
71
79
|
private isDisposalError;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { LoopDisplay, SequenceControls } from 'remotion';
|
|
1
|
+
import type { EffectDefinitionAndStack, LoopDisplay, SequenceControls } from 'remotion';
|
|
2
2
|
import { type VolumeProp } from 'remotion';
|
|
3
|
-
export declare const useMediaInTimeline: ({ volume, mediaVolume, src, mediaType, playbackRate, displayName, stack, showInTimeline, premountDisplay, postmountDisplay, loopDisplay, trimBefore, trimAfter, controls, }: {
|
|
3
|
+
export declare const useMediaInTimeline: ({ volume, mediaVolume, src, mediaType, playbackRate, displayName, stack, showInTimeline, premountDisplay, postmountDisplay, loopDisplay, trimBefore, trimAfter, controls, _experimentalEffects, }: {
|
|
4
4
|
volume: VolumeProp | undefined;
|
|
5
5
|
mediaVolume: number;
|
|
6
6
|
src: string | undefined;
|
|
@@ -15,6 +15,7 @@ export declare const useMediaInTimeline: ({ volume, mediaVolume, src, mediaType,
|
|
|
15
15
|
trimBefore: number | undefined;
|
|
16
16
|
trimAfter: number | undefined;
|
|
17
17
|
controls: SequenceControls | undefined;
|
|
18
|
+
_experimentalEffects: EffectDefinitionAndStack<unknown>[];
|
|
18
19
|
}) => {
|
|
19
20
|
id: string;
|
|
20
21
|
};
|
package/dist/video/props.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LogLevel, LoopVolumeCurveBehavior, OnVideoFrame, VolumeProp } from 'remotion';
|
|
2
|
+
import type { EffectsProp } from 'remotion';
|
|
2
3
|
import type { MediaOnError } from '../on-error';
|
|
3
4
|
export type MediaErrorEvent = {
|
|
4
5
|
error: Error;
|
|
@@ -51,6 +52,7 @@ type OptionalVideoProps = {
|
|
|
51
52
|
credentials: RequestCredentials | undefined;
|
|
52
53
|
objectFit: VideoObjectFit;
|
|
53
54
|
_experimentalInitiallyDrawCachedFrame: boolean;
|
|
55
|
+
_experimentalEffects: EffectsProp;
|
|
54
56
|
};
|
|
55
57
|
export type InnerVideoProps = MandatoryVideoProps & OuterVideoProps & OptionalVideoProps;
|
|
56
58
|
export type VideoProps = MandatoryVideoProps & Partial<OuterVideoProps> & Partial<OptionalVideoProps> & {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { LogLevel, LoopVolumeCurveBehavior, SequenceControls, VolumeProp } from 'remotion';
|
|
2
|
+
import type { EffectsProp, LogLevel, LoopVolumeCurveBehavior, SequenceControls, VolumeProp } from 'remotion';
|
|
3
3
|
import { type MediaOnError } from '../on-error';
|
|
4
4
|
import type { FallbackOffthreadVideoProps, VideoObjectFit } from './props';
|
|
5
5
|
type VideoForPreviewProps = {
|
|
@@ -27,6 +27,7 @@ type VideoForPreviewProps = {
|
|
|
27
27
|
readonly credentials: RequestCredentials | undefined;
|
|
28
28
|
readonly objectFit: VideoObjectFit;
|
|
29
29
|
readonly _experimentalInitiallyDrawCachedFrame: boolean;
|
|
30
|
+
readonly _experimentalEffects: EffectsProp;
|
|
30
31
|
};
|
|
31
32
|
export declare const VideoForPreview: React.FC<VideoForPreviewProps & {
|
|
32
33
|
readonly controls: SequenceControls | undefined;
|
package/dist/video/video.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare const Video: React.ComponentType<{
|
|
|
31
31
|
credentials: RequestCredentials | undefined;
|
|
32
32
|
objectFit: import("./props").VideoObjectFit;
|
|
33
33
|
_experimentalInitiallyDrawCachedFrame: boolean;
|
|
34
|
+
_experimentalEffects: import("remotion").EffectsProp;
|
|
34
35
|
}> & {
|
|
35
36
|
from?: number | undefined;
|
|
36
37
|
durationInFrames?: number | undefined;
|
|
@@ -25,7 +25,7 @@ export declare const extractFrameViaBroadcastChannel: ({ src, timeInSeconds, log
|
|
|
25
25
|
includeVideo: boolean;
|
|
26
26
|
isClientSideRendering: boolean;
|
|
27
27
|
loop: boolean;
|
|
28
|
-
audioStreamIndex: number;
|
|
28
|
+
audioStreamIndex: number | null;
|
|
29
29
|
trimAfter: number | undefined;
|
|
30
30
|
trimBefore: number | undefined;
|
|
31
31
|
fps: number;
|
|
@@ -9,7 +9,7 @@ export type AudioSinkResult = AudioSinks | 'no-audio-track' | 'cannot-decode-aud
|
|
|
9
9
|
export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'cannot-decode-alpha' | 'unknown-container-format' | 'network-error';
|
|
10
10
|
export declare const getSinks: (src: string, credentials: RequestCredentials | undefined) => Promise<{
|
|
11
11
|
getVideo: () => Promise<VideoSinkResult>;
|
|
12
|
-
getAudio: (index: number) => Promise<AudioSinkResult>;
|
|
12
|
+
getAudio: (index: number | null) => Promise<AudioSinkResult>;
|
|
13
13
|
actualMatroskaTimestamps: {
|
|
14
14
|
observeTimestamp: (startTime: number) => void;
|
|
15
15
|
getRealTimestamp: (observedTimestamp: number) => number | null;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { InputVideoTrack, WrappedCanvas } from 'mediabunny';
|
|
2
|
+
import type { EffectChainState, EffectsProp } from 'remotion';
|
|
2
3
|
import type { DelayPlaybackIfNotPremounting } from './delay-playback-if-not-premounting';
|
|
3
4
|
import type { Nonce } from './nonce-manager';
|
|
4
|
-
export declare const videoIteratorManager: ({ delayPlaybackHandleIfNotPremounting, canvas, context, drawDebugOverlay, logLevel, getOnVideoFrameCallback, videoTrack, getLoopSegmentMediaEndTimestamp, getStartTime, getIsLooping, }: {
|
|
5
|
+
export declare const videoIteratorManager: ({ delayPlaybackHandleIfNotPremounting, canvas, context, drawDebugOverlay, logLevel, getOnVideoFrameCallback, videoTrack, getLoopSegmentMediaEndTimestamp, getStartTime, getIsLooping, getEffects, getEffectChainState, getCurrentFrame, }: {
|
|
5
6
|
videoTrack: InputVideoTrack;
|
|
6
7
|
delayPlaybackHandleIfNotPremounting: () => DelayPlaybackIfNotPremounting;
|
|
7
8
|
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;
|
|
@@ -12,7 +13,10 @@ export declare const videoIteratorManager: ({ delayPlaybackHandleIfNotPremountin
|
|
|
12
13
|
getLoopSegmentMediaEndTimestamp: () => number;
|
|
13
14
|
getStartTime: () => number;
|
|
14
15
|
getIsLooping: () => boolean;
|
|
15
|
-
|
|
16
|
+
getEffects: () => EffectsProp;
|
|
17
|
+
getEffectChainState: (width: number, height: number) => EffectChainState | null;
|
|
18
|
+
getCurrentFrame: () => number;
|
|
19
|
+
}) => Promise<{
|
|
16
20
|
startVideoIterator: (timeToSeek: number, nonce: Nonce) => Promise<void>;
|
|
17
21
|
getVideoIteratorsCreated: () => number;
|
|
18
22
|
seek: ({ newTime, nonce }: {
|
|
@@ -32,7 +36,7 @@ export declare const videoIteratorManager: ({ delayPlaybackHandleIfNotPremountin
|
|
|
32
36
|
frame: WrappedCanvas;
|
|
33
37
|
};
|
|
34
38
|
} | null;
|
|
35
|
-
drawFrame: (frame: WrappedCanvas) => void
|
|
39
|
+
drawFrame: (frame: WrappedCanvas) => Promise<void>;
|
|
36
40
|
getFramesRendered: () => number;
|
|
37
|
-
}
|
|
38
|
-
export type VideoIteratorManager = ReturnType<typeof videoIteratorManager
|
|
41
|
+
}>;
|
|
42
|
+
export type VideoIteratorManager = Awaited<ReturnType<typeof videoIteratorManager>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.455",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"make": "tsgo && bun --env-file=../.env.bundle bundle.ts"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"mediabunny": "1.
|
|
26
|
-
"remotion": "4.0.
|
|
25
|
+
"mediabunny": "1.42.0",
|
|
26
|
+
"remotion": "4.0.455",
|
|
27
27
|
"zod": "4.3.6"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"react-dom": ">=16.8.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
34
|
+
"@remotion/eslint-config-internal": "4.0.455",
|
|
35
35
|
"@vitest/browser-webdriverio": "4.0.9",
|
|
36
36
|
"eslint": "9.19.0",
|
|
37
37
|
"react": "19.2.3",
|