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: <Artifact> API #3989

Merged
merged 40 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
79e6186
Start working on captions
JonnyBurger Jun 12, 2024
e769c82
hmm
JonnyBurger Jun 12, 2024
ef5552d
Artifact API
JonnyBurger Jun 12, 2024
b95253e
artifact
JonnyBurger Jun 12, 2024
8b0550b
Update SubtitleArtifact.tsx
JonnyBurger Jun 12, 2024
3672244
scaffold our artifact
JonnyBurger Jun 12, 2024
d654062
do something with the artifact
JonnyBurger Jun 12, 2024
c2bb5e9
general CLI handler
JonnyBurger Jun 13, 2024
fcbcac7
artifact state
JonnyBurger Jun 13, 2024
61faef0
Merge branch 'main' into captions-type
JonnyBurger Jun 14, 2024
dd1710f
add some tests to it
JonnyBurger Jun 14, 2024
2fc2eb9
cool artifacts
JonnyBurger Jun 14, 2024
a80f456
Merge branch 'main' into captions-type
JonnyBurger Jun 17, 2024
d7a75ec
artifact name
JonnyBurger Jun 17, 2024
e6f27c2
let's go
JonnyBurger Jun 17, 2024
fb2e525
artifact
JonnyBurger Jun 18, 2024
cfc2067
Merge branch 'main' into captions-type
JonnyBurger Jun 19, 2024
7fc59d8
awesome
JonnyBurger Jun 19, 2024
cff3cc9
support uint8array
JonnyBurger Jun 19, 2024
3821e95
more abstractions
JonnyBurger Jun 19, 2024
4b7bc65
Update still.ts
JonnyBurger Jun 19, 2024
8474cfd
lambda improvements
JonnyBurger Jun 19, 2024
1b95674
Update still.ts
JonnyBurger Jun 19, 2024
85d1531
Update render.ts
JonnyBurger Jun 19, 2024
8d2cc13
update documentation
JonnyBurger Jun 20, 2024
32a5c6e
document onArtifact
JonnyBurger Jun 20, 2024
cd3da52
Update artifact.mdx
JonnyBurger Jun 20, 2024
1e46e91
upgrade caniuse
JonnyBurger Jun 20, 2024
74a97cf
serialize right in browser
JonnyBurger Jun 20, 2024
5d734ca
emit to out/[composition-id]/artifact
JonnyBurger Jun 20, 2024
ed893cd
better error handling on stills
JonnyBurger Jun 20, 2024
50960df
only write to lambda once actually saved
JonnyBurger Jun 20, 2024
a817062
add docs
JonnyBurger Jun 20, 2024
495a18c
Good error handling on multiple assets
JonnyBurger Jun 20, 2024
b09d7f0
Discard changes to packages/example/runlambda.sh
JonnyBurger Jun 20, 2024
d532bcb
update error messages
JonnyBurger Jun 20, 2024
f77f9ea
Merge branch 'captions-type' of https://github.com/remotion-dev/remot…
JonnyBurger Jun 20, 2024
517dea3
Update render-still.ts
JonnyBurger Jun 20, 2024
c7ab57e
Update index.ts
JonnyBurger Jun 20, 2024
12c63f7
Update Artifact.tsx
JonnyBurger Jun 20, 2024
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"pnpm": {
"overrides": {
"caniuse-lite": "1.0.30001577"
"caniuse-lite": "1.0.30001636"
}
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ export const benchmarkCommand = async (
}).value,
compositionStart: 0,
onBrowserDownload,
onArtifact: () => undefined,
},
(run, progress) => {
benchmarkProgress.update(
Expand Down
51 changes: 51 additions & 0 deletions packages/cli/src/on-artifact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type {OnArtifact} from '@remotion/renderer';
import type {ArtifactProgress} from '@remotion/studio-shared';
import {existsSync, mkdirSync, writeFileSync} from 'fs';
import path from 'path';

export const handleOnArtifact = ({
artifactState,
onProgress,
compositionId,
}: {
artifactState: ArtifactProgress;
onProgress: (artifact: ArtifactProgress) => void;
compositionId: string;
}) => {
const initialProgress = {...artifactState};

const onArtifact: OnArtifact = (artifact) => {
// It would be nice in the future to customize the artifact output destination

const relativeOutputDestination = path.join(
'out',
compositionId,
artifact.filename.replace('/', path.sep),
);
const defaultOutName = path.join(process.cwd(), relativeOutputDestination);

if (!existsSync(path.dirname(defaultOutName))) {
mkdirSync(path.dirname(defaultOutName), {
recursive: true,
});
}

const alreadyExisted = existsSync(defaultOutName);

writeFileSync(defaultOutName, artifact.content);

initialProgress.received.push({
absoluteOutputDestination: defaultOutName,
filename: artifact.filename,
sizeInBytes: artifact.content.length,
alreadyExisted,
relativeOutputDestination,
});
};

onProgress(initialProgress);

return {
onArtifact,
};
};
28 changes: 27 additions & 1 deletion packages/cli/src/progress-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
StitchingProgressInput,
} from '@remotion/studio-server';
import {StudioServerInternals} from '@remotion/studio-server';
import {formatBytes, type ArtifactProgress} from '@remotion/studio-shared';
import {chalk} from './chalk';
import {
getFileSizeDownloadBar,
Expand Down Expand Up @@ -192,6 +193,30 @@ const makeRenderingProgress = ({
.join(' ');
};

const makeArtifactProgress = (artifactState: ArtifactProgress) => {
const {received} = artifactState;
if (received.length === 0) {
return null;
}

return received
.map((artifact) => {
return [
chalk.blue((artifact.alreadyExisted ? '○' : '+').padEnd(LABEL_WIDTH)),
chalk.blue(
makeHyperlink({
url: 'file://' + artifact.absoluteOutputDestination,
fallback: artifact.absoluteOutputDestination,
text: artifact.relativeOutputDestination,
}),
),
chalk.gray(`${formatBytes(artifact.sizeInBytes)}`),
].join(' ');
})
.filter(truthy)
.join('\n');
};

export const getRightLabelWidth = (totalFrames: number) => {
return `${totalFrames}/${totalFrames}`.length;
};
Expand Down Expand Up @@ -237,7 +262,7 @@ export const makeRenderingAndStitchingProgress = ({
progress: number;
message: string;
} => {
const {rendering, stitching, downloads, bundling} = prog;
const {rendering, stitching, downloads, bundling, artifactState} = prog;
const output = [
rendering ? makeRenderingProgress(rendering) : null,
makeMultiDownloadProgress(downloads, rendering?.totalFrames ?? 0),
Expand All @@ -247,6 +272,7 @@ export const makeRenderingAndStitchingProgress = ({
stitchingProgress: stitching,
isUsingParallelEncoding,
}),
makeArtifactProgress(artifactState),
]
.filter(truthy)
.join('\n');
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/progress-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ export const initialAggregateRenderProgress = (): AggregateRenderProgress => ({
bytes: 0,
doneIn: null,
},
artifactState: {
received: [],
},
});
17 changes: 17 additions & 0 deletions packages/cli/src/render-flows/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {
RenderingProgressInput,
StitchingProgressInput,
} from '@remotion/studio-server';
import type {ArtifactProgress} from '@remotion/studio-shared';
import fs, {existsSync} from 'node:fs';
import os from 'node:os';
import path from 'node:path';
Expand All @@ -42,6 +43,7 @@ import {makeHyperlink} from '../hyperlinks/make-link';
import {getVideoImageFormat} from '../image-formats';
import {Log} from '../log';
import {makeOnDownload} from '../make-on-download';
import {handleOnArtifact} from '../on-artifact';
import {parsedCli, quietFlagProvided} from '../parsed-cli';
import {
LABEL_WIDTH,
Expand Down Expand Up @@ -219,6 +221,8 @@ export const renderVideoFlow = async ({
doneIn: null,
};

let artifactState: ArtifactProgress = {received: []};

const updateRenderProgress = ({
newline,
printToConsole,
Expand All @@ -232,6 +236,7 @@ export const renderVideoFlow = async ({
downloads,
bundling: bundlingProgress,
copyingState,
artifactState,
};

const {output, message, progress} = makeRenderingAndStitchingProgress({
Expand Down Expand Up @@ -322,6 +327,15 @@ export const renderVideoFlow = async ({
onBrowserDownload,
});

const {onArtifact} = handleOnArtifact({
artifactState,
onProgress: (progress) => {
artifactState = progress;
updateRenderProgress({newline: false, printToConsole: true});
},
compositionId,
});

const {value: codec, source: codecReason} =
BrowserSafeApis.options.videoCodecOption.getValue(
{
Expand Down Expand Up @@ -429,6 +443,7 @@ export const renderVideoFlow = async ({
codec: shouldOutputImageSequence ? undefined : codec,
uiImageFormat,
});

if (shouldOutputImageSequence) {
fs.mkdirSync(absoluteOutputFile, {
recursive: true,
Expand Down Expand Up @@ -491,6 +506,7 @@ export const renderVideoFlow = async ({
compositionStart: 0,
forSeamlessAacConcatenation,
onBrowserDownload,
onArtifact,
});

Log.info({indent, logLevel}, chalk.blue(`▶ ${absoluteOutputFile}`));
Expand Down Expand Up @@ -580,6 +596,7 @@ export const renderVideoFlow = async ({
forSeamlessAacConcatenation,
compositionStart: 0,
onBrowserDownload,
onArtifact,
});
if (!updatesDontOverwrite) {
updateRenderProgress({newline: true, printToConsole: true});
Expand Down
22 changes: 16 additions & 6 deletions packages/cli/src/render-flows/still.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {getCompositionWithDimensionOverride} from '../get-composition-with-dimen
import {makeHyperlink} from '../hyperlinks/make-link';
import {Log} from '../log';
import {makeOnDownload} from '../make-on-download';
import {handleOnArtifact} from '../on-artifact';
import {parsedCli, quietFlagProvided} from '../parsed-cli';
import type {OverwriteableCliOutput} from '../progress-bar';
import {
Expand Down Expand Up @@ -124,15 +125,13 @@ export const renderStillFlow = async ({
const updateRenderProgress = ({
newline,
printToConsole,
isUsingParallelEncoding,
}: {
newline: boolean;
printToConsole: boolean;
isUsingParallelEncoding: boolean;
}) => {
const {output, progress, message} = makeRenderingAndStitchingProgress({
prog: aggregate,
isUsingParallelEncoding,
isUsingParallelEncoding: false,
});
if (printToConsole) {
renderProgress.update(updatesDontOverwrite ? message : output, newline);
Expand Down Expand Up @@ -176,7 +175,6 @@ export const renderStillFlow = async ({
updateRenderProgress({
newline: false,
printToConsole: true,
isUsingParallelEncoding: false,
});
},
indentOutput: indent,
Expand Down Expand Up @@ -309,7 +307,6 @@ export const renderStillFlow = async ({
updateRenderProgress({
newline: false,
printToConsole: true,
isUsingParallelEncoding: false,
});

const onDownload: RenderMediaOnDownload = makeOnDownload({
Expand All @@ -321,6 +318,19 @@ export const renderStillFlow = async ({
isUsingParallelEncoding: false,
});

const {onArtifact} = handleOnArtifact({
artifactState: aggregate.artifactState,
compositionId,
onProgress: (progress) => {
aggregate.artifactState = progress;

updateRenderProgress({
newline: false,
printToConsole: true,
});
},
});

await RenderInternals.internalRenderStill({
composition: config,
frame: stillFrame,
Expand Down Expand Up @@ -352,6 +362,7 @@ export const renderStillFlow = async ({
offthreadVideoCacheSizeInBytes,
binariesDirectory,
onBrowserDownload,
onArtifact,
});

aggregate.rendering = {
Expand All @@ -363,7 +374,6 @@ export const renderStillFlow = async ({
updateRenderProgress({
newline: true,
printToConsole: true,
isUsingParallelEncoding: false,
});
Log.info(
{indent, logLevel},
Expand Down
11 changes: 10 additions & 1 deletion packages/cloudrun/src/functions/render-media-single-thread.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type * as ff from '@google-cloud/functions-framework';
import {Storage} from '@google-cloud/storage';
import type {ChromiumOptions, RenderMediaOnProgress} from '@remotion/renderer';
import type {
ChromiumOptions,
OnArtifact,
RenderMediaOnProgress,
} from '@remotion/renderer';
import {RenderInternals} from '@remotion/renderer';
import {NoReactInternals} from 'remotion/no-react';
import {VERSION} from 'remotion/version';
Expand Down Expand Up @@ -60,6 +64,10 @@ export const renderMediaSingleThread = async (
enableMultiProcessOnLinux: true,
};

const onArtifact: OnArtifact = () => {
throw new Error('Emitting artifacts is not supported in Cloud Run');
};

await RenderInternals.internalRenderMedia({
composition: {
...composition,
Expand Down Expand Up @@ -127,6 +135,7 @@ export const renderMediaSingleThread = async (
onBrowserDownload: () => {
throw new Error('Should not download a browser in Cloud Run');
},
onArtifact,
});

const storage = new Storage();
Expand Down
3 changes: 3 additions & 0 deletions packages/cloudrun/src/functions/render-still-single-thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ export const renderStillSingleThread = async (
onBrowserDownload: () => {
throw new Error('Should not download a browser in Cloud Run');
},
onArtifact: () => {
throw new Error('Emitting artifacts is not supported in Cloud Run');
},
});
Log.info({indent: false, logLevel: body.logLevel}, 'Still rendered');

Expand Down
61 changes: 61 additions & 0 deletions packages/core/src/Artifact.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type React from 'react';
import {useContext, useEffect, useState} from 'react';
import {RenderAssetManager} from './RenderAssetManager';
import {getRemotionEnvironment} from './get-remotion-environment';
import {useCurrentFrame} from './use-current-frame';

export const Artifact: React.FC<{
readonly filename: string;
readonly content: string | Uint8Array;
}> = ({filename, content}) => {
const {registerRenderAsset, unregisterRenderAsset} =
useContext(RenderAssetManager);

const [env] = useState(() => getRemotionEnvironment());

const frame = useCurrentFrame();

const [id] = useState(() => {
return String(Math.random());
});

useEffect(() => {
if (!env.isRendering) {
return;
}

if (content instanceof Uint8Array) {
registerRenderAsset({
type: 'artifact',
id,
content: btoa(new TextDecoder('utf8').decode(content)),
filename,
frame,
binary: true,
});
} else {
registerRenderAsset({
type: 'artifact',
id,
content,
filename,
frame,
binary: false,
});
}

return () => {
return unregisterRenderAsset(id);
};
}, [
content,
env.isRendering,
filename,
frame,
id,
registerRenderAsset,
unregisterRenderAsset,
]);

return null;
};
Loading
Loading