@remotion/renderer 4.0.126 → 4.0.128

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 (59) hide show
  1. package/dist/assets/convert-assets-to-file-urls.d.ts +2 -1
  2. package/dist/assets/convert-assets-to-file-urls.js +6 -4
  3. package/dist/assets/download-map.d.ts +6 -2
  4. package/dist/assets/ffmpeg-volume-expression.js +7 -3
  5. package/dist/calculate-ffmpeg-filters.d.ts +4 -2
  6. package/dist/calculate-ffmpeg-filters.js +10 -17
  7. package/dist/check-apple-silicon.d.ts +1 -3
  8. package/dist/check-apple-silicon.js +2 -32
  9. package/dist/client.d.ts +57 -21
  10. package/dist/combine-audio.js +6 -6
  11. package/dist/combine-videos.js +1 -0
  12. package/dist/compress-audio.d.ts +2 -2
  13. package/dist/compress-audio.js +4 -7
  14. package/dist/create-audio.d.ts +11 -4
  15. package/dist/create-audio.js +7 -5
  16. package/dist/create-combined-video.d.ts +3 -2
  17. package/dist/create-combined-video.js +7 -1
  18. package/dist/create-silent-audio.d.ts +2 -2
  19. package/dist/create-silent-audio.js +2 -2
  20. package/dist/does-have-m2-bug.d.ts +3 -0
  21. package/dist/does-have-m2-bug.js +12 -0
  22. package/dist/get-extension-from-audio-codec.d.ts +2 -2
  23. package/dist/get-extra-frames-to-capture.d.ts +2 -1
  24. package/dist/get-extra-frames-to-capture.js +30 -23
  25. package/dist/index.d.ts +5 -5
  26. package/dist/logger.js +3 -1
  27. package/dist/merge-audio-track.d.ts +1 -1
  28. package/dist/merge-audio-track.js +7 -11
  29. package/dist/options/gl.d.ts +3 -3
  30. package/dist/options/index.d.ts +39 -3
  31. package/dist/options/index.js +4 -0
  32. package/dist/options/options-map.d.ts +18 -18
  33. package/dist/options/options-map.js +1 -1
  34. package/dist/options/prores-profile.d.ts +0 -0
  35. package/dist/options/prores-profile.js +1 -0
  36. package/dist/options/{separate-audio-to.d.ts → public-dir.d.ts} +5 -5
  37. package/dist/options/public-dir.js +37 -0
  38. package/dist/options/public-path.d.ts +18 -0
  39. package/dist/options/public-path.js +37 -0
  40. package/dist/preprocess-audio-track.d.ts +3 -1
  41. package/dist/preprocess-audio-track.js +7 -7
  42. package/dist/render-frames.d.ts +6 -0
  43. package/dist/render-frames.js +92 -42
  44. package/dist/render-media.d.ts +1 -0
  45. package/dist/render-media.js +5 -2
  46. package/dist/stitch-frames-to-video.d.ts +1 -1
  47. package/dist/stitch-frames-to-video.js +9 -9
  48. package/dist/stringify-ffmpeg-filter.d.ts +3 -2
  49. package/dist/stringify-ffmpeg-filter.js +56 -14
  50. package/dist/x264-preset.d.ts +15 -0
  51. package/dist/x264-preset.js +26 -1
  52. package/package.json +9 -9
  53. package/dist/can-concatenate-seamlessly.d.ts +0 -3
  54. package/dist/can-concatenate-seamlessly.js +0 -7
  55. package/dist/options/separate-audio-to.js +0 -31
  56. package/dist/should-seamless.d.ts +0 -3
  57. package/dist/should-seamless.js +0 -7
  58. package/dist/supported-audio-codecs.d.ts +0 -13
  59. package/dist/supported-audio-codecs.js +0 -16
@@ -1,9 +1,10 @@
1
1
  import type { TRenderAsset } from 'remotion/no-react';
2
2
  import type { LogLevel } from '../log-level';
3
+ import type { FrameAndAssets } from '../render-frames';
3
4
  import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
4
5
  import type { DownloadMap } from './download-map';
