@remotion/renderer 4.0.242 → 4.0.243

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.
@@ -4,6 +4,7 @@ import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
4
4
  export type AudioChannelsAndDurationResultCache = {
5
5
  channels: number;
6
6
  duration: number | null;
7
+ startTime: number | null;
7
8
  };
8
9
  export type DownloadMap = {
9
10
  id: string;
@@ -7,7 +7,8 @@ const limit = (0, p_limit_1.pLimit)(1);
7
7
  const getAudioChannelsAndDurationWithoutCache = async ({ src, indent, logLevel, binariesDirectory, cancelSignal, }) => {
8
8
  const args = [
9
9
  ['-v', 'error'],
10
- ['-show_entries', 'stream=channels:format=duration'],
10
+ ['-select_streams', 'a:0'],
11
+ ['-show_entries', 'stream=channels:stream=start_time:format=duration'],
11
12
  ['-of', 'default=nw=1'],
12
13
  [src],
13
14
  ]
@@ -24,9 +25,11 @@ const getAudioChannelsAndDurationWithoutCache = async ({ src, indent, logLevel,
24
25
  });
25
26
  const channels = task.stdout.match(/channels=([0-9]+)/);
26
27
  const duration = task.stdout.match(/duration=([0-9.]+)/);
28
+ const startTime = task.stdout.match(/start_time=([0-9.]+)/);
27
29
  const result = {
28
30
  channels: channels ? parseInt(channels[1], 10) : 0,
29
31
  duration: duration ? parseFloat(duration[1]) : null,
32
+ startTime: startTime ? parseFloat(startTime[1]) : null,
30
33
  };
31
34
  return result;
32
35
  }
package/dist/index.d.ts CHANGED
@@ -139,13 +139,13 @@ export declare const RenderInternals: {
139
139
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
140
140
  DEFAULT_BROWSER: "chrome";
141
141
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
142
- DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
142
+ DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
143
143
  validateOpenGlRenderer: (option: unknown) => import("./options/gl").OpenGlRenderer | null;
144
144
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "h264-ts", "gif"];
145
145
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
146
146
  validateJpegQuality: (q: unknown) => void;
147
147
  DEFAULT_TIMEOUT: number;
148
- DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "h264-ts" | "gif";
148
+ DEFAULT_CODEC: "aac" | "mp3" | "wav" | "h264" | "h265" | "vp8" | "vp9" | "prores" | "h264-mkv" | "h264-ts" | "gif";
149
149
  logLevels: readonly ["verbose", "info", "warn", "error"];
150
150
  isEqualOrBelowLogLevel: (currentLevel: import("./log-level").LogLevel, level: import("./log-level").LogLevel) => boolean;
151
151
  isValidLogLevel: (level: string) => boolean;
@@ -184,10 +184,10 @@ export declare const RenderInternals: {
184
184
  preferLossless: boolean;
185
185
  }) => AudioCodec | null;
