@remotion/renderer 3.1.6 → 3.1.7

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 (119) hide show
  1. package/dist/assets/convert-assets-to-file-urls.d.ts +3 -2
  2. package/dist/assets/convert-assets-to-file-urls.js +2 -2
  3. package/dist/assets/download-and-map-assets-to-file.d.ts +6 -5
  4. package/dist/assets/download-and-map-assets-to-file.js +47 -47
  5. package/dist/assets/download-map.d.ts +57 -0
  6. package/dist/assets/download-map.js +20 -0
  7. package/dist/assets/get-audio-channels.d.ts +3 -7
  8. package/dist/assets/get-audio-channels.js +6 -7
  9. package/dist/assets/get-files-in-folder.d.ts +9 -0
  10. package/dist/assets/get-files-in-folder.js +50 -0
  11. package/dist/assets/get-video-stream-duration.d.ts +3 -6
  12. package/dist/assets/get-video-stream-duration.js +9 -8
  13. package/dist/browser/TimeoutSettings.d.ts +1 -0
  14. package/dist/browser/TimeoutSettings.js +4 -4
  15. package/dist/browser-executable.d.ts +1 -0
  16. package/dist/browser-executable.js +2 -0
  17. package/dist/browser.d.ts +2 -0
  18. package/dist/browser.js +4 -0
  19. package/dist/can-use-parallel-encoding.d.ts +1 -1
  20. package/dist/can-use-parallel-encoding.js +2 -2
  21. package/dist/codec-supports-media.d.ts +1 -1
  22. package/dist/codec.d.ts +4 -0
  23. package/dist/codec.js +16 -0
  24. package/dist/combine-videos.d.ts +1 -1
  25. package/dist/combine-videos.js +7 -6
  26. package/dist/compress-assets.d.ts +7 -0
  27. package/dist/compress-assets.js +25 -0
  28. package/dist/convert-to-pcm.d.ts +1 -1
  29. package/dist/create-ffmpeg-merge-filter.js +3 -3
  30. package/dist/create-silent-audio.d.ts +1 -1
  31. package/dist/crf.d.ts +5 -0
  32. package/dist/crf.js +64 -0
  33. package/dist/ensure-presentation-timestamp.d.ts +2 -1
  34. package/dist/ensure-presentation-timestamp.js +9 -7
  35. package/dist/extract-frame-from-video.d.ts +5 -1
  36. package/dist/extract-frame-from-video.js +21 -16
  37. package/dist/ffmpeg-executable.d.ts +1 -0
  38. package/dist/ffmpeg-executable.js +2 -0
  39. package/dist/frame-range.d.ts +2 -0
  40. package/dist/frame-range.js +49 -0
  41. package/dist/get-audio-codec-name.d.ts +1 -1
  42. package/dist/get-audio-codec-name.js +2 -2
  43. package/dist/get-browser-instance.d.ts +1 -1
  44. package/dist/get-browser-instance.js +2 -2
  45. package/dist/get-codec-name.d.ts +1 -1
  46. package/dist/get-codec-name.js +2 -2
  47. package/dist/get-compositions.d.ts +8 -1
  48. package/dist/get-compositions.js +6 -6
  49. package/dist/get-extension-from-codec.d.ts +1 -1
  50. package/dist/get-frame-to-render.d.ts +1 -1
  51. package/dist/get-local-browser-executable.d.ts +2 -1
  52. package/dist/get-prores-profile-name.d.ts +2 -1
  53. package/dist/get-video-info.d.ts +3 -8
  54. package/dist/get-video-info.js +7 -8
  55. package/dist/image-format.d.ts +6 -1
  56. package/dist/image-format.js +25 -1
  57. package/dist/index.d.ts +44 -5
  58. package/dist/index.js +70 -1
  59. package/dist/is-audio-codec.d.ts +2 -0
  60. package/dist/is-audio-codec.js +7 -0
  61. package/dist/is-beyond-last-frame.d.ts +3 -2
  62. package/dist/is-beyond-last-frame.js +5 -5
  63. package/dist/last-frame-from-video-cache.d.ts +5 -3
  64. package/dist/last-frame-from-video-cache.js +17 -17
  65. package/dist/log-level.d.ts +4 -0
  66. package/dist/log-level.js +15 -0
  67. package/dist/merge-audio-track.d.ts +1 -1
  68. package/dist/merge-audio-track.js +2 -2
  69. package/dist/offthread-video-server.d.ts +5 -3
  70. package/dist/offthread-video-server.js +3 -2
  71. package/dist/open-browser.d.ts +1 -1
  72. package/dist/open-browser.js +4 -4
  73. package/dist/overwrite.d.ts +1 -0
  74. package/dist/overwrite.js +4 -0
  75. package/dist/perf.d.ts +5 -0
  76. package/dist/perf.js +35 -0
  77. package/dist/pixel-format.d.ts +5 -0
  78. package/dist/pixel-format.js +26 -0
  79. package/dist/prepare-server.d.ts +4 -3
  80. package/dist/prepare-server.js +3 -3
  81. package/dist/preprocess-audio-track.d.ts +3 -1
  82. package/dist/preprocess-audio-track.js +2 -2
  83. package/dist/prespawn-ffmpeg.d.ts +5 -1
  84. package/dist/prespawn-ffmpeg.js +9 -6
  85. package/dist/prores-profile.d.ts +5 -0
  86. package/dist/prores-profile.js +23 -0
  87. package/dist/provide-screenshot.d.ts +1 -1
  88. package/dist/quality.d.ts +1 -0
  89. package/dist/quality.js +21 -0
  90. package/dist/render-frames.d.ts +10 -1
  91. package/dist/render-frames.js +21 -16
  92. package/dist/render-media.d.ts +14 -2
  93. package/dist/render-media.js +16 -9
  94. package/dist/render-still.d.ts +9 -1
  95. package/dist/render-still.js +14 -10
  96. package/dist/screenshot-dom-element.d.ts +1 -1
  97. package/dist/screenshot-task.d.ts +1 -1
  98. package/dist/screenshot-task.js +7 -7
  99. package/dist/serve-static.d.ts +3 -2
  100. package/dist/serve-static.js +3 -4
  101. package/dist/set-props-and-env.js +2 -2
  102. package/dist/stitch-frames-to-video.d.ts +6 -1
  103. package/dist/stitch-frames-to-video.js +16 -11
  104. package/dist/stringify-ffmpeg-filter.js +2 -2
  105. package/dist/symbolicate-stacktrace.js +3 -3
  106. package/dist/truthy.d.ts +3 -0
  107. package/dist/truthy.js +7 -0
  108. package/dist/types.d.ts +1 -1
  109. package/dist/validate-even-dimensions-with-codec.d.ts +1 -1
  110. package/dist/validate-even-dimensions-with-codec.js +2 -2
  111. package/dist/validate-every-nth-frame.d.ts +1 -0
  112. package/dist/validate-every-nth-frame.js +21 -0
  113. package/dist/validate-ffmpeg.js +2 -3
  114. package/dist/validate-frame.d.ts +1 -0
  115. package/dist/validate-frame.js +24 -0
  116. package/dist/validate-opengl-renderer.d.ts +5 -0
  117. package/dist/validate-opengl-renderer.js +15 -0
  118. package/dist/validate-output-filename.d.ts +1 -1
  119. package/package.json +3 -3
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * Since audio or video can be base64-encoded, those can be really long strings.
4
+ * Since we track the `src` property for every frame, Node.JS can run out of memory easily. Instead of duplicating the src for every frame, we save memory by replacing the full base 64 encoded data with a string `same-as-[asset-id]-[frame]` referencing a previous asset with the same src.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isAssetCompressed = exports.compressAsset = void 0;
8
+ const compressAsset = (previousAssets, newAsset) => {
9
+ if (newAsset.src.length < 400) {
10
+ return newAsset;
11
+ }
12
+ const assetWithSameSrc = previousAssets.find((a) => a.src === newAsset.src);
13
+ if (!assetWithSameSrc) {
14
+ return newAsset;
15
+ }
16
+ return {
17
+ ...newAsset,
18
+ src: `same-as-${assetWithSameSrc.id}-${assetWithSameSrc.frame}`,
19
+ };
20
+ };
21
+ exports.compressAsset = compressAsset;
22
+ const isAssetCompressed = (src) => {
23
+ return src.startsWith('same-as');
24
+ };
25
+ exports.isAssetCompressed = isAssetCompressed;
@@ -1,4 +1,4 @@
1
- import type { FfmpegExecutable } from 'remotion';
1
+ import type { FfmpegExecutable } from './ffmpeg-executable';
2
2
  export declare const convertToPcm: ({ ffmpegExecutable, input, outName, }: {
3
3
  ffmpegExecutable: FfmpegExecutable;
4
4
  input: string;
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createFfmpegMergeFilter = void 0;
4
- const remotion_1 = require("remotion");
4
+ const truthy_1 = require("./truthy");
5
5
  const createFfmpegMergeFilter = (inputs) => {
6
6
  const leftChannel = new Array(inputs * 2)
7
7
  .fill(true)
8
8
  .map((_, i) => (i % 2 === 0 ? `c${i}` : null))
9
- .filter(remotion_1.Internals.truthy)
9
+ .filter(truthy_1.truthy)
10
10
  .join('+');
11
11
  const rightChannel = new Array(inputs * 2)
12
12
  .fill(true)
13
13
  .map((_, i) => (i % 2 === 1 ? `c${i}` : null))
14
- .filter(remotion_1.Internals.truthy)
14
+ .filter(truthy_1.truthy)
15
15
  .join('+');
16
16
  return `[0:a][1:a]amerge=inputs=${inputs},pan=stereo|c0=${leftChannel}|c1=${rightChannel}[a]`;
17
17
  };
@@ -1,4 +1,4 @@
1
- import type { FfmpegExecutable } from 'remotion';
1
+ import type { FfmpegExecutable } from './ffmpeg-executable';
2
2
  export declare const createSilentAudio: ({ ffmpegExecutable, numberOfSeconds, outName, }: {
3
3
  ffmpegExecutable: FfmpegExecutable;
4
4
  numberOfSeconds: number;
package/dist/crf.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { Codec } from './codec';
2
+ export declare type Crf = number | undefined;
3
+ export declare const getDefaultCrfForCodec: (codec: Codec) => number;
4
+ export declare const getValidCrfRanges: (codec: Codec) => [number, number];
5
+ export declare const validateSelectedCrfAndCodecCombination: (crf: unknown, codec: Codec) => void;
package/dist/crf.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateSelectedCrfAndCodecCombination = exports.getValidCrfRanges = exports.getDefaultCrfForCodec = void 0;
4
+ const is_audio_codec_1 = require("./is-audio-codec");
5
+ const getDefaultCrfForCodec = (codec) => {
6
+ if ((0, is_audio_codec_1.isAudioCodec)(codec)) {
7
+ return 0;
8
+ }
9
+ if (codec === 'h264' || codec === 'h264-mkv') {
10
+ return 18; // FFMPEG default 23
11
+ }
12
+ if (codec === 'h265' || codec === 'gif') {
13
+ return 23; // FFMPEG default 28
14
+ }
15
+ if (codec === 'vp8') {
16
+ return 9; // FFMPEG default 10
17
+ }
18
+ if (codec === 'vp9') {
19
+ return 28; // FFMPEG recommendation 31
20
+ }
21
+ if (codec === 'prores') {
22
+ return 0;
23
+ }
24
+ throw new TypeError(`Got unexpected codec "${codec}"`);
25
+ };
26
+ exports.getDefaultCrfForCodec = getDefaultCrfForCodec;
27
+ const getValidCrfRanges = (codec) => {
28
+ if ((0, is_audio_codec_1.isAudioCodec)(codec)) {
29
+ return [0, 0];
30
+ }
31
+ if (codec === 'prores') {
32
+ return [0, 0];
33
+ }
34
+ if (codec === 'h264' || codec === 'h264-mkv') {
35
+ return [1, 51];
36
+ }
37
+ if (codec === 'h265' || codec === 'gif') {
38
+ return [0, 51];
39
+ }
40
+ if (codec === 'vp8') {
41
+ return [4, 63];
42
+ }
43
+ if (codec === 'vp9') {
44
+ return [0, 63];
45
+ }
46
+ throw new TypeError(`Got unexpected codec "${codec}"`);
47
+ };
48
+ exports.getValidCrfRanges = getValidCrfRanges;
49
+ const validateSelectedCrfAndCodecCombination = (crf, codec) => {
50
+ if (crf === null) {
51
+ return;
52
+ }
53
+ if (typeof crf !== 'number') {
54
+ throw new TypeError('Expected CRF to be a number, but is ' + JSON.stringify(crf));
55
+ }
56
+ const range = (0, exports.getValidCrfRanges)(codec);
57
+ if (crf === 0 && (codec === 'h264' || codec === 'h264-mkv')) {
58
+ throw new TypeError("Setting the CRF to 0 with a H264 codec is not supported anymore because of it's inconsistencies between platforms. Videos with CRF 0 cannot be played on iOS/macOS. 0 is a extreme value with inefficient settings which you probably want. Set CRF to a higher value to fix this error.");
59
+ }
60
+ if (crf < range[0] || crf > range[1]) {
61
+ throw new TypeError(`CRF must be between ${range[0]} and ${range[1]} for codec ${codec}. Passed: ${crf}`);
62
+ }
63
+ };
64
+ exports.validateSelectedCrfAndCodecCombination = validateSelectedCrfAndCodecCombination;
@@ -1 +1,2 @@
1
- export declare const ensurePresentationTimestamps: (src: string) => Promise<string>;
1
+ import type { DownloadMap } from './assets/download-map';
2
+ export declare const ensurePresentationTimestamps: (downloadMap: DownloadMap, src: string) => Promise<string>;
@@ -6,9 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ensurePresentationTimestamps = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const path_1 = __importDefault(require("path"));
9
- const remotion_1 = require("remotion");
10
9
  const guess_extension_for_media_1 = require("./guess-extension-for-media");
11
- const ensureFileHasPresentationTimestamp = {};
10
+ const truthy_1 = require("./truthy");
12
11
  let callbacks = [];
13
12
  const getTemporaryOutputName = async (src) => {
14
13
  const parts = src.split(path_1.default.sep);
@@ -20,14 +19,14 @@ const getTemporaryOutputName = async (src) => {
20
19
  return parts
21
20
  .map((p, i) => {
22
21
  if (i === parts.length - 1) {
23
- return [`pts-${p}`, extraExtension].filter(remotion_1.Internals.truthy).join('.');
22
+ return [`pts-${p}`, extraExtension].filter(truthy_1.truthy).join('.');
24
23
  }
25
24
  return p;
26
25
  })
27
26
  .join(path_1.default.sep);
28
27
  };
29
- const ensurePresentationTimestamps = async (src) => {
30
- const elem = ensureFileHasPresentationTimestamp[src];
28
+ const ensurePresentationTimestamps = async (downloadMap, src) => {
29
+ const elem = downloadMap.ensureFileHasPresentationTimestamp[src];
31
30
  if ((elem === null || elem === void 0 ? void 0 : elem.type) === 'encoding') {
32
31
  return new Promise((resolve) => {
33
32
  callbacks.push({
@@ -39,7 +38,7 @@ const ensurePresentationTimestamps = async (src) => {
39
38
  if ((elem === null || elem === void 0 ? void 0 : elem.type) === 'done') {
40
39
  return elem.src;
41
40
  }
42
- ensureFileHasPresentationTimestamp[src] = { type: 'encoding' };
41
+ downloadMap.ensureFileHasPresentationTimestamp[src] = { type: 'encoding' };
43
42
  // If there is no file extension for the video, then we need to tempoa
44
43
  const output = await getTemporaryOutputName(src);
45
44
  await (0, execa_1.default)('ffmpeg', [
@@ -61,7 +60,10 @@ const ensurePresentationTimestamps = async (src) => {
61
60
  }
62
61
  return true;
63
62
  });
64
- ensureFileHasPresentationTimestamp[src] = { type: 'done', src: output };
63
+ downloadMap.ensureFileHasPresentationTimestamp[src] = {
64
+ type: 'done',
65
+ src: output,
66
+ };
65
67
  return output;
66
68
  };
67
69
  exports.ensurePresentationTimestamps = ensurePresentationTimestamps;
@@ -1,4 +1,7 @@
1
- import type { FfmpegExecutable, OffthreadVideoImageFormat } from 'remotion';
1
+ /// <reference types="node" />
2
+ import type { OffthreadVideoImageFormat } from 'remotion';
3
+ import type { DownloadMap } from './assets/download-map';
4
+ import type { FfmpegExecutable } from './ffmpeg-executable';
2
5
  import type { LastFrameOptions } from './last-frame-from-video-cache';
3
6
  export declare const getLastFrameOfVideo: (options: LastFrameOptions) => Promise<Buffer>;
4
7
  declare type Options = {
@@ -7,6 +10,7 @@ declare type Options = {
7
10
  ffmpegExecutable: FfmpegExecutable;
8
11
  ffprobeExecutable: FfmpegExecutable;
9
12
  imageFormat: OffthreadVideoImageFormat;
13
+ downloadMap: DownloadMap;
10
14
  };
11
15
  export declare const extractFrameFromVideo: (options: Options) => Promise<Buffer>;
12
16
  export {};
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.extractFrameFromVideo = exports.getLastFrameOfVideo = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
- const remotion_1 = require("remotion");
9
8
  const get_video_stream_duration_1 = require("./assets/get-video-stream-duration");
10
9
  const ensure_presentation_timestamp_1 = require("./ensure-presentation-timestamp");
11
10
  const frame_to_ffmpeg_timestamp_1 = require("./frame-to-ffmpeg-timestamp");
@@ -13,6 +12,8 @@ const get_video_info_1 = require("./get-video-info");
13
12
  const is_beyond_last_frame_1 = require("./is-beyond-last-frame");
14
13
  const last_frame_from_video_cache_1 = require("./last-frame-from-video-cache");
15
14
  const p_limit_1 = require("./p-limit");
15
+ const perf_1 = require("./perf");
16
+ const truthy_1 = require("./truthy");
16
17
  const lastFrameLimit = (0, p_limit_1.pLimit)(1);
17
18
  const mainLimit = (0, p_limit_1.pLimit)(5);
18
19
  const determineVcodecFfmepgFlags = (vcodecFlag) => {
@@ -21,7 +22,7 @@ const determineVcodecFfmepgFlags = (vcodecFlag) => {
21
22
  vcodecFlag === 'vp9' ? 'libvpx-vp9' : null,
22
23
  vcodecFlag === 'vp8' ? '-vcodec' : null,
23
24
  vcodecFlag === 'vp8' ? 'libvpx' : null,
24
- ].filter(remotion_1.Internals.truthy);
25
+ ].filter(truthy_1.truthy);
25
26
  };
26
27
  const determineResizeParams = (needsResize) => {
27
28
  if (needsResize === null) {
@@ -48,7 +49,7 @@ const getFrameOfVideoSlow = async ({ src, timestamp, ffmpegExecutable, imageForm
48
49
  'image2pipe',
49
50
  ...determineResizeParams(needsResize),
50
51
  '-',
51
- ].filter(remotion_1.Internals.truthy);
52
+ ].filter(truthy_1.truthy);
52
53
  const { stdout, stderr } = (0, execa_1.default)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : 'ffmpeg', command);
53
54
  if (!stderr) {
54
55
  throw new Error('unexpectedly did not get stderr');
@@ -76,12 +77,12 @@ const getFrameOfVideoSlow = async ({ src, timestamp, ffmpegExecutable, imageForm
76
77
  return stdoutBuffer;
77
78
  };
78
79
  const getLastFrameOfVideoFastUnlimited = async (options) => {
79
- const { ffmpegExecutable, ffprobeExecutable, offset, src } = options;
80
+ const { ffmpegExecutable, ffprobeExecutable, offset, src, downloadMap } = options;
80
81
  const fromCache = (0, last_frame_from_video_cache_1.getLastFrameFromCache)({ ...options, offset: 0 });
81
82
  if (fromCache) {
82
83
  return fromCache;
83
84
  }
84
- const { duration } = await (0, get_video_stream_duration_1.getVideoStreamDuration)(src, ffprobeExecutable);
85
+ const { duration, fps } = await (0, get_video_stream_duration_1.getVideoStreamDuration)(downloadMap, src, ffprobeExecutable);
85
86
  if (duration === null) {
86
87
  throw new Error(`Could not determine the duration of ${src} using FFMPEG. The file is not supported.`);
87
88
  }
@@ -96,7 +97,7 @@ const getLastFrameOfVideoFastUnlimited = async (options) => {
96
97
  });
97
98
  return last;
98
99
  }
99
- const actualOffset = `${duration * 1000 - offset - 10}ms`;
100
+ const actualOffset = `${duration * 1000 - offset}ms`;
100
101
  const { stdout, stderr } = (0, execa_1.default)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : 'ffmpeg', [
101
102
  '-ss',
102
103
  actualOffset,
@@ -111,7 +112,7 @@ const getLastFrameOfVideoFastUnlimited = async (options) => {
111
112
  'image2pipe',
112
113
  ...determineResizeParams(options.needsResize),
113
114
  '-',
114
- ].filter(remotion_1.Internals.truthy));
115
+ ].filter(truthy_1.truthy));
115
116
  if (!stderr) {
116
117
  throw new Error('unexpectedly did not get stderr');
117
118
  }
@@ -141,12 +142,14 @@ const getLastFrameOfVideoFastUnlimited = async (options) => {
141
142
  if (isEmpty) {
142
143
  const unlimited = await getLastFrameOfVideoFastUnlimited({
143
144
  ffmpegExecutable,
144
- offset: offset + 10,
145
+ // Decrement in 10ms increments, or 1 frame (e.g. fps = 25 --> 40ms)
146
+ offset: offset + 1000 / (fps === null ? 10 : fps),
145
147
  src,
146
148
  ffprobeExecutable,
147
149
  imageFormat: options.imageFormat,
148
150
  specialVCodecForTransparency: options.specialVCodecForTransparency,
149
151
  needsResize: options.needsResize,
152
+ downloadMap: options.downloadMap,
150
153
  });
151
154
  return unlimited;
152
155
  }
@@ -158,11 +161,11 @@ const getLastFrameOfVideo = async (options) => {
158
161
  return result;
159
162
  };
160
163
  exports.getLastFrameOfVideo = getLastFrameOfVideo;
161
- const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutable, imageFormat, ...options }) => {
164
+ const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutable, imageFormat, downloadMap, ...options }) => {
162
165
  // We make a new copy of the video only for video because the conversion may affect
163
166
  // audio rendering, so we work with 2 different files
164
- const src = await (0, ensure_presentation_timestamp_1.ensurePresentationTimestamps)(options.src);
165
- const { specialVcodec, needsResize } = await (0, get_video_info_1.getVideoInfo)(src, ffprobeExecutable);
167
+ const src = await (0, ensure_presentation_timestamp_1.ensurePresentationTimestamps)(downloadMap, options.src);
168
+ const { specialVcodec, needsResize } = await (0, get_video_info_1.getVideoInfo)(downloadMap, src, ffprobeExecutable);
166
169
  if (specialVcodec === 'vp8') {
167
170
  return getFrameOfVideoSlow({
168
171
  ffmpegExecutable,
@@ -173,7 +176,7 @@ const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutab
173
176
  needsResize,
174
177
  });
175
178
  }
176
- if ((0, is_beyond_last_frame_1.isBeyondLastFrame)(src, time)) {
179
+ if ((0, is_beyond_last_frame_1.isBeyondLastFrame)(downloadMap, src, time)) {
177
180
  const lastFrame = await (0, exports.getLastFrameOfVideo)({
178
181
  ffmpegExecutable,
179
182
  ffprobeExecutable,
@@ -182,6 +185,7 @@ const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutab
182
185
  imageFormat,
183
186
  specialVCodecForTransparency: specialVcodec,
184
187
  needsResize,
188
+ downloadMap,
185
189
  });
186
190
  return lastFrame;
187
191
  }
@@ -200,7 +204,7 @@ const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutab
200
204
  imageFormat === 'jpeg' ? 'mjpeg' : 'png',
201
205
  ...determineResizeParams(needsResize),
202
206
  '-',
203
- ].filter(remotion_1.Internals.truthy), {
207
+ ].filter(truthy_1.truthy), {
204
208
  buffer: false,
205
209
  });
206
210
  if (!stderr) {
@@ -226,7 +230,7 @@ const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutab
226
230
  stdoutBuffer,
227
231
  ]);
228
232
  if (stderrStr.includes('Output file is empty')) {
229
- (0, is_beyond_last_frame_1.markAsBeyondLastFrame)(src, time);
233
+ (0, is_beyond_last_frame_1.markAsBeyondLastFrame)(downloadMap, src, time);
230
234
  const last = await (0, exports.getLastFrameOfVideo)({
231
235
  ffmpegExecutable,
232
236
  ffprobeExecutable,
@@ -235,15 +239,16 @@ const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutab
235
239
  imageFormat,
236
240
  specialVCodecForTransparency: specialVcodec,
237
241
  needsResize,
242
+ downloadMap,
238
243
  });
239
244
  return last;
240
245
  }
241
246
  return stdOut;
242
247
  };
243
248
  const extractFrameFromVideo = async (options) => {
244
- const perf = remotion_1.Internals.perf.startPerfMeasure('extract-frame');
249
+ const perf = (0, perf_1.startPerfMeasure)('extract-frame');
245
250
  const res = await mainLimit(extractFrameFromVideoFn, options);
246
- remotion_1.Internals.perf.stopPerfMeasure(perf);
251
+ (0, perf_1.stopPerfMeasure)(perf);
247
252
  return res;
248
253
  };
249
254
  exports.extractFrameFromVideo = extractFrameFromVideo;
@@ -0,0 +1 @@
1
+ export declare type FfmpegExecutable = string | null;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export declare type FrameRange = number | [number, number];
2
+ export declare const validateFrameRange: (frameRange: FrameRange | null) => void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateFrameRange = void 0;
4
+ const validateFrameRange = (frameRange) => {
5
+ if (frameRange === null) {
6
+ return;
7
+ }
8
+ if (typeof frameRange === 'number') {
9
+ if (frameRange < 0) {
10
+ throw new TypeError('Frame must be a non-negative number, got ' + frameRange);
11
+ }
12
+ if (!Number.isFinite(frameRange)) {
13
+ throw new TypeError('Frame must be a finite number, got ' + frameRange);
14
+ }
15
+ if (!Number.isInteger(frameRange)) {
16
+ throw new Error(`Frame must be an integer, but got a float (${frameRange})`);
17
+ }
18
+ return;
19
+ }
20
+ if (Array.isArray(frameRange)) {
21
+ if (frameRange.length !== 2) {
22
+ throw new TypeError('Frame range must be a tuple, got an array with length ' +
23
+ frameRange.length);
24
+ }
25
+ for (const value of frameRange) {
26
+ if (typeof value !== 'number') {
27
+ throw new Error(`Each value of frame range must be a number, but got ${typeof value} (${JSON.stringify(value)})`);
28
+ }
29
+ if (!Number.isFinite(value)) {
30
+ throw new TypeError('Each value of frame range must be finite, but got ' + value);
31
+ }
32
+ if (!Number.isInteger(value)) {
33
+ throw new Error(`Each value of frame range must be an integer, but got a float (${value})`);
34
+ }
35
+ if (value < 0) {
36
+ throw new Error(`Each value of frame range must be non-negative, but got ${value}`);
37
+ }
38
+ }
39
+ const [first, second] = frameRange;
40
+ if (second < first) {
41
+ throw new Error('The second value of frame range must be not smaller than the first one, but got ' +
42
+ frameRange.join('-'));
43
+ }
44
+ return;
45
+ }
46
+ throw new TypeError('Frame range must be a number or a tuple of numbers, but got object of type ' +
47
+ typeof frameRange);
48
+ };
49
+ exports.validateFrameRange = validateFrameRange;
@@ -1,2 +1,2 @@
1
- import type { Codec } from 'remotion';
1
+ import type { Codec } from './codec';
2
2
  export declare const getAudioCodecName: (codec: Codec) => string | null;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAudioCodecName = void 0;
4
- const remotion_1 = require("remotion");
4
+ const is_audio_codec_1 = require("./is-audio-codec");
5
5
  const getAudioCodecName = (codec) => {
6
- if (!remotion_1.Internals.isAudioCodec(codec)) {
6
+ if (!(0, is_audio_codec_1.isAudioCodec)(codec)) {
7
7
  // The mkv container supports WAV, but MP4 does only support
8
8
  // AAC. Choose MKV codec for better quality because we can put in lossless audio
9
9
  if (codec === 'h264-mkv') {
@@ -1,4 +1,4 @@
1
- import type { BrowserExecutable } from 'remotion';
1
+ import type { BrowserExecutable } from './browser-executable';
2
2
  import type { Browser } from './browser/Browser';
3
3
  import type { Page } from './browser/BrowserPage';
4
4
  import type { ChromiumOptions } from './open-browser';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPageAndCleanupFn = void 0;
4
- const remotion_1 = require("remotion");
4
+ const browser_1 = require("./browser");
5
5
  const open_browser_1 = require("./open-browser");
6
6
  const getPageAndCleanupFn = async ({ passedInInstance, browserExecutable, chromiumOptions, }) => {
7
7
  if (passedInInstance) {
@@ -17,7 +17,7 @@ const getPageAndCleanupFn = async ({ passedInInstance, browserExecutable, chromi
17
17
  },
18
18
  };
19
19
  }
20
- const browserInstance = await (0, open_browser_1.openBrowser)(remotion_1.Internals.DEFAULT_BROWSER, {
20
+ const browserInstance = await (0, open_browser_1.openBrowser)(browser_1.DEFAULT_BROWSER, {
21
21
  browserExecutable,
22
22
  chromiumOptions,
23
23
  });
@@ -1,2 +1,2 @@
1
- import type { Codec } from 'remotion';
1
+ import type { Codec } from './codec';
2
2
  export declare const getCodecName: (codec: Codec) => string | null;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCodecName = void 0;
4
- const remotion_1 = require("remotion");
4
+ const is_audio_codec_1 = require("./is-audio-codec");
5
5
  const getCodecName = (codec) => {
6
- if (remotion_1.Internals.isAudioCodec(codec)) {
6
+ if ((0, is_audio_codec_1.isAudioCodec)(codec)) {
7
7
  return null;
8
8
  }
9
9
  if (codec === 'h264' || codec === 'h264-mkv') {
@@ -1,6 +1,9 @@
1
- import type { BrowserExecutable, FfmpegExecutable, TCompMetadata } from 'remotion';
1
+ import type { TCompMetadata } from 'remotion';
2
+ import type { DownloadMap } from './assets/download-map';
3
+ import type { BrowserExecutable } from './browser-executable';
2
4
  import type { BrowserLog } from './browser-log';
3
5
  import type { Browser } from './browser/Browser';
6
+ import type { FfmpegExecutable } from './ffmpeg-executable';
4
7
  import type { ChromiumOptions } from './open-browser';
5
8
  declare type GetCompositionsConfig = {
6
9
  inputProps?: object | null;
@@ -13,6 +16,10 @@ declare type GetCompositionsConfig = {
13
16
  ffmpegExecutable?: FfmpegExecutable;
14
17
  ffprobeExecutable?: FfmpegExecutable;
15
18
  port?: number | null;
19
+ /**
20
+ * @deprecated Only for Remotion internal usage
21
+ */
22
+ downloadMap?: DownloadMap;
16
23
  };
17
24
  export declare const getCompositions: (serveUrlOrWebpackUrl: string, config?: GetCompositionsConfig) => Promise<TCompMetadata[]>;
18
25
  export {};
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCompositions = void 0;
4
+ const download_map_1 = require("./assets/download-map");
4
5
  const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
5
6
  const get_browser_instance_1 = require("./get-browser-instance");
6
- const make_assets_download_dir_1 = require("./make-assets-download-dir");
7
7
  const prepare_server_1 = require("./prepare-server");
8
8
  const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
9
9
  const set_props_and_env_1 = require("./set-props-and-env");
@@ -52,12 +52,12 @@ const innerGetCompositions = async (serveUrl, page, config, proxyPort) => {
52
52
  return result;
53
53
  };
54
54
  const getCompositions = async (serveUrlOrWebpackUrl, config) => {
55
- var _a, _b;
56
- const downloadDir = (0, make_assets_download_dir_1.makeAssetsDownloadTmpDir)();
55
+ var _a, _b, _c;
56
+ const downloadMap = (_a = config === null || config === void 0 ? void 0 : config.downloadMap) !== null && _a !== void 0 ? _a : (0, download_map_1.makeDownloadMap)();
57
57
  const { page, cleanup } = await (0, get_browser_instance_1.getPageAndCleanupFn)({
58
58
  passedInInstance: config === null || config === void 0 ? void 0 : config.puppeteerInstance,
59
- browserExecutable: (_a = config === null || config === void 0 ? void 0 : config.browserExecutable) !== null && _a !== void 0 ? _a : null,
60
- chromiumOptions: (_b = config === null || config === void 0 ? void 0 : config.chromiumOptions) !== null && _b !== void 0 ? _b : {},
59
+ browserExecutable: (_b = config === null || config === void 0 ? void 0 : config.browserExecutable) !== null && _b !== void 0 ? _b : null,
60
+ chromiumOptions: (_c = config === null || config === void 0 ? void 0 : config.chromiumOptions) !== null && _c !== void 0 ? _c : {},
61
61
  });
62
62
  return new Promise((resolve, reject) => {
63
63
  var _a, _b, _c;
@@ -70,12 +70,12 @@ const getCompositions = async (serveUrlOrWebpackUrl, config) => {
70
70
  let close = null;
71
71
  (0, prepare_server_1.prepareServer)({
72
72
  webpackConfigOrServeUrl: serveUrlOrWebpackUrl,
73
- downloadDir,
74
73
  onDownload: () => undefined,
75
74
  onError,
76
75
  ffmpegExecutable: (_a = config === null || config === void 0 ? void 0 : config.ffmpegExecutable) !== null && _a !== void 0 ? _a : null,
77
76
  ffprobeExecutable: (_b = config === null || config === void 0 ? void 0 : config.ffprobeExecutable) !== null && _b !== void 0 ? _b : null,
78
77
  port: (_c = config === null || config === void 0 ? void 0 : config.port) !== null && _c !== void 0 ? _c : null,
78
+ downloadMap,
79
79
  })
80
80
  .then(({ serveUrl, closeServer, offthreadPort }) => {
81
81
  close = closeServer;
@@ -1,2 +1,2 @@
1
- import type { Codec } from 'remotion';
1
+ import type { Codec } from './codec';
2
2
  export declare const getFileExtensionFromCodec: (codec: Codec, type: 'chunk' | 'final') => "mp3" | "aac" | "wav" | "gif" | "webm" | "mp4" | "mov" | "mkv";
@@ -1,2 +1,2 @@
1
- import type { FrameRange } from 'remotion';
1
+ import type { FrameRange } from './frame-range';
2
2
  export declare const getRealFrameRange: (durationInFrames: number, frameRange: FrameRange | null) => [number, number];
@@ -1,3 +1,4 @@
1
- import type { Browser, BrowserExecutable } from 'remotion';
1
+ import type { Browser } from './browser';
2
+ import type { BrowserExecutable } from './browser-executable';
2
3
  export declare const ensureLocalBrowser: (browser: Browser, preferredBrowserExecutable: BrowserExecutable) => Promise<void>;
3
4
  export declare const getLocalBrowserExecutable: (browser: Browser, preferredBrowserExecutable: BrowserExecutable) => string;
@@ -1,2 +1,3 @@
1
- import type { Codec, ProResProfile } from 'remotion';
1
+ import type { Codec } from './codec';
2
+ import type { ProResProfile } from './prores-profile';
2
3
  export declare const getProResProfileName: (codec: Codec, proResProfile: ProResProfile | undefined) => string | null;
@@ -1,8 +1,3 @@
1
- import type { FfmpegExecutable } from 'remotion';
2
- declare type Result = {
3
- specialVcodec: SpecialVCodecForTransparency;
4
- needsResize: [number, number] | null;
5
- };
6
- export declare type SpecialVCodecForTransparency = 'vp9' | 'vp8' | 'none';
7
- export declare const getVideoInfo: (src: string, ffprobeExecutable: FfmpegExecutable) => Promise<Result>;
8
- export {};
1
+ import type { DownloadMap, Vp9Result } from './assets/download-map';
2
+ import type { FfmpegExecutable } from './ffmpeg-executable';
3
+ export declare const getVideoInfo: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable) => Promise<Vp9Result>;
@@ -7,12 +7,11 @@ exports.getVideoInfo = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const calculate_sar_dar_pixels_1 = require("./calculate-sar-dar-pixels");
9
9
  const p_limit_1 = require("./p-limit");
10
- const isVp9VideoCache = {};
11
10
  const limit = (0, p_limit_1.pLimit)(1);
12
- async function getVideoInfoUnlimited(src, ffprobeExecutable) {
11
+ async function getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable) {
13
12
  var _a;
14
- if (typeof isVp9VideoCache[src] !== 'undefined') {
15
- return isVp9VideoCache[src];
13
+ if (typeof downloadMap.isVp9VideoCache[src] !== 'undefined') {
14
+ return downloadMap.isVp9VideoCache[src];
16
15
  }
17
16
  const task = await (0, execa_1.default)(ffprobeExecutable !== null && ffprobeExecutable !== void 0 ? ffprobeExecutable : 'ffprobe', [src]);
18
17
  const isVp9 = task.stderr.includes('Video: vp9');
@@ -41,10 +40,10 @@ async function getVideoInfoUnlimited(src, ffprobeExecutable) {
41
40
  specialVcodec: isVp9 ? 'vp9' : isVp8 ? 'vp8' : 'none',
42
41
  needsResize,
43
42
  };
44
- isVp9VideoCache[src] = result;
45
- return isVp9VideoCache[src];
43
+ downloadMap.isVp9VideoCache[src] = result;
44
+ return downloadMap.isVp9VideoCache[src];
46
45
  }
47
- const getVideoInfo = (src, ffprobeExecutable) => {
48
- return limit(() => getVideoInfoUnlimited(src, ffprobeExecutable));
46
+ const getVideoInfo = (downloadMap, src, ffprobeExecutable) => {
47
+ return limit(() => getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable));
49
48
  };
50
49
  exports.getVideoInfo = getVideoInfo;
@@ -1,2 +1,7 @@
1
- import type { ImageFormat } from 'remotion';
1
+ import type { PixelFormat } from './pixel-format';
2
+ export declare const validImageFormats: readonly ["png", "jpeg", "none"];
3
+ export declare type ImageFormat = typeof validImageFormats[number];
4
+ export declare type StillImageFormat = 'png' | 'jpeg';
2
5
  export declare const DEFAULT_IMAGE_FORMAT: ImageFormat;
6
+ export declare const validateSelectedPixelFormatAndImageFormatCombination: (pixelFormat: PixelFormat, imageFormat: ImageFormat) => 'none' | 'valid';
7
+ export declare const validateNonNullImageFormat: (imageFormat: ImageFormat) => void;