@remotion/renderer 4.0.16 → 4.0.18

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 (66) hide show
  1. package/dist/assets/get-video-stream-duration.d.ts +9 -0
  2. package/dist/assets/get-video-stream-duration.js +71 -0
  3. package/dist/browser/BrowserFetcher.d.ts +2 -19
  4. package/dist/browser/BrowserFetcher.js +73 -263
  5. package/dist/browser/LaunchOptions.d.ts +0 -2
  6. package/dist/browser/Launcher.d.ts +0 -5
  7. package/dist/browser/Launcher.js +5 -14
  8. package/dist/browser/PuppeteerNode.d.ts +1 -8
  9. package/dist/browser/PuppeteerNode.js +10 -27
  10. package/dist/browser/node.js +1 -5
  11. package/dist/browser.d.ts +1 -1
  12. package/dist/calculate-sar-dar-pixels.d.ts +9 -0
  13. package/dist/calculate-sar-dar-pixels.js +19 -0
  14. package/dist/client.d.ts +48 -48
  15. package/dist/compositor/payloads.d.ts +18 -0
  16. package/dist/determine-resize-params.d.ts +4 -0
  17. package/dist/determine-resize-params.js +10 -0
  18. package/dist/determine-vcodec-ffmpeg-flags.d.ts +2 -0
  19. package/dist/determine-vcodec-ffmpeg-flags.js +13 -0
  20. package/dist/ensure-ffmpeg.d.ts +18 -0
  21. package/dist/ensure-ffmpeg.js +58 -0
  22. package/dist/ensure-presentation-timestamp.d.ts +15 -0
  23. package/dist/ensure-presentation-timestamp.js +88 -0
  24. package/dist/extract-frame-from-video.d.ts +16 -0
  25. package/dist/extract-frame-from-video.js +191 -0
  26. package/dist/ffmpeg-executable.d.ts +1 -0
  27. package/dist/ffmpeg-executable.js +2 -0
  28. package/dist/ffmpeg-flags.d.ts +31 -0
  29. package/dist/ffmpeg-flags.js +245 -0
  30. package/dist/frame-to-ffmpeg-timestamp.d.ts +1 -0
  31. package/dist/frame-to-ffmpeg-timestamp.js +8 -0
  32. package/dist/get-can-extract-frames-fast.d.ts +14 -0
  33. package/dist/get-can-extract-frames-fast.js +71 -0
  34. package/dist/get-extension-from-codec.d.ts +2 -2
  35. package/dist/get-frame-of-video-slow.d.ts +17 -0
  36. package/dist/get-frame-of-video-slow.js +72 -0
  37. package/dist/get-local-browser-executable.d.ts +2 -3
  38. package/dist/get-local-browser-executable.js +45 -53
  39. package/dist/get-silent-parts.d.ts +8 -0
  40. package/dist/get-silent-parts.js +56 -0
  41. package/dist/get-video-info.d.ts +8 -0
  42. package/dist/get-video-info.js +59 -0
  43. package/dist/index.d.ts +45 -42
  44. package/dist/index.js +4 -1
  45. package/dist/is-beyond-last-frame.d.ts +3 -0
  46. package/dist/is-beyond-last-frame.js +12 -0
  47. package/dist/last-frame-from-video-cache.d.ts +17 -0
  48. package/dist/last-frame-from-video-cache.js +55 -0
  49. package/dist/legacy-webpack-config.d.ts +9 -0
  50. package/dist/legacy-webpack-config.js +13 -0
  51. package/dist/open-browser.js +3 -3
  52. package/dist/quality.d.ts +1 -0
  53. package/dist/quality.js +21 -0
  54. package/dist/render-media.js +5 -2
  55. package/dist/set-props-and-env.js +6 -3
  56. package/dist/stitch-frames-to-video.d.ts +1 -0
  57. package/dist/try-to-extract-frame-of-video-fast.d.ts +12 -0
  58. package/dist/try-to-extract-frame-of-video-fast.js +55 -0
  59. package/dist/validate-ffmpeg.d.ts +7 -0
  60. package/dist/validate-ffmpeg.js +77 -0
  61. package/dist/validate-opengl-renderer.d.ts +2 -3
  62. package/dist/validate-opengl-renderer.js +9 -4
  63. package/dist/validate-output-filename.d.ts +1 -1
  64. package/dist/warn-about-ffmpeg-version.d.ts +5 -0
  65. package/dist/warn-about-ffmpeg-version.js +37 -0
  66. package/package.json +9 -10