186
186
  defaultFileExtensionMap: {
187
- h264: {
187
+ aac: {
188
188
  default: import("./file-extensions").FileExtension;
189
189
  forAudioCodec: {
190
- mp3: {
190
+ "pcm-16": {
191
191
  possible: import("./file-extensions").FileExtension[];
192
192
  default: import("./file-extensions").FileExtension;
193
193
  };
@@ -195,94 +195,94 @@ export declare const RenderInternals: {
195
195
  possible: import("./file-extensions").FileExtension[];
196
196
  default: import("./file-extensions").FileExtension;
197
197
  };
198
- "pcm-16": {
199
- possible: import("./file-extensions").FileExtension[];
200
- default: import("./file-extensions").FileExtension;
201
- };
202
198
  };
203
199
  };
204
- h265: {
200
+ mp3: {
205
201
  default: import("./file-extensions").FileExtension;
206
202
  forAudioCodec: {
207
- aac: {
203
+ "pcm-16": {
208
204
  possible: import("./file-extensions").FileExtension[];
209
205
  default: import("./file-extensions").FileExtension;
210
206
  };
211
- "pcm-16": {
207
+ mp3: {
212
208
  possible: import("./file-extensions").FileExtension[];
213
209
  default: import("./file-extensions").FileExtension;
214
210
  };
215
211
  };
216
212
  };
217
- vp8: {
213
+ wav: {
218
214
  default: import("./file-extensions").FileExtension;
219
215
  forAudioCodec: {
220
216
  "pcm-16": {
221
217
  possible: import("./file-extensions").FileExtension[];
222
218
  default: import("./file-extensions").FileExtension;
223
219
  };
224
- opus: {
225
- possible: import("./file-extensions").FileExtension[];
226
- default: import("./file-extensions").FileExtension;
227
- };
228
220
  };
229
221
  };
230
- vp9: {
222
+ h264: {
231
223
  default: import("./file-extensions").FileExtension;
232
224
  forAudioCodec: {
233
225
  "pcm-16": {
234
226
  possible: import("./file-extensions").FileExtension[];
235
227
  default: import("./file-extensions").FileExtension;
236
228
  };
237
- opus: {
229
+ aac: {
230
+ possible: import("./file-extensions").FileExtension[];
231
+ default: import("./file-extensions").FileExtension;
232
+ };
233
+ mp3: {
238
234
  possible: import("./file-extensions").FileExtension[];
239
235
  default: import("./file-extensions").FileExtension;
240
236
  };
241
237
  };
242
238
  };
243
- mp3: {
239
+ h265: {
244
240
  default: import("./file-extensions").FileExtension;
245
241
  forAudioCodec: {
246
- mp3: {
242
+ "pcm-16": {
247
243
  possible: import("./file-extensions").FileExtension[];
248
244
  default: import("./file-extensions").FileExtension;
249
245
  };
250
- "pcm-16": {
246
+ aac: {
251
247
  possible: import("./file-extensions").FileExtension[];
252
248
  default: import("./file-extensions").FileExtension;
253
249
  };
254
250
  };
255
251
  };
256
- aac: {
252
+ vp8: {
257
253
  default: import("./file-extensions").FileExtension;
258
254
  forAudioCodec: {
259
- aac: {
255
+ "pcm-16": {
260
256
  possible: import("./file-extensions").FileExtension[];
261
257
  default: import("./file-extensions").FileExtension;
262
258
  };
263
- "pcm-16": {
259
+ opus: {
264
260
  possible: import("./file-extensions").FileExtension[];
265
261
  default: import("./file-extensions").FileExtension;
266
262
  };
267
263
  };
268
264
  };
269
- wav: {
265
+ vp9: {
270
266
  default: import("./file-extensions").FileExtension;
271
267
  forAudioCodec: {
272
268
  "pcm-16": {
273
269
  possible: import("./file-extensions").FileExtension[];
274
270
  default: import("./file-extensions").FileExtension;
275
271
  };
272
+ opus: {
273
+ possible: import("./file-extensions").FileExtension[];
274
+ default: import("./file-extensions").FileExtension;
275
+ };
276
276
  };
277
277
  };
278
278
  prores: {
279
279
  default: import("./file-extensions").FileExtension;
280
280
  forAudioCodec: {
281
- aac: {
281
+ "pcm-16": {
282
282
  possible: import("./file-extensions").FileExtension[];
283
283
  default: import("./file-extensions").FileExtension;
284
284
  };
285
- "pcm-16": {
285
+ aac: {
286
286
  possible: import("./file-extensions").FileExtension[];
287
287
  default: import("./file-extensions").FileExtension;
288
288
  };
@@ -291,11 +291,11 @@ export declare const RenderInternals: {
291
291
  "h264-mkv": {
292
292
  default: import("./file-extensions").FileExtension;
293
293
  forAudioCodec: {
294
- mp3: {
294
+ "pcm-16": {
295
295
  possible: import("./file-extensions").FileExtension[];
296
296
  default: import("./file-extensions").FileExtension;
297
297
  };
298
- "pcm-16": {
298
+ mp3: {
299
299
  possible: import("./file-extensions").FileExtension[];
300
300
  default: import("./file-extensions").FileExtension;
301
301
  };
@@ -304,11 +304,11 @@ export declare const RenderInternals: {
304
304
  "h264-ts": {
305
305
  default: import("./file-extensions").FileExtension;
306
306
  forAudioCodec: {
307
- aac: {
307
+ "pcm-16": {
308
308
  possible: import("./file-extensions").FileExtension[];
309
309
  default: import("./file-extensions").FileExtension;
310
310
  };
311
- "pcm-16": {
311
+ aac: {
312
312
  possible: import("./file-extensions").FileExtension[];
313
313
  default: import("./file-extensions").FileExtension;
314
314
  };
@@ -333,8 +333,8 @@ export declare const RenderInternals: {
333
333
  readonly vp9: readonly ["opus", "pcm-16"];
334
334
  readonly wav: readonly ["pcm-16"];
335
335
  };
336
- makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "h264-ts" | "gif")[]>;
337
- defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "h264-ts" | "gif">;
336
+ makeFileExtensionMap: () => Record<string, ("aac" | "mp3" | "wav" | "h264" | "h265" | "vp8" | "vp9" | "prores" | "h264-mkv" | "h264-ts" | "gif")[]>;
337
+ defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "aac" | "mp3" | "wav" | "h264" | "h265" | "vp8" | "vp9" | "prores" | "h264-mkv" | "h264-ts" | "gif">;
338
338
  getExecutablePath: ({ indent, logLevel, type, binariesDirectory, }: {
339
339
  type: "compositor" | "ffmpeg" | "ffprobe";
340
340
  indent: boolean;
@@ -352,8 +352,8 @@ export declare const RenderInternals: {
352
352
  }) => execa.ExecaChildProcess<string>;
353
353
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
354
354
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
355
- DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
356
- DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
355
+ DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
356
+ DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
357
357
  DEFAULT_JPEG_QUALITY: number;
358
358
  chalk: {
359
359
  enabled: () => boolean;
@@ -906,14 +906,14 @@ export declare const RenderInternals: {
906
906
  hostsToTry: string[];
907
907
  };
908
908
  makeDownloadMap: () => import("./assets/download-map").DownloadMap;
909
- getExtensionFromAudioCodec: (audioCodec: AudioCodec) => "mp3" | "aac" | "wav" | "opus";
909
+ getExtensionFromAudioCodec: (audioCodec: AudioCodec) => "aac" | "mp3" | "opus" | "wav";
910
910
  makeFileExecutableIfItIsNot: (path: string) => void;
911
911
  resolveAudioCodec: ({ codec, setting, preferLossless, separateAudioTo, }: {
912
912
  setting: AudioCodec | null;
913
913
  codec: import("./codec").Codec;
914
914
  preferLossless: boolean;
915
915
  separateAudioTo: string | null;
916
- }) => "mp3" | "aac" | "pcm-16" | "opus" | null;
916
+ }) => "pcm-16" | "aac" | "mp3" | "opus" | null;
917
917
  getShouldRenderAudio: ({ codec, assetsInfo, enforceAudioTrack, muted, }: {
918
918
  codec: import("./codec").Codec;
919
919
  assetsInfo: import("./assets/download-map").RenderAssetInfo | null;
@@ -13,7 +13,7 @@ const sample_rate_1 = require("./sample-rate");
13
13
  const stringify_ffmpeg_filter_1 = require("./stringify-ffmpeg-filter");
14
14
  const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap, indent, logLevel, binariesDirectory, cancelSignal, onProgress, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, }) => {
15
15
  var _a;
16
- const { channels, duration } = await (0, get_audio_channels_1.getAudioChannelsAndDuration)({
16
+ const { channels, duration, startTime } = await (0, get_audio_channels_1.getAudioChannelsAndDuration)({
17
17
  downloadMap,
18
18
  src: (0, resolve_asset_src_1.resolveAssetSrc)(asset.src),
19
19
  indent,
@@ -33,6 +33,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
33
33
  volume: (0, flatten_volume_array_1.flattenVolumeArray)(asset.volume),
34
34
  indent,
35
35
  logLevel,
36
+ presentationTimeOffsetInSeconds: startTime !== null && startTime !== void 0 ? startTime : 0,
36
37
  });
37
38
  if (filter === null) {
38
39
  return null;
@@ -48,7 +49,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
48
49
  ['-y', outName],
49
50
  ].flat(2);
50
51
  logger_1.Log.verbose({ indent, logLevel }, 'Preprocessing audio track:', JSON.stringify(args.join(' ')), 'Filter:', filter.filter);
51
- const startTime = Date.now();
52
+ const startTimestamp = Date.now();
52
53
  const task = (0, call_ffmpeg_1.callFf)({
53
54
  bin: 'ffmpeg',
54
55
  args,
@@ -65,7 +66,7 @@ const preprocessAudioTrackUnlimited = async ({ outName, asset, fps, downloadMap,
65
66
  }
66
67
  });
67
68
  await task;
68
- logger_1.Log.verbose({ indent, logLevel }, 'Preprocessed audio track', `${Date.now() - startTime}ms`);
69
+ logger_1.Log.verbose({ indent, logLevel }, 'Preprocessed audio track', `${Date.now() - startTimestamp}ms`);
69
70
  cleanup();
70
71
  return { outName, filter };
71
72
  };
@@ -18,7 +18,7 @@ export declare const getActualTrimLeft: ({ asset, fps, trimLeftOffset, seamless,
18
18
  trimLeft: number;
19
19
  maxTrim: number | null;
20
20
  };
21
- export declare const stringifyFfmpegFilter: ({ channels, volume, fps, assetDuration, chunkLengthInSeconds, forSeamlessAacConcatenation, trimLeftOffset, trimRightOffset, asset, indent, logLevel, }: {
21
+ export declare const stringifyFfmpegFilter: ({ channels, volume, fps, assetDuration, chunkLengthInSeconds, forSeamlessAacConcatenation, trimLeftOffset, trimRightOffset, asset, indent, logLevel, presentationTimeOffsetInSeconds, }: {
22
22
  channels: number;
23
23
  volume: AssetVolume;
24
24
  fps: number;
@@ -30,4 +30,5 @@ export declare const stringifyFfmpegFilter: ({ channels, volume, fps, assetDurat
30
30
  asset: MediaAsset;
31
31
  indent: boolean;
32
32
  logLevel: LogLevel;
33
+ presentationTimeOffsetInSeconds: number;
33
34
  }) => FilterWithoutPaddingApplied | null;
@@ -97,7 +97,7 @@ const trimAndSetTempo = ({ forSeamlessAacConcatenation, assetDuration, asset, tr
97
97
  }
98
98
  throw new Error('This should never happen');
99
99
  };
100
- const stringifyFfmpegFilter = ({ channels, volume, fps, assetDuration, chunkLengthInSeconds, forSeamlessAacConcatenation, trimLeftOffset, trimRightOffset, asset, indent, logLevel, }) => {
100
+ const stringifyFfmpegFilter = ({ channels, volume, fps, assetDuration, chunkLengthInSeconds, forSeamlessAacConcatenation, trimLeftOffset, trimRightOffset, asset, indent, logLevel, presentationTimeOffsetInSeconds, }) => {
101
101
  if (channels === 0) {
102
102
  return null;
103
103
  }
@@ -133,6 +133,7 @@ const stringifyFfmpegFilter = ({ channels, volume, fps, assetDuration, chunkLeng
133
133
  allowAmplificationDuringRender: asset.allowAmplificationDuringRender,
134
134
  });
135
135
  const padAtEnd = chunkLengthInSeconds - audibleDuration - startInVideoSeconds;
136
+ const padStart = startInVideoSeconds + presentationTimeOffsetInSeconds;
136
137
  // Set as few filters as possible, as combining them can create noise
137
138
  return {
138
139
  filter: `[0:a]` +
@@ -162,10 +163,10 @@ const stringifyFfmpegFilter = ({ channels, volume, fps, assetDuration, chunkLeng
162
163
  // This should be fine because FFMPEG documentation states:
163
164
  // "Unused delays will be silently ignored."
164
165
  // https://ffmpeg.org/ffmpeg-filters.html#adelay
165
- startInVideoSeconds === 0
166
+ padStart === 0
166
167
  ? null
167
168
  : `adelay=${new Array(channels + 1)
168
- .fill((startInVideoSeconds * 1000).toFixed(0))
169
+ .fill((padStart * 1000).toFixed(0))
169
170
  .join('|')}`,
170
171
  actualTrimLeft,
171
172
  };
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.242",
6
+ "version": "4.0.243",
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.242",
22
- "@remotion/streaming": "4.0.242"
21
+ "remotion": "4.0.243",
22
+ "@remotion/streaming": "4.0.243"
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.14.0",
36
- "@remotion/eslint-config-internal": "4.0.242",
37
- "@remotion/example-videos": "4.0.242"
36
+ "@remotion/example-videos": "4.0.243",
37
+ "@remotion/eslint-config-internal": "4.0.243"
38
38
  },
39
39
  "optionalDependencies": {
40
- "@remotion/compositor-darwin-x64": "4.0.242",
41
- "@remotion/compositor-darwin-arm64": "4.0.242",
42
- "@remotion/compositor-linux-arm64-gnu": "4.0.242",
43
- "@remotion/compositor-linux-arm64-musl": "4.0.242",
44
- "@remotion/compositor-linux-x64-musl": "4.0.242",
45
- "@remotion/compositor-win32-x64-msvc": "4.0.242",
46
- "@remotion/compositor-linux-x64-gnu": "4.0.242"
40
+ "@remotion/compositor-darwin-arm64": "4.0.243",
41
+ "@remotion/compositor-darwin-x64": "4.0.243",
42
+ "@remotion/compositor-linux-arm64-musl": "4.0.243",
43
+ "@remotion/compositor-linux-x64-gnu": "4.0.243",
44
+ "@remotion/compositor-linux-x64-musl": "4.0.243",
45
+ "@remotion/compositor-win32-x64-msvc": "4.0.243",
46
+ "@remotion/compositor-linux-arm64-gnu": "4.0.243"
47
47
  },
48
48
  "keywords": [
49
49
  "remotion",