@remotion/renderer 4.0.355 → 4.0.357

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.
Files changed (44) hide show
  1. package/dist/assets/apply-tone-frequency.d.ts +11 -0
  2. package/dist/assets/apply-tone-frequency.js +34 -0
  3. package/dist/assets/change-tempo.d.ts +34 -0
  4. package/dist/assets/change-tempo.js +287 -0
  5. package/dist/assets/change-tonefrequency.d.ts +2 -0
  6. package/dist/assets/change-tonefrequency.js +28 -0
  7. package/dist/assets/inline-audio-mixing.d.ts +8 -0
  8. package/dist/assets/inline-audio-mixing.js +39 -9
  9. package/dist/assets/resample-audiodata.d.ts +6 -0
  10. package/dist/assets/resample-audiodata.js +54 -0
  11. package/dist/assets/types.d.ts +1 -1
  12. package/dist/browser/Browser.d.ts +7 -4
  13. package/dist/browser/Browser.js +6 -3
  14. package/dist/browser/BrowserPage.d.ts +10 -2
  15. package/dist/browser/BrowserPage.js +9 -16
  16. package/dist/browser/Target.d.ts +3 -2
  17. package/dist/browser/Target.js +2 -1
  18. package/dist/create-audio.js +6 -0
  19. package/dist/default-on-log.d.ts +2 -0
  20. package/dist/default-on-log.js +8 -0
  21. package/dist/esm/error-handling.mjs +22 -14
  22. package/dist/esm/index.mjs +207 -108
  23. package/dist/get-browser-instance.d.ts +3 -2
  24. package/dist/get-browser-instance.js +3 -1
  25. package/dist/get-compositions.d.ts +2 -0
  26. package/dist/get-compositions.js +4 -1
  27. package/dist/index.d.ts +10 -1
  28. package/dist/index.js +2 -0
  29. package/dist/logger.d.ts +1 -0
  30. package/dist/logger.js +24 -24
  31. package/dist/make-page.d.ts +3 -2
  32. package/dist/make-page.js +2 -2
  33. package/dist/render-frames.d.ts +2 -0
  34. package/dist/render-frames.js +6 -2
  35. package/dist/render-media.d.ts +2 -0
  36. package/dist/render-media.js +13 -15
  37. package/dist/render-still.d.ts +2 -0
  38. package/dist/render-still.js +4 -1
  39. package/dist/select-composition.js +2 -0
  40. package/dist/test-gpu.d.ts +3 -1
  41. package/dist/test-gpu.js +2 -1
  42. package/dist/validate-even-dimensions-with-codec.js +16 -23
  43. package/ensure-browser.mjs +22 -14
  44. package/package.json +12 -12
@@ -383,6 +383,23 @@ var verboseTag = (str) => {
383
383
  return isColorSupported() ? chalk.bgBlack(` ${str} `) : `[${str}]`;
384
384
  };
385
385
  var Log = {
386
+ formatLogs: (logLevel, options, args) => {
387
+ return [
388
+ options.indent ? INDENT_TOKEN : null,
389
+ options.tag ? verboseTag(options.tag) : null
390
+ ].filter(truthy).concat(args.map((a) => {
391
+ if (logLevel === "warn") {
392
+ return chalk.yellow(a);
393
+ }
394
+ if (logLevel === "error") {
395
+ return chalk.red(a);
396
+ }
397
+ if (logLevel === "verbose" || logLevel === "trace") {
398
+ return chalk.gray(a);
399
+ }
400
+ return a;
401
+ }));
402
+ },
386
403
  trace: (options, ...args) => {
387
404
  writeInRepro("trace", ...args);
388
405
  if (isEqualOrBelowLogLevel(options.logLevel, "trace")) {
@@ -390,10 +407,7 @@ var Log = {
390
407
  return process.stdout.write(`
391
408
  `);
392
409
  }
393
- return console.log(...[
394
- options.indent ? INDENT_TOKEN : null,
395
- options.tag ? verboseTag(options.tag) : null
396
- ].filter(truthy).concat(args.map((a) => chalk.gray(a))));
410
+ return console.log(...Log.formatLogs("trace", options, args));
397
411
  }
398
412
  },
399
413
  verbose: (options, ...args) => {
@@ -403,10 +417,7 @@ var Log = {
403
417
  return process.stdout.write(`
404
418
  `);
405
419
  }
406
- return console.log(...[
407
- options.indent ? INDENT_TOKEN : null,
408
- options.tag ? verboseTag(options.tag) : null
409
- ].filter(truthy).concat(args.map((a) => chalk.gray(a))));
420
+ return console.log(...Log.formatLogs("verbose", options, args));
410
421
  }
411
422
  },
412
423
  info: (options, ...args) => {
@@ -416,7 +427,7 @@ var Log = {
416
427
  return process.stdout.write(`
417
428
  `);
418
429
  }
419
- return console.log(...[options.indent ? INDENT_TOKEN : null].filter(truthy).concat(args ?? []));
430
+ return console.log(...Log.formatLogs("info", options, args));
420
431
  }