@@ -0,0 +1,72 @@
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.getFrameOfVideoSlow = void 0;
7
+ // Uses no seeking, therefore the whole video has to be decoded. This is a last resort and should only happen
8
+ // if the video is corrupted
9
+ const execa_1 = __importDefault(require("execa"));
10
+ const determine_resize_params_1 = require("./determine-resize-params");
11
+ const determine_vcodec_ffmpeg_flags_1 = require("./determine-vcodec-ffmpeg-flags");
12
+ const ffmpeg_flags_1 = require("./ffmpeg-flags");
13
+ const truthy_1 = require("./truthy");
14
+ const getFrameOfVideoSlow = async ({ src, duration, ffmpegExecutable, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, remotionRoot, }) => {
15
+ console.warn(`\nUsing a slow method to extract the frame at ${duration}ms of ${src}. See https://remotion.dev/docs/slow-method-to-extract-frame for advice`);
16
+ const actualOffset = `-${duration * 1000 - offset}ms`;
17
+ const command = [
18
+ '-itsoffset',
19
+ actualOffset,
20
+ ...(0, determine_vcodec_ffmpeg_flags_1.determineVcodecFfmpegFlags)(specialVCodecForTransparency),
21
+ '-i',
22
+ src,
23
+ '-frames:v',
24
+ '1',
25
+ '-c:v',
26
+ imageFormat === 'jpeg' ? 'mjpeg' : 'png',
27
+ '-f',
28
+ 'image2pipe',
29
+ ...(0, determine_resize_params_1.determineResizeParams)(needsResize),
30
+ '-',
31
+ ].filter(truthy_1.truthy);
32
+ const { stdout, stderr } = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffmpegExecutable, remotionRoot, 'ffmpeg'), command);
33
+ if (!stderr) {
34
+ throw new Error('unexpectedly did not get stderr');
35
+ }
36
+ if (!stdout) {
37
+ throw new Error('unexpectedly did not get stdout');
38
+ }
39
+ const stderrChunks = [];
40
+ const stdoutChunks = [];
41
+ const stdErrString = new Promise((resolve, reject) => {
42
+ stderr.on('data', (d) => stderrChunks.push(d));
43
+ stderr.on('error', (err) => reject(err));
44
+ stderr.on('end', () => resolve(Buffer.concat(stderrChunks).toString('utf-8')));
45
+ });
46
+ const stdoutChunk = new Promise((resolve, reject) => {
47
+ stdout.on('data', (d) => stdoutChunks.push(d));
48
+ stdout.on('error', (err) => reject(err));
49
+ stdout.on('end', () => resolve(Buffer.concat(stdoutChunks)));
50
+ });
51
+ const [stdErr, stdoutBuffer] = await Promise.all([stdErrString, stdoutChunk]);
52
+ const isEmpty = stdErr.includes('Output file is empty');
53
+ if (isEmpty) {
54
+ if (offset > 70) {
55
+ throw new Error(`Could not get last frame of ${src}. Tried to seek to the end using the command "ffmpeg ${command.join(' ')}" but got no frame. Most likely this video is corrupted.`);
56
+ }
57
+ return (0, exports.getFrameOfVideoSlow)({
58
+ ffmpegExecutable,
59
+ duration,
60
+ // Decrement in 10ms increments, or 1 frame (e.g. fps = 25 --> 40ms)
61
+ offset: offset + (fps === null ? 10 : 1000 / fps),
62
+ src,
63
+ imageFormat,
64
+ specialVCodecForTransparency,
65
+ needsResize,
66
+ fps,
67
+ remotionRoot,
68
+ });
69
+ }
70
+ return stdoutBuffer;
71
+ };
72
+ exports.getFrameOfVideoSlow = getFrameOfVideoSlow;
@@ -1,4 +1,3 @@
1
- import type { Browser } from './browser';
2
1
  import type { BrowserExecutable } from './browser-executable';
3
- export declare const ensureLocalBrowser: (browser: Browser, preferredBrowserExecutable: BrowserExecutable) => Promise<void>;
4
- export declare const getLocalBrowserExecutable: (browser: Browser, preferredBrowserExecutable: BrowserExecutable) => string;
2
+ export declare const ensureLocalBrowser: (preferredBrowserExecutable: BrowserExecutable) => Promise<void>;
3
+ export declare const getLocalBrowserExecutable: (preferredBrowserExecutable: BrowserExecutable) => string;
@@ -7,85 +7,77 @@ exports.getLocalBrowserExecutable = exports.ensureLocalBrowser = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_os_1 = __importDefault(require("node:os"));
9
9
  const BrowserFetcher_1 = require("./browser/BrowserFetcher");
