@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.
@@ -7,7 +7,7 @@ type ExtractAudioParams = {
7
7
  logLevel: LogLevel;
8
8
  loop: boolean;
9
9
  playbackRate: number;
10
- audioStreamIndex: number;
10
+ audioStreamIndex: number | null;
11
11
  trimBefore: number | undefined;
12
12
  trimAfter: number | undefined;
13
13
  fps: number;
@@ -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;
@@ -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 videoIteratorManager = ({
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
- if (canvas.width !== videoTrack.displayWidth || canvas.height !== videoTrack.displayHeight) {
1034
- canvas.width = videoTrack.displayWidth;
1035
- canvas.height = videoTrack.displayHeight;
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
- context.clearRect(0, 0, canvas.width, canvas.height);
1047
- context.drawImage(frame.canvas, 0, 0);
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 ?? 0;
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.computeDuration(),
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 = audioTracks[this.audioStreamIndex] ?? null;
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 ?? 0,
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: audioStreamIndex ?? 0,
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 input.getAudioTracks();
3532
- const audioTrack = audioTracks[index];
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
- if (audioSinksPromise[index]) {
3546
- return audioSinksPromise[index];
3638
+ const keyIndex = index === null ? -1 : index;
3639
+ if (audioSinksPromise[keyIndex]) {
3640
+ return audioSinksPromise[keyIndex];
3547
3641
  }
3548
- audioSinksPromise[index] = getAudioSinks(index);
3549
- return audioSinksPromise[index];
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.computeDuration();
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 ?? 0,
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;
@@ -0,0 +1,2 @@
1
+ import type { Input } from 'mediabunny';
2
+ export declare const getDurationOrCompute: (input: Input<import("mediabunny").Source>) => Promise<number>;
@@ -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;
@@ -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
  };
@@ -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;
@@ -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;
@@ -38,7 +38,7 @@ export type ExtractFrameRequest = {
38
38
  includeAudio: boolean;
39
39
  includeVideo: boolean;
40
40
  loop: boolean;
41
- audioStreamIndex: number;
41
+ audioStreamIndex: number | null;
42
42
  trimAfter: number | undefined;
43
43
  trimBefore: number | undefined;
44
44
  fps: number;
@@ -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.453",
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.39.2",
26
- "remotion": "4.0.453",
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.453",
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",