@remotion/renderer 4.0.0-fastlambda.8 → 4.0.0-lambda.3

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 (191) hide show
  1. package/dist/assets/cleanup-assets.d.ts +2 -0
  2. package/dist/assets/cleanup-assets.js +2 -0
  3. package/dist/assets/download-and-map-assets-to-file.d.ts +6 -0
  4. package/dist/assets/download-and-map-assets-to-file.js +46 -19
  5. package/dist/assets/ffmpeg-volume-expression.d.ts +2 -1
  6. package/dist/assets/ffmpeg-volume-expression.js +15 -12
  7. package/dist/assets/get-audio-channels.d.ts +5 -2
  8. package/dist/assets/get-audio-channels.js +15 -4
  9. package/dist/browser/Accessibility.d.ts +175 -0
  10. package/dist/browser/Accessibility.js +423 -0
  11. package/dist/browser/AriaQueryHandler.d.ts +20 -0
  12. package/dist/browser/AriaQueryHandler.js +108 -0
  13. package/dist/browser/Browser.d.ts +209 -0
  14. package/dist/browser/Browser.js +402 -0
  15. package/dist/browser/BrowserConnector.d.ts +26 -0
  16. package/dist/browser/BrowserConnector.js +49 -0
  17. package/dist/browser/BrowserFetcher.d.ts +89 -0
  18. package/dist/browser/BrowserFetcher.js +512 -0
  19. package/dist/browser/BrowserRunner.d.ts +39 -0
  20. package/dist/browser/BrowserRunner.js +308 -0
  21. package/dist/browser/Connection.d.ts +49 -0
  22. package/dist/browser/Connection.js +262 -0
  23. package/dist/browser/ConnectionTransport.d.ts +21 -0
  24. package/dist/browser/ConnectionTransport.js +17 -0
  25. package/dist/browser/ConsoleMessage.d.ts +55 -0
  26. package/dist/browser/ConsoleMessage.js +75 -0
  27. package/dist/browser/Coverage.d.ts +180 -0
  28. package/dist/browser/Coverage.js +371 -0
  29. package/dist/browser/DOMWorld.d.ts +50 -0
  30. package/dist/browser/DOMWorld.js +280 -0
  31. package/dist/browser/Debug.d.ts +19 -0
  32. package/dist/browser/Debug.js +42 -0
  33. package/dist/browser/DeviceDescriptors.d.ts +40 -0
  34. package/dist/browser/DeviceDescriptors.js +1407 -0
  35. package/dist/browser/EmulationManager.d.ts +7 -0
  36. package/dist/browser/EmulationManager.js +40 -0
  37. package/dist/browser/Errors.d.ts +25 -0
  38. package/dist/browser/Errors.js +35 -0
  39. package/dist/browser/EvalTypes.d.ts +27 -0
  40. package/dist/browser/EvalTypes.js +17 -0
  41. package/dist/browser/EventEmitter.d.ts +70 -0
  42. package/dist/browser/EventEmitter.js +102 -0
  43. package/dist/browser/ExecutionContext.d.ts +35 -0
  44. package/dist/browser/ExecutionContext.js +190 -0
  45. package/dist/browser/FileChooser.d.ts +56 -0
  46. package/dist/browser/FileChooser.js +86 -0
  47. package/dist/browser/FrameManager.d.ts +96 -0
  48. package/dist/browser/FrameManager.js +512 -0
  49. package/dist/browser/HTTPRequest.d.ts +42 -0
  50. package/dist/browser/HTTPRequest.js +82 -0
  51. package/dist/browser/HTTPResponse.d.ts +100 -0
  52. package/dist/browser/HTTPResponse.js +196 -0
  53. package/dist/browser/Input.d.ts +355 -0
  54. package/dist/browser/Input.js +592 -0
  55. package/dist/browser/JSHandle.d.ts +36 -0
  56. package/dist/browser/JSHandle.js +93 -0
  57. package/dist/browser/LaunchOptions.d.ts +117 -0
  58. package/dist/browser/LaunchOptions.js +17 -0
  59. package/dist/browser/Launcher.d.ts +9 -0
  60. package/dist/browser/Launcher.js +602 -0
  61. package/dist/browser/LifecycleWatcher.d.ts +29 -0
  62. package/dist/browser/LifecycleWatcher.js +193 -0
  63. package/dist/browser/NetworkConditions.d.ts +26 -0
  64. package/dist/browser/NetworkConditions.js +33 -0
  65. package/dist/browser/NetworkEventManager.d.ts +35 -0
  66. package/dist/browser/NetworkEventManager.js +128 -0
  67. package/dist/browser/NetworkManager.d.ts +36 -0
  68. package/dist/browser/NetworkManager.js +284 -0
  69. package/dist/browser/NodeWebSocketTransport.d.ts +11 -0
  70. package/dist/browser/NodeWebSocketTransport.js +90 -0
  71. package/dist/browser/PDFOptions.d.ts +165 -0
  72. package/dist/browser/PDFOptions.js +34 -0
  73. package/dist/browser/PipeTransport.d.ts +10 -0
  74. package/dist/browser/PipeTransport.js +86 -0
  75. package/dist/browser/Product.d.ts +16 -0
  76. package/dist/browser/Product.js +17 -0
  77. package/dist/browser/Puppeteer.d.ts +35 -0
  78. package/dist/browser/Puppeteer.js +17 -0
  79. package/dist/browser/PuppeteerNode.d.ts +92 -0
  80. package/dist/browser/PuppeteerNode.js +143 -0
  81. package/dist/browser/PuppeteerViewport.d.ts +5 -0
  82. package/dist/browser/PuppeteerViewport.js +2 -0
  83. package/dist/browser/QueryHandler.d.ts +64 -0
  84. package/dist/browser/QueryHandler.js +183 -0
  85. package/dist/browser/ScreenshotOptions.d.ts +14 -0
  86. package/dist/browser/ScreenshotOptions.js +2 -0
  87. package/dist/browser/SecurityDetails.d.ts +55 -0
  88. package/dist/browser/SecurityDetails.js +95 -0
  89. package/dist/browser/Target.d.ts +61 -0
  90. package/dist/browser/Target.js +146 -0
  91. package/dist/browser/TaskQueue.d.ts +20 -0
  92. package/dist/browser/TaskQueue.js +47 -0
  93. package/dist/browser/TimeoutSettings.d.ts +23 -0
  94. package/dist/browser/TimeoutSettings.js +62 -0
  95. package/dist/browser/Tracing.d.ts +45 -0
  96. package/dist/browser/Tracing.js +136 -0
  97. package/dist/browser/USKeyboardLayout.d.ts +39 -0
  98. package/dist/browser/USKeyboardLayout.js +406 -0
  99. package/dist/browser/WebWorker.d.ts +96 -0
  100. package/dist/browser/WebWorker.js +122 -0
  101. package/dist/browser/assert.d.ts +21 -0
  102. package/dist/browser/assert.js +29 -0
  103. package/dist/browser/compat.d.ts +2 -0
  104. package/dist/browser/compat.js +17 -0
  105. package/dist/browser/create-browser-fetcher.d.ts +17 -0
  106. package/dist/browser/create-browser-fetcher.js +140 -0
  107. package/dist/browser/dialog.d.ts +70 -0
  108. package/dist/browser/dialog.js +114 -0
  109. package/dist/browser/environment.d.ts +16 -0
  110. package/dist/browser/environment.js +19 -0
  111. package/dist/browser/fetch.d.ts +16 -0
  112. package/dist/browser/fetch.js +46 -0
  113. package/dist/browser/find-up.d.ts +4 -0
  114. package/dist/browser/find-up.js +85 -0
  115. package/dist/browser/get-download-destination.d.ts +1 -0
  116. package/dist/browser/get-download-destination.js +38 -0
  117. package/dist/browser/mitt/index.d.ts +22 -0
  118. package/dist/browser/mitt/index.js +49 -0
  119. package/dist/browser/node.d.ts +2 -0
  120. package/dist/browser/node.js +9 -0
  121. package/dist/browser/page.d.ts +78 -0
  122. package/dist/browser/page.js +277 -0
  123. package/dist/browser/pkg-dir.d.ts +3 -0
  124. package/dist/browser/pkg-dir.js +13 -0
  125. package/dist/browser/revisions.d.ts +21 -0
  126. package/dist/browser/revisions.js +22 -0
  127. package/dist/browser/util.d.ts +46 -0
  128. package/dist/browser/util.js +161 -0
  129. package/dist/calculate-ffmpeg-filters.js +2 -2
  130. package/dist/combine-videos.d.ts +2 -1
  131. package/dist/combine-videos.js +8 -1
  132. package/dist/cycle-browser-tabs.d.ts +2 -1
  133. package/dist/cycle-browser-tabs.js +9 -2
  134. package/dist/ensure-presentation-timestamp.d.ts +1 -0
  135. package/dist/ensure-presentation-timestamp.js +57 -0
  136. package/dist/extract-frame-from-video.d.ts +11 -0
  137. package/dist/extract-frame-from-video.js +197 -0
  138. package/dist/frame-to-ffmpeg-timestamp.d.ts +1 -0
  139. package/dist/frame-to-ffmpeg-timestamp.js +8 -0
  140. package/dist/get-compositions.d.ts +5 -2
  141. package/dist/get-compositions.js +23 -5
  142. package/dist/get-duration-of-asset.d.ts +7 -0
  143. package/dist/get-duration-of-asset.js +36 -0
  144. package/dist/get-port.js +26 -24
  145. package/dist/index.d.ts +33 -9
  146. package/dist/index.js +14 -5
  147. package/dist/is-beyond-last-frame.d.ts +2 -0
  148. package/dist/is-beyond-last-frame.js +12 -0
  149. package/dist/last-frame-from-video-cache.d.ts +10 -0
  150. package/dist/last-frame-from-video-cache.js +50 -0
  151. package/dist/make-assets-download-dir.js +6 -1
  152. package/dist/make-cancel-signal.d.ts +7 -0
  153. package/dist/make-cancel-signal.js +25 -0
  154. package/dist/merge-audio-track.js +2 -2
  155. package/dist/offthread-video-server.d.ts +14 -0
  156. package/dist/offthread-video-server.js +67 -0
  157. package/dist/open-browser.d.ts +6 -6
  158. package/dist/open-browser.js +24 -20
  159. package/dist/prepare-server.d.ts +13 -2
  160. package/dist/prepare-server.js +35 -5
  161. package/dist/preprocess-audio-track.d.ts +1 -0
  162. package/dist/preprocess-audio-track.js +2 -2
  163. package/dist/prespawn-ffmpeg.d.ts +2 -0
  164. package/dist/prespawn-ffmpeg.js +10 -9
  165. package/dist/provide-screenshot.js +1 -1
  166. package/dist/puppeteer-screenshot.js +5 -1
  167. package/dist/render-frames.d.ts +6 -1
  168. package/dist/render-frames.js +96 -37
  169. package/dist/render-media.d.ts +12 -2
  170. package/dist/render-media.js +127 -54
  171. package/dist/render-still.d.ts +14 -4
  172. package/dist/render-still.js +58 -19
  173. package/dist/serve-handler/glob-slash.d.ts +1 -0
  174. package/dist/serve-handler/glob-slash.js +12 -0
  175. package/dist/serve-handler/index.d.ts +4 -0
  176. package/dist/serve-handler/index.js +205 -0
  177. package/dist/serve-handler/is-path-inside.d.ts +1 -0
  178. package/dist/serve-handler/is-path-inside.js +27 -0
  179. package/dist/serve-handler/range-parser.d.ts +13 -0
  180. package/dist/serve-handler/range-parser.js +57 -0
  181. package/dist/serve-static.d.ts +10 -3
  182. package/dist/serve-static.js +22 -4
  183. package/dist/set-props-and-env.d.ts +3 -1
  184. package/dist/set-props-and-env.js +28 -6
  185. package/dist/stitch-frames-to-video.d.ts +4 -1
  186. package/dist/stitch-frames-to-video.js +36 -15
  187. package/dist/stringify-ffmpeg-filter.js +3 -0
  188. package/dist/tmp-dir.js +5 -1
  189. package/dist/validate-fps-for-gif.d.ts +2 -0
  190. package/dist/validate-fps-for-gif.js +9 -0
  191. package/package.json +6 -7
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright 2020 Google Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ declare type Revisions = Readonly<{
17
+ readonly chromium: string;
18
+ readonly firefox: string;
19
+ }>;
20
+ export declare const PUPPETEER_REVISIONS: Revisions;
21
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright 2020 Google Inc. All rights reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.PUPPETEER_REVISIONS = void 0;
19
+ exports.PUPPETEER_REVISIONS = {
20
+ chromium: '1002410',
21
+ firefox: 'latest',
22
+ };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright 2017 Google Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /// <reference types="node" />
17
+ import { Protocol } from 'devtools-protocol';
18
+ import { CDPSession } from './Connection';
19
+ import { CommonEventEmitter } from './EventEmitter';
20
+ export declare function getExceptionMessage(exceptionDetails: Protocol.Runtime.ExceptionDetails): string;
21
+ export declare function valueFromRemoteObject(remoteObject: Protocol.Runtime.RemoteObject): any;
22
+ export declare function releaseObject(client: CDPSession, remoteObject: Protocol.Runtime.RemoteObject): Promise<void>;
23
+ export interface PuppeteerEventListener {
24
+ emitter: CommonEventEmitter;
25
+ eventName: string | symbol;
26
+ handler: (...args: any[]) => void;
27
+ }
28
+ export declare function addEventListener(emitter: CommonEventEmitter, eventName: string | symbol, handler: (...args: any[]) => void): PuppeteerEventListener;
29
+ export declare function removeEventListeners(listeners: Array<{
30
+ emitter: CommonEventEmitter;
31
+ eventName: string | symbol;
32
+ handler: (...args: any[]) => void;
33
+ }>): void;
34
+ export declare const isString: (obj: unknown) => obj is string;
35
+ export declare function evaluationString(fun: Function | string, ...args: unknown[]): string;
36
+ export declare function pageBindingDeliverResultString(name: string, seq: number, result: unknown): string;
37
+ export declare function pageBindingDeliverErrorString(name: string, seq: number, message: string, stack?: string): string;
38
+ 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
+ interface ErrorLike extends Error {
41
+ name: string;
42
+ message: string;
43
+ }
44
+ export declare function isErrorLike(obj: unknown): obj is ErrorLike;
45
+ export declare function isErrnoException(obj: unknown): obj is NodeJS.ErrnoException;
46
+ export {};
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright 2017 Google Inc. All rights reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.isErrnoException = exports.isErrorLike = exports.waitWithTimeout = exports.pageBindingDeliverErrorValueString = exports.pageBindingDeliverErrorString = exports.pageBindingDeliverResultString = exports.evaluationString = exports.isString = exports.removeEventListeners = exports.addEventListener = exports.releaseObject = exports.valueFromRemoteObject = exports.getExceptionMessage = void 0;
19
+ const assert_1 = require("./assert");
20
+ const Errors_1 = require("./Errors");
21
+ function getExceptionMessage(exceptionDetails) {
22
+ if (exceptionDetails.exception) {
23
+ return (exceptionDetails.exception.description || exceptionDetails.exception.value);
24
+ }
25
+ let message = exceptionDetails.text;
26
+ if (exceptionDetails.stackTrace) {
27
+ for (const callframe of exceptionDetails.stackTrace.callFrames) {
28
+ const location = callframe.url +
29
+ ':' +
30
+ callframe.lineNumber +
31
+ ':' +
32
+ callframe.columnNumber;
33
+ const functionName = callframe.functionName || '<anonymous>';
34
+ message += `\n at ${functionName} (${location})`;
35
+ }
36
+ }
37
+ return message;
38
+ }
39
+ exports.getExceptionMessage = getExceptionMessage;
40
+ function valueFromRemoteObject(remoteObject) {
41
+ (0, assert_1.assert)(!remoteObject.objectId, 'Cannot extract value when objectId is given');
42
+ if (remoteObject.unserializableValue) {
43
+ if (remoteObject.type === 'bigint' && typeof BigInt !== 'undefined') {
44
+ return BigInt(remoteObject.unserializableValue.replace('n', ''));
45
+ }
46
+ switch (remoteObject.unserializableValue) {
47
+ case '-0':
48
+ return -0;
49
+ case 'NaN':
50
+ return NaN;
51
+ case 'Infinity':
52
+ return Infinity;
53
+ case '-Infinity':
54
+ return -Infinity;
55
+ default:
56
+ throw new Error('Unsupported unserializable value: ' +
57
+ remoteObject.unserializableValue);
58
+ }
59
+ }
60
+ return remoteObject.value;
61
+ }
62
+ exports.valueFromRemoteObject = valueFromRemoteObject;
63
+ async function releaseObject(client, remoteObject) {
64
+ if (!remoteObject.objectId) {
65
+ return;
66
+ }
67
+ await client
68
+ .send('Runtime.releaseObject', { objectId: remoteObject.objectId })
69
+ .catch(() => {
70
+ // Exceptions might happen in case of a page been navigated or closed.
71
+ // Swallow these since they are harmless and we don't leak anything in this case.
72
+ });
73
+ }
74
+ exports.releaseObject = releaseObject;
75
+ function addEventListener(emitter, eventName, handler) {
76
+ emitter.on(eventName, handler);
77
+ return { emitter, eventName, handler };
78
+ }
79
+ exports.addEventListener = addEventListener;
80
+ function removeEventListeners(listeners) {
81
+ for (const listener of listeners) {
82
+ listener.emitter.removeListener(listener.eventName, listener.handler);
83
+ }
84
+ listeners.length = 0;
85
+ }
86
+ exports.removeEventListeners = removeEventListeners;
87
+ const isString = (obj) => {
88
+ return typeof obj === 'string' || obj instanceof String;
89
+ };
90
+ exports.isString = isString;
91
+ function evaluationString(fun, ...args) {
92
+ if ((0, exports.isString)(fun)) {
93
+ (0, assert_1.assert)(args.length === 0, 'Cannot evaluate a string with arguments');
94
+ return fun;
95
+ }
96
+ function serializeArgument(arg) {
97
+ if (Object.is(arg, undefined)) {
98
+ return 'undefined';
99
+ }
100
+ return JSON.stringify(arg);
101
+ }
102
+ return `(${fun})(${args.map(serializeArgument).join(',')})`;
103
+ }
104
+ exports.evaluationString = evaluationString;
105
+ function pageBindingDeliverResultString(name, seq, result) {
106
+ function deliverResult(_name, _seq, _result) {
107
+ window[_name].callbacks.get(_seq).resolve(_result);
108
+ window[_name].callbacks.delete(_seq);
109
+ }
110
+ return evaluationString(deliverResult, name, seq, result);
111
+ }
112
+ exports.pageBindingDeliverResultString = pageBindingDeliverResultString;
113
+ function pageBindingDeliverErrorString(name, seq, message, stack) {
114
+ function deliverError(_name, _seq, _message, _stack) {
115
+ const error = new Error(_message);
116
+ error.stack = _stack;
117
+ window[_name].callbacks.get(_seq).reject(error);
118
+ window[_name].callbacks.delete(_seq);
119
+ }
120
+ return evaluationString(deliverError, name, seq, message, stack);
121
+ }
122
+ exports.pageBindingDeliverErrorString = pageBindingDeliverErrorString;
123
+ function pageBindingDeliverErrorValueString(name, seq, value) {
124
+ function deliverErrorValue(_name, _seq, _value) {
125
+ window[_name].callbacks.get(_seq).reject(_value);
126
+ window[_name].callbacks.delete(_seq);
127
+ }
128
+ return evaluationString(deliverErrorValue, name, seq, value);
129
+ }
130
+ exports.pageBindingDeliverErrorValueString = pageBindingDeliverErrorValueString;
131
+ async function waitWithTimeout(promise, taskName, timeout) {
132
+ let reject;
133
+ const timeoutError = new Errors_1.TimeoutError(`waiting for ${taskName} failed: timeout ${timeout}ms exceeded`);
134
+ const timeoutPromise = new Promise((_res, rej) => {
135
+ reject = rej;
136
+ });
137
+ let timeoutTimer = null;
138
+ if (timeout) {
139
+ timeoutTimer = setTimeout(() => {
140
+ return reject(timeoutError);
141
+ }, timeout);
142
+ }
143
+ try {
144
+ return await Promise.race([promise, timeoutPromise]);
145
+ }
146
+ finally {
147
+ if (timeoutTimer) {
148
+ clearTimeout(timeoutTimer);
149
+ }
150
+ }
151
+ }
152
+ exports.waitWithTimeout = waitWithTimeout;
153
+ function isErrorLike(obj) {
154
+ return (typeof obj === 'object' && obj !== null && 'name' in obj && 'message' in obj);
155
+ }
156
+ exports.isErrorLike = isErrorLike;
157
+ function isErrnoException(obj) {
158
+ return (isErrorLike(obj) &&
159
+ ('errno' in obj || 'code' in obj || 'path' in obj || 'syscall' in obj));
160
+ }
161
+ exports.isErrnoException = isErrnoException;
@@ -7,8 +7,8 @@ const calculateFfmpegFilter = ({ asset, fps, durationInFrames, channels, assetDu
7
7
  if (channels === 0) {
8
8
  return null;
9
9
  }
10
- const assetTrimLeft = asset.trimLeft / fps;
11
- const assetTrimRight = (asset.trimLeft + asset.duration * asset.playbackRate) / fps;
10
+ const assetTrimLeft = (asset.trimLeft * asset.playbackRate) / fps;
11
+ const assetTrimRight = assetTrimLeft + (asset.duration * asset.playbackRate) / fps;
12
12
  return (0, stringify_ffmpeg_filter_1.stringifyFfmpegFilter)({
13
13
  channels,
14
14
  startInVideo: asset.startInVideo,
@@ -1,9 +1,10 @@
1
1
  import { Codec } from 'remotion';
2
- export declare const combineVideos: ({ files, filelistDir, output, onProgress, numberOfFrames, codec, }: {
2
+ export declare const combineVideos: ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, }: {
3
3
  files: string[];
4
4
  filelistDir: string;
5
5
  output: string;
6
6
  onProgress: (p: number) => void;
7
7
  numberOfFrames: number;
8
8
  codec: Codec;
9
+ fps: number;
9
10
  }) => Promise<void>;
@@ -11,13 +11,15 @@ const path_1 = require("path");
11
11
  const remotion_1 = require("remotion");
12
12
  const get_audio_codec_name_1 = require("./get-audio-codec-name");
13
13
  const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
14
- const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, }) => {
14
+ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, }) => {
15
15
  var _a;
16
16
  const fileList = files.map((p) => `file '${p}'`).join('\n');
17
17
  const fileListTxt = (0, path_1.join)(filelistDir, 'files.txt');
18
18
  (0, fs_1.writeFileSync)(fileListTxt, fileList);
19
19
  try {
20
20
  const task = (0, execa_1.default)('ffmpeg', [
21
+ remotion_1.Internals.isAudioCodec(codec) ? null : '-r',
22
+ remotion_1.Internals.isAudioCodec(codec) ? null : String(fps),
21
23
  '-f',
22
24
  'concat',
23
25
  '-safe',
@@ -28,6 +30,11 @@ const combineVideos = async ({ files, filelistDir, output, onProgress, numberOfF
28
30
  remotion_1.Internals.isAudioCodec(codec) ? null : 'copy',
29
31
  '-c:a',
30
32
  (0, get_audio_codec_name_1.getAudioCodecName)(codec),
33
+ // Set max bitrate up to 1024kbps, will choose lower if that's too much
34
+ '-b:a',
35
+ '512K',
36
+ codec === 'h264' ? '-movflags' : null,
37
+ codec === 'h264' ? 'faststart' : null,
31
38
  '-shortest',
32
39
  '-y',
33
40
  output,
@@ -1,6 +1,7 @@
1
1
  import { openBrowser } from './open-browser';
2
2
  declare type Await<T> = T extends PromiseLike<infer U> ? U : T;
3
- export declare const cycleBrowserTabs: (puppeteerInstance: Await<ReturnType<typeof openBrowser>>, concurrency: number) => {
3
+ declare type Browser = Await<ReturnType<typeof openBrowser>>;
4
+ export declare const cycleBrowserTabs: (puppeteerInstance: Browser, concurrency: number) => {
4
5
  stopCycling: () => void;
5
6
  };
6
7
  export {};
@@ -9,15 +9,21 @@ const cycleBrowserTabs = (puppeteerInstance, concurrency) => {
9
9
  }
10
10
  let interval = null;
11
11
  let i = 0;
12
+ let stopped = false;
12
13
  const set = () => {
13
14
  interval = setTimeout(() => {
14
15
  puppeteerInstance
15
16
  .pages()
16
17
  .then((pages) => {
17
- var _a, _b;
18
+ var _a;
19
+ if (pages.length === 0) {
20
+ return;
21
+ }
18
22
  const currentPage = pages[i % pages.length];
19
23
  i++;
20
- if (!((_b = (_a = currentPage === null || currentPage === void 0 ? void 0 : currentPage.isClosed) === null || _a === void 0 ? void 0 : _a.call(currentPage)) !== null && _b !== void 0 ? _b : true)) {
24
+ if (!((_a = currentPage === null || currentPage === void 0 ? void 0 : currentPage.isClosed) === null || _a === void 0 ? void 0 : _a.call(currentPage)) &&
25
+ !stopped &&
26
+ (currentPage === null || currentPage === void 0 ? void 0 : currentPage.url()) !== 'about:blank') {
21
27
  return currentPage.bringToFront();
22
28
  }
23
29
  })
@@ -33,6 +39,7 @@ const cycleBrowserTabs = (puppeteerInstance, concurrency) => {
33
39
  if (!interval) {
34
40
  return;
35
41
  }
42
+ stopped = true;
36
43
  return clearInterval(interval);
37
44
  },
38
45
  };
@@ -0,0 +1 @@
1
+ export declare const ensurePresentationTimestamps: (src: string) => Promise<unknown>;
@@ -0,0 +1,57 @@
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.ensurePresentationTimestamps = void 0;
7
+ const execa_1 = __importDefault(require("execa"));
8
+ const promises_1 = require("fs/promises");
9
+ const path_1 = __importDefault(require("path"));
10
+ const ensureFileHasPresentationTimestamp = {};
11
+ let callbacks = [];
12
+ const ensurePresentationTimestamps = async (src) => {
13
+ if (ensureFileHasPresentationTimestamp[src] === 'encoding') {
14
+ return new Promise((resolve) => {
15
+ callbacks.push({
16
+ src,
17
+ fn: () => resolve,
18
+ });
19
+ });
20
+ }
21
+ if (ensureFileHasPresentationTimestamp[src] === 'done') {
22
+ return;
23
+ }
24
+ ensureFileHasPresentationTimestamp[src] = 'encoding';
25
+ const parts = src.split(path_1.default.sep);
26
+ const output = parts
27
+ .map((p, i) => {
28
+ if (i === parts.length - 1) {
29
+ return `pts-${p}`;
30
+ }
31
+ return p;
32
+ })
33
+ .join(path_1.default.sep);
34
+ await (0, execa_1.default)('ffmpeg', [
35
+ '-i',
36
+ src,
37
+ '-fflags',
38
+ '+genpts+igndts',
39
+ '-vcodec',
40
+ 'copy',
41
+ '-acodec',
42
+ 'copy',
43
+ output,
44
+ '-y',
45
+ ]);
46
+ await (0, promises_1.unlink)(src);
47
+ await (0, promises_1.rename)(output, src);
48
+ callbacks = callbacks.filter((c) => {
49
+ if (c.src === src) {
50
+ c.fn();
51
+ return false;
52
+ }
53
+ return true;
54
+ });
55
+ ensureFileHasPresentationTimestamp[src] = 'done';
56
+ };
57
+ exports.ensurePresentationTimestamps = ensurePresentationTimestamps;
@@ -0,0 +1,11 @@
1
+ import { FfmpegExecutable } from 'remotion';
2
+ import { LastFrameOptions } from './last-frame-from-video-cache';
3
+ export declare const getLastFrameOfVideo: (options: LastFrameOptions) => Promise<Buffer>;
4
+ declare type Options = {
5
+ time: number;
6
+ src: string;
7
+ ffmpegExecutable: FfmpegExecutable;
8
+ ffprobeExecutable: FfmpegExecutable;
9
+ };
10
+ export declare const extractFrameFromVideo: (options: Options) => Promise<Buffer>;
11
+ export {};
@@ -0,0 +1,197 @@
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.extractFrameFromVideo = exports.getLastFrameOfVideo = void 0;
7
+ const execa_1 = __importDefault(require("execa"));
8
+ const remotion_1 = require("remotion");
9
+ const get_audio_channels_1 = require("./assets/get-audio-channels");
10
+ const ensure_presentation_timestamp_1 = require("./ensure-presentation-timestamp");
11
+ const frame_to_ffmpeg_timestamp_1 = require("./frame-to-ffmpeg-timestamp");
12
+ const is_beyond_last_frame_1 = require("./is-beyond-last-frame");
13
+ const last_frame_from_video_cache_1 = require("./last-frame-from-video-cache");
14
+ const p_limit_1 = require("./p-limit");
15
+ const lastFrameLimit = (0, p_limit_1.pLimit)(1);
16
+ const mainLimit = (0, p_limit_1.pLimit)(5);
17
+ // Uses no seeking, therefore the whole video has to be decoded. This is a last resort and should only happen
18
+ // if the video is corrupted
19
+ const getLastFrameOfVideoSlow = async ({ src, duration, ffmpegExecutable, }) => {
20
+ console.warn(`\nUsing a slow method to determine the last frame of ${src}. The render can be sped up by re-encoding the video properly.`);
21
+ const actualOffset = `-${duration * 1000}ms`;
22
+ const command = [
23
+ '-itsoffset',
24
+ actualOffset,
25
+ '-i',
26
+ src,
27
+ '-frames:v',
28
+ '1',
29
+ '-f',
30
+ 'image2pipe',
31
+ '-',
32
+ ];
33
+ const { stdout, stderr } = (0, execa_1.default)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : 'ffmpeg', command);
34
+ if (!stderr) {
35
+ throw new Error('unexpectedly did not get stderr');
36
+ }
37
+ if (!stdout) {
38
+ throw new Error('unexpectedly did not get stdout');
39
+ }
40
+ const stderrChunks = [];
41
+ const stdoutChunks = [];
42
+ const stdErrString = new Promise((resolve, reject) => {
43
+ stderr.on('data', (d) => stderrChunks.push(d));
44
+ stderr.on('error', (err) => reject(err));
45
+ stderr.on('end', () => resolve(Buffer.concat(stderrChunks).toString('utf-8')));
46
+ });
47
+ const stdoutChunk = new Promise((resolve, reject) => {
48
+ stdout.on('data', (d) => stdoutChunks.push(d));
49
+ stdout.on('error', (err) => reject(err));
50
+ stdout.on('end', () => resolve(Buffer.concat(stdoutChunks)));
51
+ });
52
+ const [stdErr, stdoutBuffer] = await Promise.all([stdErrString, stdoutChunk]);
53
+ const isEmpty = stdErr.includes('Output file is empty');
54
+ if (isEmpty) {
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 stdoutBuffer;
58
+ };
59
+ const getLastFrameOfVideoFastUnlimited = async (options) => {
60
+ const { ffmpegExecutable, ffprobeExecutable, offset, src } = options;
61
+ const fromCache = (0, last_frame_from_video_cache_1.getLastFrameFromCache)({ ...options, offset: 0 });
62
+ if (fromCache) {
63
+ return fromCache;
64
+ }
65
+ const { duration } = await (0, get_audio_channels_1.getAudioChannelsAndDuration)(src, ffprobeExecutable);
66
+ if (duration === null) {
67
+ throw new Error(`Could not determine the duration of ${src} using FFMPEG. The file is not supported.`);
68
+ }
69
+ if (offset > 40) {
70
+ const last = await getLastFrameOfVideoSlow({
71
+ duration,
72
+ ffmpegExecutable,
73
+ src,
74
+ });
75
+ return last;
76
+ }
77
+ const actualOffset = `${duration * 1000 - offset - 10}ms`;
78
+ const { stdout, stderr } = (0, execa_1.default)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : 'ffmpeg', [
79
+ '-ss',
80
+ actualOffset,
81
+ '-i',
82
+ src,
83
+ '-frames:v',
84
+ '1',
85
+ '-f',
86
+ 'image2pipe',
87
+ '-',
88
+ ]);
89
+ if (!stderr) {
90
+ throw new Error('unexpectedly did not get stderr');
91
+ }
92
+ if (!stdout) {
93
+ throw new Error('unexpectedly did not get stdout');
94
+ }
95
+ const stderrChunks = [];
96
+ const stdoutChunks = [];
97
+ const stdErrString = new Promise((resolve, reject) => {
98
+ stderr.on('data', (d) => stderrChunks.push(d));
99
+ stderr.on('error', (err) => reject(err));
100
+ stderr.on('end', () => resolve(Buffer.concat(stderrChunks).toString('utf-8')));
101
+ });
102
+ const stdoutChunk = new Promise((resolve, reject) => {
103
+ stdout.on('data', (d) => {
104
+ stdoutChunks.push(d);
105
+ });
106
+ stdout.on('error', (err) => {
107
+ reject(err);
108
+ });
109
+ stdout.on('end', () => {
110
+ resolve(Buffer.concat(stdoutChunks));
111
+ });
112
+ });
113
+ const [stdErr, stdoutBuffer] = await Promise.all([stdErrString, stdoutChunk]);
114
+ const isEmpty = stdErr.includes('Output file is empty');
115
+ if (isEmpty) {
116
+ const unlimited = await getLastFrameOfVideoFastUnlimited({
117
+ ffmpegExecutable,
118
+ offset: offset + 10,
119
+ src,
120
+ ffprobeExecutable,
121
+ });
122
+ return unlimited;
123
+ }
124
+ return stdoutBuffer;
125
+ };
126
+ const getLastFrameOfVideo = async (options) => {
127
+ const result = await lastFrameLimit(getLastFrameOfVideoFastUnlimited, options);
128
+ (0, last_frame_from_video_cache_1.setLastFrameInCache)(options, result);
129
+ return result;
130
+ };
131
+ exports.getLastFrameOfVideo = getLastFrameOfVideo;
132
+ const extractFrameFromVideoFn = async ({ time, src, ffmpegExecutable, ffprobeExecutable, }) => {
133
+ await (0, ensure_presentation_timestamp_1.ensurePresentationTimestamps)(src);
134
+ if ((0, is_beyond_last_frame_1.isBeyondLastFrame)(src, time)) {
135
+ const lastFrame = await (0, exports.getLastFrameOfVideo)({
136
+ ffmpegExecutable,
137
+ ffprobeExecutable,
138
+ offset: 0,
139
+ src,
140
+ });
141
+ return lastFrame;
142
+ }
143
+ const ffmpegTimestamp = (0, frame_to_ffmpeg_timestamp_1.frameToFfmpegTimestamp)(time);
144
+ const { stdout, stderr } = (0, execa_1.default)(ffmpegExecutable !== null && ffmpegExecutable !== void 0 ? ffmpegExecutable : 'ffmpeg', [
145
+ '-ss',
146
+ ffmpegTimestamp,
147
+ '-i',
148
+ src,
149
+ '-frames:v',
150
+ '1',
151
+ '-f',
152
+ 'image2pipe',
153
+ '-',
154
+ ], {
155
+ buffer: false,
156
+ });
157
+ if (!stderr) {
158
+ throw new Error('unexpectedly did not get stderr');
159
+ }
160
+ if (!stdout) {
161
+ throw new Error('unexpectedly did not get stdout');
162
+ }
163
+ const stdoutChunks = [];
164
+ const stderrChunks = [];
165
+ const stderrStringProm = new Promise((resolve, reject) => {
166
+ stderr.on('data', (d) => stderrChunks.push(d));
167
+ stderr.on('error', (err) => reject(err));
168
+ stderr.on('end', () => resolve(Buffer.concat(stderrChunks).toString('utf8')));
169
+ });
170
+ const stdoutBuffer = new Promise((resolve, reject) => {
171
+ stdout.on('data', (d) => stdoutChunks.push(d));
172
+ stdout.on('error', (err) => reject(err));
173
+ stdout.on('end', () => resolve(Buffer.concat(stdoutChunks)));
174
+ });
175
+ const [stderrStr, stdOut] = await Promise.all([
176
+ stderrStringProm,
177
+ stdoutBuffer,
178
+ ]);
179
+ if (stderrStr.includes('Output file is empty')) {
180
+ (0, is_beyond_last_frame_1.markAsBeyondLastFrame)(src, time);
181
+ const last = await (0, exports.getLastFrameOfVideo)({
182
+ ffmpegExecutable,
183
+ ffprobeExecutable,
184
+ offset: 0,
185
+ src,
186
+ });
187
+ return last;
188
+ }
189
+ return stdOut;
190
+ };
191
+ const extractFrameFromVideo = async (options) => {
192
+ const perf = remotion_1.Internals.perf.startPerfMeasure('extract-frame');
193
+ const res = await mainLimit(extractFrameFromVideoFn, options);
194
+ remotion_1.Internals.perf.stopPerfMeasure(perf);
195
+ return res;
196
+ };
197
+ exports.extractFrameFromVideo = extractFrameFromVideo;
@@ -0,0 +1 @@
1
+ export declare const frameToFfmpegTimestamp: (time: number) => string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.frameToFfmpegTimestamp = void 0;
4
+ const frameToFfmpegTimestamp = (time) => {
5
+ // We ceil because FFMPEG seeks to the closest frame BEFORE the position
6
+ return (Math.ceil(time * 1000000) / 1000).toFixed(3) + 'ms';
7
+ };
8
+ exports.frameToFfmpegTimestamp = frameToFfmpegTimestamp;
@@ -1,5 +1,5 @@
1
1
  import { Browser } from 'puppeteer-core';
2
- import { BrowserExecutable, TCompMetadata } from 'remotion';
2
+ import { BrowserExecutable, FfmpegExecutable, TCompMetadata } from 'remotion';
3
3
  import { BrowserLog } from './browser-log';
4
4
  import { ChromiumOptions } from './open-browser';
5
5
  declare type GetCompositionsConfig = {
@@ -10,6 +10,9 @@ declare type GetCompositionsConfig = {
10
10
  browserExecutable?: BrowserExecutable;
11
11
  timeoutInMilliseconds?: number;
12
12
  chromiumOptions?: ChromiumOptions;
13
+ ffmpegExecutable?: FfmpegExecutable;
14
+ ffprobeExecutable?: FfmpegExecutable;
15
+ port?: number | null;
13
16
  };
14
- export declare const getCompositions: (serveUrlOrWebpackUrl: string, config?: GetCompositionsConfig | undefined) => Promise<TCompMetadata[]>;
17
+ export declare const getCompositions: (serveUrlOrWebpackUrl: string, config?: GetCompositionsConfig) => Promise<TCompMetadata[]>;
15
18
  export {};