@remotion/renderer 4.0.336 → 4.0.340

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.
@@ -47,6 +47,7 @@ const calculateAssetPositions = (frames) => {
47
47
  playbackRate: asset.playbackRate,
48
48
  toneFrequency: asset.toneFrequency,
49
49
  audioStartFrame: asset.audioStartFrame,
50
+ audioStreamIndex: asset.audioStreamIndex,
50
51
  });
51
52
  }
52
53
  const found = assets.find((a) => a.duration === null && areEqual(a, asset));
@@ -7,7 +7,7 @@ export type RenderMediaOnDownload = (src: string) => ((progress: {
7
7
  downloaded: number;
8
8
  totalSize: number | null;
9
9
  }) => void) | undefined | void;
10
- export declare const downloadAsset: ({ src, downloadMap, indent, logLevel, shouldAnalyzeAudioImmediately, binariesDirectory, cancelSignalForAudioAnalysis, }: {
10
+ export declare const downloadAsset: ({ src, downloadMap, indent, logLevel, shouldAnalyzeAudioImmediately, binariesDirectory, cancelSignalForAudioAnalysis, audioStreamIndex, }: {
11
11
  src: string;
12
12
  downloadMap: DownloadMap;
13
13
  indent: boolean;
@@ -15,6 +15,7 @@ export declare const downloadAsset: ({ src, downloadMap, indent, logLevel, shoul
15
15
  shouldAnalyzeAudioImmediately: boolean;
16
16
  binariesDirectory: string | null;
17
17
  cancelSignalForAudioAnalysis: CancelSignal | undefined;
18
+ audioStreamIndex: number | undefined;
18
19
  }) => Promise<string>;
19
20
  export declare const markAllAssetsAsDownloaded: (downloadMap: DownloadMap) => void;
20
21
  export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, contentDisposition, contentType, }: {
@@ -123,7 +123,7 @@ function validateBufferEncoding(potentialEncoding, dataUrl) {
123
123
  throw new TypeError(errMessage);
124
124
  }
125
125
  }
126
- const downloadAsset = async ({ src, downloadMap, indent, logLevel, shouldAnalyzeAudioImmediately, binariesDirectory, cancelSignalForAudioAnalysis, }) => {
126
+ const downloadAsset = async ({ src, downloadMap, indent, logLevel, shouldAnalyzeAudioImmediately, binariesDirectory, cancelSignalForAudioAnalysis, audioStreamIndex, }) => {
127
127
  var _a, _b, _c;
128
128
  if ((0, compress_assets_1.isAssetCompressed)(src)) {
129
129
  return src;
@@ -198,6 +198,7 @@ const downloadAsset = async ({ src, downloadMap, indent, logLevel, shouldAnalyze
198
198
  indent,
199
199
  logLevel,
200
200
  cancelSignal: cancelSignalForAudioAnalysis,
201
+ audioStreamIndex,
201
202
  });
202
203
  }
203
204
  return to;
@@ -266,6 +267,7 @@ const downloadAndMapAssetsToFileUrl = async ({ renderAsset, onDownload, download
266
267
  shouldAnalyzeAudioImmediately,
267
268
  binariesDirectory,
268
269
  cancelSignalForAudioAnalysis,
270
+ audioStreamIndex: renderAsset.audioStreamIndex,
269
271
  });
270
272
  cleanup();
271
273
  return {
@@ -1,18 +1,20 @@
1
1
  import type { LogLevel } from '../log-level';
2
2
  import type { CancelSignal } from '../make-cancel-signal';
3
3
  import type { AudioChannelsAndDurationResultCache, DownloadMap } from './download-map';
4
- export declare const getAudioChannelsAndDurationWithoutCache: ({ src, indent, logLevel, binariesDirectory, cancelSignal, }: {
4
+ export declare const getAudioChannelsAndDurationWithoutCache: ({ src, indent, logLevel, binariesDirectory, cancelSignal, audioStreamIndex, }: {
5
5
  src: string;
6
6
  indent: boolean;
7
7
  logLevel: LogLevel;
8
8
  binariesDirectory: string | null;
9
9
  cancelSignal: CancelSignal | undefined;
10
+ audioStreamIndex: number | undefined;
10
11
  }) => Promise<AudioChannelsAndDurationResultCache>;
11
- export declare const getAudioChannelsAndDuration: ({ downloadMap, src, indent, logLevel, binariesDirectory, cancelSignal, }: {
12
+ export declare const getAudioChannelsAndDuration: ({ downloadMap, src, indent, logLevel, binariesDirectory, cancelSignal, audioStreamIndex, }: {
12
13
  downloadMap: DownloadMap;
13
14
  src: string;
14
15
  indent: boolean;
15
16
  logLevel: LogLevel;
16
17
  binariesDirectory: string | null;
17
18
  cancelSignal: CancelSignal | undefined;
19
+ audioStreamIndex: number | undefined;
18
20
  }) => Promise<AudioChannelsAndDurationResultCache>;
@@ -4,10 +4,10 @@ exports.getAudioChannelsAndDuration = exports.getAudioChannelsAndDurationWithout
4
4
  const call_ffmpeg_1 = require("../call-ffmpeg");
5
5
  const p_limit_1 = require("../p-limit");
6
6
  const limit = (0, p_limit_1.pLimit)(1);
7
- const getAudioChannelsAndDurationWithoutCache = async ({ src, indent, logLevel, binariesDirectory, cancelSignal, }) => {
7
+ const getAudioChannelsAndDurationWithoutCache = async ({ src, indent, logLevel, binariesDirectory, cancelSignal, audioStreamIndex, }) => {
8
8
  const args = [
9
9
  ['-v', 'error'],
10
- ['-select_streams', 'a:0'],
10
+ ['-select_streams', audioStreamIndex ? `a:${audioStreamIndex}` : 'a:0'],
11
11
  [
12
12
  '-show_entries',
13
13
  'stream=channels:stream=start_time:format=duration:format=format_name',
@@ -48,9 +48,10 @@ const getAudioChannelsAndDurationWithoutCache = async ({ src, indent, logLevel,
48
48
  }
49
49
  };
50
50
  exports.getAudioChannelsAndDurationWithoutCache = getAudioChannelsAndDurationWithoutCache;
51
- async function getAudioChannelsAndDurationUnlimited({ downloadMap, src, indent, logLevel, binariesDirectory, cancelSignal, }) {
52
- if (downloadMap.durationOfAssetCache[src]) {
53
- return downloadMap.durationOfAssetCache[src];
51
+ async function getAudioChannelsAndDurationUnlimited({ downloadMap, src, indent, logLevel, binariesDirectory, cancelSignal, audioStreamIndex, }) {
52
+ const cacheKey = audioStreamIndex ? `${src}-${audioStreamIndex}` : src;
53
+ if (downloadMap.durationOfAssetCache[cacheKey]) {
54
+ return downloadMap.durationOfAssetCache[cacheKey];
54
55
  }
55
56
  const result = await (0, exports.getAudioChannelsAndDurationWithoutCache)({
56
57
  src,
@@ -58,11 +59,12 @@ async function getAudioChannelsAndDurationUnlimited({ downloadMap, src, indent,
58
59
  logLevel,
59
60
  binariesDirectory,
60
61
  cancelSignal,
62
+ audioStreamIndex,
61
63
  });
62
- downloadMap.durationOfAssetCache[src] = result;
64
+ downloadMap.durationOfAssetCache[cacheKey] = result;
63
65
  return result;
64
66
  }
65
- const getAudioChannelsAndDuration = ({ downloadMap, src, indent, logLevel, binariesDirectory, cancelSignal, }) => {
67
+ const getAudioChannelsAndDuration = ({ downloadMap, src, indent, logLevel, binariesDirectory, cancelSignal, audioStreamIndex, }) => {
66
68
  return limit(() => getAudioChannelsAndDurationUnlimited({
67
69
  downloadMap,
68
70
  src,
@@ -70,6 +72,7 @@ const getAudioChannelsAndDuration = ({ downloadMap, src, indent, logLevel, binar
70
72
  logLevel,
71
73
  binariesDirectory,
72
74
  cancelSignal,
75
+ audioStreamIndex,
73
76
  }));
74
77
  };
75
78
  exports.getAudioChannelsAndDuration = getAudioChannelsAndDuration;
@@ -7,6 +7,7 @@ export type UnsafeAsset = Omit<AudioOrVideoAsset, 'frame' | 'id' | 'volume' | 'm
7
7
  id: string;
8
8
  playbackRate: number;
9
9
  toneFrequency: number | null;
10
+ audioStreamIndex: number;
10
11
  };
11
12
  export type AssetVolume = number | number[];
12
13
  export type MediaAsset = Omit<UnsafeAsset, 'duration' | 'volume'> & {
@@ -58,6 +58,7 @@ const createAudio = async ({ assets, onDownload, fps, logLevel, onProgress, down
58
58
  trimLeftOffset,
59
59
  trimRightOffset,
60
60
  forSeamlessAacConcatenation,
61
+ audioStreamIndex: asset.audioStreamIndex,
61
62
  });
62
63
  preprocessProgress[index] = 1;
63
64
  updateProgress();
@@ -14178,11 +14178,12 @@ var getAudioChannelsAndDurationWithoutCache = async ({
14178
14178
  indent,
14179
14179
  logLevel,
14180
14180
  binariesDirectory,
14181
- cancelSignal
14181
+ cancelSignal,
14182
+ audioStreamIndex
14182
14183
  }) => {
14183
14184
  const args = [
14184
14185
  ["-v", "error"],
14185
- ["-select_streams", "a:0"],
14186
+ ["-select_streams", audioStreamIndex ? `a:${audioStreamIndex}` : "a:0"],
14186
14187
  [
14187
14188
  "-show_entries",
14188
14189
  "stream=channels:stream=start_time:format=duration:format=format_name"
@@ -14223,19 +14224,22 @@ async function getAudioChannelsAndDurationUnlimited({
14223
14224
  indent,
14224
14225
  logLevel,
14225
14226
  binariesDirectory,
14226
- cancelSignal
14227
+ cancelSignal,
14228
+ audioStreamIndex
14227
14229
  }) {
14228
- if (downloadMap.durationOfAssetCache[src]) {
14229
- return downloadMap.durationOfAssetCache[src];
14230
+ const cacheKey = audioStreamIndex ? `${src}-${audioStreamIndex}` : src;
14231
+ if (downloadMap.durationOfAssetCache[cacheKey]) {
14232
+ return downloadMap.durationOfAssetCache[cacheKey];
14230
14233
  }
14231
14234
  const result = await getAudioChannelsAndDurationWithoutCache({
14232
14235
  src,
14233
14236
  indent,
14234
14237
  logLevel,
14235
14238
  binariesDirectory,
14236
- cancelSignal
14239
+ cancelSignal,
14240
+ audioStreamIndex
14237
14241
  });
14238
- downloadMap.durationOfAssetCache[src] = result;
14242
+ downloadMap.durationOfAssetCache[cacheKey] = result;
14239
14243
  return result;
14240
14244
  }
14241
14245
  var getAudioChannelsAndDuration = ({
@@ -14244,7 +14248,8 @@ var getAudioChannelsAndDuration = ({
14244
14248
  indent,
14245
14249
  logLevel,
14246
14250
  binariesDirectory,
14247
- cancelSignal
14251
+ cancelSignal,
14252
+ audioStreamIndex
14248
14253
  }) => {
14249
14254
  return limit(() => getAudioChannelsAndDurationUnlimited({
14250
14255
  downloadMap,
@@ -14252,7 +14257,8 @@ var getAudioChannelsAndDuration = ({
14252
14257
  indent,
14253
14258
  logLevel,
14254
14259
  binariesDirectory,
14255
- cancelSignal
14260
+ cancelSignal,
14261
+ audioStreamIndex
14256
14262
  }));
14257
14263
  };
14258
14264
 
@@ -14414,7 +14420,8 @@ var downloadAsset = async ({
14414
14420
  logLevel,
14415
14421
  shouldAnalyzeAudioImmediately,
14416
14422
  binariesDirectory,
14417
- cancelSignalForAudioAnalysis
14423
+ cancelSignalForAudioAnalysis,
14424
+ audioStreamIndex
14418
14425
  }) => {
14419
14426
  if (isAssetCompressed(src)) {
14420
14427
  return src;
@@ -14487,7 +14494,8 @@ var downloadAsset = async ({
14487
14494
  src: to,
14488
14495
  indent,
14489
14496
  logLevel,
14490
- cancelSignal: cancelSignalForAudioAnalysis
14497
+ cancelSignal: cancelSignalForAudioAnalysis,
14498
+ audioStreamIndex
14491
14499
  });
14492
14500
  }
14493
14501
  return to;
@@ -14567,7 +14575,8 @@ var downloadAndMapAssetsToFileUrl = async ({
14567
14575
  logLevel,
14568
14576
  shouldAnalyzeAudioImmediately,
14569
14577
  binariesDirectory,
14570
- cancelSignalForAudioAnalysis
14578
+ cancelSignalForAudioAnalysis,
14579
+ audioStreamIndex: renderAsset.audioStreamIndex
14571
14580
  });
14572
14581
  cleanup();
14573
14582
  return {
@@ -14915,7 +14924,8 @@ var startOffthreadVideoServer = ({
14915
14924
  logLevel,
14916
14925
  binariesDirectory,
14917
14926
  cancelSignalForAudioAnalysis: undefined,
14918
- shouldAnalyzeAudioImmediately: true
14927
+ shouldAnalyzeAudioImmediately: true,
14928
+ audioStreamIndex: undefined
14919
14929
  }).then((to) => {
14920
14930
  return new Promise((resolve2, reject) => {
14921
14931
  if (closed) {
@@ -19741,7 +19751,8 @@ var calculateAssetPositions = (frames) => {
19741
19751
  volume: [],
19742
19752
  playbackRate: asset.playbackRate,
19743
19753
  toneFrequency: asset.toneFrequency,
19744
- audioStartFrame: asset.audioStartFrame
19754
+ audioStartFrame: asset.audioStartFrame,
19755
+ audioStreamIndex: asset.audioStreamIndex
19745
19756
  });
19746
19757
  }
19747
19758
  const found = assets.find((a) => a.duration === null && areEqual(a, asset));
@@ -20306,7 +20317,7 @@ var stringifyFfmpegFilter = ({
20306
20317
  const padAtEnd = chunkLengthInSeconds - audibleDuration - startInVideoSeconds;
20307
20318
  const padStart = startInVideoSeconds + (asset.trimLeft === 0 ? presentationTimeOffsetInSeconds : 0);
20308
20319
  return {
20309
- filter: `[0:a]` + [
20320
+ filter: "[0:a]" + [
20310
20321
  `aformat=sample_fmts=s32:sample_rates=${DEFAULT_SAMPLE_RATE}`,
20311
20322
  ...trimAndTempoFilter,
20312
20323
  volumeFilter.value === "1" ? null : `volume=${volumeFilter.value}:eval=${volumeFilter.eval}`,
@@ -20332,7 +20343,8 @@ var preprocessAudioTrackUnlimited = async ({
20332
20343
  chunkLengthInSeconds,
20333
20344
  trimLeftOffset,
20334
20345
  trimRightOffset,
20335
- forSeamlessAacConcatenation
20346
+ forSeamlessAacConcatenation,
20347
+ audioStreamIndex
20336
20348
  }) => {
20337
20349
  const { channels, duration, startTime } = await getAudioChannelsAndDuration({
20338
20350
  downloadMap,
@@ -20340,7 +20352,8 @@ var preprocessAudioTrackUnlimited = async ({
20340
20352
  indent,
20341
20353
  logLevel,
20342
20354
  binariesDirectory,
20343
- cancelSignal
20355
+ cancelSignal,
20356
+ audioStreamIndex
20344
20357
  });
20345
20358
  const filter = stringifyFfmpegFilter({
20346
20359
  asset,
@@ -20363,6 +20376,7 @@ var preprocessAudioTrackUnlimited = async ({
20363
20376
  const args = [
20364
20377
  ["-hide_banner"],
20365
20378
  ["-i", resolveAssetSrc(asset.src)],
20379
+ audioStreamIndex ? ["-map", `0:a:${audioStreamIndex}`] : [],
20366
20380
  ["-ac", "2"],
20367
20381
  ["-filter_script:a", file],
20368
20382
  ["-c:a", "pcm_s16le"],
@@ -20454,7 +20468,8 @@ var createAudio = async ({
20454
20468
  chunkLengthInSeconds,
20455
20469
  trimLeftOffset,
20456
20470
  trimRightOffset,
20457
- forSeamlessAacConcatenation
20471
+ forSeamlessAacConcatenation,
20472
+ audioStreamIndex: asset.audioStreamIndex
20458
20473
  });
20459
20474
  preprocessProgress[index] = 1;
20460
20475
  updateProgress();
@@ -101,6 +101,7 @@ const startOffthreadVideoServer = ({ downloadMap, logLevel, indent, offthreadVid
101
101
  binariesDirectory,
102
102
  cancelSignalForAudioAnalysis: undefined,
103
103
  shouldAnalyzeAudioImmediately: true,
104
+ audioStreamIndex: undefined,
104
105
  })
105
106
  .then((to) => {
106
107
  return new Promise((resolve, reject) => {
@@ -17,6 +17,7 @@ type Options = {
17
17
  trimRightOffset: number;
18
18
  forSeamlessAacConcatenation: boolean;
19
19
  onProgress: (progress: number) => void;
20
+ audioStreamIndex: number;
20
21
  };
21
22
  export type PreprocessedAudioTrack = {
22
23
  outName: string;
@@ -11,7 +11,7 @@ const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
11
11
  const resolve_asset_src_1 = require("./resolve-asset-src");
12
12
  const sample_rate_1 = require("./sample-rate");
13
13
  const stringify_ffmpeg_filter_1 = require("./stringify-ffmpeg-filter");
14
- const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap, indent, logLevel, binariesDirectory, cancelSignal, onProgress, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, }) => {
14
+ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap, indent, logLevel, binariesDirectory, cancelSignal, onProgress, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, audioStreamIndex, }) => {
15
15
  var _a;
16
16
  const { channels, duration, startTime } = await (0, get_audio_channels_1.getAudioChannelsAndDuration)({
17
17
  downloadMap,
@@ -20,6 +20,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
20
20
  logLevel,
21
21
  binariesDirectory,
22
22
  cancelSignal,
23
+ audioStreamIndex,
23
24
  });
24
25
  const filter = (0, stringify_ffmpeg_filter_1.stringifyFfmpegFilter)({
25
26
  asset,
@@ -42,6 +43,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
42
43
  const args = [
43
44
  ['-hide_banner'],
44
45
  ['-i', (0, resolve_asset_src_1.resolveAssetSrc)(asset.src)],
46
+ audioStreamIndex ? ['-map', `0:a:${audioStreamIndex}`] : [],
45
47
  ['-ac', '2'],
46
48
  ['-filter_script:a', file],
47
49
  ['-c:a', 'pcm_s16le'],
@@ -118,7 +118,7 @@ const stringifyFfmpegFilter = ({ channels, volume, fps, assetDuration, chunkLeng
118
118
  (asset.trimLeft === 0 ? presentationTimeOffsetInSeconds : 0);
119
119
  // Set as few filters as possible, as combining them can create noise
120
120
  return {
121
- filter: `[0:a]` +
121
+ filter: '[0:a]' +
122
122
  [
123
123
  `aformat=sample_fmts=s32:sample_rates=${sample_rate_1.DEFAULT_SAMPLE_RATE}`,
124
124
  // The order matters here! For speed and correctness, we first trim the audio
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/renderer"
4
4
  },
5
5
  "name": "@remotion/renderer",
6
- "version": "4.0.336",
6
+ "version": "4.0.340",
7
7
  "description": "Render Remotion videos using Node.js or Bun",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
@@ -18,8 +18,8 @@
18
18
  "extract-zip": "2.0.1",
19
19
  "source-map": "^0.8.0-beta.0",
20
20
  "ws": "8.17.1",
21
- "remotion": "4.0.336",
22
- "@remotion/streaming": "4.0.336"
21
+ "remotion": "4.0.340",
22
+ "@remotion/streaming": "4.0.340"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "react": ">=16.8.0",
@@ -33,17 +33,17 @@
33
33
  "react-dom": "19.0.0",
34
34
  "@types/ws": "8.5.10",
35
35
  "eslint": "9.19.0",
36
- "@remotion/example-videos": "4.0.336",
37
- "@remotion/eslint-config-internal": "4.0.336"
36
+ "@remotion/example-videos": "4.0.340",
37
+ "@remotion/eslint-config-internal": "4.0.340"
38
38
  },
39
39
  "optionalDependencies": {
40
- "@remotion/compositor-darwin-arm64": "4.0.336",
41
- "@remotion/compositor-darwin-x64": "4.0.336",
42
- "@remotion/compositor-linux-arm64-musl": "4.0.336",
43
- "@remotion/compositor-linux-arm64-gnu": "4.0.336",
44
- "@remotion/compositor-linux-x64-gnu": "4.0.336",
45
- "@remotion/compositor-linux-x64-musl": "4.0.336",
46
- "@remotion/compositor-win32-x64-msvc": "4.0.336"
40
+ "@remotion/compositor-darwin-arm64": "4.0.340",
41
+ "@remotion/compositor-darwin-x64": "4.0.340",
42
+ "@remotion/compositor-linux-arm64-musl": "4.0.340",
43
+ "@remotion/compositor-linux-arm64-gnu": "4.0.340",
44
+ "@remotion/compositor-linux-x64-musl": "4.0.340",
45
+ "@remotion/compositor-win32-x64-msvc": "4.0.340",
46
+ "@remotion/compositor-linux-x64-gnu": "4.0.340"
47
47
  },
48
48
  "keywords": [
49
49
  "remotion",