10
- const create_browser_fetcher_1 = require("./browser/create-browser-fetcher");
11
- const revisions_1 = require("./browser/revisions");
12
- const getSearchPathsForProduct = (product) => {
10
+ const logger_1 = require("./logger");
11
+ const getSearchPathsForProduct = () => {
13
12
  var _a;
14
- if (product === 'chrome') {
15
- return [
16
- (_a = process.env.PUPPETEER_EXECUTABLE_PATH) !== null && _a !== void 0 ? _a : null,
17
- process.platform === 'darwin'
18
- ? '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
19
- : null,
20
- process.platform === 'linux' ? '/usr/bin/google-chrome' : null,
21
- process.platform === 'linux' ? '/usr/bin/chromium-browser' : null,
22
- process.platform === 'linux' ? '/usr/bin/chromium' : null,
23
- process.platform === 'linux'
24
- ? '/app/.apt/usr/bin/google-chrome-stable'
25
- : null,
26
- process.platform === 'win32'
27
- ? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
28
- : null,
29
- process.platform === 'win32'
30
- ? 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
31
- : null,
32
- process.platform === 'win32'
33
- ? node_os_1.default.homedir() +
34
- '\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe'
35
- : null,
36
- process.platform === 'win32'
37
- ? 'C:\\Program Files\\Google\\Chrome SxS\\Application\\chrome.exe'
38
- : null,
39
- process.platform === 'win32'
40
- ? 'C:\\Program Files (x86)\\Google\\Chrome SxS\\Application\\chrome.exe'
41
- : null,
42
- process.platform === 'win32'
43
- ? node_os_1.default.homedir() +
44
- '\\AppData\\Local\\Google\\Chrome SxS\\Application\\chrome.exe'
45
- : null,
46
- ].filter(Boolean);
47
- }
48
- if (product === 'firefox') {
49
- return [].filter(Boolean);
50
- }
51
- throw new TypeError(`Unknown browser product: ${product}`);
13
+ return [
14
+ (_a = process.env.PUPPETEER_EXECUTABLE_PATH) !== null && _a !== void 0 ? _a : null,
15
+ process.platform === 'darwin'
16
+ ? '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
17
+ : null,
18
+ process.platform === 'linux' ? '/usr/bin/google-chrome' : null,
19
+ process.platform === 'linux' ? '/usr/bin/chromium-browser' : null,
20
+ process.platform === 'linux' ? '/usr/bin/chromium' : null,
21
+ process.platform === 'linux'
22
+ ? '/app/.apt/usr/bin/google-chrome-stable'
23
+ : null,
24
+ process.platform === 'win32'
25
+ ? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
26
+ : null,
27
+ process.platform === 'win32'
28
+ ? 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
29
+ : null,
30
+ process.platform === 'win32'
31
+ ? node_os_1.default.homedir() +
32
+ '\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe'
33
+ : null,
34
+ process.platform === 'win32'
35
+ ? 'C:\\Program Files\\Google\\Chrome SxS\\Application\\chrome.exe'
36
+ : null,
37
+ process.platform === 'win32'
38
+ ? 'C:\\Program Files (x86)\\Google\\Chrome SxS\\Application\\chrome.exe'
39
+ : null,
40
+ process.platform === 'win32'
41
+ ? node_os_1.default.homedir() +
42
+ '\\AppData\\Local\\Google\\Chrome SxS\\Application\\chrome.exe'
43
+ : null,
44
+ ].filter(Boolean);
52
45
  };
53
- const mapBrowserToProduct = (browser) => browser;
54
- const getLocalBrowser = (product) => {
55
- for (const p of getSearchPathsForProduct(product)) {
46
+ const getLocalBrowser = () => {
47
+ for (const p of getSearchPathsForProduct()) {
56
48
  if (node_fs_1.default.existsSync(p)) {
57
49
  return p;
58
50
  }
59
51
  }
60
52
  return null;
61
53
  };
62
- const getBrowserStatus = (product, browserExecutablePath) => {
54
+ const getBrowserStatus = (browserExecutablePath) => {
63
55
  if (browserExecutablePath) {
64
56
  if (!node_fs_1.default.existsSync(browserExecutablePath)) {
65
57
  console.warn(`Browser executable was specified as '${browserExecutablePath}' but the path doesn't exist.`);
66
58
  }
67
59
  return { path: browserExecutablePath, type: 'user-defined-path' };
68
60
  }
69
- const localBrowser = getLocalBrowser(product);
61
+ const localBrowser = getLocalBrowser();
70
62
  if (localBrowser !== null) {
71
63
  return { path: localBrowser, type: 'local-browser' };
72
64
  }
73
- const revision = (0, BrowserFetcher_1.getRevisionInfo)(revisions_1.PUPPETEER_REVISIONS.chromium, product);
65
+ const revision = (0, BrowserFetcher_1.getRevisionInfo)();
74
66
  if (revision.local && node_fs_1.default.existsSync(revision.executablePath)) {
75
67
  return { path: revision.executablePath, type: 'local-puppeteer-browser' };
76
68
  }
77
69
  return { type: 'no-browser' };
78
70
  };
79
- const ensureLocalBrowser = async (browser, preferredBrowserExecutable) => {
80
- const status = getBrowserStatus(mapBrowserToProduct(browser), preferredBrowserExecutable);
71
+ const ensureLocalBrowser = async (preferredBrowserExecutable) => {
72
+ const status = getBrowserStatus(preferredBrowserExecutable);
81
73
  if (status.type === 'no-browser') {
82
- console.log('No local browser could be found. Downloading one from the internet...');
83
- await (0, create_browser_fetcher_1.downloadBrowser)(browser);
74
+ logger_1.Log.info('No local browser could be found. Downloading Thorium https://www.remotion.dev/docs/thorium-browser');
75
+ await (0, BrowserFetcher_1.downloadBrowser)();
84
76
  }
85
77
  };
86
78
  exports.ensureLocalBrowser = ensureLocalBrowser;
87
- const getLocalBrowserExecutable = (browser, preferredBrowserExecutable) => {
88
- const status = getBrowserStatus(mapBrowserToProduct(browser), preferredBrowserExecutable);
79
+ const getLocalBrowserExecutable = (preferredBrowserExecutable) => {
80
+ const status = getBrowserStatus(preferredBrowserExecutable);
89
81
  if (status.type === 'no-browser') {
90
82
  throw new TypeError('No browser found for rendering frames! Please open a GitHub issue and describe ' +
91
83
  'how you reached this error: https://github.com/remotion-dev/remotion/issues');
@@ -0,0 +1,8 @@
1
+ import type { GetSilentPartsResponse } from './compositor/payloads';
2
+ import type { LogLevel } from './log-level';
3
+ export declare const getSilentParts: ({ src, noiseThresholdInDecibels: passedNoiseThresholdInDecibels, minDurationInSeconds: passedMinDuration, logLevel, }: {
4
+ src: string;
5
+ minDurationInSeconds?: number | undefined;
6
+ logLevel?: "verbose" | "info" | "warn" | "error" | undefined;
7
+ noiseThresholdInDecibels?: number | undefined;
8
+ }) => Promise<GetSilentPartsResponse>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSilentParts = void 0;
4
+ const compositor_1 = require("./compositor/compositor");
5
+ const getSilentParts = async ({ src, noiseThresholdInDecibels: passedNoiseThresholdInDecibels, minDurationInSeconds: passedMinDuration, logLevel, }) => {
6
+ const compositor = (0, compositor_1.startLongRunningCompositor)((0, compositor_1.getIdealMaximumFrameCacheItems)(), logLevel !== null && logLevel !== void 0 ? logLevel : 'info', false);
7
+ const minDurationInSeconds = passedMinDuration !== null && passedMinDuration !== void 0 ? passedMinDuration : 1;
8
+ if (typeof minDurationInSeconds !== 'number') {
9
+ throw new Error(`minDurationInSeconds must be a number, but was ${minDurationInSeconds}`);
10
+ }
11
+ if (minDurationInSeconds <= 0) {
12
+ throw new Error(`minDurationInSeconds must be greater than 0, but was ${minDurationInSeconds}`);
13
+ }
14
+ const noiseThresholdInDecibels = passedNoiseThresholdInDecibels !== null && passedNoiseThresholdInDecibels !== void 0 ? passedNoiseThresholdInDecibels : -20;
15
+ if (typeof noiseThresholdInDecibels !== 'number') {
16
+ throw new Error(`noiseThresholdInDecibels must be a number, but was ${noiseThresholdInDecibels}`);
17
+ }
18
+ if (noiseThresholdInDecibels >= 30) {
19
+ throw new Error(`noiseThresholdInDecibels must be less than 30, but was ${noiseThresholdInDecibels}`);
20
+ }
21
+ const res = await compositor.executeCommand('GetSilences', {
22
+ src,
23
+ minDurationInSeconds,
24
+ noiseThresholdInDecibels,
25
+ });
26
+ const response = JSON.parse(res.toString('utf-8'));
27
+ compositor.finishCommands();
28
+ await compositor.waitForDone();
29
+ const { silentParts, durationInSeconds } = response;
30
+ return {
31
+ silentParts,
32
+ audibleParts: getAudibleParts({ silentParts, durationInSeconds }),
33
+ durationInSeconds,
34
+ };
35
+ };
36
+ exports.getSilentParts = getSilentParts;
37
+ const getAudibleParts = ({ silentParts, durationInSeconds, }) => {
38
+ const audibleParts = [];
39
+ let lastEnd = 0;
40
+ for (const silentPart of silentParts) {
41
+ if (silentPart.startInSeconds - lastEnd > 0) {
42
+ audibleParts.push({
43
+ startInSeconds: lastEnd,
44
+ endInSeconds: silentPart.startInSeconds,
45
+ });
46
+ }
47
+ lastEnd = silentPart.endInSeconds;
48
+ }
49
+ if (durationInSeconds - lastEnd > 0) {
50
+ audibleParts.push({
51
+ startInSeconds: lastEnd,
52
+ endInSeconds: durationInSeconds,
53
+ });
54
+ }
55
+ return audibleParts;
56
+ };
@@ -0,0 +1,8 @@
1
+ import type { DownloadMap, Vp9Result } from './assets/download-map';
2
+ import type { FfmpegExecutable } from './ffmpeg-executable';
3
+ export declare function getVideoInfoUncached({ src, ffprobeExecutable, remotionRoot, }: {
4
+ src: string;
5
+ ffprobeExecutable: FfmpegExecutable;
6
+ remotionRoot: string;
7
+ }): Promise<Vp9Result>;
8
+ export declare const getVideoInfo: (downloadMap: DownloadMap, src: string, ffprobeExecutable: FfmpegExecutable, remotionRoot: string) => Promise<Vp9Result>;
@@ -0,0 +1,59 @@
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.getVideoInfo = exports.getVideoInfoUncached = void 0;
7
+ const execa_1 = __importDefault(require("execa"));
8
+ const calculate_sar_dar_pixels_1 = require("./calculate-sar-dar-pixels");
9
+ const ffmpeg_flags_1 = require("./ffmpeg-flags");
10
+ const p_limit_1 = require("./p-limit");
11
+ const limit = (0, p_limit_1.pLimit)(1);
12
+ async function getVideoInfoUncached({ src, ffprobeExecutable, remotionRoot, }) {
13
+ var _a;
14
+ const task = await (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffprobeExecutable, remotionRoot, 'ffprobe'), [src]);
15
+ const isVp9 = task.stderr.includes('Video: vp9');
16
+ const isVp8 = task.stderr.includes('Video: vp8');
17
+ const dimensions = (_a = task.stderr
18
+ .split('\n')
19
+ .find((n) => n.trim().startsWith('Stream #'))) === null || _a === void 0 ? void 0 : _a.match(/([0-9]{2,6})x([0-9]{2,6})/);
20
+ const dar = task.stderr.match(/DAR\s([0-9]+):([0-9]+)/);
21
+ let needsResize = null;
22
+ if (dimensions && dar) {
23
+ const width = parseInt(dimensions[1], 10);
24
+ const height = parseInt(dimensions[2], 10);
25
+ const darWidth = parseInt(dar[1], 10);
26
+ const darHeight = parseInt(dar[2], 10);
27
+ const { width: actualWidth, height: actualHeight } = (0, calculate_sar_dar_pixels_1.calculateDisplayVideoSize)({
28
+ darX: darWidth,
29
+ darY: darHeight,
30
+ x: width,
31
+ y: height,
32
+ });
33
+ if (actualWidth !== width || actualHeight !== height) {
34
+ needsResize = [actualWidth, actualHeight];
35
+ }
36
+ }
37
+ const result = {
38
+ specialVcodecForTransparency: isVp9 ? 'vp9' : isVp8 ? 'vp8' : 'none',
39
+ needsResize,
40
+ };
41
+ return result;
42
+ }
43
+ exports.getVideoInfoUncached = getVideoInfoUncached;
44
+ async function getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot) {
45
+ if (typeof downloadMap.isVp9VideoCache[src] !== 'undefined') {
46
+ return downloadMap.isVp9VideoCache[src];
47
+ }
48
+ const result = await getVideoInfoUncached({
49
+ ffprobeExecutable,
50
+ remotionRoot,
51
+ src,
52
+ });
53
+ downloadMap.isVp9VideoCache[src] = result;
54
+ return downloadMap.isVp9VideoCache[src];
55
+ }
56
+ const getVideoInfo = (downloadMap, src, ffprobeExecutable, remotionRoot) => {
57
+ return limit(() => getVideoInfoUnlimited(downloadMap, src, ffprobeExecutable, remotionRoot));
58
+ };
59
+ exports.getVideoInfo = getVideoInfo;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import execa from 'execa';
2
3
  import { HeadlessBrowser } from './browser/Browser';
3
4
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
@@ -16,6 +17,7 @@ export type { FfmpegOverrideFn } from './ffmpeg-override';
16
17
  export { FileExtension } from './file-extensions';
17
18
  export { FrameRange } from './frame-range';
18
19
  export { getCompositions, GetCompositionsOptions } from './get-compositions';
20
+ export { getSilentParts } from './get-silent-parts';
19
21
  export { getVideoMetadata } from './get-video-metadata';
20
22
  export { ImageFormat, StillImageFormat, validateSelectedPixelFormatAndImageFormatCombination, VideoImageFormat, } from './image-format';
21
23
  export type { LogLevel } from './log-level';
@@ -36,7 +38,7 @@ export { OnStartData, RenderFramesOutput } from './types';
36
38
  export { OpenGlRenderer } from './validate-opengl-renderer';
37
39
  export { validateOutputFilename } from './validate-output-filename';
38
40
  export declare const RenderInternals: {
39
- ensureLocalBrowser: (browser: import("./browser").Browser, preferredBrowserExecutable: import("./browser-executable").BrowserExecutable) => Promise<void>;
41
+ ensureLocalBrowser: (preferredBrowserExecutable: import("./browser-executable").BrowserExecutable) => Promise<void>;
40
42
  getActualConcurrency: (userPreference: string | number | null) => number;
41
43
  serveStatic: (path: string | null, options: {
42
44
  port: number | null;
@@ -54,9 +56,9 @@ export declare const RenderInternals: {
54
56
  width: number;
55
57
  height: number;
56
58
  scale: number;
57
- codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
59
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
58
60
  }) => void;
59
- getFileExtensionFromCodec: <T extends "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: "pcm-16" | "aac" | "mp3" | "opus" | null) => import("./file-extensions").FileExtension;
61
+ getFileExtensionFromCodec: <T extends "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">(codec: T, audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null) => import("./file-extensions").FileExtension;
60
62
  tmpDir: (str: string) => string;
61
63
  deleteDirectory: (directory: string) => void;
62
64
  isServeUrl: (potentialUrl: string) => boolean;
@@ -106,21 +108,21 @@ export declare const RenderInternals: {
106
108
  };
107
109
  registerErrorSymbolicationLock: () => number;
108
110
  unlockErrorSymbolicationLock: (id: number) => void;
109
- canUseParallelEncoding: (codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
111
+ canUseParallelEncoding: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => boolean;
110
112
  mimeContentType: typeof mimeContentType;
111
113
  mimeLookup: typeof mimeLookup;
112
114
  validateConcurrency: (value: unknown, setting: string) => void;
113
115
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
114
- DEFAULT_BROWSER: import("./browser").Browser;
116
+ DEFAULT_BROWSER: "chrome";
115
117
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
116
- DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
117
- validateOpenGlRenderer: (option: "swangle" | "angle" | "egl" | "swiftshader" | null) => "swangle" | "angle" | "egl" | "swiftshader" | null;
118
+ DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
119
+ validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
118
120
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
119
121
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
120
122
  validateJpegQuality: (q: number | undefined) => void;
121
123
  DEFAULT_TIMEOUT: number;
122
- DEFAULT_CODEC: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
123
- isAudioCodec: (codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
124
+ DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
125
+ isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
124
126
  logLevels: readonly ["verbose", "info", "warn", "error"];
125
127
  isEqualOrBelowLogLevel: (currentLevel: "verbose" | "info" | "warn" | "error", level: "verbose" | "info" | "warn" | "error") => boolean;
126
128
  isValidLogLevel: (level: string) => boolean;
@@ -137,23 +139,23 @@ export declare const RenderInternals: {
137
139
  output: string;
138
140
  onProgress: (p: number) => void;
139
141
  numberOfFrames: number;
140
- codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
142
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
141
143
  fps: number;
142
144
  numberOfGifLoops: number | null;
143
- audioCodec: "pcm-16" | "aac" | "mp3" | "opus" | null;
145
+ audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null;
144
146
  }) => Promise<void>;
145
147
  getMinConcurrency: () => number;
146
148
  getMaxConcurrency: () => any;
147
149
  getDefaultAudioCodec: ({ codec, preferLossless, }: {
148
- codec: "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif";
150
+ codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
149
151
  preferLossless: boolean;
150
- }) => "pcm-16" | "aac" | "mp3" | "opus" | null;
152
+ }) => "mp3" | "aac" | "pcm-16" | "opus" | null;
151
153
  validAudioCodecs: readonly ["pcm-16", "aac", "mp3", "opus"];
152
154
  defaultFileExtensionMap: {
153
- aac: {
155
+ h264: {
154
156
  default: import("./file-extensions").FileExtension;
155
157
  forAudioCodec: {
156
- "pcm-16": {
158
+ mp3: {
157
159
  possible: import("./file-extensions").FileExtension[];
158
160
  default: import("./file-extensions").FileExtension;
159
161
  };
@@ -161,72 +163,72 @@ export declare const RenderInternals: {
161
163
  possible: import("./file-extensions").FileExtension[];
162
164
  default: import("./file-extensions").FileExtension;
163
165
  };
166
+ "pcm-16": {
167
+ possible: import("./file-extensions").FileExtension[];
168
+ default: import("./file-extensions").FileExtension;
169
+ };
164
170
  };
165
171
  };
166
- mp3: {
172
+ h265: {
167
173
  default: import("./file-extensions").FileExtension;
168
174
  forAudioCodec: {
169
- "pcm-16": {
175
+ aac: {
170
176
  possible: import("./file-extensions").FileExtension[];
171
177
  default: import("./file-extensions").FileExtension;
172
178
  };
173
- mp3: {
179
+ "pcm-16": {
174
180
  possible: import("./file-extensions").FileExtension[];
175
181
  default: import("./file-extensions").FileExtension;
176
182
  };
177
183
  };
178
184
  };
179
- h264: {
185
+ vp8: {
180
186
  default: import("./file-extensions").FileExtension;
181
187
  forAudioCodec: {
182
188
  "pcm-16": {
183
189
  possible: import("./file-extensions").FileExtension[];
184
190
  default: import("./file-extensions").FileExtension;
185
191
  };
186
- aac: {
187
- possible: import("./file-extensions").FileExtension[];
188
- default: import("./file-extensions").FileExtension;
189
- };
190
- mp3: {
192
+ opus: {
191
193
  possible: import("./file-extensions").FileExtension[];
192
194
  default: import("./file-extensions").FileExtension;
193
195
  };
194
196
  };
195
197
  };
196
- h265: {
198
+ vp9: {
197
199
  default: import("./file-extensions").FileExtension;
198
200
  forAudioCodec: {
199
201
  "pcm-16": {
200
202
  possible: import("./file-extensions").FileExtension[];
201
203
  default: import("./file-extensions").FileExtension;
202
204
  };
203
- aac: {
205
+ opus: {
204
206
  possible: import("./file-extensions").FileExtension[];
205
207
  default: import("./file-extensions").FileExtension;
206
208
  };
207
209
  };
208
210
  };
209
- vp8: {
211
+ mp3: {
210
212
  default: import("./file-extensions").FileExtension;
211
213
  forAudioCodec: {
212
- "pcm-16": {
214
+ mp3: {
213
215
  possible: import("./file-extensions").FileExtension[];
214
216
  default: import("./file-extensions").FileExtension;
215
217
  };
216
- opus: {
218
+ "pcm-16": {
217
219
  possible: import("./file-extensions").FileExtension[];
218
220
  default: import("./file-extensions").FileExtension;
219
221
  };
220
222
  };
221
223
  };
222
- vp9: {
224
+ aac: {
223
225
  default: import("./file-extensions").FileExtension;
224
226
  forAudioCodec: {
225
- "pcm-16": {
227
+ aac: {
226
228
  possible: import("./file-extensions").FileExtension[];
227
229
  default: import("./file-extensions").FileExtension;
228
230
  };
229
- opus: {
231
+ "pcm-16": {
230
232
  possible: import("./file-extensions").FileExtension[];
231
233
  default: import("./file-extensions").FileExtension;
232
234
  };
@@ -244,11 +246,11 @@ export declare const RenderInternals: {
244
246
  prores: {
245
247
  default: import("./file-extensions").FileExtension;
246
248
  forAudioCodec: {
247
- "pcm-16": {
249
+ aac: {
248
250
  possible: import("./file-extensions").FileExtension[];
249
251
  default: import("./file-extensions").FileExtension;
250
252
  };
251
- aac: {
253
+ "pcm-16": {
252
254
  possible: import("./file-extensions").FileExtension[];
253
255
  default: import("./file-extensions").FileExtension;
254
256
  };
@@ -257,11 +259,11 @@ export declare const RenderInternals: {
257
259
  "h264-mkv": {
258
260
  default: import("./file-extensions").FileExtension;
259
261
  forAudioCodec: {
260
- "pcm-16": {
262
+ mp3: {
261
263
  possible: import("./file-extensions").FileExtension[];
262
264
  default: import("./file-extensions").FileExtension;
263
265
  };
264
- mp3: {
266
+ "pcm-16": {
265
267
  possible: import("./file-extensions").FileExtension[];
266
268
  default: import("./file-extensions").FileExtension;
267
269
  };
@@ -284,8 +286,8 @@ export declare const RenderInternals: {
284
286
  readonly vp9: readonly ["opus", "pcm-16"];
285
287
  readonly wav: readonly ["pcm-16"];
286
288
  };
287
- makeFileExtensionMap: () => Record<string, ("aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
288
- defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "aac" | "mp3" | "h264" | "h265" | "vp8" | "vp9" | "wav" | "prores" | "h264-mkv" | "gif">;
289
+ makeFileExtensionMap: () => Record<string, ("h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif")[]>;
290
+ defaultCodecsForFileExtension: Record<import("./file-extensions").FileExtension, "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif">;
289
291
  getExecutablePath: (type: "compositor" | "ffmpeg" | "ffprobe" | "ffmpeg-cwd") => string;
290
292
  callFf: (bin: "ffmpeg" | "ffprobe", args: (string | null)[], options?: execa.Options<string> | undefined) => execa.ExecaChildProcess<string>;
291
293
  dynamicLibraryPathOptions: () => {
@@ -302,8 +304,8 @@ export declare const RenderInternals: {
302
304
  };
303
305
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
304
306
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
305
- DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
306
- DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
307
+ DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
308
+ DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
307
309
  DEFAULT_JPEG_QUALITY: number;
308
310
  chalk: {
309
311
  enabled: () => boolean;
@@ -414,7 +416,7 @@ export declare const RenderInternals: {
414
416
  frame: number;
415
417
  serializedInputPropsWithCustomSchema: string;
416
418
  serializedResolvedPropsWithCustomSchema: string;
417
- imageFormat: "png" | "jpeg" | "pdf" | "webp";
419
+ imageFormat: "jpeg" | "png" | "webp" | "pdf";
418
420
  jpegQuality: number;
419
421
  puppeteerInstance: HeadlessBrowser | null;
420
422
  envVariables: Record<string, string>;
@@ -440,7 +442,7 @@ export declare const RenderInternals: {
440
442
  forceDeviceScaleFactor: number | undefined;
441
443
  viewport: import("./browser/PuppeteerViewport").Viewport | null;
442
444
  indent: boolean;
443
- browser: import("./browser").Browser;
445
+ browser: "chrome";
444
446
  logLevel: "verbose" | "info" | "warn" | "error";
445
447
  }) => Promise<HeadlessBrowser>;
446
448
  internalSelectComposition: (options: {
@@ -480,4 +482,5 @@ export declare const RenderInternals: {
480
482
  buffer: Buffer | null;
481
483
  slowestFrames: import("./render-media").SlowFrame[];
482
484
  }>;
485
+ validOpenGlRenderers: readonly ["swangle", "angle", "egl", "swiftshader"];
483
486
  };
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.RenderInternals = exports.validateOutputFilename = exports.stitchFramesToVideo = exports.selectComposition = exports.renderStill = exports.renderMedia = exports.renderFrames = exports.openBrowser = exports.makeCancelSignal = exports.validateSelectedPixelFormatAndImageFormatCombination = exports.getVideoMetadata = exports.getCompositions = exports.ErrorWithStackFrame = void 0;
29
+ exports.RenderInternals = exports.validateOutputFilename = exports.stitchFramesToVideo = exports.selectComposition = exports.renderStill = exports.renderMedia = exports.renderFrames = exports.openBrowser = exports.makeCancelSignal = exports.validateSelectedPixelFormatAndImageFormatCombination = exports.getVideoMetadata = exports.getSilentParts = exports.getCompositions = exports.ErrorWithStackFrame = void 0;
30
30
  const execa_1 = __importDefault(require("execa"));
31
31
  const download_file_1 = require("./assets/download-file");
32
32
  const audio_codec_1 = require("./audio-codec");
@@ -86,6 +86,8 @@ var handle_javascript_exception_1 = require("./error-handling/handle-javascript-
86
86
  Object.defineProperty(exports, "ErrorWithStackFrame", { enumerable: true, get: function () { return handle_javascript_exception_1.ErrorWithStackFrame; } });
87
87
  var get_compositions_2 = require("./get-compositions");
88
88
  Object.defineProperty(exports, "getCompositions", { enumerable: true, get: function () { return get_compositions_2.getCompositions; } });
89
+ var get_silent_parts_1 = require("./get-silent-parts");
90
+ Object.defineProperty(exports, "getSilentParts", { enumerable: true, get: function () { return get_silent_parts_1.getSilentParts; } });
89
91
  var get_video_metadata_1 = require("./get-video-metadata");
90
92
  Object.defineProperty(exports, "getVideoMetadata", { enumerable: true, get: function () { return get_video_metadata_1.getVideoMetadata; } });
91
93
  var image_format_2 = require("./image-format");
@@ -184,6 +186,7 @@ exports.RenderInternals = {
184
186
  internalGetCompositions: get_compositions_1.internalGetCompositions,
185
187
  internalRenderFrames: render_frames_1.internalRenderFrames,
186
188
  internalRenderMedia: render_media_1.internalRenderMedia,
189
+ validOpenGlRenderers: validate_opengl_renderer_1.validOpenGlRenderers,
187
190
  };
188
191
  // Warn of potential performance issues with Apple Silicon (M1 chip under Rosetta)
189
192
  (0, check_apple_silicon_1.checkNodeVersionAndWarnAboutRosetta)();
@@ -0,0 +1,3 @@
1
+ import type { DownloadMap } from './assets/download-map';
2
+ export declare const isBeyondLastFrame: (downloadMap: DownloadMap, src: string, time: number) => boolean | 0;
3
+ export declare const markAsBeyondLastFrame: (downloadMap: DownloadMap, src: string, time: number) => void;