5
6
  export declare const convertAssetsToFileUrls: ({ assets, onDownload, downloadMap, indent, logLevel, }: {
6
- assets: TRenderAsset[][];
7
+ assets: FrameAndAssets[];
7
8
  onDownload: RenderMediaOnDownload;
8
9
  downloadMap: DownloadMap;
9
10
  indent: boolean;
@@ -13,8 +13,8 @@ const convertAssetsToFileUrls = async ({ assets, onDownload, downloadMap, indent
13
13
  const chunks = chunk(assets, 1000);
14
14
  const results = [];
15
15
  for (const ch of chunks) {
16
- const result = await Promise.all(ch.map((assetsForFrame) => {
17
- return Promise.all(assetsForFrame.map((a) => {
16
+ const assetPromises = ch.map((frame) => {
17
+ const frameAssetPromises = frame.assets.map((a) => {
18
18
  return (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
19
19
  renderAsset: a,
20
20
  onDownload,
@@ -22,8 +22,10 @@ const convertAssetsToFileUrls = async ({ assets, onDownload, downloadMap, indent
22
22
  indent,
23
23
  logLevel,
24
24
  });
25
- }));
26
- }));
25
+ });
26
+ return Promise.all(frameAssetPromises);
27
+ });
28
+ const result = await Promise.all(assetPromises);
27
29
  results.push(result);
28
30
  }
29
31
  return results.flat(1);
@@ -1,5 +1,5 @@
1
- import type { TRenderAsset } from 'remotion/no-react';
2
1
  import { OffthreadVideoServerEmitter } from '../offthread-video-server';
2
+ import type { FrameAndAssets } from '../render-frames';
3
3
  import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
4
4
  export type AudioChannelsAndDurationResultCache = {
5
5
  channels: number;
@@ -41,10 +41,14 @@ export type DownloadMap = {
41
41
  isPreventedFromCleanup: () => boolean;
42
42
  };
43
43
  export type RenderAssetInfo = {
44
- assets: TRenderAsset[][];
44
+ assets: FrameAndAssets[];
45
45
  imageSequenceName: string;
46
46
  firstFrameIndex: number;
47
47
  downloadMap: DownloadMap;
48
+ chunkLengthInSeconds: number;
49
+ trimLeftOffset: number;
50
+ trimRightOffset: number;
51
+ forSeamlessAacConcatenation: boolean;
48
52
  };
49
53
  export declare const makeDownloadMap: () => DownloadMap;
50
54
  export declare const cleanDownloadMap: (downloadMap: DownloadMap) => void;
@@ -32,7 +32,7 @@ const ffmpegIsOneOfFrames = ({ frames, trimLeft, fps, }) => {
32
32
  })
33
33
  .join('+');
34
34
  };
35
- const ffmpegBuildVolumeExpression = (arr, delay, fps) => {
35
+ const ffmpegBuildVolumeExpression = ({ arr, delay, fps, }) => {
36
36
  if (arr.length === 0) {
37
37
  throw new Error('Volume array expression should never have length 0');
38
38
  }
@@ -41,7 +41,7 @@ const ffmpegBuildVolumeExpression = (arr, delay, fps) => {
41
41
  }
42
42
  const [first, ...rest] = arr;
43
43
  const [volume, frames] = first;
44
- return ffmpegIfOrElse(ffmpegIsOneOfFrames({ frames, trimLeft: delay, fps }), String(volume), ffmpegBuildVolumeExpression(rest, delay, fps));
44
+ return ffmpegIfOrElse(ffmpegIsOneOfFrames({ frames, trimLeft: delay, fps }), String(volume), ffmpegBuildVolumeExpression({ arr: rest, delay, fps }));
45
45
  };
46
46
  const ffmpegVolumeExpression = ({ volume, fps, trimLeft, allowAmplificationDuringRender, }) => {
47
47
  const maxVolume = allowAmplificationDuringRender ? Infinity : 1;
@@ -85,7 +85,11 @@ const ffmpegVolumeExpression = ({ volume, fps, trimLeft, allowAmplificationDurin
85
85
  .map((key) => [Number(key), volumeMap[key]])
86
86
  .sort((a, b) => a[1].length - b[1].length);
87
87
  // Construct and tell FFMPEG it has to evaluate expression on each frame
88
- const expression = ffmpegBuildVolumeExpression(volumeArray, trimLeft, fps);
88
+ const expression = ffmpegBuildVolumeExpression({
89
+ arr: volumeArray,
90
+ delay: trimLeft,
91
+ fps,
92
+ });
89
93
  return {
90
94
  eval: 'frame',
91
95
  value: `'${expression}'`,
@@ -1,10 +1,12 @@
1
1
  import type { MediaAsset } from './assets/types';
2
2
  import type { FilterWithoutPaddingApplied } from './stringify-ffmpeg-filter';
3
- export declare const calculateFfmpegFilter: ({ asset, fps, durationInFrames, channels, assetDuration, forSeamlessAacConcatenation, }: {
3
+ export declare const calculateFfmpegFilter: ({ asset, fps, channels, assetDuration, trimLeftOffset, trimRightOffset, chunkLengthInSeconds, forSeamlessAacConcatenation, }: {
4
4
  asset: MediaAsset;
5
5
  fps: number;
6
- durationInFrames: number;
7
6
  channels: number;
8
7
  assetDuration: number | null;
8
+ trimLeftOffset: number;
9
+ trimRightOffset: number;
10
+ chunkLengthInSeconds: number;
9
11
  forSeamlessAacConcatenation: boolean;
10
12
  }) => FilterWithoutPaddingApplied | null;
@@ -2,36 +2,29 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.calculateFfmpegFilter = void 0;
4
4
  const flatten_volume_array_1 = require("./assets/flatten-volume-array");
5
- const combine_audio_1 = require("./combine-audio");
6
- const sample_rate_1 = require("./sample-rate");
7
5
  const stringify_ffmpeg_filter_1 = require("./stringify-ffmpeg-filter");
8
- const calculateFfmpegFilter = ({ asset, fps, durationInFrames, channels, assetDuration, forSeamlessAacConcatenation, }) => {
6
+ const calculateFfmpegFilter = ({ asset, fps, channels, assetDuration, trimLeftOffset, trimRightOffset, chunkLengthInSeconds, forSeamlessAacConcatenation, }) => {
9
7
  if (channels === 0) {
10
8
  return null;
11
9
  }
12
- const assetTrimLeft = forSeamlessAacConcatenation
13
- ? Math.max(0, (0, combine_audio_1.getClosestAlignedTime)(((asset.trimLeft * asset.playbackRate) / fps) * 1000000) /
14
- 1000000 -
15
- 2 * (1024 / sample_rate_1.DEFAULT_SAMPLE_RATE))
16
- : (asset.trimLeft * asset.playbackRate) / fps;
17
- const assetTrimRight = forSeamlessAacConcatenation
18
- ? (0, combine_audio_1.getClosestAlignedTime)(((asset.trimLeft + asset.duration * asset.playbackRate) / fps) *
19
- 1000000) /
20
- 1000000 +
21
- 2 * (1024 / sample_rate_1.DEFAULT_SAMPLE_RATE)
22
- : assetTrimLeft + (asset.duration * asset.playbackRate) / fps;
10
+ const trimLeft = (asset.trimLeft * asset.playbackRate) / fps +
11
+ trimLeftOffset * asset.playbackRate;
12
+ const trimRight = trimLeft +
13
+ (asset.duration * asset.playbackRate) / fps +
14
+ trimRightOffset * asset.playbackRate;
23
15
  return (0, stringify_ffmpeg_filter_1.stringifyFfmpegFilter)({
24
16
  channels,
25
17
  startInVideo: asset.startInVideo,
26
- trimLeft: assetTrimLeft,
27
- trimRight: assetTrimRight,
18
+ trimLeft,
19
+ trimRight,
28
20
  volume: (0, flatten_volume_array_1.flattenVolumeArray)(asset.volume),
29
21
  fps,
30
22
  playbackRate: asset.playbackRate,
31
- durationInFrames,
32
23
  assetDuration,
33
24
  allowAmplificationDuringRender: asset.allowAmplificationDuringRender,
34
25
  toneFrequency: asset.toneFrequency,
26
+ chunkLengthInSeconds,
27
+ forSeamlessAacConcatenation,
35
28
  });
36
29
  };
37
30
  exports.calculateFfmpegFilter = calculateFfmpegFilter;
@@ -1,3 +1 @@
1
- import type { LogLevel } from './log-level';
2
- export declare const gLibCErrorMessage: (libCString: string) => string | null;
3
- export declare const checkNodeVersionAndWarnAboutRosetta: (logLevel: LogLevel, indent: boolean) => void;
1
+ export declare const checkNodeVersionAndWarnAboutRosetta: () => void;
@@ -1,42 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkNodeVersionAndWarnAboutRosetta = exports.gLibCErrorMessage = void 0;
4
- const logger_1 = require("./logger");
5
- const gLibCErrorMessage = (libCString) => {
6
- const split = libCString.split('.');
7
- if (split.length !== 2) {
8
- return null;
9
- }
10
- if (split[0] === '2' && Number(split[1]) >= 35) {
11
- return null;
12
- }
13
- if (Number(split[0]) > 2) {
14
- return null;
15
- }
16
- return `Rendering videos requires glibc 2.35 or higher. Your system has glibc ${libCString}.`;
17
- };
18
- exports.gLibCErrorMessage = gLibCErrorMessage;
19
- const checkLibCRequirement = (logLevel, indent) => {
20
- const { report } = process;
21
- if (report) {
22
- // @ts-expect-error no types
23
- const { glibcVersionRuntime } = report.getReport().header;
24
- if (!glibcVersionRuntime) {
25
- return;
26
- }
27
- const error = (0, exports.gLibCErrorMessage)(glibcVersionRuntime);
28
- if (error) {
29
- logger_1.Log.warn({ logLevel, indent }, error);
30
- }
31
- }
32
- };
33
- const checkNodeVersionAndWarnAboutRosetta = (logLevel, indent) => {
3
+ exports.checkNodeVersionAndWarnAboutRosetta = void 0;
4
+ const checkNodeVersionAndWarnAboutRosetta = () => {
34
5
  const version = process.version.replace('v', '').split('.');
35
6
  const majorVersion = Number(version[0]);
36
7
  const requiredNodeVersion = 16;
37
8
  if (majorVersion < 16) {
38
9
  throw new Error(`Remotion requires at least Node ${requiredNodeVersion}. You currently have ${process.version}. Update your node version to ${requiredNodeVersion} to use Remotion.`);
39
10
  }
40
- checkLibCRequirement(logLevel, indent);
41
11
  };
42
12
  exports.checkNodeVersionAndWarnAboutRosetta = checkNodeVersionAndWarnAboutRosetta;
package/dist/client.d.ts CHANGED
@@ -464,19 +464,19 @@ export declare const BrowserSafeApis: {
464
464
  cliFlag: "gl";
465
465
  docLink: string;
466
466
  name: string;
467
- type: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
467
+ type: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null;
468
468
  ssrName: string;
469
469
  description: () => import("react/jsx-runtime").JSX.Element;
470
470
  getValue: ({ commandLine }: {
471
471
  commandLine: Record<string, unknown>;
472
472
  }) => {
473
- value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
473
+ value: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl";
474
474
  source: string;
475
475
  } | {
476
476
  value: null;
477
477
  source: string;
478
478
  };
479
- setConfig: (value: "angle" | "swangle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null) => void;
479
+ setConfig: (value: "swangle" | "angle" | "egl" | "swiftshader" | "vulkan" | "angle-egl" | null) => void;
480
480
  };
481
481
  enableLambdaInsights: {
482
482
  name: string;
@@ -724,6 +724,42 @@ export declare const BrowserSafeApis: {
724
724
  ssrName: string;
725
725
  type: string | null;
726
726
  };
727
+ publicPathOption: {
728
+ name: string;
729
+ cliFlag: "public-path";
730
+ description: () => import("react/jsx-runtime").JSX.Element;
731
+ ssrName: "publicPath";
732
+ docLink: string;
733
+ getValue: ({ commandLine }: {
734
+ commandLine: Record<string, unknown>;
735
+ }) => {
736
+ source: string;
737
+ value: string;
738
+ } | {
739
+ source: string;
740
+ value: null;
741
+ };
742
+ setConfig: (value: string | null) => void;
743
+ type: string | null;
744
+ };
745
+ publicDirOption: {
746
+ name: string;
747
+ cliFlag: "public-dir";
748
+ description: () => import("react/jsx-runtime").JSX.Element;
749
+ ssrName: "publicDir";
750
+ docLink: string;
751
+ getValue: ({ commandLine }: {
752
+ commandLine: Record<string, unknown>;
753
+ }) => {
754
+ source: string;
755
+ value: string;
756
+ } | {
757
+ source: string;
758
+ value: null;
759
+ };
760
+ setConfig: (value: string | null) => void;
761
+ type: string | null;
762
+ };
727
763
  };
728
764
  validColorSpaces: readonly ["default", "bt709", "bt2020-ncl"];
729
765
  optionsMap: {
@@ -1033,24 +1069,6 @@ export declare const BrowserSafeApis: {
1033
1069
  };
1034
1070
  };
1035
1071
  readonly stitchFramesToVideo: {
1036
- readonly forSeamlessAacConcatenation: {
1037
- name: string;
1038
- cliFlag: "for-seamless-aac-concatenation";
1039
- description: () => import("react/jsx-runtime").JSX.Element;
1040
- docLink: string;
1041
- getValue: ({ commandLine }: {
1042
- commandLine: Record<string, unknown>;
1043
- }) => {
1044
- source: string;
1045
- value: true;
1046
- } | {
1047
- source: string;
1048
- value: false;
1049
- };
1050
- setConfig: (value: boolean) => void;
1051
- ssrName: string;
1052
- type: boolean;
1053
- };
1054
1072
  readonly separateAudioTo: {
1055
1073
  cliFlag: string;
1056
1074
  description: () => string;
@@ -1281,6 +1299,24 @@ export declare const BrowserSafeApis: {
1281
1299
  };
1282
1300
  };
1283
1301
  readonly renderFrames: {
1302
+ readonly forSeamlessAacConcatenation: {
1303
+ name: string;
1304
+ cliFlag: "for-seamless-aac-concatenation";
1305
+ description: () => import("react/jsx-runtime").JSX.Element;
1306
+ docLink: string;
1307
+ getValue: ({ commandLine }: {
1308
+ commandLine: Record<string, unknown>;
1309
+ }) => {
1310
+ source: string;
1311
+ value: true;
1312
+ } | {
1313
+ source: string;
1314
+ value: false;
1315
+ };
1316
+ setConfig: (value: boolean) => void;
1317
+ ssrName: string;
1318
+ type: boolean;
1319
+ };
1284
1320
  readonly offthreadVideoCacheSizeInBytes: {
1285
1321
  name: string;
1286
1322
  cliFlag: "offthreadvideo-cache-size-in-bytes";
@@ -12,9 +12,9 @@ const sample_rate_1 = require("./sample-rate");
12
12
  const truthy_1 = require("./truthy");
13
13
  exports.durationOf1Frame = (1024 / sample_rate_1.DEFAULT_SAMPLE_RATE) * 1000000;
14
14
  const getClosestAlignedTime = (targetTime) => {
15
- const decimalFramesToTargetTime = targetTime / exports.durationOf1Frame;
15
+ const decimalFramesToTargetTime = (targetTime * 1000000) / exports.durationOf1Frame;
16
16
  const nearestFrameIndexForTargetTime = Math.round(decimalFramesToTargetTime);
17
- return nearestFrameIndexForTargetTime * exports.durationOf1Frame;
17
+ return (nearestFrameIndexForTargetTime * exports.durationOf1Frame) / 1000000;
18
18
  };
19
19
  exports.getClosestAlignedTime = getClosestAlignedTime;
20
20
  const encodeAudio = async ({ files, resolvedAudioCodec, audioBitrate, filelistDir, output, indent, logLevel, addRemotionMetadata, fps, binariesDirectory, cancelSignal, onProgress, }) => {
@@ -79,10 +79,10 @@ const combineAudioSeamlessly = async ({ files, filelistDir, indent, logLevel, ou
79
79
  const fileList = files
80
80
  .map((p, i) => {
81
81
  const isLast = i === files.length - 1;
82
- const targetStart = i * chunkDurationInSeconds * 1000000;
83
- const endStart = (i + 1) * chunkDurationInSeconds * 1000000;
84
- const startTime = (0, exports.getClosestAlignedTime)(targetStart);
85
- const endTime = (0, exports.getClosestAlignedTime)(endStart);
82
+ const targetStart = i * chunkDurationInSeconds;
83
+ const endStart = (i + 1) * chunkDurationInSeconds;
84
+ const startTime = (0, exports.getClosestAlignedTime)(targetStart) * 1000000;
85
+ const endTime = (0, exports.getClosestAlignedTime)(endStart) * 1000000;
86
86
  const realDuration = endTime - startTime;
87
87
  let inpoint = 0;
88
88
  if (i > 0) {
@@ -74,6 +74,7 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
74
74
  })
75
75
  : null,
76
76
  ].filter(truthy_1.truthy));
77
+ // Either only audio or only video
77
78
  if (!(audioOutput && shouldCreateVideo)) {
78
79
  (0, node_fs_1.rmSync)(filelistDir, { recursive: true });
79
80
  return;
@@ -1,7 +1,7 @@
1
1
  import type { LogLevel } from './log-level';
2
2
  import type { CancelSignal } from './make-cancel-signal';
3
3
  import type { AudioCodec } from './options/audio-codec';
4
- export declare const compressAudio: ({ audioCodec, outName, binariesDirectory, indent, logLevel, audioBitrate, cancelSignal, inName, onProgress, expectedFrames, fps, }: {
4
+ export declare const compressAudio: ({ audioCodec, outName, binariesDirectory, indent, logLevel, audioBitrate, cancelSignal, inName, onProgress, chunkLengthInSeconds, fps, }: {
5
5
  audioCodec: AudioCodec;
6
6
  outName: string;
7
7
  indent: boolean;
@@ -11,6 +11,6 @@ export declare const compressAudio: ({ audioCodec, outName, binariesDirectory, i
11
11
  cancelSignal: CancelSignal | undefined;
12
12
  inName: string;
13
13
  onProgress: (progress: number) => void;
14
- expectedFrames: number;
14
+ chunkLengthInSeconds: number;
15
15
  fps: number;
16
16
  }) => Promise<void>;
@@ -3,17 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.compressAudio = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const call_ffmpeg_1 = require("./call-ffmpeg");
6
- const logger_1 = require("./logger");
7
6
  const audio_codec_1 = require("./options/audio-codec");
8
7
  const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
9
8
  const truthy_1 = require("./truthy");
10
- const compressAudio = async ({ audioCodec, outName, binariesDirectory, indent, logLevel, audioBitrate, cancelSignal, inName, onProgress, expectedFrames, fps, }) => {
9
+ const compressAudio = async ({ audioCodec, outName, binariesDirectory, indent, logLevel, audioBitrate, cancelSignal, inName, onProgress, chunkLengthInSeconds, fps, }) => {
11
10
  var _a;
12
11
  if (audioCodec === 'pcm-16') {
13
12
  (0, node_fs_1.cpSync)(inName, outName);
14
13
  return onProgress(1);
15
14
  }
16
15
  const args = [
16
+ ['-hide_banner'],
17
17
  ['-i', inName],
18
18
  ['-c:a', (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(audioCodec)],
19
19
  audioCodec === 'aac' ? ['-f', 'adts'] : null,
@@ -35,11 +35,8 @@ const compressAudio = async ({ audioCodec, outName, binariesDirectory, indent, l
35
35
  (_a = task.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
36
36
  const utf8 = data.toString('utf8');
37
37
  const parsed = (0, parse_ffmpeg_progress_1.parseFfmpegProgress)(utf8, fps);
38
- if (parsed === undefined) {
39
- logger_1.Log.verbose({ indent, logLevel }, utf8);
40
- }
41
- else {
42
- onProgress(parsed / expectedFrames);
38
+ if (parsed !== undefined) {
39
+ onProgress(parsed / (chunkLengthInSeconds * fps));
43
40
  }
44
41
  });
45
42
  await task;
@@ -1,14 +1,18 @@
1
- import type { TRenderAsset } from 'remotion/no-react';
2
1
  import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
3
2
  import type { DownloadMap } from './assets/download-map';
4
3
  import type { LogLevel } from './log-level';
5
4
  import type { CancelSignal } from './make-cancel-signal';
6
5
  import type { AudioCodec } from './options/audio-codec';
7
- export declare const createAudio: ({ assets, onDownload, fps, expectedFrames, logLevel, onProgress, downloadMap, remotionRoot, indent, binariesDirectory, audioBitrate, audioCodec, cancelSignal, forSeamlessAacConcatenation, }: {
8
- assets: TRenderAsset[][];
6
+ import type { FrameAndAssets } from './render-frames';
7
+ export type SeamlessAudioInfo = {
8
+ chunkLengthInSeconds: number;
9
+ trimLeftOffset: number;
10
+ trimRightOffset: number;
11
+ };
12
+ export declare const createAudio: ({ assets, onDownload, fps, logLevel, onProgress, downloadMap, remotionRoot, indent, binariesDirectory, audioBitrate, audioCodec, cancelSignal, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, }: {
13
+ assets: FrameAndAssets[];
9
14
  onDownload: RenderMediaOnDownload | undefined;
10
15
  fps: number;
11
- expectedFrames: number;
12
16
  logLevel: LogLevel;
13
17
  onProgress: (progress: number) => void;
14
18
  downloadMap: DownloadMap;
@@ -18,5 +22,8 @@ export declare const createAudio: ({ assets, onDownload, fps, expectedFrames, lo
18
22
  audioBitrate: string | null;
19
23
  audioCodec: AudioCodec;
20
24
  cancelSignal: CancelSignal | undefined;
25
+ chunkLengthInSeconds: number;
26
+ trimLeftOffset: number;
27
+ trimRightOffset: number;
21
28
  forSeamlessAacConcatenation: boolean;
22
29
  }) => Promise<string>;
@@ -15,7 +15,7 @@ const merge_audio_track_1 = require("./merge-audio-track");
15
15
  const audio_codec_1 = require("./options/audio-codec");
16
16
  const preprocess_audio_track_1 = require("./preprocess-audio-track");
17
17
  const truthy_1 = require("./truthy");
18
- const createAudio = async ({ assets, onDownload, fps, expectedFrames, logLevel, onProgress, downloadMap, remotionRoot, indent, binariesDirectory, audioBitrate, audioCodec, cancelSignal, forSeamlessAacConcatenation, }) => {
18
+ const createAudio = async ({ assets, onDownload, fps, logLevel, onProgress, downloadMap, remotionRoot, indent, binariesDirectory, audioBitrate, audioCodec, cancelSignal, chunkLengthInSeconds, trimLeftOffset, trimRightOffset, forSeamlessAacConcatenation, }) => {
19
19
  const fileUrlAssets = await (0, convert_assets_to_file_urls_1.convertAssetsToFileUrls)({
20
20
  assets,
21
21
  onDownload: onDownload !== null && onDownload !== void 0 ? onDownload : (() => () => undefined),
@@ -41,18 +41,20 @@ const createAudio = async ({ assets, onDownload, fps, expectedFrames, logLevel,
41
41
  const result = await (0, preprocess_audio_track_1.preprocessAudioTrack)({
42
42
  outName: filterFile,
43
43
  asset,
44
- expectedFrames,
45
44
  fps,
46
45
  downloadMap,
47
46
  indent,
48
47
  logLevel,
49
48
  binariesDirectory,
50
49
  cancelSignal,
51
- forSeamlessAacConcatenation,
52
50
  onProgress: (progress) => {
53
51
  preprocessProgress[index] = progress;
54
52
  updateProgress();
55
53
  },
54
+ chunkLengthInSeconds,
55
+ trimLeftOffset,
56
+ trimRightOffset,
57
+ forSeamlessAacConcatenation,
56
58
  });
57
59
  preprocessProgress[index] = 1;
58
60
  updateProgress();
@@ -76,7 +78,7 @@ const createAudio = async ({ assets, onDownload, fps, expectedFrames, logLevel,
76
78
  mergeProgress = progress;
77
79
  updateProgress();
78
80
  },
79
- expectedFrames,
81
+ chunkLengthInSeconds,
80
82
  });
81
83
  await (0, compress_audio_1.compressAudio)({
82
84
  audioBitrate,
@@ -87,7 +89,7 @@ const createAudio = async ({ assets, onDownload, fps, expectedFrames, logLevel,
87
89
  inName: merged,
88
90
  outName,
89
91
  cancelSignal,
90
- expectedFrames,
92
+ chunkLengthInSeconds,
91
93
  fps,
92
94
  onProgress: (progress) => {
93
95
  compressProgress = progress;
@@ -1,7 +1,7 @@
1
1
  import type { Codec } from './codec';
2
2
  import type { LogLevel } from './log-level';
3
3
  import type { CancelSignal } from './make-cancel-signal';
4
- export declare const createCombinedVideo: ({ addRemotionMetadata, binariesDirectory, cancelSignal, codec, filelistDir, files, fps, indent, logLevel, numberOfGifLoops, onProgress, output, }: {
4
+ export declare const createCombinedVideo: ({ addRemotionMetadata, binariesDirectory, cancelSignal, codec, filelistDir, files, fps, indent, logLevel, numberOfGifLoops, onProgress, output, seamless, }: {
5
5
  fps: number;
6
6
  codec: Codec;
7
7
  filelistDir: string;
@@ -14,4 +14,5 @@ export declare const createCombinedVideo: ({ addRemotionMetadata, binariesDirect
14
14
  addRemotionMetadata: boolean;
15
15
  binariesDirectory: string | null;
16
16
  cancelSignal: CancelSignal | undefined;
17
- }) => Promise<void>;
17
+ seamless: boolean;
18
+ }) => Promise<string | undefined>;
@@ -2,7 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createCombinedVideo = void 0;
4
4
  const combine_video_streams_1 = require("./combine-video-streams");
5
- const createCombinedVideo = async ({ addRemotionMetadata, binariesDirectory, cancelSignal, codec, filelistDir, files, fps, indent, logLevel, numberOfGifLoops, onProgress, output, }) => {
5
+ const combine_video_streams_seamlessly_1 = require("./combine-video-streams-seamlessly");
6
+ const createCombinedVideo = async ({ addRemotionMetadata, binariesDirectory, cancelSignal, codec, filelistDir, files, fps, indent, logLevel, numberOfGifLoops, onProgress, output, seamless, }) => {
7
+ if (seamless) {
8
+ return (0, combine_video_streams_seamlessly_1.combineVideoStreamsSeamlessly)({
9
+ files,
10
+ });
11
+ }
6
12
  await (0, combine_video_streams_1.combineVideoStreams)({
7
13
  addRemotionMetadata,
8
14
  binariesDirectory,
@@ -1,7 +1,7 @@
1
1
  import type { LogLevel } from './log-level';
2
2
  import type { CancelSignal } from './make-cancel-signal';
3
- export declare const createSilentAudio: ({ numberOfSeconds, outName, indent, logLevel, binariesDirectory, cancelSignal, }: {
4
- numberOfSeconds: number;
3
+ export declare const createSilentAudio: ({ outName, indent, logLevel, binariesDirectory, cancelSignal, chunkLengthInSeconds, }: {
4
+ chunkLengthInSeconds: number;
5
5
  outName: string;
6
6
  indent: boolean;
7
7
  logLevel: LogLevel;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createSilentAudio = void 0;
4
4
  const call_ffmpeg_1 = require("./call-ffmpeg");
5
5
  const sample_rate_1 = require("./sample-rate");
6
- const createSilentAudio = async ({ numberOfSeconds, outName, indent, logLevel, binariesDirectory, cancelSignal, }) => {
6
+ const createSilentAudio = async ({ outName, indent, logLevel, binariesDirectory, cancelSignal, chunkLengthInSeconds, }) => {
7
7
  await (0, call_ffmpeg_1.callFf)({
8
8
  bin: 'ffmpeg',
9
9
  args: [
@@ -14,7 +14,7 @@ const createSilentAudio = async ({ numberOfSeconds, outName, indent, logLevel, b
14
14
  '-c:a',
15
15
  'pcm_s16le',
16
16
  '-t',
17
- String(numberOfSeconds),
17
+ String(chunkLengthInSeconds),
18
18
  '-ar',
19
19
  String(sample_rate_1.DEFAULT_SAMPLE_RATE),
20
20
  outName,
@@ -0,0 +1,3 @@
1
+ import type { Codec } from './codec';
2
+ import type { PixelFormat } from './pixel-format';
3
+ export declare const warnAboutM2Bug: (codec: Codec | null, pixelFormat: PixelFormat | null) => void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.warnAboutM2Bug = void 0;
4
+ const node_os_1 = require("node:os");
5
+ const warnAboutM2Bug = (codec, pixelFormat) => {
6
+ const isM2 = (0, node_os_1.cpus)().find((c) => c.model.includes('Apple M2'));
7
+ if (codec === 'prores' && pixelFormat === 'yuv422p10le' && isM2) {
8
+ console.warn();
9
+ console.warn('⚠️ Known issue: Apple M2 CPUs currently suffer from a bug where transparent ProRes videos have flickering. https://github.com/remotion-dev/remotion/issues/1929');
10
+ }
11
+ };
12
+ exports.warnAboutM2Bug = warnAboutM2Bug;
@@ -1,2 +1,2 @@
1
- import type { AudioCodec } from './options/audio-codec';
2
- export declare const getExtensionFromAudioCodec: (audioCodec: AudioCodec) => "aac" | "mp3" | "opus" | "wav";
1
+ import type { AudioCodec } from './audio-codec';
2
+ export declare const getExtensionFromAudioCodec: (audioCodec: AudioCodec) => "mp3" | "aac" | "wav" | "opus";
@@ -1,5 +1,6 @@
1
1
  type ReturnType = {
2
- extraFramesToCaptureAssets: number[];
2
+ extraFramesToCaptureAssetsFrontend: number[];
3
+ extraFramesToCaptureAssetsBackend: number[];
3
4
  trimLeftOffset: number;
4
5
  trimRightOffset: number;
5
6
  chunkLengthInSeconds: number;