Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@remotion/renderer: Internal experiment allowing frames to be rendered in a different order #4830

Merged
merged 6 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/src/render-flows/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ export const renderVideoFlow = async ({

const puppeteerInstance = await browserInstance;
addCleanupCallback(`Closing browser instance`, () =>
puppeteerInstance.close(false, logLevel, indent),
puppeteerInstance.close({silent: false}),
);

const resolvedConcurrency = RenderInternals.resolveConcurrency(concurrency);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/render-flows/still.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export const renderStillFlow = async ({

const puppeteerInstance = await browserInstance;
addCleanupCallback(`Close browser`, () =>
puppeteerInstance.close(false, logLevel, indent),
puppeteerInstance.close({silent: false}),
);

const {compositionId, config, reason, argsAfterComposition} =
Expand Down
1 change: 1 addition & 0 deletions packages/it-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"test": "bun test src/rendering --run",
"testssr": "bun test src/ssr src/bundle src/templates src/monorepo --timeout 40000",
"testlambda": "exit 0",
"lint": "tsc -d",
"formatting": "prettier src --check"
},
"private": true,
Expand Down
1 change: 1 addition & 0 deletions packages/it-tests/props.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"flag":true}
11 changes: 9 additions & 2 deletions packages/it-tests/src/bundle/bundle-studio.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import path from 'path';
test('Bundle studio', async () => {
const browser = openBrowser('chrome');

const tab = await (await browser).newPage(() => null, 'info', false);
const tab = await (
await browser
).newPage({
context: () => null,
logLevel: 'info',
indent: false,
pageIndex: 0,
});
const folder = path.join(process.cwd(), '..', 'example', 'build');
const indexHtmlExists = existsSync(path.join(folder, 'index.html'));
if (!indexHtmlExists) {
Expand Down Expand Up @@ -42,6 +49,6 @@ test('Bundle studio', async () => {
});
expect(result.toString()).toBeGreaterThan(1);

await (await browser).close(false, 'info', false);
await (await browser).close({silent: false});
await close();
});
1 change: 1 addition & 0 deletions packages/it-tests/src/monorepo/go-package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ test('Go package should create the same payload as normal Lambda package', async
metadata: {
Author: 'Remotion',
},
apiKey: null,
});

expect(removeUndefined(parsed)).toEqual(removeUndefined(nativeVersion));
Expand Down
1 change: 1 addition & 0 deletions packages/it-tests/src/monorepo/php-package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class Semantic
metadata: {
Author: 'Remotion',
},
apiKey: null,
});
const jsonOutput = toParse.substring(0, toParse.lastIndexOf('}') + 1);
const parsedJson = JSON.parse(jsonOutput);
Expand Down
2 changes: 2 additions & 0 deletions packages/it-tests/src/monorepo/python-package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ test('Python package should create the same renderMedia payload as normal Lambda
metadata: {
Author: 'Lunar',
},
apiKey: null,
});
const jsonOutput = toParse.substring(0, toParse.lastIndexOf('}') + 1);
const parsedJson = JSON.parse(jsonOutput);
Expand Down Expand Up @@ -181,6 +182,7 @@ test('Python package should create the same renderStill payload as normal Lambda
dumpBrowserLogs: false,
quality: undefined,
forcePathStyle: false,
apiKey: null,
});
const jsonOutput = toParse.substring(0, toParse.lastIndexOf('}') + 1);
const {streamed: _, ...parsedJson} = JSON.parse(jsonOutput);
Expand Down
2 changes: 2 additions & 0 deletions packages/it-tests/src/rendering/rendering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ test("Should succeed to render an audio file that doesn't have any audio inputs"

test('Should render a still that uses the staticFile() API and should apply props', async () => {
const out = outputPath.replace('.mp4', '.png');
await Bun.write('props.json', JSON.stringify({flag: true}));
const task = await execa(
'pnpm',
[
Expand All @@ -470,6 +471,7 @@ test('Should render a still that uses the staticFile() API and should apply prop
],
{
cwd: path.join(process.cwd(), '..', 'example'),
// @ts-expect-error staticfile
env: {
REMOTION_FLAG: 'hi',
},
Expand Down
3 changes: 3 additions & 0 deletions packages/it-tests/src/size-benchmark/run-benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ export const runBenchmark = async ({
if (!fps) {
throw new Error('Could not get fps of video');
}
if (!dimensions) {
throw new Error('Could not get fps of video');
}

const output = `${os.tmpdir()}/output.mp4`;

Expand Down
2 changes: 1 addition & 1 deletion packages/it-tests/src/ssr/render-frames.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,5 @@ test('Legacy SSR way of rendering videos should still work', async () => {
expect(probe.stderr).toMatch(/Video: h264/);

RenderInternals.deleteDirectory(framesDir);
await puppeteerInstance.close(false, 'info', false);
await puppeteerInstance.close({silent: false});
});
4 changes: 2 additions & 2 deletions packages/it-tests/src/ssr/render-media.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ test('Render video with browser instance open', async () => {
puppeteerInstance,
metadata: {Author: 'Lunar'},
});
await puppeteerInstance.close(false, 'info', false);
await puppeteerInstance.close({silent: false});
expect(existsSync(outPath)).toBe(true);
});

Expand Down Expand Up @@ -99,7 +99,7 @@ test('should fail on invalid CRF', async () => {
);
}

await browserInstance.close(false, 'info', false);
await browserInstance.close({silent: false});
});

test('Render video to a buffer', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/it-tests/src/ssr/render-still.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ test('Render video with browser instance open', async () => {
puppeteerInstance,
});
expect(buffer).toBe(null);
await puppeteerInstance.close(false, 'info', false);
await puppeteerInstance.close({silent: false});
});

test('Render still with browser instance not open and legacy webpack config', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/lambda-php/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/renderer/src/browser-instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const browserInstances: HeadlessBrowser[] = [];
export const killAllBrowsers = async () => {
for (const browser of browserInstances) {
try {
await browser.close(true, 'info', false);
await browser.close({silent: true});
} catch {}
}
};
Expand Down
80 changes: 52 additions & 28 deletions packages/renderer/src/browser/Browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,31 @@ export class HeadlessBrowser extends EventEmitter {
}
}

newPage(
context: SourceMapGetter,
logLevel: LogLevel,
indent: boolean,
): Promise<Page> {
return this.#defaultContext.newPage(context, logLevel, indent);
newPage({
context,
logLevel,
indent,
pageIndex,
}: {
context: SourceMapGetter;
logLevel: LogLevel;
indent: boolean;
pageIndex: number;
}): Promise<Page> {
return this.#defaultContext.newPage({context, logLevel, indent, pageIndex});
}

async _createPageInContext(
context: SourceMapGetter,
logLevel: LogLevel,
indent: boolean,
): Promise<Page> {
async _createPageInContext({
context,
logLevel,
indent,
pageIndex,
}: {
context: SourceMapGetter;
logLevel: LogLevel;
indent: boolean;
pageIndex: number;
}): Promise<Page> {
const {
value: {targetId},
} = await this.connection.send('Target.createTarget', {
Expand All @@ -210,7 +222,12 @@ export class HeadlessBrowser extends EventEmitter {
throw new Error(`Failed to create target for page (id = ${targetId})`);
}

const page = await target.page(context, logLevel, indent);
const page = await target.page({
sourceMapGetter: context,
logLevel,
indent,
pageIndex,
});
if (!page) {
throw new Error(`Failed to create a page for context`);
}
Expand Down Expand Up @@ -256,10 +273,10 @@ export class HeadlessBrowser extends EventEmitter {
}
}

async pages(logLevel: LogLevel, indent: boolean): Promise<Page[]> {
async pages(): Promise<Page[]> {
const contextPages = await Promise.all(
this.browserContexts().map((context) => {
return context.pages(logLevel, indent);
return context.pages();
}),
);
// Flatten array.
Expand All @@ -268,13 +285,9 @@ export class HeadlessBrowser extends EventEmitter {
}, []);
}

async close(
silent: boolean,
logLevel: LogLevel,
indent: boolean,
): Promise<void> {
async close({silent}: {silent: boolean}): Promise<void> {
await this.runner.closeProcess();
(await this.pages(logLevel, indent)).forEach((page) => {
(await this.pages()).forEach((page) => {
page.emit(PageEmittedEvents.Disposed);
page.closed = true;
});
Expand Down Expand Up @@ -313,23 +326,34 @@ export class BrowserContext extends EventEmitter {
}, options);
}

async pages(logLevel: LogLevel, indent: boolean): Promise<Page[]> {
async pages(): Promise<Page[]> {
const pages = await Promise.all(
this.targets()
.filter((target) => target.type() === 'page')
.map((target) => target.page(() => null, logLevel, indent)),
.map((target) => target.expectPage()),
);
return pages.filter((page): page is Page => {
return Boolean(page);
});
}

newPage(
context: SourceMapGetter,
logLevel: LogLevel,
indent: boolean,
): Promise<Page> {
return this.#browser._createPageInContext(context, logLevel, indent);
newPage({
context,
logLevel,
indent,
pageIndex,
}: {
context: SourceMapGetter;
logLevel: LogLevel;
indent: boolean;
pageIndex: number;
}): Promise<Page> {
return this.#browser._createPageInContext({
context,
logLevel,
indent,
pageIndex,
});
}

browser(): HeadlessBrowser {
Expand Down
7 changes: 7 additions & 0 deletions packages/renderer/src/browser/BrowserPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export class Page extends EventEmitter {
sourceMapGetter,
logLevel,
indent,
pageIndex,
}: {
client: CDPSession;
target: Target;
Expand All @@ -105,6 +106,7 @@ export class Page extends EventEmitter {
sourceMapGetter: SourceMapGetter;
logLevel: LogLevel;
indent: boolean;
pageIndex: number;
}): Promise<Page> {
const page = new Page({
client,
Expand All @@ -113,6 +115,7 @@ export class Page extends EventEmitter {
sourceMapGetter,
logLevel,
indent,
pageIndex,
});
await page.#initialize();
await page.setViewport(defaultViewport);
Expand All @@ -130,6 +133,7 @@ export class Page extends EventEmitter {
screenshotTaskQueue: TaskQueue;
sourceMapGetter: SourceMapGetter;
logLevel: LogLevel;
pageIndex: number;

constructor({
client,
Expand All @@ -138,13 +142,15 @@ export class Page extends EventEmitter {
sourceMapGetter,
logLevel,
indent,
pageIndex,
}: {
client: CDPSession;
target: Target;
browser: HeadlessBrowser;
sourceMapGetter: SourceMapGetter;
logLevel: LogLevel;
indent: boolean;
pageIndex: number;
}) {
super();
this.#client = client;
Expand All @@ -155,6 +161,7 @@ export class Page extends EventEmitter {
this.id = String(Math.random());
this.sourceMapGetter = sourceMapGetter;
this.logLevel = logLevel;
this.pageIndex = pageIndex;

client.on('Target.attachedToTarget', (event: AttachedToTargetEvent) => {
switch (event.targetInfo.type) {
Expand Down
2 changes: 1 addition & 1 deletion packages/renderer/src/browser/Launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const launchChrome = async ({
{timeout},
);
} catch (error) {
await browser.close(false, logLevel, indent);
await browser.close({silent: false});
throw error;
}

Expand Down
21 changes: 16 additions & 5 deletions packages/renderer/src/browser/Target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,17 @@ export class Target {
/**
* If the target is not of type `"page"` or `"background_page"`, returns `null`.
*/
async page(
sourceMapGetter: SourceMapGetter,
logLevel: LogLevel,
indent: boolean,
): Promise<Page | null> {
async page({
sourceMapGetter,
logLevel,
indent,
pageIndex,
}: {
sourceMapGetter: SourceMapGetter;
logLevel: LogLevel;
indent: boolean;
pageIndex: number;
}): Promise<Page | null> {
if (isPagetTarget(this.#targetInfo) && !this.#pagePromise) {
this.#pagePromise = this.#sessionFactory().then((client) => {
return Page._create({
Expand All @@ -108,13 +114,18 @@ export class Target {
sourceMapGetter,
logLevel,
indent,
pageIndex,
});
});
}

return (await this.#pagePromise) ?? null;
}

async expectPage(): Promise<Page | null> {
return (await this.#pagePromise) ?? null;
}

url(): string {
return this.#targetInfo.url;
}
Expand Down
Loading
Loading