@remotion/renderer 3.0.24 → 3.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/assets/download-and-map-assets-to-file.d.ts +21 -8
  2. package/dist/assets/download-and-map-assets-to-file.js +68 -42
  3. package/dist/assets/download-file.d.ts +10 -5
  4. package/dist/assets/download-file.js +18 -5
  5. package/dist/assets/ffmpeg-volume-expression.d.ts +1 -2
  6. package/dist/assets/ffmpeg-volume-expression.js +2 -3
  7. package/dist/assets/read-file.js +4 -1
  8. package/dist/browser/Browser.d.ts +5 -0
  9. package/dist/browser/Browser.js +2 -1
  10. package/dist/browser/DOMWorld.d.ts +4 -1
  11. package/dist/browser/DOMWorld.js +11 -3
  12. package/dist/browser/FrameManager.d.ts +2 -1
  13. package/dist/browser/FrameManager.js +2 -2
  14. package/dist/browser/Page.d.ts +5 -3
  15. package/dist/browser/Page.js +6 -5
  16. package/dist/browser/Target.js +1 -1
  17. package/dist/browser/util.d.ts +2 -1
  18. package/dist/browser/util.js +10 -2
  19. package/dist/calculate-sar-dar-pixels.d.ts +9 -0
  20. package/dist/calculate-sar-dar-pixels.js +19 -0
  21. package/dist/extract-frame-from-video.d.ts +2 -4
  22. package/dist/get-compositions.js +1 -1
  23. package/dist/get-port.js +5 -14
  24. package/dist/get-video-info.d.ts +0 -0
  25. package/dist/get-video-info.js +7 -2
  26. package/dist/index.d.ts +14 -6
  27. package/dist/index.js +3 -0
  28. package/dist/last-frame-from-video-cache.d.ts +1 -0
  29. package/dist/offthread-video-server.js +2 -6
  30. package/dist/prepare-server.js +5 -2
  31. package/dist/provide-screenshot.d.ts +1 -0
  32. package/dist/puppeteer-screenshot.d.ts +1 -0
  33. package/dist/render-frames.js +39 -44
  34. package/dist/render-media.d.ts +3 -2
  35. package/dist/render-media.js +8 -3
  36. package/dist/screenshot-dom-element.d.ts +1 -0
  37. package/dist/screenshot-task.d.ts +1 -0
  38. package/dist/seek-to-frame.js +2 -2
  39. package/dist/stitch-frames-to-video.d.ts +4 -3
  40. package/dist/stitch-frames-to-video.js +31 -13
  41. package/dist/stringify-ffmpeg-filter.js +6 -7
  42. package/dist/wait-for-symbolication-error-to-be-done.d.ts +3 -0
  43. package/dist/wait-for-symbolication-error-to-be-done.js +34 -0
  44. package/package.json +3 -3
@@ -1,20 +1,33 @@
1
1
  import type { TAsset } from 'remotion';
2
2
  export declare type RenderMediaOnDownload = (src: string) => ((progress: {
3
- percent: number;
3
+ percent: number | null;
4
+ downloaded: number;
5
+ totalSize: number | null;
4
6
  }) => void) | undefined | void;
5
- export declare const waitForAssetToBeDownloaded: (src: string, to: string) => Promise<void>;
7
+ export declare const waitForAssetToBeDownloaded: ({ src, downloadDir, }: {
8
+ src: string;
9
+ downloadDir: string;
10
+ }) => Promise<string>;
11
+ export declare const downloadAsset: ({ src, onDownload, downloadDir, }: {
12
+ src: string;
13
+ onDownload: RenderMediaOnDownload;
14
+ downloadDir: string;
15
+ }) => Promise<string>;
6
16
  export declare const markAllAssetsAsDownloaded: () => void;