421
432
  },
422
433
  warn: (options, ...args) => {
@@ -426,7 +437,7 @@ var Log = {
426
437
  return process.stdout.write(`
427
438
  `);
428
439
  }
429
- return console.warn(...[options.indent ? chalk.yellow(INDENT_TOKEN) : null].filter(truthy).concat(args.map((a) => chalk.yellow(a))));
440
+ return console.warn(...Log.formatLogs("warn", options, args));
430
441
  }
431
442
  },
432
443
  error: (options, ...args) => {
@@ -436,10 +447,7 @@ var Log = {
436
447
  return process.stdout.write(`
437
448
  `);
438
449
  }
439
- return console.error(...[
440
- options.indent ? INDENT_TOKEN : null,
441
- options.tag ? verboseTag(options.tag) : null
442
- ].filter(truthy).concat(args.map((a) => chalk.red(a))));
450
+ return console.error(...Log.formatLogs("error", options, args));
443
451
  }
444
452
  }
445
453
  };
@@ -2736,7 +2744,8 @@ class Page extends EventEmitter {
2736
2744
  logLevel,
2737
2745
  indent,
2738
2746
  pageIndex,
2739
- onBrowserLog
2747
+ onBrowserLog,
2748
+ onLog
2740
2749
  }) {
2741
2750
  const page = new Page({
2742
2751
  client,
@@ -2746,7 +2755,8 @@ class Page extends EventEmitter {
2746
2755
  logLevel,
2747
2756
  indent,
2748
2757
  pageIndex,
2749
- onBrowserLog
2758
+ onBrowserLog,
2759
+ onLog
2750
2760
  });
2751
2761
  await page.#initialize();
2752
2762
  await page.setViewport(defaultViewport);
@@ -2765,6 +2775,7 @@ class Page extends EventEmitter {
2765
2775
  indent;
2766
2776
  pageIndex;
2767
2777
  onBrowserLog;
2778
+ onLog;
2768
2779
  constructor({
2769
2780
  client,
2770
2781
  target,
@@ -2773,7 +2784,8 @@ class Page extends EventEmitter {
2773
2784
  logLevel,
2774
2785
  indent,
2775
2786
  pageIndex,
2776
- onBrowserLog
2787
+ onBrowserLog,
2788
+ onLog
2777
2789
  }) {
2778
2790
  super();
2779
2791
  this.#client = client;
@@ -2787,6 +2799,7 @@ class Page extends EventEmitter {
2787
2799
  this.indent = indent;
2788
2800
  this.pageIndex = pageIndex;
2789
2801
  this.onBrowserLog = onBrowserLog;
2802
+ this.onLog = onLog;
2790
2803
  client.on("Target.attachedToTarget", (event) => {
2791
2804
  switch (event.targetInfo.type) {
2792
2805
  case "iframe":
@@ -2839,19 +2852,11 @@ class Page extends EventEmitter {
2839
2852
  const tabInfo = `Tab ${this.pageIndex}`;
2840
2853
  const tagInfo = [origPosition?.name, isDelayRenderClear ? null : file].filter(truthy).join("@");
2841
2854
  const tag = [tabInfo, log.tag, log.tag ? null : tagInfo].filter(truthy).join(", ");
2842
- if (log.type === "error") {
2843
- Log.error({
2844
- logLevel,
2845
- tag,
2846
- indent
2847
- }, log.previewString);
2848
- } else {
2849
- Log[logLevel]({
2850
- logLevel,
2851
- tag,
2852
- indent
2853
- }, log.previewString);
2854
- }
2855
+ this.onLog({
2856
+ logLevel: log.logLevel,
2857
+ tag,
2858
+ previewString: log.previewString
2859
+ });
2855
2860
  } else if (log.type === "error") {
2856
2861
  if (log.text.includes("Failed to load resource:")) {
2857
2862
  Log.error({ logLevel, tag: url, indent }, log.text.replace(/\(\)$/, ""));
@@ -3519,7 +3524,8 @@ class Target {
3519
3524
  logLevel,
3520
3525
  indent,
3521
3526
  pageIndex,
3522
- onBrowserLog
3527
+ onBrowserLog,
3528
+ onLog
3523
3529
  }) {
3524
3530
  if (isPagetTarget(this.#targetInfo) && !this.#pagePromise) {
3525
3531
  this.#pagePromise = this.#sessionFactory().then((client) => {
@@ -3532,7 +3538,8 @@ class Target {
3532
3538
  logLevel,
3533
3539
  indent,
3534
3540
  pageIndex,
3535
- onBrowserLog
3541
+ onBrowserLog,
3542
+ onLog
3536
3543
  });
3537
3544
  });
3538
3545
  }
@@ -3672,14 +3679,16 @@ class HeadlessBrowser extends EventEmitter {
3672
3679
  logLevel,
3673
3680
  indent,
3674
3681
  pageIndex,
3675
- onBrowserLog
3682
+ onBrowserLog,
3683
+ onLog
3676
3684
  }) {
3677
3685
  return this.#defaultContext.newPage({
3678
3686
  context,
3679
3687
  logLevel,
3680
3688
  indent,
3681
3689
  pageIndex,
3682
- onBrowserLog
3690
+ onBrowserLog,
3691
+ onLog
3683
3692
  });
3684
3693
  }
3685
3694
  async _createPageInContext({
@@ -3687,7 +3696,8 @@ class HeadlessBrowser extends EventEmitter {
3687
3696
  logLevel,
3688
3697
  indent,
3689
3698
  pageIndex,
3690
- onBrowserLog
3699
+ onBrowserLog,
3700
+ onLog
3691
3701
  }) {
3692
3702
  const {
3693
3703
  value: { targetId }
@@ -3708,7 +3718,8 @@ class HeadlessBrowser extends EventEmitter {
3708
3718
  logLevel,
3709
3719
  indent,
3710
3720
  pageIndex,
3711
- onBrowserLog
3721
+ onBrowserLog,
3722
+ onLog
3712
3723
  });
3713
3724
  if (!page) {
3714
3725
  throw new Error(`Failed to create a page for context`);
@@ -3795,14 +3806,16 @@ class BrowserContext extends EventEmitter {
3795
3806
  logLevel,
3796
3807
  indent,
3797
3808
  pageIndex,
3798
- onBrowserLog
3809
+ onBrowserLog,
3810
+ onLog
3799
3811
  }) {
3800
3812
  return this.#browser._createPageInContext({
3801
3813
  context,
3802
3814
  logLevel,
3803
3815
  indent,
3804
3816
  pageIndex,
3805
- onBrowserLog
3817
+ onBrowserLog,
3818
+ onLog
3806
3819
  });
3807
3820
  }
3808
3821
  browser() {
@@ -4658,6 +4671,11 @@ var defaultBrowserDownloadProgress = ({
4658
4671
  };
4659
4672
  };
4660
4673
 
4674
+ // src/default-on-log.ts
4675
+ var defaultOnLog = ({ logLevel, tag, previewString }) => {
4676
+ Log[logLevel]({ logLevel, tag, indent: false }, previewString);
4677
+ };
4678
+
4661
4679
  // src/open-browser.ts
4662
4680
  import fs9 from "node:fs";
4663
4681
  import os3 from "node:os";
@@ -5353,7 +5371,8 @@ var getPageAndCleanupFn = async ({
5353
5371
  onBrowserDownload,
5354
5372
  chromeMode,
5355
5373
  pageIndex,
5356
- onBrowserLog
5374
+ onBrowserLog,
5375
+ onLog
5357
5376
  }) => {
5358
5377
  if (passedInInstance) {
5359
5378
  const page = await passedInInstance.newPage({
@@ -5361,7 +5380,8 @@ var getPageAndCleanupFn = async ({
5361
5380
  logLevel,
5362
5381
  indent,
5363
5382
  pageIndex,
5364
- onBrowserLog
5383
+ onBrowserLog,
5384
+ onLog
5365
5385
  });
5366
5386
  return {
5367
5387
  page,
@@ -5391,7 +5411,8 @@ var getPageAndCleanupFn = async ({
5391
5411
  logLevel,
5392
5412
  indent,
5393
5413
  pageIndex,
5394
- onBrowserLog
5414
+ onBrowserLog,
5415
+ onLog
5395
5416
  });
5396
5417
  return {
5397
5418
  page: browserPage,
@@ -15080,6 +15101,43 @@ import path14 from "node:path";
15080
15101
  // src/sample-rate.ts
15081
15102
  var DEFAULT_SAMPLE_RATE = 48000;
15082
15103
 
15104
+ // src/assets/apply-tone-frequency.ts
15105
+ var applyToneFrequencyUsingFfmpeg = async ({
15106
+ input,
15107
+ output,
15108
+ toneFrequency,
15109
+ indent,
15110
+ logLevel,
15111
+ binariesDirectory,
15112
+ cancelSignal
15113
+ }) => {
15114
+ const filter = `asetrate=${DEFAULT_SAMPLE_RATE}*${toneFrequency},aresample=${DEFAULT_SAMPLE_RATE},atempo=1/${toneFrequency}`;
15115
+ const args = [
15116
+ "-hide_banner",
15117
+ "-i",
15118
+ input,
15119
+ ["-ac", "2"],
15120
+ "-filter:a",
15121
+ filter,
15122
+ ["-c:a", "pcm_s16le"],
15123
+ ["-ar", String(DEFAULT_SAMPLE_RATE)],
15124
+ "-y",
15125
+ output
15126
+ ].flat(2);
15127
+ Log.verbose({ indent, logLevel }, "Changing tone frequency using FFmpeg:", JSON.stringify(args.join(" ")), "Filter:", filter);
15128
+ const startTimestamp = Date.now();
15129
+ const task = callFf({
15130
+ bin: "ffmpeg",
15131
+ args,
15132
+ indent,
15133
+ logLevel,
15134
+ binariesDirectory,
15135
+ cancelSignal
15136
+ });
15137
+ await task;
15138
+ Log.verbose({ indent, logLevel }, "Changed tone frequency using FFmpeg", `${Date.now() - startTimestamp}ms`);
15139
+ };
15140
+
15083
15141
  // src/assets/inline-audio-mixing.ts
15084
15142
  var numberTo32BiIntLittleEndian = (num) => {
15085
15143
  return new Uint8Array([
@@ -15094,10 +15152,12 @@ var numberTo16BitLittleEndian = (num) => {
15094
15152
  };
15095
15153
  var BIT_DEPTH = 16;
15096
15154
  var BYTES_PER_SAMPLE = BIT_DEPTH / 8;
15155
+ var NUMBER_OF_CHANNELS = 2;
15097
15156
  var makeInlineAudioMixing = (dir) => {
15098
15157
  const folderToAdd = makeAndReturn(dir, "remotion-inline-audio-mixing");
15099
15158
  const openFiles = {};
15100
15159
  const writtenHeaders = {};
15160
+ const toneFrequencies = {};
15101
15161
  const cleanup = () => {
15102
15162
  for (const fd of Object.values(openFiles)) {
15103
15163
  try {
@@ -15127,9 +15187,8 @@ var makeInlineAudioMixing = (dir) => {
15127
15187
  return;
15128
15188
  }
15129
15189
  writtenHeaders[filePath] = true;
15130
- const expectedDataSize = Math.round((totalNumberOfFrames / fps - trimLeftOffset + trimRightOffset) * asset.numberOfChannels * DEFAULT_SAMPLE_RATE * BYTES_PER_SAMPLE);
15190
+ const expectedDataSize = Math.round((totalNumberOfFrames / fps - trimLeftOffset + trimRightOffset) * NUMBER_OF_CHANNELS * DEFAULT_SAMPLE_RATE * BYTES_PER_SAMPLE);
15131
15191
  const expectedSize = 40 + expectedDataSize;
15132
- const { numberOfChannels } = asset;
15133
15192
  const fd = openFiles[filePath];
15134
15193
  writeSync(fd, new Uint8Array([82, 73, 70, 70]), 0, 4, 0);
15135
15194
  writeSync(fd, new Uint8Array(numberTo32BiIntLittleEndian(expectedSize)), 0, 4, 4);
@@ -15137,14 +15196,37 @@ var makeInlineAudioMixing = (dir) => {
15137
15196
  writeSync(fd, new Uint8Array([102, 109, 116, 32]), 0, 4, 12);
15138
15197
  writeSync(fd, new Uint8Array([BIT_DEPTH, 0, 0, 0]), 0, 4, 16);
15139
15198
  writeSync(fd, new Uint8Array([1, 0]), 0, 2, 20);
15140
- writeSync(fd, new Uint8Array([numberOfChannels, 0]), 0, 2, 22);
15199
+ writeSync(fd, new Uint8Array([NUMBER_OF_CHANNELS, 0]), 0, 2, 22);
15141
15200
  writeSync(fd, new Uint8Array(numberTo32BiIntLittleEndian(DEFAULT_SAMPLE_RATE)), 0, 4, 24);
15142
- writeSync(fd, new Uint8Array(numberTo32BiIntLittleEndian(DEFAULT_SAMPLE_RATE * numberOfChannels * BYTES_PER_SAMPLE)), 0, 4, 28);
15143
- writeSync(fd, new Uint8Array(numberTo16BitLittleEndian(numberOfChannels * BYTES_PER_SAMPLE)), 0, 2, 32);
15201
+ writeSync(fd, new Uint8Array(numberTo32BiIntLittleEndian(DEFAULT_SAMPLE_RATE * NUMBER_OF_CHANNELS * BYTES_PER_SAMPLE)), 0, 4, 28);
15202
+ writeSync(fd, new Uint8Array(numberTo16BitLittleEndian(NUMBER_OF_CHANNELS * BYTES_PER_SAMPLE)), 0, 2, 32);
15144
15203
  writeSync(fd, numberTo16BitLittleEndian(BIT_DEPTH), 0, 2, 34);
15145
15204
  writeSync(fd, new Uint8Array([100, 97, 116, 97]), 0, 4, 36);
15146
15205
  writeSync(fd, new Uint8Array(numberTo32BiIntLittleEndian(expectedDataSize)), 0, 4, 40);
15147
15206
  };
15207
+ const finish = async ({
15208
+ binariesDirectory,
15209
+ indent,
15210
+ logLevel,
15211
+ cancelSignal
15212
+ }) => {
15213
+ for (const fd of Object.keys(openFiles)) {
15214
+ const frequency = toneFrequencies[fd];
15215
+ if (frequency !== 1) {
15216
+ const tmpFile = fd.replace(/.wav$/, "-tmp.wav");
15217
+ await applyToneFrequencyUsingFfmpeg({
15218
+ input: fd,
15219
+ output: tmpFile,
15220
+ toneFrequency: frequency,
15221
+ indent,
15222
+ logLevel,
15223
+ binariesDirectory,
15224
+ cancelSignal
15225
+ });
15226
+ fs12.renameSync(tmpFile, fd);
15227
+ }
15228
+ }
15229
+ };
15148
15230
  const addAsset = ({
15149
15231
  asset,
15150
15232
  fps,
@@ -15161,7 +15243,11 @@ var makeInlineAudioMixing = (dir) => {
15161
15243
  trimRightOffset
15162
15244
  });
15163
15245
  const filePath = getFilePath(asset);
15246
+ if (toneFrequencies[filePath] !== undefined && toneFrequencies[filePath] !== asset.toneFrequency) {
15247
+ throw new Error(`toneFrequency must be the same across the entire audio, got ${asset.toneFrequency}, but before it was ${toneFrequencies[filePath]}`);
15248
+ }
15164
15249
  const fileDescriptor = openFiles[filePath];
15250
+ toneFrequencies[filePath] = asset.toneFrequency;
15165
15251
  let arr = new Int16Array(asset.audio);
15166
15252
  const isFirst = asset.frame === firstFrame;
15167
15253
  const isLast = asset.frame === totalNumberOfFrames + firstFrame - 1;
@@ -15174,19 +15260,20 @@ var makeInlineAudioMixing = (dir) => {
15174
15260
  throw new Error(`samplesToShaveFromStart should be approximately an integer, is ${samplesToShaveFromStart}`);
15175
15261
  }
15176
15262
  if (isFirst) {
15177
- arr = arr.slice(Math.round(samplesToShaveFromStart) * asset.numberOfChannels);
15263
+ arr = arr.slice(Math.round(samplesToShaveFromStart) * NUMBER_OF_CHANNELS);
15178
15264
  }
15179
15265
  if (isLast) {
15180
- arr = arr.slice(0, arr.length + Math.round(samplesToShaveFromEnd) * asset.numberOfChannels);
15266
+ arr = arr.slice(0, arr.length + Math.round(samplesToShaveFromEnd) * NUMBER_OF_CHANNELS);
15181
15267
  }
15182
15268
  const positionInSeconds = (asset.frame - firstFrame) / fps - (isFirst ? 0 : trimLeftOffset);
15183
- const position = Math.round(positionInSeconds * DEFAULT_SAMPLE_RATE) * asset.numberOfChannels * BYTES_PER_SAMPLE;
15269
+ const position = Math.floor(positionInSeconds * DEFAULT_SAMPLE_RATE) * NUMBER_OF_CHANNELS * BYTES_PER_SAMPLE;
15184
15270
  writeSync(fileDescriptor, arr, 0, arr.byteLength, 44 + position);
15185
15271
  };
15186
15272
  return {
15187
15273
  cleanup,
15188
15274
  addAsset,
15189
- getListOfAssets
15275
+ getListOfAssets,
15276
+ finish
15190
15277
  };
15191
15278
  };
15192
15279
 
@@ -16724,7 +16811,8 @@ var internalGetCompositionsRaw = async ({
16724
16811
  onBrowserDownload,
16725
16812
  chromeMode,
16726
16813
  offthreadVideoThreads,
16727
- mediaCacheSizeInBytes
16814
+ mediaCacheSizeInBytes,
16815
+ onLog
16728
16816
  }) => {
16729
16817
  const { page, cleanupPage } = await getPageAndCleanupFn({
16730
16818
  passedInInstance: puppeteerInstance,
@@ -16736,7 +16824,8 @@ var internalGetCompositionsRaw = async ({
16736
16824
  onBrowserDownload,
16737
16825
  chromeMode,
16738
16826
  pageIndex: 0,
16739
- onBrowserLog
16827
+ onBrowserLog,
16828
+ onLog
16740
16829
  });
16741
16830
  const cleanup = [cleanupPage];
16742
16831
  return new Promise((resolve2, reject) => {
@@ -16842,7 +16931,8 @@ var getCompositions = (serveUrlOrWebpackUrl, config) => {
16842
16931
  }),
16843
16932
  chromeMode: chromeMode ?? "headless-shell",
16844
16933
  offthreadVideoThreads: offthreadVideoThreads ?? null,
16845
- mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null
16934
+ mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null,
16935
+ onLog: defaultOnLog
16846
16936
  });
16847
16937
  };
16848
16938
 
@@ -17808,9 +17898,10 @@ var makePage = async ({
17808
17898
  serializedResolvedPropsWithCustomSchema,
17809
17899
  pageIndex,
17810
17900
  isMainTab,
17811
- mediaCacheSizeInBytes
17901
+ mediaCacheSizeInBytes,
17902
+ onLog
17812
17903
  }) => {
17813
- const page = await browserReplacer.getBrowser().newPage({ context, logLevel, indent, pageIndex, onBrowserLog });
17904
+ const page = await browserReplacer.getBrowser().newPage({ context, logLevel, indent, pageIndex, onBrowserLog, onLog });
17814
17905
  pagesArray.push(page);
17815
17906
  await page.setViewport({
17816
17907
  width: composition.width,
@@ -18790,7 +18881,8 @@ var innerRenderFrames = async ({
18790
18881
  onArtifact,
18791
18882
  binariesDirectory,
18792
18883
  imageSequencePattern,
18793
- mediaCacheSizeInBytes
18884
+ mediaCacheSizeInBytes,
18885
+ onLog
18794
18886
  }) => {
18795
18887
  if (outputDir) {
18796
18888
  if (!fs14.existsSync(outputDir)) {
@@ -18837,7 +18929,8 @@ var innerRenderFrames = async ({
18837
18929
  timeoutInMilliseconds,
18838
18930
  pageIndex,
18839
18931
  isMainTab: pageIndex === 0,
18840
- mediaCacheSizeInBytes
18932
+ mediaCacheSizeInBytes,
18933
+ onLog
18841
18934
  });
18842
18935
  };
18843
18936
  const getPool = async () => {
@@ -18980,7 +19073,8 @@ var internalRenderFramesRaw = ({
18980
19073
  chromeMode,
18981
19074
  offthreadVideoThreads,
18982
19075
  imageSequencePattern,
18983
- mediaCacheSizeInBytes
19076
+ mediaCacheSizeInBytes,
19077
+ onLog
18984
19078
  }) => {
18985
19079
  validateDimension(composition.height, "height", "in the `config` object passed to `renderFrames()`");
18986
19080
  validateDimension(composition.width, "width", "in the `config` object passed to `renderFrames()`");
@@ -19084,7 +19178,8 @@ var internalRenderFramesRaw = ({
19084
19178
  chromeMode,
19085
19179
  offthreadVideoThreads,
19086
19180
  imageSequencePattern,
19087
- mediaCacheSizeInBytes
19181
+ mediaCacheSizeInBytes,
19182
+ onLog
19088
19183
  });
19089
19184
  })
19090
19185
  ]).then((res) => {
@@ -19213,7 +19308,8 @@ var renderFrames = (options) => {
19213
19308
  chromeMode: chromeMode ?? "headless-shell",
19214
19309
  offthreadVideoThreads: offthreadVideoThreads ?? null,
19215
19310
  imageSequencePattern: imageSequencePattern ?? null,
19216
- mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null
19311
+ mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null,
19312
+ onLog: defaultOnLog
19217
19313
  });
19218
19314
  };
19219
19315
 
@@ -19671,40 +19767,35 @@ var validateEvenDimensionsWithCodec = ({
19671
19767
  indent,
19672
19768
  logLevel
19673
19769
  }) => {
19674
- let actualWidth = width * scale;
19675
- let actualHeight = height * scale;
19676
19770
  if (wantsImageSequence) {
19677
19771
  return {
19678
- actualWidth,
19679
- actualHeight
19772
+ actualWidth: width,
19773
+ actualHeight: height
19680
19774
  };
19681
19775
  }
19682
19776
  if (codec !== "h264-mkv" && codec !== "h264" && codec !== "h265" && codec !== "h264-ts") {
19683
19777
  return {
19684
- actualWidth,
19685
- actualHeight
19778
+ actualWidth: width,
19779
+ actualHeight: height
19686
19780
  };
19687
19781
  }
19688
- if (actualWidth % 1 !== 0 && (actualWidth % 1 < 0.005 || actualWidth % 1 > 0.005)) {
19689
- Log.verbose({ indent, logLevel }, `Rounding width to an even number from ${actualWidth} to ${Math.round(actualWidth)}`);
19690
- actualWidth = Math.round(actualWidth);
19782
+ let heightEvenDimensions = height;
19783
+ while (Math.round(heightEvenDimensions * scale) % 2 !== 0) {
19784
+ heightEvenDimensions--;
19691
19785
  }
19692
- if (actualHeight % 1 !== 0 && (actualHeight % 1 < 0.005 || actualHeight % 1 > 0.005)) {
19693
- Log.verbose({ indent, logLevel }, `Rounding height to an even number from ${actualHeight} to ${Math.round(actualHeight)}`);
19694
- actualHeight = Math.round(actualHeight);
19786
+ let widthEvenDimensions = width;
19787
+ while (Math.round(widthEvenDimensions * scale) % 2 !== 0) {
19788
+ widthEvenDimensions--;
19695
19789
  }
19696
- const displayName = codec === "h265" ? "H265" : "H264";
19697
- if (actualWidth % 2 !== 0) {
19698
- Log.verbose({ indent, logLevel }, `Rounding width down to an even number from ${actualWidth} to ${actualWidth - 1} for ${displayName} codec compatibility`);
19699
- actualWidth -= 1;
19790
+ if (widthEvenDimensions !== width) {
19791
+ Log.verbose({ indent, logLevel }, `Rounding width to an even number from ${width} to ${widthEvenDimensions}`);
19700
19792
  }
19701
- if (actualHeight % 2 !== 0) {
19702
- Log.verbose({ indent, logLevel }, `Rounding height down to an even number from ${actualHeight} to ${actualHeight - 1} for ${displayName} codec compatibility`);
19703
- actualHeight -= 1;
19793
+ if (heightEvenDimensions !== height) {
19794
+ Log.verbose({ indent, logLevel }, `Rounding height to an even number from ${height} to ${heightEvenDimensions}`);
19704
19795
  }
19705
19796
  return {
19706
- actualWidth,
19707
- actualHeight
19797
+ actualWidth: widthEvenDimensions,
19798
+ actualHeight: heightEvenDimensions
19708
19799
  };
19709
19800
  };
19710
19801
 
@@ -20701,6 +20792,12 @@ var createAudio = async ({
20701
20792
  updateProgress();
20702
20793
  return result;
20703
20794
  }));
20795
+ await downloadMap.inlineAudioMixing.finish({
20796
+ indent,
20797
+ logLevel,
20798
+ binariesDirectory,
20799
+ cancelSignal
20800
+ });
20704
20801
  const inlinedAudio = downloadMap.inlineAudioMixing.getListOfAssets();
20705
20802
  const preprocessed = [
20706
20803
  ...audioTracks.filter(truthy),
@@ -21275,7 +21372,7 @@ var validateOutputFilename = ({
21275
21372
 
21276
21373
  // src/render-media.ts
21277
21374
  var SLOWEST_FRAME_COUNT = 10;
21278
- var MAX_RECENT_FRAME_TIMINGS = 50;
21375
+ var MAX_RECENT_FRAME_TIMINGS = 150;
21279
21376
  var internalRenderMediaRaw = ({
21280
21377
  proResProfile,
21281
21378
  x264Preset,
@@ -21333,7 +21430,8 @@ var internalRenderMediaRaw = ({
21333
21430
  hardwareAcceleration,
21334
21431
  chromeMode,
21335
21432
  offthreadVideoThreads,
21336
- mediaCacheSizeInBytes
21433
+ mediaCacheSizeInBytes,
21434
+ onLog
21337
21435
  }) => {
21338
21436
  const pixelFormat = userPixelFormat ?? compositionWithPossibleUnevenDimensions.defaultPixelFormat ?? DEFAULT_PIXEL_FORMAT;
21339
21437
  if (repro) {
@@ -21448,21 +21546,7 @@ var internalRenderMediaRaw = ({
21448
21546
  if (onCtrlCExit && workingDir) {
21449
21547
  onCtrlCExit(`Delete ${workingDir}`, () => deleteDirectory(workingDir));
21450
21548
  }
21451
- const {
21452
- actualWidth: widthEvenDimensionsUndivided,
21453
- actualHeight: heightEvenDimensionsUndivided
21454
- } = validateEvenDimensionsWithCodec({
21455
- codec,
21456
- height: compositionWithPossibleUnevenDimensions.height,
21457
- scale,
21458
- width: compositionWithPossibleUnevenDimensions.width,
21459
- wantsImageSequence: false,
21460
- indent,
21461
- logLevel
21462
- });
21463
- const heightEvenDimensions = Math.round(heightEvenDimensionsUndivided / scale);
21464
- const widthEvenDimensions = Math.round(widthEvenDimensionsUndivided / scale);
21465
- const { actualWidth, actualHeight } = validateEvenDimensionsWithCodec({
21549
+ const { actualWidth: widthEvenDimensions, actualHeight: heightEvenDimensions } = validateEvenDimensionsWithCodec({
21466
21550
  codec,
21467
21551
  height: compositionWithPossibleUnevenDimensions.height,
21468
21552
  scale,
@@ -21471,6 +21555,8 @@ var internalRenderMediaRaw = ({
21471
21555
  indent,
21472
21556
  logLevel
21473
21557
  });
21558
+ const actualWidth = widthEvenDimensions * scale;
21559
+ const actualHeight = heightEvenDimensions * scale;
21474
21560
  const composition = {
21475
21561
  ...compositionWithPossibleUnevenDimensions,
21476
21562
  height: heightEvenDimensions,
@@ -21583,10 +21669,14 @@ var internalRenderMediaRaw = ({
21583
21669
  });
21584
21670
  }).then(({ server, cleanupServer }) => {
21585
21671
  cleanupServerFn = cleanupServer;
21672
+ let timeOfLastFrame = Date.now();
21586
21673
  const renderFramesProc = internalRenderFrames({
21587
21674
  composition,
21588
- onFrameUpdate: (frame, frameIndex, timeToRenderInMilliseconds) => {
21675
+ onFrameUpdate: (frame, frameIndex) => {
21589
21676
  renderedFrames = frame;
21677
+ const now = Date.now();
21678
+ const timeToRenderInMilliseconds = now - timeOfLastFrame;
21679
+ timeOfLastFrame = now;
21590
21680
  recentFrameTimings.push(timeToRenderInMilliseconds);
21591
21681
  if (recentFrameTimings.length > MAX_RECENT_FRAME_TIMINGS) {
21592
21682
  recentFrameTimings.shift();
@@ -21653,7 +21743,8 @@ var internalRenderMediaRaw = ({
21653
21743
  onArtifact,
21654
21744
  chromeMode,
21655
21745
  imageSequencePattern: null,
21656
- mediaCacheSizeInBytes
21746
+ mediaCacheSizeInBytes,
21747
+ onLog
21657
21748
  });
21658
21749
  return renderFramesProc;
21659
21750
  }).then((renderFramesReturn) => {
@@ -21911,7 +22002,8 @@ var renderMedia = ({
21911
22002
  compositionStart: compositionStart ?? 0,
21912
22003
  hardwareAcceleration: hardwareAcceleration ?? "disable",
21913
22004
  chromeMode: chromeMode ?? "headless-shell",
21914
- mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null
22005
+ mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null,
22006
+ onLog: defaultOnLog
21915
22007
  });
21916
22008
  };
21917
22009
 
@@ -21945,7 +22037,8 @@ var innerRenderStill = async ({
21945
22037
  onBrowserDownload,
21946
22038
  onArtifact,
21947
22039
  chromeMode,
21948
- mediaCacheSizeInBytes
22040
+ mediaCacheSizeInBytes,
22041
+ onLog
21949
22042
  }) => {
21950
22043
  validateDimension(composition.height, "height", "in the `config` object passed to `renderStill()`");
21951
22044
  validateDimension(composition.width, "width", "in the `config` object passed to `renderStill()`");
@@ -21996,7 +22089,8 @@ var innerRenderStill = async ({
21996
22089
  logLevel,
21997
22090
  indent,
21998
22091
  pageIndex: 0,
21999
- onBrowserLog
22092
+ onBrowserLog,
22093
+ onLog
22000
22094
  });
22001
22095
  await page.setViewport({
22002
22096
  width: composition.width,
@@ -22246,7 +22340,8 @@ var renderStill = (options) => {
22246
22340
  onArtifact: onArtifact ?? null,
22247
22341
  chromeMode: chromeMode ?? "headless-shell",
22248
22342
  offthreadVideoThreads: offthreadVideoThreads ?? null,
22249
- mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null
22343
+ mediaCacheSizeInBytes: mediaCacheSizeInBytes ?? null,
22344
+ onLog: defaultOnLog
22250
22345
  });
22251
22346
  };
22252
22347
 
@@ -22384,7 +22479,8 @@ var internalSelectCompositionRaw = async (options) => {
22384
22479
  onBrowserDownload,
22385
22480
  chromeMode,
22386
22481
  pageIndex: 0,
22387
- onBrowserLog
22482
+ onBrowserLog,
22483
+ onLog: RenderInternals.defaultOnLog
22388
22484
  }),
22389
22485
  makeOrReuseServer(options.server, {
22390
22486
  webpackConfigOrServeUrl: serveUrlOrWebpackUrl,
@@ -22514,7 +22610,8 @@ var getChromiumGpuInformation = async ({
22514
22610
  chromiumOptions,
22515
22611
  timeoutInMilliseconds,
22516
22612
  onBrowserDownload,
22517
- chromeMode
22613
+ chromeMode,
22614
+ onLog
22518
22615
  }) => {
22519
22616
  const { page, cleanupPage: cleanup } = await getPageAndCleanupFn({
22520
22617
  passedInInstance: undefined,
@@ -22526,7 +22623,8 @@ var getChromiumGpuInformation = async ({
22526
22623
  onBrowserDownload,
22527
22624
  chromeMode,
22528
22625
  pageIndex: 0,
22529
- onBrowserLog: null
22626
+ onBrowserLog: null,
22627
+ onLog
22530
22628
  });
22531
22629
  await page.goto({ url: "chrome://gpu", timeout: 12000 });
22532
22630
  const { value } = await puppeteerEvaluateWithCatch({
@@ -23078,7 +23176,8 @@ var RenderInternals = {
23078
23176
  DEFAULT_RENDER_FRAMES_OFFTHREAD_VIDEO_THREADS,
23079
23177
  canConcatVideoSeamlessly,
23080
23178
  canConcatAudioSeamlessly,
23081
- internalCombineChunks
23179
+ internalCombineChunks,
23180
+ defaultOnLog
23082
23181
  };
23083
23182
  checkRuntimeVersion("info", false);
23084
23183
  export {