@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
@@ -1,7 +1,8 @@
1
1
  import type { TAsset } from 'remotion';
2
2
  import type { RenderMediaOnDownload } from './download-and-map-assets-to-file';
3
- export declare const convertAssetsToFileUrls: ({ assets, downloadDir, onDownload, }: {
3
+ import type { DownloadMap } from './download-map';
4
+ export declare const convertAssetsToFileUrls: ({ assets, onDownload, downloadMap, }: {
4
5
  assets: TAsset[][];
5
- downloadDir: string;
6
6
  onDownload: RenderMediaOnDownload;
7
+ downloadMap: DownloadMap;
7
8
  }) => Promise<TAsset[][]>;
@@ -9,7 +9,7 @@ const chunk = (input, size) => {
9
9
  : [...arr.slice(0, -1), [...arr.slice(-1)[0], item]];
10
10
  }, []);
11
11
  };
12
- const convertAssetsToFileUrls = async ({ assets, downloadDir, onDownload, }) => {
12
+ const convertAssetsToFileUrls = async ({ assets, onDownload, downloadMap, }) => {
13
13
  const chunks = chunk(assets, 1000);
14
14
  const results = [];
15
15
  for (const ch of chunks) {
@@ -17,8 +17,8 @@ const convertAssetsToFileUrls = async ({ assets, downloadDir, onDownload, }) =>
17
17
  return Promise.all(assetsForFrame.map((a) => {
18
18
  return (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
19
19
  asset: a,
20
- downloadDir,
21
20
  onDownload,
21
+ downloadMap,
22
22
  });
23
23
  }));
24
24
  }));
@@ -1,22 +1,23 @@
1
1
  import type { TAsset } from 'remotion';
2
+ import type { DownloadMap } from './download-map';
2
3
  export declare type RenderMediaOnDownload = (src: string) => ((progress: {
3
4
  percent: number | null;
4
5
  downloaded: number;
5
6
  totalSize: number | null;
6
7
  }) => void) | undefined | void;
7
- export declare const downloadAsset: ({ src, onDownload, downloadDir, }: {
8
+ export declare const downloadAsset: ({ src, onDownload, downloadMap, }: {
8
9
  src: string;
9
10
  onDownload: RenderMediaOnDownload;
10
- downloadDir: string;
11
+ downloadMap: DownloadMap;
11
12
  }) => Promise<string>;
12
- export declare const markAllAssetsAsDownloaded: () => void;
13
+ export declare const markAllAssetsAsDownloaded: (downloadMap: DownloadMap) => void;
13
14
  export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, contentDisposition, }: {
14
15
  src: string;
15
16
  downloadDir: string;
16
17
  contentDisposition: string | null;
17
18
  }) => string;
