@remotion/renderer 4.0.45 → 4.0.47
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.
- package/LICENSE.md +1 -1
- package/dist/assets/calculate-asset-positions.js +1 -0
- package/dist/assets/types.d.ts +1 -0
- package/dist/audio-codec.d.ts +1 -1
- package/dist/audio-codec.js +7 -2
- package/dist/browser/Browser.d.ts +12 -2
- package/dist/browser/Browser.js +12 -7
- package/dist/browser/BrowserRunner.d.ts +2 -0
- package/dist/browser/BrowserRunner.js +22 -0
- package/dist/browser/Connection.d.ts +1 -0
- package/dist/browser/Connection.js +14 -15
- package/dist/browser/Launcher.js +2 -0
- package/dist/browser/NodeWebSocketTransport.d.ts +3 -1
- package/dist/browser/NodeWebSocketTransport.js +14 -20
- package/dist/calculate-ffmpeg-filters.js +1 -0
- package/dist/combine-videos.d.ts +1 -0
- package/dist/combine-videos.js +5 -4
- package/dist/index.d.ts +1 -0
- package/dist/locks.js +3 -0
- package/dist/puppeteer-evaluate.js +8 -2
- package/dist/set-props-and-env.js +8 -3
- package/dist/stitch-frames-to-video.js +4 -4
- package/dist/stringify-ffmpeg-filter.d.ts +2 -1
- package/dist/stringify-ffmpeg-filter.js +7 -1
- package/package.json +10 -10
package/LICENSE.md
CHANGED
|
@@ -38,4 +38,4 @@ Support is provided on a best-we-can-do basis via GitHub Issues and Discord.
|
|
|
38
38
|
|
|
39
39
|
You are required to obtain a company license to use Remotion if you are not within the group of entities eligible for a free license. This license will enable you to use Remotion for the allowed use cases specified in the free license, and give you access to prioritized support (read the [Support Policy](/docs/support)).
|
|
40
40
|
|
|
41
|
-
Visit [
|
|
41
|
+
Visit [remotion.pro](https://www.remotion.pro) for pricing and to buy a license.
|
|
@@ -43,6 +43,7 @@ const calculateAssetPositions = (frames) => {
|
|
|
43
43
|
volume: [],
|
|
44
44
|
playbackRate: asset.playbackRate,
|
|
45
45
|
allowAmplificationDuringRender: asset.allowAmplificationDuringRender,
|
|
46
|
+
toneFrequency: asset.toneFrequency,
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
const found = assets.find((a) => a.duration === null && areEqual(a, asset));
|
package/dist/assets/types.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type UnsafeAsset = Omit<TRenderAsset, 'frame' | 'id' | 'volume' | 'mediaF
|
|
|
7
7
|
id: string;
|
|
8
8
|
playbackRate: number;
|
|
9
9
|
allowAmplificationDuringRender: boolean;
|
|
10
|
+
toneFrequency: number | null;
|
|
10
11
|
};
|
|
11
12
|
export type AssetVolume = number | number[];
|
|
12
13
|
export type MediaAsset = Omit<UnsafeAsset, 'duration' | 'volume'> & {
|
package/dist/audio-codec.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare const supportedAudioCodecs: {
|
|
|
13
13
|
readonly vp9: readonly ["opus", "pcm-16"];
|
|
14
14
|
readonly wav: readonly ["pcm-16"];
|
|
15
15
|
};
|
|
16
|
-
declare const audioCodecNames: readonly ["pcm_s16le", "
|
|
16
|
+
declare const audioCodecNames: readonly ["pcm_s16le", "libfdk_aac", "libmp3lame", "libopus"];
|
|
17
17
|
type FfmpegAudioCodecName = (typeof audioCodecNames)[number];
|
|
18
18
|
export declare const mapAudioCodecToFfmpegAudioCodecName: (audioCodec: AudioCodec) => FfmpegAudioCodecName;
|
|
19
19
|
export declare const defaultAudioCodecs: {
|
package/dist/audio-codec.js
CHANGED
|
@@ -18,10 +18,15 @@ const _satisfies = exports.supportedAudioCodecs;
|
|
|
18
18
|
if (_satisfies) {
|
|
19
19
|
// Just for type checking
|
|
20
20
|
}
|
|
21
|
-
const audioCodecNames = [
|
|
21
|
+
const audioCodecNames = [
|
|
22
|
+
'pcm_s16le',
|
|
23
|
+
'libfdk_aac',
|
|
24
|
+
'libmp3lame',
|
|
25
|
+
'libopus',
|
|
26
|
+
];
|
|
22
27
|
const mapAudioCodecToFfmpegAudioCodecName = (audioCodec) => {
|
|
23
28
|
if (audioCodec === 'aac') {
|
|
24
|
-
return '
|
|
29
|
+
return 'libfdk_aac';
|
|
25
30
|
}
|
|
26
31
|
if (audioCodec === 'mp3') {
|
|
27
32
|
return 'libmp3lame';
|
|
@@ -32,14 +32,24 @@ export declare const enum BrowserEmittedEvents {
|
|
|
32
32
|
}
|
|
33
33
|
export declare class HeadlessBrowser extends EventEmitter {
|
|
34
34
|
#private;
|
|
35
|
-
static _create({ connection, defaultViewport, closeCallback, }: {
|
|
35
|
+
static _create({ connection, defaultViewport, closeCallback, forgetEventLoop, rememberEventLoop, }: {
|
|
36
36
|
connection: Connection;
|
|
37
37
|
defaultViewport: Viewport;
|
|
38
38
|
closeCallback: BrowserCloseCallback;
|
|
39
|
+
forgetEventLoop: () => void;
|
|
40
|
+
rememberEventLoop: () => void;
|
|
39
41
|
}): Promise<HeadlessBrowser>;
|
|
40
42
|
connection: Connection;
|
|
43
|
+
forgetEventLoop: () => void;
|
|
44
|
+
rememberEventLoop: () => void;
|
|
41
45
|
get _targets(): Map<string, Target>;
|
|
42
|
-
constructor(
|
|
46
|
+
constructor({ closeCallback, connection, defaultViewport, forgetEventLoop, rememberEventLoop, }: {
|
|
47
|
+
connection: Connection;
|
|
48
|
+
defaultViewport: Viewport;
|
|
49
|
+
closeCallback: BrowserCloseCallback;
|
|
50
|
+
forgetEventLoop: () => void;
|
|
51
|
+
rememberEventLoop: () => void;
|
|
52
|
+
});
|
|
43
53
|
browserContexts(): BrowserContext[];
|
|
44
54
|
newPage(context: Promise<AnySourceMapConsumer | null>, logLevel: LogLevel, indent: boolean): Promise<Page>;
|
|
45
55
|
_createPageInContext(context: Promise<AnySourceMapConsumer | null>, logLevel: LogLevel, indent: boolean): Promise<Page>;
|
package/dist/browser/Browser.js
CHANGED
|
@@ -33,15 +33,21 @@ const EventEmitter_1 = require("./EventEmitter");
|
|
|
33
33
|
const Target_1 = require("./Target");
|
|
34
34
|
const util_1 = require("./util");
|
|
35
35
|
class HeadlessBrowser extends EventEmitter_1.EventEmitter {
|
|
36
|
-
static async _create({ connection, defaultViewport, closeCallback, }) {
|
|
37
|
-
const browser = new HeadlessBrowser(
|
|
36
|
+
static async _create({ connection, defaultViewport, closeCallback, forgetEventLoop, rememberEventLoop, }) {
|
|
37
|
+
const browser = new HeadlessBrowser({
|
|
38
|
+
connection,
|
|
39
|
+
defaultViewport,
|
|
40
|
+
closeCallback,
|
|
41
|
+
forgetEventLoop,
|
|
42
|
+
rememberEventLoop,
|
|
43
|
+
});
|
|
38
44
|
await connection.send('Target.setDiscoverTargets', { discover: true });
|
|
39
45
|
return browser;
|
|
40
46
|
}
|
|
41
47
|
get _targets() {
|
|
42
48
|
return __classPrivateFieldGet(this, _HeadlessBrowser_targets, "f");
|
|
43
49
|
}
|
|
44
|
-
constructor(connection, defaultViewport,
|
|
50
|
+
constructor({ closeCallback, connection, defaultViewport, forgetEventLoop, rememberEventLoop, }) {
|
|
45
51
|
super();
|
|
46
52
|
_HeadlessBrowser_instances.add(this);
|
|
47
53
|
_HeadlessBrowser_defaultViewport.set(this, void 0);
|
|
@@ -51,16 +57,15 @@ class HeadlessBrowser extends EventEmitter_1.EventEmitter {
|
|
|
51
57
|
_HeadlessBrowser_targets.set(this, void 0);
|
|
52
58
|
__classPrivateFieldSet(this, _HeadlessBrowser_defaultViewport, defaultViewport, "f");
|
|
53
59
|
this.connection = connection;
|
|
54
|
-
__classPrivateFieldSet(this, _HeadlessBrowser_closeCallback, closeCallback
|
|
55
|
-
function () {
|
|
56
|
-
return undefined;
|
|
57
|
-
}, "f");
|
|
60
|
+
__classPrivateFieldSet(this, _HeadlessBrowser_closeCallback, closeCallback, "f");
|
|
58
61
|
__classPrivateFieldSet(this, _HeadlessBrowser_defaultContext, new BrowserContext(this), "f");
|
|
59
62
|
__classPrivateFieldSet(this, _HeadlessBrowser_contexts, new Map(), "f");
|
|
60
63
|
__classPrivateFieldSet(this, _HeadlessBrowser_targets, new Map(), "f");
|
|
61
64
|
this.connection.on('Target.targetCreated', __classPrivateFieldGet(this, _HeadlessBrowser_instances, "m", _HeadlessBrowser_targetCreated).bind(this));
|
|
62
65
|
this.connection.on('Target.targetDestroyed', __classPrivateFieldGet(this, _HeadlessBrowser_instances, "m", _HeadlessBrowser_targetDestroyed).bind(this));
|
|
63
66
|
this.connection.on('Target.targetInfoChanged', __classPrivateFieldGet(this, _HeadlessBrowser_instances, "m", _HeadlessBrowser_targetInfoChanged).bind(this));
|
|
67
|
+
this.forgetEventLoop = forgetEventLoop;
|
|
68
|
+
this.rememberEventLoop = rememberEventLoop;
|
|
64
69
|
}
|
|
65
70
|
browserContexts() {
|
|
66
71
|
return [__classPrivateFieldGet(this, _HeadlessBrowser_defaultContext, "f"), ...Array.from(__classPrivateFieldGet(this, _HeadlessBrowser_contexts, "f").values())];
|
|
@@ -153,6 +153,28 @@ class BrowserRunner {
|
|
|
153
153
|
(0, util_1.removeEventListeners)(__classPrivateFieldGet(this, _BrowserRunner_listeners, "f"));
|
|
154
154
|
return __classPrivateFieldGet(this, _BrowserRunner_processClosing, "f");
|
|
155
155
|
}
|
|
156
|
+
forgetEventLoop() {
|
|
157
|
+
var _a, _b;
|
|
158
|
+
(0, assert_1.assert)(this.proc, 'BrowserRunner not started.');
|
|
159
|
+
this.proc.unref();
|
|
160
|
+
// @ts-expect-error
|
|
161
|
+
(_a = this.proc.stdout) === null || _a === void 0 ? void 0 : _a.unref();
|
|
162
|
+
// @ts-expect-error
|
|
163
|
+
(_b = this.proc.stderr) === null || _b === void 0 ? void 0 : _b.unref();
|
|
164
|
+
(0, assert_1.assert)(this.connection, 'BrowserRunner not connected.');
|
|
165
|
+
this.connection.transport.forgetEventLoop();
|
|
166
|
+
}
|
|
167
|
+
rememberEventLoop() {
|
|
168
|
+
var _a, _b;
|
|
169
|
+
(0, assert_1.assert)(this.proc, 'BrowserRunner not started.');
|
|
170
|
+
this.proc.ref();
|
|
171
|
+
// @ts-expect-error
|
|
172
|
+
(_a = this.proc.stdout) === null || _a === void 0 ? void 0 : _a.ref();
|
|
173
|
+
// @ts-expect-error
|
|
174
|
+
(_b = this.proc.stderr) === null || _b === void 0 ? void 0 : _b.ref();
|
|
175
|
+
(0, assert_1.assert)(this.connection, 'BrowserRunner not connected.');
|
|
176
|
+
this.connection.transport.rememberEventLoop();
|
|
177
|
+
}
|
|
156
178
|
kill() {
|
|
157
179
|
var _a;
|
|
158
180
|
// If the process failed to launch (for example if the browser executable path
|
|
@@ -4,6 +4,7 @@ import { EventEmitter } from './EventEmitter';
|
|
|
4
4
|
import type { NodeWebSocketTransport } from './NodeWebSocketTransport';
|
|
5
5
|
export declare class Connection extends EventEmitter {
|
|
6
6
|
#private;
|
|
7
|
+
transport: NodeWebSocketTransport;
|
|
7
8
|
constructor(transport: NodeWebSocketTransport);
|
|
8
9
|
static fromSession(session: CDPSession): Connection | undefined;
|
|
9
10
|
session(sessionId: string): CDPSession | null;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
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");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
2
7
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
8
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
9
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
11
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
12
|
};
|
|
8
|
-
var
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
-
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");
|
|
11
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
|
-
var _Connection_instances, _Connection_transport, _Connection_lastId, _Connection_sessions, _Connection_closed, _Connection_callbacks, _Connection_onMessage, _Connection_onClose, _CDPSession_sessionId, _CDPSession_targetType, _CDPSession_callbacks, _CDPSession_connection;
|
|
13
|
+
var _Connection_instances, _Connection_lastId, _Connection_sessions, _Connection_closed, _Connection_callbacks, _Connection_onMessage, _Connection_onClose, _CDPSession_sessionId, _CDPSession_targetType, _CDPSession_callbacks, _CDPSession_connection;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.CDPSession = exports.CDPSessionEmittedEvents = exports.Connection = void 0;
|
|
16
16
|
/**
|
|
@@ -38,14 +38,13 @@ class Connection extends EventEmitter_1.EventEmitter {
|
|
|
38
38
|
constructor(transport) {
|
|
39
39
|
super();
|
|
40
40
|
_Connection_instances.add(this);
|
|
41
|
-
_Connection_transport.set(this, void 0);
|
|
42
41
|
_Connection_lastId.set(this, 0);
|
|
43
42
|
_Connection_sessions.set(this, new Map());
|
|
44
43
|
_Connection_closed.set(this, false);
|
|
45
44
|
_Connection_callbacks.set(this, new Map());
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
this.transport = transport;
|
|
46
|
+
this.transport.onmessage = __classPrivateFieldGet(this, _Connection_instances, "m", _Connection_onMessage).bind(this);
|
|
47
|
+
this.transport.onclose = __classPrivateFieldGet(this, _Connection_instances, "m", _Connection_onClose).bind(this);
|
|
49
48
|
}
|
|
50
49
|
static fromSession(session) {
|
|
51
50
|
return session.connection();
|
|
@@ -75,12 +74,12 @@ class Connection extends EventEmitter_1.EventEmitter {
|
|
|
75
74
|
var _a;
|
|
76
75
|
const id = __classPrivateFieldSet(this, _Connection_lastId, (_a = __classPrivateFieldGet(this, _Connection_lastId, "f"), ++_a), "f");
|
|
77
76
|
const stringifiedMessage = JSON.stringify({ ...message, id });
|
|
78
|
-
|
|
77
|
+
this.transport.send(stringifiedMessage);
|
|
79
78
|
return id;
|
|
80
79
|
}
|
|
81
80
|
dispose() {
|
|
82
81
|
__classPrivateFieldGet(this, _Connection_instances, "m", _Connection_onClose).call(this);
|
|
83
|
-
|
|
82
|
+
this.transport.close();
|
|
84
83
|
}
|
|
85
84
|
/**
|
|
86
85
|
* @param targetInfo - The target info
|
|
@@ -99,7 +98,7 @@ class Connection extends EventEmitter_1.EventEmitter {
|
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
exports.Connection = Connection;
|
|
102
|
-
|
|
101
|
+
_Connection_lastId = new WeakMap(), _Connection_sessions = new WeakMap(), _Connection_closed = new WeakMap(), _Connection_callbacks = new WeakMap(), _Connection_instances = new WeakSet(), _Connection_onMessage = function _Connection_onMessage(message) {
|
|
103
102
|
const object = JSON.parse(message);
|
|
104
103
|
if (object.method === 'Target.attachedToTarget') {
|
|
105
104
|
const { sessionId } = object.params;
|
|
@@ -152,8 +151,8 @@ _Connection_transport = new WeakMap(), _Connection_lastId = new WeakMap(), _Conn
|
|
|
152
151
|
if (__classPrivateFieldGet(this, _Connection_closed, "f")) {
|
|
153
152
|
return;
|
|
154
153
|
}
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
this.transport.onmessage = undefined;
|
|
155
|
+
this.transport.onclose = undefined;
|
|
157
156
|
for (const callback of __classPrivateFieldGet(this, _Connection_callbacks, "f").values()) {
|
|
158
157
|
callback.reject(rewriteError(new Errors_1.ProtocolError(), `Protocol error (${callback.method}): Target closed. https://www.remotion.dev/docs/target-closed`));
|
|
159
158
|
}
|
package/dist/browser/Launcher.js
CHANGED
|
@@ -6,12 +6,14 @@ interface ConnectionTransport {
|
|
|
6
6
|
onclose?: () => void;
|
|
7
7
|
}
|
|
8
8
|
export declare class NodeWebSocketTransport implements ConnectionTransport {
|
|
9
|
-
#private;
|
|
10
9
|
static create(urlString: string): Promise<NodeWebSocketTransport>;
|
|
10
|
+
websocket: WS;
|
|
11
11
|
onmessage?: (message: string) => void;
|
|
12
12
|
onclose?: () => void;
|
|
13
13
|
constructor(ws: WS);
|
|
14
14
|
send(message: string): void;
|
|
15
15
|
close(): void;
|
|
16
|
+
forgetEventLoop(): void;
|
|
17
|
+
rememberEventLoop(): void;
|
|
16
18
|
}
|
|
17
19
|
export {};
|
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
-
};
|
|
8
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
-
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");
|
|
11
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
|
-
var _NodeWebSocketTransport_ws;
|
|
14
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
3
|
exports.NodeWebSocketTransport = void 0;
|
|
16
4
|
/**
|
|
@@ -61,27 +49,33 @@ class NodeWebSocketTransport {
|
|
|
61
49
|
});
|
|
62
50
|
}
|
|
63
51
|
constructor(ws) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
__classPrivateFieldGet(this, _NodeWebSocketTransport_ws, "f").addEventListener('message', (event) => {
|
|
52
|
+
this.websocket = ws;
|
|
53
|
+
this.websocket.addEventListener('message', (event) => {
|
|
67
54
|
if (this.onmessage) {
|
|
68
55
|
this.onmessage.call(null, event.data);
|
|
69
56
|
}
|
|
70
57
|
});
|
|
71
|
-
|
|
58
|
+
this.websocket.addEventListener('close', () => {
|
|
72
59
|
if (this.onclose) {
|
|
73
60
|
this.onclose.call(null);
|
|
74
61
|
}
|
|
75
62
|
});
|
|
76
63
|
// Silently ignore all errors - we don't know what to do with them.
|
|
77
|
-
|
|
64
|
+
this.websocket.addEventListener('error', () => undefined);
|
|
78
65
|
}
|
|
79
66
|
send(message) {
|
|
80
|
-
|
|
67
|
+
this.websocket.send(message);
|
|
81
68
|
}
|
|
82
69
|
close() {
|
|
83
|
-
|
|
70
|
+
this.websocket.close();
|
|
71
|
+
}
|
|
72
|
+
forgetEventLoop() {
|
|
73
|
+
// @ts-expect-error
|
|
74
|
+
this.websocket._socket.unref();
|
|
75
|
+
}
|
|
76
|
+
rememberEventLoop() {
|
|
77
|
+
// @ts-expect-error
|
|
78
|
+
this.websocket._socket.ref();
|
|
84
79
|
}
|
|
85
80
|
}
|
|
86
81
|
exports.NodeWebSocketTransport = NodeWebSocketTransport;
|
|
87
|
-
_NodeWebSocketTransport_ws = new WeakMap();
|
|
@@ -20,6 +20,7 @@ const calculateFfmpegFilter = ({ asset, fps, durationInFrames, channels, assetDu
|
|
|
20
20
|
durationInFrames,
|
|
21
21
|
assetDuration,
|
|
22
22
|
allowAmplificationDuringRender: asset.allowAmplificationDuringRender,
|
|
23
|
+
toneFrequency: asset.toneFrequency,
|
|
23
24
|
});
|
|
24
25
|
};
|
|
25
26
|
exports.calculateFfmpegFilter = calculateFfmpegFilter;
|
package/dist/combine-videos.d.ts
CHANGED
package/dist/combine-videos.js
CHANGED
|
@@ -12,7 +12,7 @@ const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
|
12
12
|
const truthy_1 = require("./truthy");
|
|
13
13
|
const combineVideos = async (options) => {
|
|
14
14
|
var _a;
|
|
15
|
-
const { files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, audioCodec, } = options;
|
|
15
|
+
const { files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, audioCodec, audioBitrate, } = options;
|
|
16
16
|
const fileList = files.map((p) => `file '${p}'`).join('\n');
|
|
17
17
|
const fileListTxt = (0, node_path_1.join)(filelistDir, 'files.txt');
|
|
18
18
|
(0, node_fs_1.writeFileSync)(fileListTxt, fileList);
|
|
@@ -38,9 +38,10 @@ const combineVideos = async (options) => {
|
|
|
38
38
|
resolvedAudioCodec
|
|
39
39
|
? (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec)
|
|
40
40
|
: null,
|
|
41
|
-
|
|
41
|
+
resolvedAudioCodec === 'aac' ? '-cutoff' : null,
|
|
42
|
+
resolvedAudioCodec === 'aac' ? '18000' : null,
|
|
42
43
|
'-b:a',
|
|
43
|
-
'
|
|
44
|
+
audioBitrate ? audioBitrate : '320k',
|
|
44
45
|
codec === 'h264' ? '-movflags' : null,
|
|
45
46
|
codec === 'h264' ? 'faststart' : null,
|
|
46
47
|
'-y',
|
|
@@ -56,7 +57,7 @@ const combineVideos = async (options) => {
|
|
|
56
57
|
logger_1.Log.verbose(data.toString('utf8'));
|
|
57
58
|
}
|
|
58
59
|
else {
|
|
59
|
-
logger_1.Log.verbose(parsed);
|
|
60
|
+
logger_1.Log.verbose(`Combined ${parsed} frames`);
|
|
60
61
|
onProgress(parsed);
|
|
61
62
|
}
|
|
62
63
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -152,6 +152,7 @@ export declare const RenderInternals: {
|
|
|
152
152
|
fps: number;
|
|
153
153
|
numberOfGifLoops: number | null;
|
|
154
154
|
audioCodec: "mp3" | "aac" | "pcm-16" | "opus" | null;
|
|
155
|
+
audioBitrate: string | null;
|
|
155
156
|
}) => Promise<void>;
|
|
156
157
|
getMinConcurrency: () => number;
|
|
157
158
|
getMaxConcurrency: () => number;
|
package/dist/locks.js
CHANGED
|
@@ -26,9 +26,10 @@ function valueFromRemoteObject(remoteObject) {
|
|
|
26
26
|
return remoteObject.value;
|
|
27
27
|
}
|
|
28
28
|
function puppeteerEvaluateWithCatchAndTimeout({ args, frame, page, pageFunction, }) {
|
|
29
|
+
let timeout = null;
|
|
29
30
|
return Promise.race([
|
|
30
31
|
new Promise((_, reject) => {
|
|
31
|
-
setTimeout(() => {
|
|
32
|
+
timeout = setTimeout(() => {
|
|
32
33
|
reject(new Error(
|
|
33
34
|
// This means the page is not responding anymore
|
|
34
35
|
// This error message is retryable - sync it with packages/lambda/src/shared/is-flaky-error.ts
|
|
@@ -41,7 +42,12 @@ function puppeteerEvaluateWithCatchAndTimeout({ args, frame, page, pageFunction,
|
|
|
41
42
|
page,
|
|
42
43
|
pageFunction,
|
|
43
44
|
}),
|
|
44
|
-
])
|
|
45
|
+
]).then((data) => {
|
|
46
|
+
if (timeout !== null) {
|
|
47
|
+
clearTimeout(timeout);
|
|
48
|
+
}
|
|
49
|
+
return data;
|
|
50
|
+
});
|
|
45
51
|
}
|
|
46
52
|
exports.puppeteerEvaluateWithCatchAndTimeout = puppeteerEvaluateWithCatchAndTimeout;
|
|
47
53
|
async function puppeteerEvaluateWithCatch({ page, pageFunction, frame, args, }) {
|
|
@@ -150,14 +150,19 @@ const innerSetPropsAndEnv = async ({ serializedInputPropsWithCustomSchema, envVa
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
|
-
const setPropsAndEnv = (params) => {
|
|
154
|
-
|
|
153
|
+
const setPropsAndEnv = async (params) => {
|
|
154
|
+
let timeout = null;
|
|
155
|
+
const result = await Promise.race([
|
|
155
156
|
innerSetPropsAndEnv(params),
|
|
156
157
|
new Promise((_, reject) => {
|
|
157
|
-
setTimeout(() => {
|
|
158
|
+
timeout = setTimeout(() => {
|
|
158
159
|
reject(new Error(`Timed out after ${params.timeoutInMilliseconds} while setting up the headless browser. This could be because the you specified takes a long time to load (or network resources that it includes like fonts) or because the browser is not responding. Optimize the site or increase the browser timeout.`));
|
|
159
160
|
}, params.timeoutInMilliseconds);
|
|
160
161
|
}),
|
|
161
162
|
]);
|
|
163
|
+
if (timeout !== null) {
|
|
164
|
+
clearTimeout(timeout);
|
|
165
|
+
}
|
|
166
|
+
return result;
|
|
162
167
|
};
|
|
163
168
|
exports.setPropsAndEnv = setPropsAndEnv;
|
|
@@ -193,9 +193,8 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec,
|
|
|
193
193
|
audio,
|
|
194
194
|
'-c:a',
|
|
195
195
|
(0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec),
|
|
196
|
-
// Set bitrate up to 320k, for aac it might effectively be lower
|
|
197
196
|
'-b:a',
|
|
198
|
-
audioBitrate
|
|
197
|
+
audioBitrate ? audioBitrate : '320k',
|
|
199
198
|
force ? '-y' : null,
|
|
200
199
|
outputLocation !== null && outputLocation !== void 0 ? outputLocation : tempFile,
|
|
201
200
|
].filter(remotion_1.Internals.truthy));
|
|
@@ -254,8 +253,9 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec,
|
|
|
254
253
|
resolvedAudioCodec
|
|
255
254
|
? ['-c:a', (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec)]
|
|
256
255
|
: null,
|
|
257
|
-
|
|
258
|
-
resolvedAudioCodec
|
|
256
|
+
resolvedAudioCodec ? ['-b:a', audioBitrate || '320k'] : null,
|
|
257
|
+
resolvedAudioCodec === 'aac' ? '-cutoff' : null,
|
|
258
|
+
resolvedAudioCodec === 'aac' ? '18000' : null,
|
|
259
259
|
// Ignore metadata that may come from remote media
|
|
260
260
|
['-map_metadata', '-1'],
|
|
261
261
|
[
|
|
@@ -6,7 +6,7 @@ export type ProcessedTrack = {
|
|
|
6
6
|
pad_start: string | null;
|
|
7
7
|
pad_end: string | null;
|
|
8
8
|
};
|
|
9
|
-
export declare const stringifyFfmpegFilter: ({ trimLeft, trimRight, channels, startInVideo, volume, fps, playbackRate, durationInFrames, assetDuration, allowAmplificationDuringRender, }: {
|
|
9
|
+
export declare const stringifyFfmpegFilter: ({ trimLeft, trimRight, channels, startInVideo, volume, fps, playbackRate, durationInFrames, assetDuration, allowAmplificationDuringRender, toneFrequency, }: {
|
|
10
10
|
trimLeft: number;
|
|
11
11
|
trimRight: number;
|
|
12
12
|
channels: number;
|
|
@@ -17,4 +17,5 @@ export declare const stringifyFfmpegFilter: ({ trimLeft, trimRight, channels, st
|
|
|
17
17
|
playbackRate: number;
|
|
18
18
|
assetDuration: number | null;
|
|
19
19
|
allowAmplificationDuringRender: boolean;
|
|
20
|
+
toneFrequency: number | null;
|
|
20
21
|
}) => FilterWithoutPaddingApplied | null;
|
|
@@ -5,11 +5,14 @@ const calculate_atempo_1 = require("./assets/calculate-atempo");
|
|
|
5
5
|
const ffmpeg_volume_expression_1 = require("./assets/ffmpeg-volume-expression");
|
|
6
6
|
const sample_rate_1 = require("./sample-rate");
|
|
7
7
|
const truthy_1 = require("./truthy");
|
|
8
|
-
const stringifyFfmpegFilter = ({ trimLeft, trimRight, channels, startInVideo, volume, fps, playbackRate, durationInFrames, assetDuration, allowAmplificationDuringRender, }) => {
|
|
8
|
+
const stringifyFfmpegFilter = ({ trimLeft, trimRight, channels, startInVideo, volume, fps, playbackRate, durationInFrames, assetDuration, allowAmplificationDuringRender, toneFrequency, }) => {
|
|
9
9
|
const startInVideoSeconds = startInVideo / fps;
|
|
10
10
|
if (assetDuration && trimLeft >= assetDuration) {
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
|
+
if (toneFrequency !== null && (toneFrequency <= 0 || toneFrequency > 2)) {
|
|
14
|
+
throw new Error('toneFrequency must be a positive number between 0.01 and 2');
|
|
15
|
+
}
|
|
13
16
|
const volumeFilter = (0, ffmpeg_volume_expression_1.ffmpegVolumeExpression)({
|
|
14
17
|
volume,
|
|
15
18
|
fps,
|
|
@@ -37,6 +40,9 @@ const stringifyFfmpegFilter = ({ trimLeft, trimRight, channels, startInVideo, vo
|
|
|
37
40
|
volumeFilter.value === '1'
|
|
38
41
|
? null
|
|
39
42
|
: `volume=${volumeFilter.value}:eval=${volumeFilter.eval}`,
|
|
43
|
+
toneFrequency && toneFrequency !== 1
|
|
44
|
+
? `asetrate=${sample_rate_1.DEFAULT_SAMPLE_RATE}*${toneFrequency},aresample=${sample_rate_1.DEFAULT_SAMPLE_RATE},atempo=1/${toneFrequency}`
|
|
45
|
+
: null,
|
|
40
46
|
// For n channels, we delay n + 1 channels.
|
|
41
47
|
// This is because `ffprobe` for some audio files reports the wrong amount
|
|
42
48
|
// of channels.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/renderer",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.47",
|
|
4
4
|
"description": "Renderer for Remotion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
"extract-zip": "2.0.1",
|
|
19
19
|
"source-map": "^0.8.0-beta.0",
|
|
20
20
|
"ws": "8.7.0",
|
|
21
|
-
"remotion": "4.0.
|
|
21
|
+
"remotion": "4.0.47"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"react": ">=16.8.0",
|
|
25
25
|
"react-dom": ">=16.8.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@jonny/eslint-config": "3.0.
|
|
28
|
+
"@jonny/eslint-config": "3.0.276",
|
|
29
29
|
"@testing-library/dom": "^8.16.0",
|
|
30
30
|
"@testing-library/react": "13.3.0",
|
|
31
31
|
"@types/node": "18.14.6",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"vitest": "0.31.1"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|
|
43
|
-
"@remotion/compositor-darwin-arm64": "4.0.
|
|
44
|
-
"@remotion/compositor-darwin-x64": "4.0.
|
|
45
|
-
"@remotion/compositor-linux-arm64-gnu": "4.0.
|
|
46
|
-
"@remotion/compositor-linux-arm64-musl": "4.0.
|
|
47
|
-
"@remotion/compositor-linux-x64-gnu": "4.0.
|
|
48
|
-
"@remotion/compositor-linux-x64-musl": "4.0.
|
|
49
|
-
"@remotion/compositor-win32-x64-msvc": "4.0.
|
|
43
|
+
"@remotion/compositor-darwin-arm64": "4.0.47",
|
|
44
|
+
"@remotion/compositor-darwin-x64": "4.0.47",
|
|
45
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.47",
|
|
46
|
+
"@remotion/compositor-linux-arm64-musl": "4.0.47",
|
|
47
|
+
"@remotion/compositor-linux-x64-gnu": "4.0.47",
|
|
48
|
+
"@remotion/compositor-linux-x64-musl": "4.0.47",
|
|
49
|
+
"@remotion/compositor-win32-x64-msvc": "4.0.47"
|
|
50
50
|
},
|
|
51
51
|
"keywords": [
|
|
52
52
|
"remotion",
|