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

feat(render-still): handle negativ frame index #1364

Merged
merged 5 commits into from
Oct 4, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/docs/docs/cli/still.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ Specify a location for a dotenv file. Default `.env`.

### `--frame`

Which frame should be rendered. Example `--frame=10`. Default `0`.
Which frame should be rendered. Example `--frame=10`. Default `0`.
From v3.2.26, negative values are allowed, with `-1` being the last frame.

### `--bundle-cache`

Expand Down
4 changes: 3 additions & 1 deletion packages/docs/docs/lambda/renderstillonlambda.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ One of:

_optional - default `0`_

Which frame of the composition should be rendered.
Which frame of the composition should be rendered. Frames are zero-indexed.

From v3.2.26, negative values are allowed, with `-1` being the last frame.

### `imageFormat?`

Expand Down
4 changes: 3 additions & 1 deletion packages/docs/docs/renderer/render-still.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ _optional_

_optional - default: 0_

Which frame should be rendered based on its number.
Which frame should be rendered based on its number. Frames are zero-indexed.

From v3.2.26, negative values are allowed, with `-1` being the last frame.

### `imageFormat?`

Expand Down
Binary file not shown.
5 changes: 4 additions & 1 deletion packages/lambda/src/functions/still.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ const innerStillHandler = async (
serveUrl: lambdaParams.serveUrl,
dumpBrowserLogs: false,
envVariables: lambdaParams.envVariables,
frame: lambdaParams.frame,
frame: RenderInternals.convertToPositiveFrameIndex({
frame: lambdaParams.frame,
durationInFrames: composition.durationInFrames,
}),
imageFormat: lambdaParams.imageFormat as StillImageFormat,
inputProps: lambdaParams.inputProps,
overwrite: false,
Expand Down
10 changes: 10 additions & 0 deletions packages/renderer/src/convert-to-positive-frame-index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Handle negative indices (e.g. -1 being the last frame)
export const convertToPositiveFrameIndex = ({
frame,
durationInFrames,
}: {
frame: number;
durationInFrames: number;
}) => {
return frame < 0 ? durationInFrames - frame : frame;
};
2 changes: 2 additions & 0 deletions packages/renderer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {DEFAULT_BROWSER} from './browser';
import {DEFAULT_TIMEOUT} from './browser/TimeoutSettings';
import {canUseParallelEncoding} from './can-use-parallel-encoding';
import {DEFAULT_CODEC, validCodecs} from './codec';
import {convertToPositiveFrameIndex} from './convert-to-positive-frame-index';
import {
getDefaultCrfForCodec,
getValidCrfRanges,
Expand Down Expand Up @@ -165,4 +166,5 @@ export const RenderInternals = {
perf,
makeDownloadMap,
cleanDownloadMap,
convertToPositiveFrameIndex,
};
11 changes: 8 additions & 3 deletions packages/renderer/src/render-still.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {cleanDownloadMap, makeDownloadMap} from './assets/download-map';
import {DEFAULT_BROWSER} from './browser';
import type {BrowserExecutable} from './browser-executable';
import type {Browser as PuppeteerBrowser} from './browser/Browser';
import {convertToPositiveFrameIndex} from './convert-to-positive-frame-index';
import {ensureOutputDirectory} from './ensure-output-directory';
import {handleJavascriptException} from './error-handling/handle-javascript-exception';
import type {FfmpegExecutable} from './ffmpeg-executable';
Expand Down Expand Up @@ -103,6 +104,10 @@ const innerRenderStill = async ({
);
validateNonNullImageFormat(imageFormat);
validateFrame(frame, composition.durationInFrames);
const stillFrame = convertToPositiveFrameIndex({
durationInFrames: composition.durationInFrames,
frame,
});
validatePuppeteerTimeout(timeoutInMilliseconds);
validateScale(scale);

Expand Down Expand Up @@ -185,7 +190,7 @@ const innerRenderStill = async ({
envVariables,
page,
serveUrl,
initialFrame: frame,
initialFrame: stillFrame,
timeoutInMilliseconds,
proxyPort,
retriesRemaining: 2,
Expand Down Expand Up @@ -224,14 +229,14 @@ const innerRenderStill = async ({
frame: null,
page,
});
await seekToFrame({frame, page});
await seekToFrame({frame: stillFrame, page});

await provideScreenshot({
page,
imageFormat,
quality,
options: {
frame,
frame: stillFrame,
output,
},
});
Expand Down
6 changes: 5 additions & 1 deletion packages/renderer/src/test/frame.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {expect, test} from 'vitest';
import {validateFrame} from '../validate-frame';

test('Validate frame', () => {
expect(() => validateFrame(-1, 100)).toThrow(/Frame -1 cannot be negative/);
expect(() => validateFrame(Infinity, 100)).toThrow(
/Frame Infinity is not finite/
);
Expand All @@ -18,4 +17,9 @@ test('Validate frame', () => {
);
expect(() => validateFrame(0, 1)).not.toThrow();
expect(() => validateFrame(1, 2)).not.toThrow();
expect(() => validateFrame(-1, 100)).not.toThrow();
expect(() => validateFrame(-100, 100)).not.toThrow();
expect(() => validateFrame(-101, 100)).toThrow(
/Cannot use frame -101: Duration of composition is 100, therefore the lowest frame that can be rendered is -100/
);
});
12 changes: 8 additions & 4 deletions packages/renderer/src/validate-frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ export const validateFrame = (frame: number, durationInFrames: number) => {
);
}

if (frame < 0) {
throw new RangeError(`Frame ${frame} cannot be negative`);
}

if (!Number.isFinite(frame)) {
throw new RangeError(`Frame ${frame} is not finite`);
}
Expand All @@ -23,6 +19,14 @@ export const validateFrame = (frame: number, durationInFrames: number) => {
);
}

if (frame < 0 && frame < -durationInFrames) {
throw new RangeError(
`Cannot use frame ${frame}: Duration of composition is ${durationInFrames}, therefore the lowest frame that can be rendered is ${
-durationInFrames
}`
);
}

if (frame > durationInFrames - 1) {
throw new RangeError(
`Cannot use frame ${frame}: Duration of composition is ${durationInFrames}, therefore the highest frame that can be rendered is ${
Expand Down