7
- export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, }: {
17
+ export declare const getFilename: ({ contentDisposition, src, }: {
18
+ src: string;
19
+ contentDisposition: string | null;
20
+ }) => {
21
+ pathname: string;
22
+ search: string;
23
+ };
24
+ export declare const getSanitizedFilenameForAssetUrl: ({ src, downloadDir, contentDisposition, }: {
8
25
  src: string;
9
26
  downloadDir: string;
27
+ contentDisposition: string | null;
10
28
  }) => string;
11
29
  export declare const downloadAndMapAssetsToFileUrl: ({ asset, downloadDir, onDownload, }: {
12
30
  asset: TAsset;
13
31
  downloadDir: string;
14
32
  onDownload: RenderMediaOnDownload;
15
33
  }) => Promise<TAsset>;
16
- export declare const startDownloadForSrc: ({ src, downloadDir, onDownload, }: {
17
- src: string;
18
- downloadDir: string;
19
- onDownload: RenderMediaOnDownload;
20
- }) => Promise<string>;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.startDownloadForSrc = exports.downloadAndMapAssetsToFileUrl = exports.getSanitizedFilenameForAssetUrl = exports.markAllAssetsAsDownloaded = exports.waitForAssetToBeDownloaded = void 0;
6
+ exports.downloadAndMapAssetsToFileUrl = exports.getSanitizedFilenameForAssetUrl = exports.getFilename = exports.markAllAssetsAsDownloaded = exports.downloadAsset = exports.waitForAssetToBeDownloaded = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const remotion_1 = require("remotion");
@@ -13,38 +13,41 @@ const sanitize_filepath_1 = require("./sanitize-filepath");
13
13
  const isDownloadingMap = {};
14
14
  const hasBeenDownloadedMap = {};
15
15
  const listeners = {};
16
- const waitForAssetToBeDownloaded = (src, to) => {
17
- var _a;
18
- if ((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[to]) {
19
- return Promise.resolve();
16
+ const waitForAssetToBeDownloaded = ({ src, downloadDir, }) => {
17
+ 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]);
20
20
  }
21
21
  if (!listeners[src]) {
22
22
  listeners[src] = {};
23
23
  }
24
- if (!listeners[src][to]) {
25
- listeners[src][to] = [];
24
+ if (!listeners[src][downloadDir]) {
25
+ listeners[src][downloadDir] = [];
26
26
  }
27
27
  return new Promise((resolve) => {
28
- listeners[src][to].push(() => resolve());
28
+ listeners[src][downloadDir].push(() => {
29
+ var _a;
30
+ resolve((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]);
31
+ });
29
32
  });
30
33
  };
31
34
  exports.waitForAssetToBeDownloaded = waitForAssetToBeDownloaded;
32
- const notifyAssetIsDownloaded = (src, to) => {
35
+ const notifyAssetIsDownloaded = ({ src, downloadDir, to, }) => {
33
36
  if (!listeners[src]) {
34
37
  listeners[src] = {};
35
38
  }
36
- if (!listeners[src][to]) {
37
- listeners[src][to] = [];
39
+ if (!listeners[src][downloadDir]) {
40
+ listeners[src][downloadDir] = [];
38
41
  }
39
- listeners[src][to].forEach((fn) => fn());
42
+ listeners[src][downloadDir].forEach((fn) => fn());
40
43
  if (!isDownloadingMap[src]) {
41
44
  isDownloadingMap[src] = {};
42
45
  }
43
- isDownloadingMap[src][to] = false;
46
+ isDownloadingMap[src][downloadDir] = true;
44
47
  if (!hasBeenDownloadedMap[src]) {
45
48
  hasBeenDownloadedMap[src] = {};
46
49
  }
47
- hasBeenDownloadedMap[src][to] = true;
50
+ hasBeenDownloadedMap[src][downloadDir] = to;
48
51
  };
49
52
  const validateMimeType = (mimeType, src) => {
50
53
  if (!mimeType.includes('/')) {
@@ -85,21 +88,29 @@ function validateBufferEncoding(potentialEncoding, dataUrl) {
85
88
  throw new TypeError(errMessage);
86
89
  }
87
90
  }
88
- const downloadAsset = async (src, to, onDownload) => {
89
- var _a, _b;
90
- if ((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[to]) {
91
- return;
91
+ const downloadAsset = async ({ src, onDownload, downloadDir, }) => {
92
+ var _a, _b, _c;
93
+ if (remotion_1.Internals.AssetCompression.isAssetCompressed(src)) {
94
+ return src;
95
+ }
96
+ if ((_a = hasBeenDownloadedMap[src]) === null || _a === void 0 ? void 0 : _a[downloadDir]) {
97
+ return (_b = hasBeenDownloadedMap[src]) === null || _b === void 0 ? void 0 : _b[downloadDir];
92
98
  }
93
- if ((_b = isDownloadingMap[src]) === null || _b === void 0 ? void 0 : _b[to]) {
94
- return (0, exports.waitForAssetToBeDownloaded)(src, to);
99
+ if ((_c = isDownloadingMap[src]) === null || _c === void 0 ? void 0 : _c[downloadDir]) {
100
+ return (0, exports.waitForAssetToBeDownloaded)({ src, downloadDir });
95
101
  }
96
102
  if (!isDownloadingMap[src]) {
97
103
  isDownloadingMap[src] = {};
98
104
  }
99
- isDownloadingMap[src][to] = true;
105
+ isDownloadingMap[src][downloadDir] = true;
100
106
  const onProgress = onDownload(src);
101
- (0, ensure_output_directory_1.ensureOutputDirectory)(to);
102
107
  if (src.startsWith('data:')) {
108
+ const output = (0, exports.getSanitizedFilenameForAssetUrl)({
109
+ contentDisposition: null,
110
+ downloadDir,
111
+ src,
112
+ });
113
+ (0, ensure_output_directory_1.ensureOutputDirectory)(output);
103
114
  const [assetDetails, assetData] = src.substring('data:'.length).split(',');
104
115
  if (!assetDetails.includes(';')) {
105
116
  const errMessage = [
@@ -114,17 +125,21 @@ const downloadAsset = async (src, to, onDownload) => {
114
125
  validateMimeType(mimeType, src);
115
126
  validateBufferEncoding(encoding, src);
116
127
  const buff = Buffer.from(assetData, encoding);
117
- await fs_1.default.promises.writeFile(to, buff);
118
- notifyAssetIsDownloaded(src, to);
119
- return;
128
+ await fs_1.default.promises.writeFile(output, buff);
129
+ notifyAssetIsDownloaded({ src, downloadDir, to: output });
130
+ return output;
120
131
  }
121
- await (0, download_file_1.downloadFile)(src, to, ({ progress }) => {
122
- onProgress === null || onProgress === void 0 ? void 0 : onProgress({
123
- percent: progress,
124
- });
132
+ const { to } = await (0, download_file_1.downloadFile)({
133
+ url: src,
134
+ onProgress: (progress) => {
135
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress(progress);
136
+ },
137
+ to: (contentDisposition) => (0, exports.getSanitizedFilenameForAssetUrl)({ contentDisposition, downloadDir, src }),
125
138
  });
126
- notifyAssetIsDownloaded(src, to);
139
+ notifyAssetIsDownloaded({ src, downloadDir, to });
140
+ return to;
127
141
  };
142
+ exports.downloadAsset = downloadAsset;
128
143
  const markAllAssetsAsDownloaded = () => {
129
144
  Object.keys(hasBeenDownloadedMap).forEach((key) => {
130
145
  delete hasBeenDownloadedMap[key];
@@ -134,21 +149,40 @@ const markAllAssetsAsDownloaded = () => {
134
149
  });
135
150
  };
136
151
  exports.markAllAssetsAsDownloaded = markAllAssetsAsDownloaded;
137
- const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, }) => {
152
+ const getFilename = ({ contentDisposition, src, }) => {
153
+ const filenameProbe = 'filename=';
154
+ if (contentDisposition === null || contentDisposition === void 0 ? void 0 : contentDisposition.includes(filenameProbe)) {
155
+ const start = contentDisposition.indexOf(filenameProbe);
156
+ const onlyFromFileName = contentDisposition.substring(start + filenameProbe.length);
157
+ const hasSemi = onlyFromFileName.indexOf(';');
158
+ if (hasSemi === -1) {
159
+ return { pathname: onlyFromFileName.trim(), search: '' };
160
+ }
161
+ return {
162
+ search: '',
163
+ pathname: onlyFromFileName.substring(0, hasSemi).trim(),
164
+ };
165
+ }
166
+ const { pathname, search } = new URL(src);
167
+ return { pathname, search };
168
+ };
169
+ exports.getFilename = getFilename;
170
+ const getSanitizedFilenameForAssetUrl = ({ src, downloadDir, contentDisposition, }) => {
138
171
  if (remotion_1.Internals.AssetCompression.isAssetCompressed(src)) {
139
172
  return src;
140
173
  }
141
- const { pathname, search } = new URL(src);
174
+ const { pathname, search } = (0, exports.getFilename)({ contentDisposition, src });
142
175
  const split = pathname.split('.');
143
176
  const fileExtension = split.length > 1 && split[split.length - 1]
144
177
  ? `.${split[split.length - 1]}`
145
178
  : '';
146
179
  const hashedFileName = String((0, remotion_1.random)(`${pathname}${search}`)).replace('0.', '');
147
- return path_1.default.join(downloadDir, (0, sanitize_filepath_1.sanitizeFilePath)(hashedFileName + fileExtension));
180
+ const filename = hashedFileName + fileExtension;
181
+ return path_1.default.join(downloadDir, (0, sanitize_filepath_1.sanitizeFilePath)(filename));
148
182
  };
149
183
  exports.getSanitizedFilenameForAssetUrl = getSanitizedFilenameForAssetUrl;
150
184
  const downloadAndMapAssetsToFileUrl = async ({ asset, downloadDir, onDownload, }) => {
151
- const newSrc = await (0, exports.startDownloadForSrc)({
185
+ const newSrc = await (0, exports.downloadAsset)({
152
186
  src: asset.src,
153
187
  downloadDir,
154
188
  onDownload,
@@ -159,11 +193,3 @@ const downloadAndMapAssetsToFileUrl = async ({ asset, downloadDir, onDownload, }
159
193
  };
160
194
  };
161
195
  exports.downloadAndMapAssetsToFileUrl = downloadAndMapAssetsToFileUrl;
162
- const startDownloadForSrc = async ({ src, downloadDir, onDownload, }) => {
163
- const newSrc = (0, exports.getSanitizedFilenameForAssetUrl)({ downloadDir, src });
164
- if (!remotion_1.Internals.AssetCompression.isAssetCompressed(newSrc)) {
165
- await downloadAsset(src, newSrc, onDownload);
166
- }
167
- return newSrc;
168
- };
169
- exports.startDownloadForSrc = startDownloadForSrc;
@@ -1,7 +1,12 @@
1
- export declare const downloadFile: (url: string, to: string, onProgress: ((progress: {
2
- progress: number;
3
- downloaded: number;
4
- totalSize: number;
5
- }) => void) | undefined) => Promise<{
1
+ export declare const downloadFile: ({ onProgress, url, to: toFn, }: {
2
+ url: string;
3
+ to: (contentDisposition: string | null) => string;
4
+ onProgress: ((progress: {
5
+ percent: number | null;
6
+ downloaded: number;
7
+ totalSize: number | null;
8
+ }) => void) | undefined;
9
+ }) => Promise<{
6
10
  sizeInBytes: number;
11
+ to: string;
7
12
  }>;
@@ -2,25 +2,38 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.downloadFile = void 0;
4
4
  const fs_1 = require("fs");
5
+ const ensure_output_directory_1 = require("../ensure-output-directory");
5
6
  const read_file_1 = require("./read-file");
6
- const downloadFile = (url, to, onProgress) => {
7
+ const downloadFile = ({ onProgress, url, to: toFn, }) => {
7
8
  return new Promise((resolve, reject) => {
8
9
  (0, read_file_1.readFile)(url)
9
10
  .then((res) => {
10
- const totalSize = Number(res.headers['content-length']);
11
+ var _a;
12
+ const contentDisposition = (_a = res.headers['content-disposition']) !== null && _a !== void 0 ? _a : null;
13
+ const to = toFn(contentDisposition);
14
+ (0, ensure_output_directory_1.ensureOutputDirectory)(to);
15
+ const sizeHeader = res.headers['content-length'];
16
+ const totalSize = typeof sizeHeader === 'undefined' ? null : Number(sizeHeader);
11
17
  const writeStream = (0, fs_1.createWriteStream)(to);
18
+ let downloaded = 0;
12
19
  // Listen to 'close' event instead of more
13
20
  // concise method to avoid this problem
14
21
  // https://github.com/remotion-dev/remotion/issues/384#issuecomment-844398183
15
- writeStream.on('close', () => resolve({ sizeInBytes: totalSize }));
22
+ writeStream.on('close', () => {
23
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress({
24
+ downloaded,
25
+ percent: 1,
26
+ totalSize: downloaded,
27
+ });
28
+ return resolve({ sizeInBytes: downloaded, to });
29
+ });
16
30
  writeStream.on('error', (err) => reject(err));
17
- let downloaded = 0;
18
31
  res.pipe(writeStream).on('error', (err) => reject(err));
19
32
  res.on('data', (d) => {
20
33
  downloaded += d.length;
21
34
  onProgress === null || onProgress === void 0 ? void 0 : onProgress({
22
35
  downloaded,
23
- progress: downloaded / totalSize,
36
+ percent: totalSize === null ? null : downloaded / totalSize,
24
37
  totalSize,
25
38
  });
26
39
  });
@@ -4,9 +4,8 @@ declare type FfmpegVolumeExpression = {
4
4
  eval: FfmpegEval;
5
5
  value: string;
6
6
  };
7
- export declare const ffmpegVolumeExpression: ({ volume, startInVideo, fps, trimLeft, }: {
7
+ export declare const ffmpegVolumeExpression: ({ volume, fps, trimLeft, }: {
8
8
  volume: AssetVolume;
9
- startInVideo: number;
10
9
  trimLeft: number;
11
10
  fps: number;
12
11
  }) => FfmpegVolumeExpression;
@@ -43,7 +43,7 @@ const ffmpegBuildVolumeExpression = (arr, delay, fps) => {
43
43
  const [volume, frames] = first;
44
44
  return ffmpegIfOrElse(ffmpegIsOneOfFrames({ frames, trimLeft: delay, fps }), String(volume), ffmpegBuildVolumeExpression(rest, delay, fps));
45
45
  };
46
- const ffmpegVolumeExpression = ({ volume, startInVideo, fps, trimLeft, }) => {
46
+ const ffmpegVolumeExpression = ({ volume, fps, trimLeft, }) => {
47
47
  // If it's a static volume, we return it and tell
48
48
  // FFMPEG it only has to evaluate it once
49
49
  if (typeof volume === 'number') {
@@ -55,7 +55,6 @@ const ffmpegVolumeExpression = ({ volume, startInVideo, fps, trimLeft, }) => {
55
55
  if ([...new Set(volume)].length === 1) {
56
56
  return (0, exports.ffmpegVolumeExpression)({
57
57
  volume: volume[0],
58
- startInVideo,
59
58
  fps,
60
59
  trimLeft,
61
60
  });
@@ -76,7 +75,7 @@ const ffmpegVolumeExpression = ({ volume, startInVideo, fps, trimLeft, }) => {
76
75
  if (!volumeMap[actualVolume]) {
77
76
  volumeMap[actualVolume] = [];
78
77
  }
79
- volumeMap[actualVolume].push(frame + startInVideo);
78
+ volumeMap[actualVolume].push(frame);
80
79
  });
81
80
  // Sort the map so that the most common volume is last
82
81
  // this is going to be the else statement so the expression is short
@@ -29,7 +29,10 @@ const readFile = async (url, redirectsSoFar = 0) => {
29
29
  throw new Error(`Too many redirects while downloading ${url}`);
30
30
  }
31
31
  const file = await readFileWithoutRedirect(url);
32
- if (file.statusCode === 302 || file.statusCode === 301) {
32
+ if (file.statusCode === 302 ||
33
+ file.statusCode === 301 ||
34
+ file.statusCode === 307 ||
35
+ file.statusCode === 308) {
33
36
  if (!file.headers.location) {
34
37
  throw new Error(`Received a status code ${file.statusCode} but no "Location" header while calling ${file.headers.location}`);
35
38
  }
@@ -22,6 +22,11 @@ declare type BrowserCloseCallback = () => Promise<void> | void;
22
22
  interface WaitForTargetOptions {
23
23
  timeout?: number;
24
24
  }
25
+ export declare const enum BrowserEmittedEvents {
26
+ TargetChanged = "targetchanged",
27
+ TargetCreated = "targetcreated",
28
+ Closed = "closed"
29
+ }
25
30
  export declare class Browser extends EventEmitter {
26
31
  #private;
27
32
  static _create({ connection, contextIds, defaultViewport, closeCallback, }: {
@@ -111,7 +111,7 @@ class Browser extends EventEmitter_1.EventEmitter {
111
111
  return await targetPromise;
112
112
  }
113
113
  this.targets().forEach(check);
114
- return await (0, util_1.waitWithTimeout)(targetPromise, 'target', timeout);
114
+ return await (0, util_1.waitWithTimeout)(targetPromise, 'target', timeout, this);
115
115
  }
116
116
  finally {
117
117
  this.off("targetcreated" /* BrowserEmittedEvents.TargetCreated */, check);
@@ -136,6 +136,7 @@ class Browser extends EventEmitter_1.EventEmitter {
136
136
  async close() {
137
137
  await __classPrivateFieldGet(this, _Browser_closeCallback, "f").call(null);
138
138
  this.disconnect();
139
+ this.emit("closed" /* BrowserEmittedEvents.Closed */);
139
140
  }
140
141
  disconnect() {
141
142
  __classPrivateFieldGet(this, _Browser_connection, "f").dispose();
@@ -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
+ import type { Browser } from './Browser';
16
17
  import type { EvaluateFn, EvaluateFnReturnType, EvaluateHandleFn, SerializableOrJSHandle, UnwrapPromiseLike } from './EvalTypes';
17
18
  import type { ExecutionContext } from './ExecutionContext';
18
19
  import type { Frame } from './FrameManager';
@@ -29,7 +30,7 @@ export declare class DOMWorld {
29
30
  executionContext(): Promise<ExecutionContext>;
30
31
  evaluateHandle<HandlerType extends JSHandle = JSHandle>(pageFunction: EvaluateHandleFn, ...args: SerializableOrJSHandle[]): Promise<HandlerType>;
31
32
  evaluate<T extends EvaluateFn>(pageFunction: T, ...args: SerializableOrJSHandle[]): Promise<UnwrapPromiseLike<EvaluateFnReturnType<T>>>;
32
- waitForFunction(pageFunction: Function | string, ...args: SerializableOrJSHandle[]): Promise<JSHandle>;
33
+ waitForFunction(browser: Browser, pageFunction: Function | string, ...args: SerializableOrJSHandle[]): Promise<JSHandle>;
33
34
  title(): Promise<string>;
34
35
  }
35
36
  interface WaitTaskOptions {
@@ -37,12 +38,14 @@ interface WaitTaskOptions {
37
38
  predicateBody: Function | string;
38
39
  title: string;
39
40
  timeout: number;
41
+ browser: Browser;
40
42
  args: SerializableOrJSHandle[];
41
43
  }
42
44
  declare class WaitTask {
43
45
  #private;
44
46
  promise: Promise<JSHandle>;
45
47
  constructor(options: WaitTaskOptions);
48
+ onBrowserClose: () => void;
46
49
  terminate(error: Error): void;
47
50
  rerun(): Promise<void>;
48
51
  }
@@ -25,7 +25,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
25
25
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
26
26
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
27
27
  };
28
- var _DOMWorld_frame, _DOMWorld_timeoutSettings, _DOMWorld_contextPromise, _DOMWorld_contextResolveCallback, _DOMWorld_detached, _DOMWorld_waitTasks, _WaitTask_instances, _WaitTask_domWorld, _WaitTask_timeout, _WaitTask_predicateBody, _WaitTask_args, _WaitTask_runCount, _WaitTask_resolve, _WaitTask_reject, _WaitTask_timeoutTimer, _WaitTask_terminated, _WaitTask_cleanup;
28
+ var _DOMWorld_frame, _DOMWorld_timeoutSettings, _DOMWorld_contextPromise, _DOMWorld_contextResolveCallback, _DOMWorld_detached, _DOMWorld_waitTasks, _WaitTask_instances, _WaitTask_domWorld, _WaitTask_timeout, _WaitTask_predicateBody, _WaitTask_args, _WaitTask_runCount, _WaitTask_resolve, _WaitTask_reject, _WaitTask_timeoutTimer, _WaitTask_terminated, _WaitTask_browser, _WaitTask_cleanup;
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.DOMWorld = void 0;
31
31
  const assert_1 = require("./assert");
@@ -93,7 +93,7 @@ class DOMWorld {
93
93
  const context = await this.executionContext();
94
94
  return context.evaluate(pageFunction, ...args);
95
95
  }
96
- waitForFunction(pageFunction, ...args) {
96
+ waitForFunction(browser, pageFunction, ...args) {
97
97
  const timeout = __classPrivateFieldGet(this, _DOMWorld_timeoutSettings, "f").timeout();
98
98
  const waitTaskOptions = {
99
99
  domWorld: this,
@@ -101,6 +101,7 @@ class DOMWorld {
101
101
  title: 'function',
102
102
  timeout,
103
103
  args,
104
+ browser,
104
105
  };
105
106
  const waitTask = new WaitTask(waitTaskOptions);
106
107
  return waitTask.promise;
@@ -126,6 +127,10 @@ class WaitTask {
126
127
  _WaitTask_reject.set(this, noop);
127
128
  _WaitTask_timeoutTimer.set(this, void 0);
128
129
  _WaitTask_terminated.set(this, false);
130
+ _WaitTask_browser.set(this, void 0);
131
+ this.onBrowserClose = () => {
132
+ return this.terminate(new Error('Browser was closed'));
133
+ };
129
134
  function getPredicateBody(predicateBody) {
130
135
  if ((0, util_1.isString)(predicateBody)) {
131
136
  return `return (${predicateBody});`;
@@ -150,6 +155,8 @@ class WaitTask {
150
155
  return this.terminate(timeoutError);
151
156
  }, options.timeout), "f");
152
157
  }
158
+ __classPrivateFieldSet(this, _WaitTask_browser, options.browser, "f");
159
+ __classPrivateFieldGet(this, _WaitTask_browser, "f").on("closed" /* BrowserEmittedEvents.Closed */, this.onBrowserClose);
153
160
  this.rerun();
154
161
  }
155
162
  terminate(error) {
@@ -230,10 +237,11 @@ class WaitTask {
230
237
  __classPrivateFieldGet(this, _WaitTask_instances, "m", _WaitTask_cleanup).call(this);
231
238
  }
232
239
  }
233
- _WaitTask_domWorld = new WeakMap(), _WaitTask_timeout = new WeakMap(), _WaitTask_predicateBody = new WeakMap(), _WaitTask_args = new WeakMap(), _WaitTask_runCount = new WeakMap(), _WaitTask_resolve = new WeakMap(), _WaitTask_reject = new WeakMap(), _WaitTask_timeoutTimer = new WeakMap(), _WaitTask_terminated = new WeakMap(), _WaitTask_instances = new WeakSet(), _WaitTask_cleanup = function _WaitTask_cleanup() {
240
+ _WaitTask_domWorld = new WeakMap(), _WaitTask_timeout = new WeakMap(), _WaitTask_predicateBody = new WeakMap(), _WaitTask_args = new WeakMap(), _WaitTask_runCount = new WeakMap(), _WaitTask_resolve = new WeakMap(), _WaitTask_reject = new WeakMap(), _WaitTask_timeoutTimer = new WeakMap(), _WaitTask_terminated = new WeakMap(), _WaitTask_browser = new WeakMap(), _WaitTask_instances = new WeakSet(), _WaitTask_cleanup = function _WaitTask_cleanup() {
234
241
  if (__classPrivateFieldGet(this, _WaitTask_timeoutTimer, "f") !== undefined) {
235
242
  clearTimeout(__classPrivateFieldGet(this, _WaitTask_timeoutTimer, "f"));
236
243
  }
244
+ __classPrivateFieldGet(this, _WaitTask_browser, "f").off("closed" /* BrowserEmittedEvents.Closed */, this.onBrowserClose);
237
245
  __classPrivateFieldGet(this, _WaitTask_domWorld, "f")._waitTasks.delete(this);
238
246
  };
239
247
  function waitForPredicatePageFunction(predicateBody, timeout, ...args) {
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import type { Protocol } from 'devtools-protocol';
17
+ import type { Browser } from './Browser';
17
18
  import type { CDPSession } from './Connection';
18
19
  import { DOMWorld } from './DOMWorld';
19
20
  import type { EvaluateFn, EvaluateFnReturnType, EvaluateHandleFn, SerializableOrJSHandle, UnwrapPromiseLike } from './EvalTypes';
@@ -82,7 +83,7 @@ export declare class Frame {
82
83
  evaluate<T extends EvaluateFn>(pageFunction: T, ...args: SerializableOrJSHandle[]): Promise<UnwrapPromiseLike<EvaluateFnReturnType<T>>>;
83
84
  url(): string;
84
85
  childFrames(): Frame[];
85
- waitForFunction(pageFunction: Function | string, ...args: SerializableOrJSHandle[]): Promise<JSHandle>;
86
+ waitForFunction(browser: Browser, pageFunction: Function | string, ...args: SerializableOrJSHandle[]): Promise<JSHandle>;
86
87
  _navigated(framePayload: Protocol.Page.Frame): void;
87
88
  _navigatedWithinDocument(url: string): void;
88
89
  _onLifecycleEvent(loaderId: string, name: string): void;
@@ -460,8 +460,8 @@ class Frame {
460
460
  childFrames() {
461
461
  return Array.from(this._childFrames);
462
462
  }
463
- waitForFunction(pageFunction, ...args) {
464
- return this._mainWorld.waitForFunction(pageFunction, ...args);
463
+ waitForFunction(browser, pageFunction, ...args) {
464
+ return this._mainWorld.waitForFunction(browser, pageFunction, ...args);
465
465
  }
466
466
  _navigated(framePayload) {
467
467
  this._name = framePayload.name;
@@ -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
+ import type { Browser } from './Browser';
16
17
  import type { CDPSession } from './Connection';
17
18
  import { ConsoleMessage } from './ConsoleMessage';
18
19
  import type { EvaluateFn, EvaluateFnReturnType, EvaluateHandleFn, SerializableOrJSHandle, UnwrapPromiseLike } from './EvalTypes';
@@ -32,9 +33,10 @@ interface PageEventObject {
32
33
  }
33
34
  export declare class Page extends EventEmitter {
34
35
  #private;
35
- static _create(client: CDPSession, target: Target, defaultViewport: Viewport): Promise<Page>;
36
+ static _create(client: CDPSession, target: Target, defaultViewport: Viewport, browser: Browser): Promise<Page>;
37
+ browser: Browser;
36
38
  screenshotTaskQueue: TaskQueue;
37
- constructor(client: CDPSession, target: Target);
39
+ constructor(client: CDPSession, target: Target, browser: Browser);
38
40
  /**
39
41
  * Listen to page events.
40
42
  */
@@ -67,6 +69,6 @@ export declare class Page extends EventEmitter {
67
69
  runBeforeUnload?: boolean;
68
70
  }): Promise<void>;
69
71
  isClosed(): boolean;
70
- waitForFunction(pageFunction: Function | string, ...args: SerializableOrJSHandle[]): Promise<JSHandle>;
72
+ waitForFunction(browser: Browser, pageFunction: Function | string, ...args: SerializableOrJSHandle[]): Promise<JSHandle>;
71
73
  }
72
74
  export {};
@@ -37,7 +37,7 @@ const TaskQueue_1 = require("./TaskQueue");
37
37
  const TimeoutSettings_1 = require("./TimeoutSettings");
38
38
  const util_1 = require("./util");
39
39
  class Page extends EventEmitter_1.EventEmitter {
40
- constructor(client, target) {
40
+ constructor(client, target, browser) {
41
41
  super();
42
42
  _Page_instances.add(this);
43
43
  _Page_closed.set(this, false);
@@ -50,6 +50,7 @@ class Page extends EventEmitter_1.EventEmitter {
50
50
  __classPrivateFieldSet(this, _Page_target, target, "f");
51
51
  __classPrivateFieldSet(this, _Page_frameManager, new FrameManager_1.FrameManager(client, this, __classPrivateFieldGet(this, _Page_timeoutSettings, "f")), "f");
52
52
  this.screenshotTaskQueue = new TaskQueue_1.TaskQueue();
53
+ this.browser = browser;
53
54
  client.on('Target.attachedToTarget', (event) => {
54
55
  switch (event.targetInfo.type) {
55
56
  case 'iframe':
@@ -83,8 +84,8 @@ class Page extends EventEmitter_1.EventEmitter {
83
84
  return __classPrivateFieldGet(this, _Page_instances, "m", _Page_onLogEntryAdded).call(this, event);
84
85
  });
85
86
  }
86
- static async _create(client, target, defaultViewport) {
87
- const page = new Page(client, target);
87
+ static async _create(client, target, defaultViewport, browser) {
88
+ const page = new Page(client, target, browser);
88
89
  await __classPrivateFieldGet(page, _Page_instances, "m", _Page_initialize).call(page);
89
90
  await page.setViewport(defaultViewport);
90
91
  return page;
@@ -180,8 +181,8 @@ class Page extends EventEmitter_1.EventEmitter {
180
181
  isClosed() {
181
182
  return __classPrivateFieldGet(this, _Page_closed, "f");
182
183
  }
183
- waitForFunction(pageFunction, ...args) {
184
- return this.mainFrame().waitForFunction(pageFunction, ...args);
184
+ waitForFunction(browser, pageFunction, ...args) {
185
+ return this.mainFrame().waitForFunction(browser, pageFunction, ...args);
185
186
  }
186
187
  }
187
188
  exports.Page = Page;
@@ -84,7 +84,7 @@ class Target {
84
84
  if (isPagetTarget(__classPrivateFieldGet(this, _Target_targetInfo, "f")) && !__classPrivateFieldGet(this, _Target_pagePromise, "f")) {
85
85
  __classPrivateFieldSet(this, _Target_pagePromise, __classPrivateFieldGet(this, _Target_sessionFactory, "f").call(this).then((client) => {
86
86
  var _a;
87
- return Page_1.Page._create(client, this, (_a = __classPrivateFieldGet(this, _Target_defaultViewport, "f")) !== null && _a !== void 0 ? _a : null);
87
+ return Page_1.Page._create(client, this, (_a = __classPrivateFieldGet(this, _Target_defaultViewport, "f")) !== null && _a !== void 0 ? _a : null, this.browser());
88
88
  }), "f");
89
89
  }
90
90
  return (_a = (await __classPrivateFieldGet(this, _Target_pagePromise, "f"))) !== null && _a !== void 0 ? _a : null;
@@ -15,6 +15,7 @@
15
15
  */
16
16
  /// <reference types="node" />
17
17
  import type { Protocol } from 'devtools-protocol';
18
+ import type { Browser } from './Browser';
18
19
  import type { CDPSession } from './Connection';
19
20
  import type { CommonEventEmitter } from './EventEmitter';
20
21
  export declare function getExceptionMessage(exceptionDetails: Protocol.Runtime.ExceptionDetails): string;
@@ -36,7 +37,7 @@ export declare function evaluationString(fun: Function | string, ...args: unknow
36
37
  export declare function pageBindingDeliverResultString(name: string, seq: number, result: unknown): string;
37
38
  export declare function pageBindingDeliverErrorString(name: string, seq: number, message: string, stack?: string): string;
38
39
  export declare function pageBindingDeliverErrorValueString(name: string, seq: number, value: unknown): string;
39
- export declare function waitWithTimeout<T>(promise: Promise<T>, taskName: string, timeout: number): Promise<T>;
40
+ export declare function waitWithTimeout<T>(promise: Promise<T>, taskName: string, timeout: number, browser: Browser): Promise<T>;
40
41
  interface ErrorLike extends Error {
41
42
  name: string;
42
43
  message: string;
@@ -128,7 +128,7 @@ function pageBindingDeliverErrorValueString(name, seq, value) {
128
128
  return evaluationString(deliverErrorValue, name, seq, value);
129
129
  }
130
130
  exports.pageBindingDeliverErrorValueString = pageBindingDeliverErrorValueString;
131
- async function waitWithTimeout(promise, taskName, timeout) {
131
+ async function waitWithTimeout(promise, taskName, timeout, browser) {
132
132
  let reject;
133
133
  const timeoutError = new Errors_1.TimeoutError(`waiting for ${taskName} failed: timeout ${timeout}ms exceeded`);
134
134
  const timeoutPromise = new Promise((_res, rej) => {
@@ -141,7 +141,15 @@ async function waitWithTimeout(promise, taskName, timeout) {
141
141
  }, timeout);
142
142
  }
143
143
  try {
144
- return await Promise.race([promise, timeoutPromise]);
144
+ return await Promise.race([
145
+ new Promise((_, rej) => {
146
+ browser.once("closed" /* BrowserEmittedEvents.Closed */, () => {
147
+ return rej();
148
+ });
149
+ }),
150
+ promise,
151
+ timeoutPromise,
152
+ ]);
145
153
  }
146
154
  finally {
147
155
  if (timeoutTimer) {
@@ -0,0 +1,9 @@
1
+ export declare const calculateDisplayVideoSize: ({ darX, darY, x, y, }: {
2
+ x: number;
3
+ y: number;
4
+ darX: number;
5
+ darY: number;
6
+ }) => {
7
+ width: number;
8
+ height: number;
9
+ };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ // https://superuser.com/questions/907933/correct-aspect-ratio-without-re-encoding-video-file
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.calculateDisplayVideoSize = void 0;
5
+ const calculateDisplayVideoSize = ({ darX, darY, x, y, }) => {
6
+ // We know two equations:
7
+ // newWidth / newHeight = darX / darY
8
+ // and:
9
+ // x * y = (newWidth * newHeight)
10
+ // I solved it then on pen and paper and simplified the formula:
11
+ const dimensions = x * y;
12
+ const newWidth = Math.sqrt(dimensions * (darX / darY));
13
+ const newHeight = dimensions / newWidth;
14
+ return {
15
+ height: Math.round(newHeight),
16
+ width: Math.round(newWidth),
17
+ };
18
+ };
19
+ exports.calculateDisplayVideoSize = calculateDisplayVideoSize;