18
- export declare const downloadAndMapAssetsToFileUrl: ({ asset, downloadDir, onDownload, }: {
19
+ export declare const downloadAndMapAssetsToFileUrl: ({ asset, onDownload, downloadMap, }: {
19
20
  asset: TAsset;
20
- downloadDir: string;
21
21
  onDownload: RenderMediaOnDownload;
22
+ downloadMap: DownloadMap;
22
23
  }) => Promise<TAsset>;
@@ -7,26 +7,24 @@ exports.downloadAndMapAssetsToFileUrl = exports.getSanitizedFilenameForAssetUrl
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const remotion_1 = require("remotion");
10
+ const compress_assets_1 = require("../compress-assets");
10
11
  const ensure_output_directory_1 = require("../ensure-output-directory");
11
12
  const download_file_1 = require("./download-file");
12
13
  const sanitize_filepath_1 = require("./sanitize-filepath");
13
- const isDownloadingMap = {};
14
- const hasBeenDownloadedMap = {};
15
- const listeners = {};
16
- const waitForAssetToBeDownloaded = ({ src, downloadDir, }) => {
14
+ const waitForAssetToBeDownloaded = ({ src, downloadDir, downloadMap, }) => {
17
15
  var _a, _b;
18
- if ((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
19
- return Promise.resolve((_b = hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir]);
16
+ if ((_a = downloadMap.hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
17
+ return Promise.resolve((_b = downloadMap.hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir]);
20
18
  }
21
- if (!listeners[src]) {
22
- listeners[src] = {};
19
+ if (!downloadMap.listeners[src]) {
20
+ downloadMap.listeners[src] = {};
23
21
  }
24
- if (!listeners[src][downloadDir]) {
25
- listeners[src][downloadDir] = [];
22
+ if (!downloadMap.listeners[src][downloadDir]) {
23
+ downloadMap.listeners[src][downloadDir] = [];
26
24
  }
27
25
  return new Promise((resolve) => {
28
- listeners[src][downloadDir].push(() => {
29
- const srcMap = hasBeenDownloadedMap[src];
26
+ downloadMap.listeners[src][downloadDir].push(() => {
27
+ const srcMap = downloadMap.hasBeenDownloadedMap[src];
30
28
  if (!srcMap || !srcMap[downloadDir]) {
31
29
  throw new Error('Expected file for ' + src + 'to be available in ' + downloadDir);
32
30
  }
@@ -34,22 +32,22 @@ const waitForAssetToBeDownloaded = ({ src, downloadDir, }) => {
34
32
  });
35
33
  });
36
34
  };
37
- const notifyAssetIsDownloaded = ({ src, downloadDir, to, }) => {
38
- if (!listeners[src]) {
39
- listeners[src] = {};
35
+ const notifyAssetIsDownloaded = ({ src, downloadDir, to, downloadMap, }) => {
36
+ if (!downloadMap.listeners[src]) {
37
+ downloadMap.listeners[src] = {};
40
38
  }
41
- if (!listeners[src][downloadDir]) {
42
- listeners[src][downloadDir] = [];
39
+ if (!downloadMap.listeners[src][downloadDir]) {
40
+ downloadMap.listeners[src][downloadDir] = [];
43
41
  }
44
- if (!isDownloadingMap[src]) {
45
- isDownloadingMap[src] = {};
42
+ if (!downloadMap.isDownloadingMap[src]) {
43
+ downloadMap.isDownloadingMap[src] = {};
46
44
  }
47
- isDownloadingMap[src][downloadDir] = true;
48
- if (!hasBeenDownloadedMap[src]) {
49
- hasBeenDownloadedMap[src] = {};
45
+ downloadMap.isDownloadingMap[src][downloadDir] = false;
46
+ if (!downloadMap.hasBeenDownloadedMap[src]) {
47
+ downloadMap.hasBeenDownloadedMap[src] = {};
50
48
  }
51
- hasBeenDownloadedMap[src][downloadDir] = to;
52
- listeners[src][downloadDir].forEach((fn) => fn());
49
+ downloadMap.hasBeenDownloadedMap[src][downloadDir] = to;
50
+ downloadMap.listeners[src][downloadDir].forEach((fn) => fn());
53
51
  };
54
52
  const validateMimeType = (mimeType, src) => {
55
53
  if (!mimeType.includes('/')) {
@@ -90,32 +88,34 @@ function validateBufferEncoding(potentialEncoding, dataUrl) {
90
88
  throw new TypeError(errMessage);
91
89
  }
92
90
  }
93
- const downloadAsset = async ({ src, onDownload, downloadDir, }) => {
91
+ const downloadAsset = async ({ src, onDownload, downloadMap, }) => {
94
92
  var _a, _b, _c;
95
- if (remotion_1.Internals.AssetCompression.isAssetCompressed(src)) {
93
+ if ((0, compress_assets_1.isAssetCompressed)(src)) {
96
94
  return src;
97
95
  }
98
- if ((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
99
- const claimedDownloadLocation = (_b = hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir];
96
+ const { downloadDir } = downloadMap;
97
+ if ((_a = downloadMap.hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
98
+ const claimedDownloadLocation = (_b = downloadMap.hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir];
100
99
  // The OS might have deleted the file since even though we marked it as downloaded. In that case we reset the state and download it again
101
100
  if (fs_1.default.existsSync(claimedDownloadLocation)) {
102
101
  return claimedDownloadLocation;
103
102
  }
104
103
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
105
- hasBeenDownloadedMap[src][downloadDir] = null;
106
- if (!isDownloadingMap[src]) {
107
- isDownloadingMap[src] = {};
104
+ downloadMap.hasBeenDownloadedMap[src][downloadDir] = null;
105
+ if (!downloadMap.isDownloadingMap[src]) {
106
+ downloadMap.isDownloadingMap[src] = {};
108
107
  }
109
108
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
110
- isDownloadingMap[src][downloadDir] = false;
109
+ downloadMap.isDownloadingMap[src][downloadDir] = false;
111
110
  }
112
- if ((_c = isDownloadingMap[src]) === null || _c === void 0 ? void 0 : _c[downloadDir]) {
113
- return waitForAssetToBeDownloaded({ src, downloadDir });
111
+ if ((_c = downloadMap.isDownloadingMap[src]) === null || _c === void 0 ? void 0 : _c[downloadDir]) {
112
+ console.log('TRIGGER WAIT', { src, downloadDir });
113
+ return waitForAssetToBeDownloaded({ downloadMap, src, downloadDir });
114
114
  }
115
- if (!isDownloadingMap[src]) {
116
- isDownloadingMap[src] = {};
115
+ if (!downloadMap.isDownloadingMap[src]) {
116
+ downloadMap.isDownloadingMap[src] = {};
117
117
  }
118
- isDownloadingMap[src][downloadDir] = true;
118
+ downloadMap.isDownloadingMap[src][downloadDir] = true;
119
119
  const onProgress = onDownload(src);
120
120
  if (src.startsWith('data:')) {
121
121
  const output = (0, exports.getSanitizedFilenameForAssetUrl)({
@@ -139,7 +139,7 @@ const downloadAsset = async ({ src, onDownload, downloadDir, }) => {
139
139
  validateBufferEncoding(encoding, src);
140
140
  const buff = Buffer.from(assetData, encoding);
141
141
  await fs_1.default.promises.writeFile(output, buff);
142
- notifyAssetIsDownloaded({ src, downloadDir, to: output });
142
+ notifyAssetIsDownloaded({ src, downloadMap, downloadDir, to: output });
143
143
  return output;
144
144
  }
145
145
  const { to } = await (0, download_file_1.downloadFile)({
@@ -149,16 +149,16 @@ const downloadAsset = async ({ src, onDownload, downloadDir, }) => {
149
149
  },
150
150
  to: (contentDisposition) => (0, exports.getSanitizedFilenameForAssetUrl)({ contentDisposition, downloadDir, src }),
151
151
  });
152
- notifyAssetIsDownloaded({ src, downloadDir, to });
152
+ notifyAssetIsDownloaded({ src, downloadMap, downloadDir, to });
153
153
  return to;
154
154
  };
155
155
  exports.downloadAsset = downloadAsset;
156
- const markAllAssetsAsDownloaded = () => {
157
- Object.keys(hasBeenDownloadedMap).forEach((key) => {
158
- delete hasBeenDownloadedMap[key];
156
+ const markAllAssetsAsDownloaded = (downloadMap) => {
157
+ Object.keys(downloadMap.hasBeenDownloadedMap).forEach((key) => {
158
+ delete downloadMap.hasBeenDownloadedMap[key];
159
159
  });
160
- Object.keys(isDownloadingMap).forEach((key) => {
161
- delete isDownloadingMap[key];
160
+ Object.keys(downloadMap.isDownloadingMap).forEach((key) => {
161
+ delete downloadMap.isDownloadingMap[key];
162
162
  });
163
163
  };
164
164
  exports.markAllAssetsAsDownloaded = markAllAssetsAsDownloaded;
@@ -180,7 +180,7 @@ const getFilename = ({ contentDisposition, src, }) => {
180
180
  return { pathname, search };
181
181
  };
182
182
  const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition, }) => {
183
- if (remotion_1.Internals.AssetCompression.isAssetCompressed(src)) {
183
+ if ((0, compress_assets_1.isAssetCompressed)(src)) {
184
184
  return src;
185
185
  }
186
186
  const { pathname, search } = getFilename({ contentDisposition, src });
@@ -193,11 +193,11 @@ const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition,
193
193
  return path_1.default.join(downloadDir, (0, sanitize_filepath_1.sanitizeFilePath)(filename));
194
194
  };
195
195
  exports.getSanitizedFilenameForAssetUrl = getSanitizedFilenameForAssetUrl;
196
- const downloadAndMapAssetsToFileUrl = async ({ asset, downloadDir, onDownload, }) => {
196
+ const downloadAndMapAssetsToFileUrl = async ({ asset, onDownload, downloadMap, }) => {
197
197
  const newSrc = await (0, exports.downloadAsset)({
198
198
  src: asset.src,
199
- downloadDir,
200
199
  onDownload,
200
+ downloadMap,
201
201
  });
202
202
  return {
203
203
  ...asset,
@@ -0,0 +1,57 @@
1
+ /// <reference types="node" />
2
+ import type { TAsset } from 'remotion';
3
+ declare type EncodingStatus = {
4
+ type: 'encoding';
5
+ } | {
6
+ type: 'done';
7
+ src: string;
8
+ } | undefined;
9
+ export declare type SpecialVCodecForTransparency = 'vp9' | 'vp8' | 'none';
10
+ export declare type Vp9Result = {
11
+ specialVcodec: SpecialVCodecForTransparency;
12
+ needsResize: [number, number] | null;
13
+ };
14
+ export declare type VideoDurationResult = {
15
+ duration: number | null;
16
+ fps: number | null;
17
+ };
18
+ export declare type AudioChannelsAndDurationResultCache = {
19
+ channels: number;
20
+ duration: number | null;
21
+ };
22
+ export declare type DownloadMap = {
23
+ id: string;
24
+ isDownloadingMap: {
25
+ [src: string]: {
26
+ [downloadDir: string]: boolean;
27
+ } | undefined;
28
+ };
29
+ hasBeenDownloadedMap: {
30
+ [src: string]: {
31
+ [downloadDir: string]: string | null;
32
+ } | undefined;
33
+ };
34
+ listeners: {
35
+ [key: string]: {
36
+ [downloadDir: string]: (() => void)[];
37
+ };
38
+ };
39
+ lastFrameMap: Record<string, {
40
+ lastAccessed: number;
41
+ data: Buffer;
42
+ }>;
43
+ isBeyondLastFrameMap: Record<string, number>;
44
+ isVp9VideoCache: Record<string, Vp9Result>;
45
+ ensureFileHasPresentationTimestamp: Record<string, EncodingStatus>;
46
+ videoDurationResultCache: Record<string, VideoDurationResult>;
47
+ durationOfAssetCache: Record<string, AudioChannelsAndDurationResultCache>;
48
+ downloadDir: string;
49
+ };
50
+ export declare type RenderAssetInfo = {
51
+ assets: TAsset[][];
52
+ imageSequenceName: string;
53
+ firstFrameIndex: number;
54
+ downloadMap: DownloadMap;
55
+ };
56
+ export declare const makeDownloadMap: () => DownloadMap;
57
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeDownloadMap = void 0;
4
+ const tmp_dir_1 = require("../tmp-dir");
5
+ const makeDownloadMap = () => {
6
+ return {
7
+ isDownloadingMap: {},
8
+ hasBeenDownloadedMap: {},
9
+ listeners: {},
10
+ lastFrameMap: {},
11
+ isBeyondLastFrameMap: {},
12
+ ensureFileHasPresentationTimestamp: {},
13
+ isVp9VideoCache: {},
14
+ videoDurationResultCache: {},
15
+ durationOfAssetCache: {},
16
+ id: String(Math.random()),
17
+ downloadDir: (0, tmp_dir_1.tmpDir)('remotion-assets-dir'),
18
+ };
19
+ };
20
+ exports.makeDownloadMap = makeDownloadMap;
@@ -1,7 +1,3 @@
1
- import type { FfmpegExecutable } from 'remotion';
2
- declare type Result = {
3
- channels: number;
4
- duration: number | null;
5
- };
6
- export declare const getAudioChannelsAndDuration: (src: string, ffprobeExecutable: FfmpegExecutable) => Promise<Result>;
7
- export {};
1
+ import type { FfmpegExecutable } from '../ffmpeg-executable';
2
+ import type { AudioChannelsAndDurationResultCache, DownloadMap } from './download-map';
3
+ export declare const getAudioChannelsAndDuration: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable) => Promise<AudioChannelsAndDurationResultCache>;
@@ -6,11 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getAudioChannelsAndDuration = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const p_limit_1 = require("../p-limit");
9
- const durationOfAssetCache = {};
10
9
  const limit = (0, p_limit_1.pLimit)(1);
11
- async function getAudioChannelsAndDurationUnlimited(src, ffprobeExecutable) {
12
- if (durationOfAssetCache[src]) {
13
- return durationOfAssetCache[src];
10
+ async function getAudioChannelsAndDurationUnlimited(downloadMap, src, ffprobeExecutable) {
11
+ if (downloadMap.durationOfAssetCache[src]) {
12
+ return downloadMap.durationOfAssetCache[src];
14
13
  }
15
14
  const args = [
16
15
  ['-v', 'error'],
@@ -27,10 +26,10 @@ async function getAudioChannelsAndDurationUnlimited(src, ffprobeExecutable) {
27
26
  channels: channels ? parseInt(channels[1], 10) : 0,
28
27
  duration: duration ? parseFloat(duration[1]) : null,
29
28
  };
30
- durationOfAssetCache[src] = result;
29
+ downloadMap.durationOfAssetCache[src] = result;
31
30
  return result;
32
31
  }
33
- const getAudioChannelsAndDuration = (src, ffprobeExecutable) => {
34
- return limit(() => getAudioChannelsAndDurationUnlimited(src, ffprobeExecutable));
32
+ const getAudioChannelsAndDuration = (downloadMap, src, ffprobeExecutable) => {
33
+ return limit(() => getAudioChannelsAndDurationUnlimited(downloadMap, src, ffprobeExecutable));
35
34
  };
36
35
  exports.getAudioChannelsAndDuration = getAudioChannelsAndDuration;
@@ -0,0 +1,9 @@
1
+ export declare type FileNameAndSize = {
2
+ filename: string;
3
+ size: number;
4
+ };
5
+ export declare function getFolderFiles(folder: string): FileNameAndSize[];
6
+ export declare const getTmpDirStateIfENoSp: () => {
7
+ files: FileNameAndSize[];
8
+ total: number;
9
+ };
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getTmpDirStateIfENoSp = exports.getFolderFiles = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function getFolderFiles(folder) {
10
+ const files = fs_1.default.readdirSync(folder);
11
+ const paths = [];
12
+ files.forEach((file) => {
13
+ const full = path_1.default.join(folder, file);
14
+ try {
15
+ const stat = fs_1.default.statSync(full);
16
+ if (stat.isDirectory()) {
17
+ paths.push(...getFolderFiles(full));
18
+ }
19
+ else {
20
+ paths.push({
21
+ filename: full,
22
+ size: stat.size,
23
+ });
24
+ }
25
+ }
26
+ catch (err) {
27
+ if (err.message.includes('ENOENT')) {
28
+ // Race condition: File was deleted in the meanwhile.
29
+ // Do nothing
30
+ }
31
+ else {
32
+ throw err;
33
+ }
34
+ }
35
+ });
36
+ return paths;
37
+ }
38
+ exports.getFolderFiles = getFolderFiles;
39
+ const getTmpDirStateIfENoSp = () => {
40
+ const files = getFolderFiles('/tmp');
41
+ return {
42
+ files: files
43
+ .slice(0)
44
+ .sort((a, b) => a.size - b.size)
45
+ .reverse()
46
+ .slice(0, 100),
47
+ total: files.reduce((a, b) => a + b.size, 0),
48
+ };
49
+ };
50
+ exports.getTmpDirStateIfENoSp = getTmpDirStateIfENoSp;
@@ -1,6 +1,3 @@
1
- import type { FfmpegExecutable } from 'remotion';
2
- declare type Result = {
3
- duration: number | null;
4
- };
5
- export declare const getVideoStreamDuration: (src: string, ffprobeExecutable: FfmpegExecutable) => Promise<Result>;
6
- export {};
1
+ import type { FfmpegExecutable } from '../ffmpeg-executable';
2
+ import type { DownloadMap, VideoDurationResult } from './download-map';
3
+ export declare const getVideoStreamDuration: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable) => Promise<VideoDurationResult>;
@@ -6,29 +6,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getVideoStreamDuration = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const p_limit_1 = require("../p-limit");
9
- const durationOfAssetCache = {};
10
9
  const limit = (0, p_limit_1.pLimit)(1);
11
- async function getVideoStreamDurationUnlimited(src, ffprobeExecutable) {
12
- if (durationOfAssetCache[src]) {
13
- return durationOfAssetCache[src];
10
+ async function getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable) {
11
+ if (downloadMap.videoDurationResultCache[src]) {
12
+ return downloadMap.videoDurationResultCache[src];
14
13
  }
15
14
  const args = [
16
15
  ['-v', 'error'],
17
16
  ['-select_streams', 'v:0'],
18
- ['-show_entries', 'stream=duration'],
17
+ ['-show_entries', 'stream=duration,r_frame_rate'],
19
18
  [src],
20
19
  ]
21
20
  .reduce((acc, val) => acc.concat(val), [])
22
21
  .filter(Boolean);
23
22
  const task = await (0, execa_1.default)(ffprobeExecutable !== null && ffprobeExecutable !== void 0 ? ffprobeExecutable : 'ffprobe', args);
24
23
  const duration = task.stdout.match(/duration=([0-9.]+)/);
24
+ const fps = task.stdout.match(/r_frame_rate=([0-9.]+)\/([0-9.]+)/);
25
25
  const result = {
26
26
  duration: duration ? parseFloat(duration[1]) : null,
27
+ fps: fps ? parseInt(fps[1], 10) / parseInt(fps[2], 10) : null,
27
28
  };
28
- durationOfAssetCache[src] = result;
29
+ downloadMap.videoDurationResultCache[src] = result;
29
30
  return result;
30
31
  }
31
- const getVideoStreamDuration = (src, ffprobeExecutable) => {
32
- return limit(() => getVideoStreamDurationUnlimited(src, ffprobeExecutable));
32
+ const getVideoStreamDuration = (downloadMap, src, ffprobeExecutable) => {
33
+ return limit(() => getVideoStreamDurationUnlimited(downloadMap, src, ffprobeExecutable));
33
34
  };
34
35
  exports.getVideoStreamDuration = getVideoStreamDuration;
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ export declare const DEFAULT_TIMEOUT = 30000;
16
17
  export declare class TimeoutSettings {
17
18
  #private;
18
19
  constructor();
@@ -27,8 +27,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
27
27
  };
28
28
  var _TimeoutSettings_defaultTimeout, _TimeoutSettings_defaultNavigationTimeout;
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.TimeoutSettings = void 0;
31
- const DEFAULT_TIMEOUT = 30000;
30
+ exports.TimeoutSettings = exports.DEFAULT_TIMEOUT = void 0;
31
+ exports.DEFAULT_TIMEOUT = 30000;
32
32
  class TimeoutSettings {
33
33
  constructor() {
34
34
  _TimeoutSettings_defaultTimeout.set(this, void 0);
@@ -49,13 +49,13 @@ class TimeoutSettings {
49
49
  if (__classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f") !== null) {
50
50
  return __classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f");
51
51
  }
52
- return DEFAULT_TIMEOUT;
52
+ return exports.DEFAULT_TIMEOUT;
53
53
  }
54
54
  timeout() {
55
55
  if (__classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f") !== null) {
56
56
  return __classPrivateFieldGet(this, _TimeoutSettings_defaultTimeout, "f");
57
57
  }
58
- return DEFAULT_TIMEOUT;
58
+ return exports.DEFAULT_TIMEOUT;
59
59
  }
60
60
  }
61
61
  exports.TimeoutSettings = TimeoutSettings;
@@ -0,0 +1 @@
1
+ export declare type BrowserExecutable = string | null;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export declare type Browser = 'chrome' | 'firefox';
2
+ export declare const DEFAULT_BROWSER: Browser;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_BROWSER = void 0;
4
+ exports.DEFAULT_BROWSER = 'chrome';
@@ -1,2 +1,2 @@
1
- import type { Codec } from 'remotion';
1
+ import type { Codec } from './codec';
2
2
  export declare const canUseParallelEncoding: (codec: Codec) => boolean;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.canUseParallelEncoding = void 0;
4
- const remotion_1 = require("remotion");
4
+ const is_audio_codec_1 = require("./is-audio-codec");
5
5
  const canUseParallelEncoding = (codec) => {
6
- if (remotion_1.Internals.isAudioCodec(codec)) {
6
+ if ((0, is_audio_codec_1.isAudioCodec)(codec)) {
7
7
  return false;
8
8
  }
9
9
  return codec === 'h264' || codec === 'h264-mkv' || codec === 'h265';
@@ -1,4 +1,4 @@
1
- import type { Codec } from 'remotion';
1
+ import type { Codec } from './codec';
2
2
  declare type MediaSupport = {
3
3
  video: boolean;
4
4
  audio: boolean;
@@ -0,0 +1,4 @@
1
+ export declare const validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
2
+ export declare type Codec = typeof validCodecs[number];
3
+ export declare type CodecOrUndefined = Codec | undefined;
4
+ export declare const DEFAULT_CODEC: Codec;
package/dist/codec.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_CODEC = exports.validCodecs = void 0;
4
+ exports.validCodecs = [
5
+ 'h264',
6
+ 'h265',
7
+ 'vp8',
8
+ 'vp9',
9
+ 'mp3',
10
+ 'aac',
11
+ 'wav',
12
+ 'prores',
13
+ 'h264-mkv',
14
+ 'gif',
15
+ ];
16
+ exports.DEFAULT_CODEC = 'h264';
@@ -1,4 +1,4 @@
1
- import type { Codec } from 'remotion';
1
+ import type { Codec } from './codec';
2
2
  export declare const combineVideos: ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, }: {
3
3
  files: string[];
4
4
  filelistDir: string;
@@ -8,9 +8,10 @@ exports.combineVideos = void 0;
8
8
  const execa_1 = __importDefault(require("execa"));
9
9
  const fs_1 = require("fs");
10
10
  const path_1 = require("path");
11
- const remotion_1 = require("remotion");
12
11
  const get_audio_codec_name_1 = require("./get-audio-codec-name");
12
+ const is_audio_codec_1 = require("./is-audio-codec");
13
13
  const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
14
+ const truthy_1 = require("./truthy");
14
15
  const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, }) => {
15
16
  var _a;
16
17
  const fileList = files.map((p) => `file '${p}'`).join('\n');
@@ -18,8 +19,8 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
18
19
  (0, fs_1.writeFileSync)(fileListTxt, fileList);
19
20
  try {
20
21
  const task = (0, execa_1.default)('ffmpeg', [
21
- remotion_1.Internals.isAudioCodec(codec) ? null : '-r',
22
- remotion_1.Internals.isAudioCodec(codec) ? null : String(fps),
22
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-r',
23
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : String(fps),
23
24
  '-f',
24
25
  'concat',
25
26
  '-safe',
@@ -32,8 +33,8 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
32
33
  : typeof numberOfGifLoops === 'number'
33
34
  ? String(numberOfGifLoops)
34
35
  : '-1',
35
- remotion_1.Internals.isAudioCodec(codec) ? null : '-c:v',
36
- remotion_1.Internals.isAudioCodec(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
36
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : '-c:v',
37
+ (0, is_audio_codec_1.isAudioCodec)(codec) ? null : codec === 'gif' ? 'gif' : 'copy',
37
38
  '-c:a',
38
39
  (0, get_audio_codec_name_1.getAudioCodecName)(codec),
39
40
  // Set max bitrate up to 1024kbps, will choose lower if that's too much
@@ -44,7 +45,7 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
44
45
  '-shortest',
45
46
  '-y',
46
47
  output,
47
- ].filter(remotion_1.Internals.truthy));
48
+ ].filter(truthy_1.truthy));
48
49
  (_a = task.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
49
50
  if (onProgress) {
50
51
  const parsed = (0, parse_ffmpeg_progress_1.parseFfmpegProgress)(data.toString());
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Since audio or video can be base64-encoded, those can be really long strings.
3
+ * 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.
4
+ */
5
+ import type { TAsset } from 'remotion';
6
+ export declare const compressAsset: (previousAssets: TAsset[], newAsset: TAsset) => TAsset;
7
+ export declare const isAssetCompressed: (src: string) => boolean;