Skip to content

Commit

Permalink
Merge pull request #1364 from Slashgear/negativ-frames
Browse files Browse the repository at this point in the history
  • Loading branch information
JonnyBurger committed Oct 4, 2022
2 parents 7692bff + 9089316 commit 5460153
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 12 deletions.
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

1 comment on commit 5460153

@vercel
Copy link

@vercel vercel bot commented on 5460153 Oct 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.