@remotion/media 4.0.453 → 4.0.454

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;
@@ -758,6 +758,13 @@ 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
+
761
768
  // src/is-type-of-error.ts
762
769
  function isNetworkError(error) {
763
770
  if (error.message.includes("Failed to fetch") || error.message.includes("Load failed") || error.message.includes("NetworkError when attempting to fetch resource")) {
@@ -1013,7 +1020,7 @@ var createVideoIterator = async (timeToSeek, cache) => {
1013
1020
  };
1014
1021
 
1015
1022
  // src/video-iterator-manager.ts
1016
- var videoIteratorManager = ({
1023
+ var videoIteratorManager = async ({
1017
1024
  delayPlaybackHandleIfNotPremounting,
1018
1025
  canvas,
1019
1026
  context,
@@ -1030,9 +1037,11 @@ var videoIteratorManager = ({
1030
1037
  let framesRendered = 0;
1031
1038
  let currentDelayHandle = null;
1032
1039
  if (canvas) {
1033
- if (canvas.width !== videoTrack.displayWidth || canvas.height !== videoTrack.displayHeight) {
1034
- canvas.width = videoTrack.displayWidth;
1035
- canvas.height = videoTrack.displayHeight;
1040
+ const displayWidth = await videoTrack.getDisplayWidth();
1041
+ const displayHeight = await videoTrack.getDisplayHeight();
1042
+ if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
1043
+ canvas.width = displayWidth;
1044
+ canvas.height = displayHeight;
1036
1045
  }
1037
1046
  }
1038
1047
  const canvasSink = new CanvasSink(videoTrack, {
@@ -1186,7 +1195,7 @@ class MediaPlayer {
1186
1195
  this.loop = loop;
1187
1196
  this.trimBefore = trimBefore;
1188
1197
  this.trimAfter = trimAfter;
1189
- this.audioStreamIndex = audioStreamIndex ?? 0;
1198
+ this.audioStreamIndex = audioStreamIndex;
1190
1199
  this.fps = fps;
1191
1200
  this.debugOverlay = debugOverlay;
1192
1201
  this.bufferState = bufferState;
@@ -1271,7 +1280,7 @@ class MediaPlayer {
1271
1280
  return { type: "unknown-container-format" };
1272
1281
  }
1273
1282
  const [durationInSeconds, videoTrack, audioTracks] = await Promise.all([
1274
- this.input.computeDuration(),
1283
+ getDurationOrCompute(this.input),
1275
1284
  this.input.getPrimaryVideoTrack(),
1276
1285
  this.input.getAudioTracks()
1277
1286
  ]);
@@ -1279,11 +1288,17 @@ class MediaPlayer {
1279
1288
  return { type: "disposed" };
1280
1289
  }
1281
1290
  this.totalDuration = durationInSeconds;
1282
- const audioTrack = audioTracks[this.audioStreamIndex] ?? null;
1291
+ const audioTrack = await (this.audioStreamIndex === null ? videoTrack?.getPrimaryPairableAudioTrack() : audioTracks[this.audioStreamIndex] ?? null);
1283
1292
  if (!videoTrack && !audioTrack) {
1284
1293
  return { type: "no-tracks" };
1285
1294
  }
1286
1295
  if (videoTrack && this.tagType === "video") {
1296
+ if (await videoTrack.isLive()) {
1297
+ throw new Error("Live streams are not currently supported by Remotion. Sorry! Source: " + this.src);
1298
+ }
1299
+ if (await videoTrack.isRelativeToUnixEpoch()) {
1300
+ throw new Error("Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: " + this.src);
1301
+ }
1287
1302
  const canDecode = await videoTrack.canDecode();
1288
1303
  if (!canDecode) {
1289
1304
  return { type: "cannot-decode" };
@@ -1291,7 +1306,7 @@ class MediaPlayer {
1291
1306
  if (this.input.disposed) {
1292
1307
  return { type: "disposed" };
1293
1308
  }
1294
- this.videoIteratorManager = videoIteratorManager({
1309
+ this.videoIteratorManager = await videoIteratorManager({
1295
1310
  videoTrack,
1296
1311
  delayPlaybackHandleIfNotPremounting: this.delayPlaybackHandleIfNotPremounting,
1297
1312
  context: this.context,
@@ -1309,6 +1324,12 @@ class MediaPlayer {
1309
1324
  throw new Error(`should have asserted that the time is not null`);
1310
1325
  }
1311
1326
  if (audioTrack && this.sharedAudioContext) {
1327
+ if (await audioTrack.isLive()) {
1328
+ throw new Error("Live streams are not currently supported by Remotion. Sorry! Source: " + this.src);
1329
+ }
1330
+ if (await audioTrack.isRelativeToUnixEpoch()) {
1331
+ throw new Error("Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: " + this.src);
1332
+ }
1312
1333
  const canDecode = await audioTrack.canDecode();
1313
1334
  if (!canDecode) {
1314
1335
  return { type: "cannot-decode" };
@@ -2106,7 +2127,7 @@ var AudioForPreviewAssertedShowing = ({
2106
2127
  fps: videoConfig.fps,
2107
2128
  canvas: null,
2108
2129
  playbackRate: initialPlaybackRate.current,
2109
- audioStreamIndex: audioStreamIndex ?? 0,
2130
+ audioStreamIndex: audioStreamIndex ?? null,
2110
2131
  debugOverlay: false,
2111
2132
  bufferState: buffer,
2112
2133
  isPostmounting: initialIsPostmounting.current,
@@ -2283,7 +2304,7 @@ var AudioForPreview = ({
2283
2304
  return null;
2284
2305
  }
2285
2306
  return /* @__PURE__ */ jsx(AudioForPreviewAssertedShowing, {
2286
- audioStreamIndex: audioStreamIndex ?? 0,
2307
+ audioStreamIndex,
2287
2308
  src: preloadedSrc,
2288
2309
  playbackRate,
2289
2310
  logLevel: logLevel ?? defaultLogLevel,
@@ -3495,6 +3516,12 @@ var getSinks = async (src, credentials) => {
3495
3516
  if (!videoTrack) {
3496
3517
  return "no-video-track";
3497
3518
  }
3519
+ if (await videoTrack.isLive()) {
3520
+ throw new Error("Live streams are not currently supported by Remotion. Sorry! Source: " + src);
3521
+ }
3522
+ if (await videoTrack.isRelativeToUnixEpoch()) {
3523
+ throw new Error("Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: " + src);
3524
+ }
3498
3525
  const canDecode = await videoTrack.canDecode();
3499
3526
  if (!canDecode) {
3500
3527
  return "cannot-decode";
@@ -3528,8 +3555,8 @@ var getSinks = async (src, credentials) => {
3528
3555
  if (format === "network-error") {
3529
3556
  return "network-error";
3530
3557
  }
3531
- const audioTracks = await input.getAudioTracks();
3532
- const audioTrack = audioTracks[index];
3558
+ const videoTrack = await input.getPrimaryVideoTrack();
3559
+ const audioTrack = videoTrack === null ? (await input.getAudioTracks())[index ?? 0] : await (index === null ? videoTrack?.getPrimaryPairableAudioTrack() : (await input.getAudioTracks())[index] ?? null);
3533
3560
  if (!audioTrack) {
3534
3561
  return "no-audio-track";
3535
3562
  }
@@ -3542,11 +3569,12 @@ var getSinks = async (src, credentials) => {
3542
3569
  };
3543
3570
  };
3544
3571
  const getAudioSinksPromise = (index) => {
3545
- if (audioSinksPromise[index]) {
3546
- return audioSinksPromise[index];
3572
+ const keyIndex = index === null ? -1 : index;
3573
+ if (audioSinksPromise[keyIndex]) {
3574
+ return audioSinksPromise[keyIndex];
3547
3575
  }
3548
- audioSinksPromise[index] = getAudioSinks(index);
3549
- return audioSinksPromise[index];
3576
+ audioSinksPromise[keyIndex] = getAudioSinks(index);
3577
+ return audioSinksPromise[keyIndex];
3550
3578
  };
3551
3579
  return {
3552
3580
  getVideo: () => getVideoSinksPromise(),
@@ -3554,7 +3582,7 @@ var getSinks = async (src, credentials) => {
3554
3582
  actualMatroskaTimestamps: rememberActualMatroskaTimestamps(isMatroska),
3555
3583
  isMatroska,
3556
3584
  getDuration: () => {
3557
- return input.computeDuration();
3585
+ return getDurationOrCompute(input);
3558
3586
  }
3559
3587
  };
3560
3588
  };
@@ -4250,7 +4278,7 @@ var AudioForRendering = ({
4250
4278
  includeVideo: false,
4251
4279
  isClientSideRendering: environment.isClientSideRendering,
4252
4280
  loop: loop ?? false,
4253
- audioStreamIndex: audioStreamIndex ?? 0,
4281
+ audioStreamIndex: audioStreamIndex ?? null,
4254
4282
  trimAfter,
4255
4283
  trimBefore,
4256
4284
  fps,
@@ -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;
@@ -54,7 +54,7 @@ export declare class MediaPlayer {
54
54
  trimAfter: number | undefined;
55
55
  playbackRate: number;
56
56
  globalPlaybackRate: number;
57
- audioStreamIndex: number;
57
+ audioStreamIndex: number | null;
58
58
  fps: number;
59
59
  debugOverlay: boolean;
60
60
  bufferState: ReturnType<typeof useBufferState>;
@@ -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;
@@ -12,7 +12,7 @@ export declare const videoIteratorManager: ({ delayPlaybackHandleIfNotPremountin
12
12
  getLoopSegmentMediaEndTimestamp: () => number;
13
13
  getStartTime: () => number;
14
14
  getIsLooping: () => boolean;
15
- }) => {
15
+ }) => Promise<{
16
16
  startVideoIterator: (timeToSeek: number, nonce: Nonce) => Promise<void>;
17
17
  getVideoIteratorsCreated: () => number;
18
18
  seek: ({ newTime, nonce }: {
@@ -34,5 +34,5 @@ export declare const videoIteratorManager: ({ delayPlaybackHandleIfNotPremountin
34
34
  } | null;
35
35
  drawFrame: (frame: WrappedCanvas) => void;
36
36
  getFramesRendered: () => number;
37
- };
38
- export type VideoIteratorManager = ReturnType<typeof videoIteratorManager>;
37
+ }>;
38
+ 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.454",
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.454",
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.454",
35
35
  "@vitest/browser-webdriverio": "4.0.9",
36
36
  "eslint": "9.19.0",
37
37
  "react": "19.2.3",