diff --git a/.claude/skills/web-renderer-test/SKILL.md b/.claude/skills/web-renderer-test/SKILL.md index ea67b729c20..c493f445ba3 100644 --- a/.claude/skills/web-renderer-test/SKILL.md +++ b/.claude/skills/web-renderer-test/SKILL.md @@ -76,3 +76,4 @@ test('should render background-color', async () => { 2. **Important**: Add the fixture to `packages/web-renderer/src/test/Root.tsx` to add a way to preview it. 3. Add a new test in `packages/web-renderer/src/test`. 4. Run `bunx vitest src/test/video.test.tsx` to execute the test. +5. **Important**: Update `packages/docs/docs/client-side-rendering/limitations.mdx` to reflect the newly supported property. diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 6fc7855c914..05b8c72d783 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -2,6 +2,10 @@ on: release: types: [published] workflow_dispatch: + inputs: + tag: + description: 'Release tag to post (e.g. v4.0.422). Leave empty for latest.' + required: false name: Publish latest release jobs: @@ -18,4 +22,4 @@ jobs: DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} run: | cd packages/discord-poster - bun post.ts + bun post.ts ${{ github.event.inputs.tag }} diff --git a/.github/workflows/pullfrog.yml b/.github/workflows/pullfrog.yml new file mode 100644 index 00000000000..d8647943214 --- /dev/null +++ b/.github/workflows/pullfrog.yml @@ -0,0 +1,46 @@ +# PULLFROG ACTION — DO NOT EDIT EXCEPT WHERE INDICATED +name: Pullfrog +run-name: ${{ inputs.name || github.workflow }} +on: + workflow_dispatch: + inputs: + prompt: + type: string + description: Agent prompt + name: + type: string + description: Run name + +permissions: + id-token: write + contents: write + pull-requests: write + issues: write + actions: read + checks: read + +jobs: + pullfrog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 1 + - name: Run agent + uses: pullfrog/pullfrog@v0 + with: + prompt: ${{ inputs.prompt }} + env: + # add any additional keys your agent(s) need + # optionally, comment out any you won't use + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} + GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} + DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + diff --git a/bun.lock b/bun.lock index 4f3e227714e..611d2f6c3fe 100644 --- a/bun.lock +++ b/bun.lock @@ -97,6 +97,8 @@ "@remotion/media-parser": "workspace:*", "@remotion/studio": "workspace:*", "@remotion/studio-shared": "workspace:*", + "@rspack/core": "1.7.6", + "@rspack/plugin-react-refresh": "1.6.1", "css-loader": "5.2.7", "esbuild": "0.25.0", "react-refresh": "0.9.0", @@ -3849,6 +3851,8 @@ "@rspack/lite-tapable": ["@rspack/lite-tapable@1.1.0", "", {}, "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw=="], + "@rspack/plugin-react-refresh": ["@rspack/plugin-react-refresh@1.6.1", "", { "dependencies": { "error-stack-parser": "^2.1.4", "html-entities": "^2.6.0" }, "peerDependencies": { "react-refresh": ">=0.10.0 <1.0.0", "webpack-hot-middleware": "2.x" }, "optionalPeers": ["webpack-hot-middleware"] }, "sha512-eqqW5645VG3CzGzFgNg5HqNdHVXY+567PGjtDhhrM8t67caxmsSzRmT5qfoEIfBcGgFkH9vEg7kzXwmCYQdQDw=="], + "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], "@rushstack/eslint-patch": ["@rushstack/eslint-patch@1.10.4", "", {}, "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA=="], @@ -5387,6 +5391,8 @@ "error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="], + "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], + "es-abstract": ["es-abstract@1.23.9", "", { "dependencies": { "array-buffer-byte-length": "1.0.2", "arraybuffer.prototype.slice": "1.0.4", "available-typed-arrays": "1.0.7", "call-bind": "1.0.8", "call-bound": "1.0.3", "data-view-buffer": "1.0.2", "data-view-byte-length": "1.0.2", "data-view-byte-offset": "1.0.1", "es-define-property": "1.0.1", "es-errors": "1.3.0", "es-object-atoms": "1.0.0", "es-set-tostringtag": "2.1.0", "es-to-primitive": "1.3.0", "function.prototype.name": "1.1.8", "get-intrinsic": "1.2.7", "get-proto": "1.0.1", "get-symbol-description": "1.1.0", "globalthis": "1.0.4", "gopd": "1.2.0", "has-property-descriptors": "1.0.2", "has-proto": "1.2.0", "has-symbols": "1.1.0", "hasown": "2.0.2", "internal-slot": "1.1.0", "is-array-buffer": "3.0.5", "is-callable": "1.2.7", "is-data-view": "1.0.2", "is-regex": "1.2.1", "is-shared-array-buffer": "1.0.4", "is-string": "1.1.1", "is-typed-array": "1.1.15", "is-weakref": "1.1.0", "math-intrinsics": "1.1.0", "object-inspect": "1.13.3", "object-keys": "1.1.1", "object.assign": "4.1.7", "own-keys": "1.0.1", "regexp.prototype.flags": "1.5.4", "safe-array-concat": "1.1.3", "safe-push-apply": "1.0.0", "safe-regex-test": "1.1.0", "set-proto": "1.0.0", "string.prototype.trim": "1.2.10", "string.prototype.trimend": "1.0.9", "string.prototype.trimstart": "1.0.8", "typed-array-buffer": "1.0.3", "typed-array-byte-length": "1.0.3", "typed-array-byte-offset": "1.0.4", "typed-array-length": "1.0.7", "unbox-primitive": "1.1.0", "which-typed-array": "1.1.18" } }, "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA=="], "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], @@ -5785,7 +5791,7 @@ "hpack.js": ["hpack.js@2.1.6", "", { "dependencies": { "inherits": "2.0.4", "obuf": "1.1.2", "readable-stream": "2.3.8", "wbuf": "1.7.3" } }, "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ=="], - "html-entities": ["html-entities@2.5.2", "", {}, "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA=="], + "html-entities": ["html-entities@2.6.0", "", {}, "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="], "html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="], @@ -7237,6 +7243,8 @@ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="], + "state-local": ["state-local@1.0.7", "", {}, "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="], "stats-gl": ["stats-gl@2.4.2", "", { "peerDependencies": { "@types/three": "0.170.0", "three": "0.178.0" } }, "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ=="], @@ -8451,6 +8459,8 @@ "@google-cloud/common/google-auth-library": ["google-auth-library@9.11.0", "", { "dependencies": { "base64-js": "1.5.1", "ecdsa-sig-formatter": "1.0.11", "gaxios": "6.6.0", "gcp-metadata": "6.1.0", "gtoken": "7.1.0", "jws": "4.0.0" } }, "sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw=="], + "@google-cloud/common/html-entities": ["html-entities@2.5.2", "", {}, "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA=="], + "@google-cloud/functions-framework/@types/express": ["@types/express@5.0.1", "", { "dependencies": { "@types/body-parser": "1.19.1", "@types/express-serve-static-core": "5.0.4", "@types/serve-static": "1.13.10" } }, "sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ=="], "@google-cloud/functions-framework/express": ["express@4.21.2", "", { "dependencies": { "accepts": "1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "1.0.5", "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "2.0.0", "escape-html": "1.0.3", "etag": "1.8.1", "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "1.1.2", "on-finished": "2.4.1", "parseurl": "1.3.3", "path-to-regexp": "0.1.12", "proxy-addr": "2.0.7", "qs": "6.13.0", "range-parser": "1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "1.6.18", "utils-merge": "1.0.1", "vary": "1.1.2" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="], @@ -8465,6 +8475,8 @@ "@google-cloud/storage/google-auth-library": ["google-auth-library@9.11.0", "", { "dependencies": { "base64-js": "1.5.1", "ecdsa-sig-formatter": "1.0.11", "gaxios": "6.6.0", "gcp-metadata": "6.1.0", "gtoken": "7.1.0", "jws": "4.0.0" } }, "sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw=="], + "@google-cloud/storage/html-entities": ["html-entities@2.5.2", "", {}, "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA=="], + "@google-cloud/storage/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "@google-cloud/text-to-speech/google-gax": ["google-gax@3.6.1", "", { "dependencies": { "@grpc/grpc-js": "1.8.22", "@grpc/proto-loader": "0.7.13", "@types/long": "4.0.2", "@types/rimraf": "3.0.2", "abort-controller": "3.0.0", "duplexify": "4.1.3", "fast-text-encoding": "1.0.6", "google-auth-library": "8.7.0", "is-stream-ended": "0.1.4", "node-fetch": "2.6.9", "object-hash": "3.0.0", "proto3-json-serializer": "1.1.1", "protobufjs": "7.2.4", "protobufjs-cli": "1.1.1", "retry-request": "5.0.2" }, "bin": { "compileProtos": "build/tools/compileProtos.js", "minifyProtoJson": "build/tools/minify.js" } }, "sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w=="], @@ -8939,6 +8951,8 @@ "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "@rspack/plugin-react-refresh/react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="], + "@shopify/react-native-skia/react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], "@smithy/abort-controller/@smithy/types": ["@smithy/types@4.2.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg=="], diff --git a/packages/bundler/package.json b/packages/bundler/package.json index 36a501f5b2a..1c84faebc67 100644 --- a/packages/bundler/package.json +++ b/packages/bundler/package.json @@ -19,6 +19,8 @@ "author": "Jonny Burger ", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { + "@rspack/core": "1.7.6", + "@rspack/plugin-react-refresh": "1.6.1", "css-loader": "5.2.7", "esbuild": "0.25.0", "react-refresh": "0.9.0", diff --git a/packages/bundler/src/bundle.ts b/packages/bundler/src/bundle.ts index 84c7945b2d7..b13f0ff35da 100644 --- a/packages/bundler/src/bundle.ts +++ b/packages/bundler/src/bundle.ts @@ -9,6 +9,7 @@ import webpack from 'webpack'; import {copyDir} from './copy-dir'; import {indexHtml} from './index-html'; import {readRecursively} from './read-recursively'; +import {rspackConfig} from './rspack-config'; import type {WebpackOverrideFn} from './webpack-config'; import {webpackConfig} from './webpack-config'; @@ -52,6 +53,7 @@ export type MandatoryLegacyBundleOptions = { onSymlinkDetected: (path: string) => void; keyboardShortcutsEnabled: boolean; askAIEnabled: boolean; + rspack: boolean; }; export type LegacyBundleOptions = Partial; @@ -72,10 +74,10 @@ export const getConfig = ({ bufferStateDelayInMilliseconds: number | null; experimentalClientSideRenderingEnabled: boolean; maxTimelineTracks: number | null; - onProgress?: (progress: number) => void; - options?: LegacyBundleOptions; + onProgress: (progress: number) => void; + options: MandatoryLegacyBundleOptions; }) => { - return webpackConfig({ + const configArgs = { entry: path.join( require.resolve('@remotion/studio/renderEntry'), '..', @@ -84,9 +86,9 @@ export const getConfig = ({ ), userDefinedComponent: entryPoint, outDir, - environment: 'production', + environment: 'production' as const, webpackOverride: options?.webpackOverride ?? ((f) => f), - onProgress: (p) => { + onProgress: (p: number) => { onProgress?.(p); }, enableCaching: options?.enableCaching ?? true, @@ -97,7 +99,13 @@ export const getConfig = ({ poll: null, experimentalClientSideRenderingEnabled, askAIEnabled: options?.askAIEnabled ?? true, - }); + }; + + if (options.rspack) { + return rspackConfig(configArgs); + } + + return webpackConfig(configArgs); }; type NewBundleOptions = { @@ -229,20 +237,59 @@ export const internalBundle = async ( actualArgs.experimentalClientSideRenderingEnabled, }); - const output = (await promisified([config])) as - | webpack.MultiStats - | undefined; - if (isMainThread) { - process.chdir(currentCwd); - } + if (actualArgs.rspack) { + const {rspack: rspackFn} = require('@rspack/core'); + const rspackCompiler = rspackFn(config); + const rspackOutput = await new Promise<{ + toJson: (opts: unknown) => { + errors?: Array<{message: string; details: string}>; + }; + }>((resolve, reject) => { + rspackCompiler.run( + ( + err: Error | null, + stats: { + toJson: (opts: unknown) => { + errors?: Array<{message: string; details: string}>; + }; + }, + ) => { + if (err) { + reject(err); + return; + } + + rspackCompiler.close(() => { + resolve(stats); + }); + }, + ); + }); - if (!output) { - throw new Error('Expected webpack output'); - } + if (isMainThread) { + process.chdir(currentCwd); + } - const {errors} = output.toJson(); - if (errors !== undefined && errors.length > 0) { - throw new Error(errors[0].message + '\n' + errors[0].details); + const {errors} = rspackOutput.toJson({}); + if (errors !== undefined && errors.length > 0) { + throw new Error(errors[0].message + '\n' + errors[0].details); + } + } else { + const output = (await promisified([config as webpack.Configuration])) as + | webpack.MultiStats + | undefined; + if (isMainThread) { + process.chdir(currentCwd); + } + + if (!output) { + throw new Error('Expected webpack output'); + } + + const {errors} = output.toJson(); + if (errors !== undefined && errors.length > 0) { + throw new Error(errors[0].message + '\n' + errors[0].details); + } } const publicPath = actualArgs?.publicPath ?? '/'; @@ -368,6 +415,7 @@ export async function bundle(...args: Arguments): Promise { renderDefaults: actualArgs.renderDefaults ?? null, askAIEnabled: actualArgs.askAIEnabled ?? true, keyboardShortcutsEnabled: actualArgs.keyboardShortcutsEnabled ?? true, + rspack: actualArgs.rspack ?? false, }); return result; } diff --git a/packages/bundler/src/define-plugin-definitions.ts b/packages/bundler/src/define-plugin-definitions.ts new file mode 100644 index 00000000000..52c64775d00 --- /dev/null +++ b/packages/bundler/src/define-plugin-definitions.ts @@ -0,0 +1,21 @@ +export const getDefinePluginDefinitions = ({ + maxTimelineTracks, + askAIEnabled, + keyboardShortcutsEnabled, + bufferStateDelayInMilliseconds, + experimentalClientSideRenderingEnabled, +}: { + maxTimelineTracks: number | null; + askAIEnabled: boolean; + keyboardShortcutsEnabled: boolean; + bufferStateDelayInMilliseconds: number | null; + experimentalClientSideRenderingEnabled: boolean; +}) => ({ + 'process.env.MAX_TIMELINE_TRACKS': maxTimelineTracks, + 'process.env.ASK_AI_ENABLED': askAIEnabled, + 'process.env.KEYBOARD_SHORTCUTS_ENABLED': keyboardShortcutsEnabled, + 'process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS': + bufferStateDelayInMilliseconds, + 'process.env.EXPERIMENTAL_CLIENT_SIDE_RENDERING_ENABLED': + experimentalClientSideRenderingEnabled, +}); diff --git a/packages/bundler/src/index.ts b/packages/bundler/src/index.ts index e9e7286d870..7cbd0de2324 100644 --- a/packages/bundler/src/index.ts +++ b/packages/bundler/src/index.ts @@ -1,6 +1,7 @@ import {findClosestFolderWithItem, getConfig, internalBundle} from './bundle'; import {indexHtml} from './index-html'; import {readRecursively} from './read-recursively'; +import {createRspackCompiler, rspackConfig} from './rspack-config'; import {cacheExists, clearCache} from './webpack-cache'; import {webpackConfig} from './webpack-config'; import esbuild = require('esbuild'); @@ -9,6 +10,8 @@ import webpack = require('webpack'); export const BundlerInternals = { esbuild, webpackConfig, + rspackConfig, + createRspackCompiler, indexHtml, cacheExists, clearCache, diff --git a/packages/bundler/src/rspack-config.ts b/packages/bundler/src/rspack-config.ts new file mode 100644 index 00000000000..2c66a297368 --- /dev/null +++ b/packages/bundler/src/rspack-config.ts @@ -0,0 +1,157 @@ +import type {Configuration} from '@rspack/core'; +import {DefinePlugin, ProgressPlugin, rspack} from '@rspack/core'; +import ReactRefreshPlugin from '@rspack/plugin-react-refresh'; +import {getDefinePluginDefinitions} from './define-plugin-definitions'; +import { + computeHashAndFinalConfig, + getBaseConfig, + getOutputConfig, + getResolveConfig, + getSharedModuleRules, +} from './shared-bundler-config'; +import type {WebpackOverrideFn} from './webpack-config'; + +export type RspackConfiguration = Configuration; + +export const rspackConfig = async ({ + entry, + userDefinedComponent, + outDir, + environment, + webpackOverride = (f) => f, + onProgress, + enableCaching = true, + maxTimelineTracks, + remotionRoot, + keyboardShortcutsEnabled, + bufferStateDelayInMilliseconds, + poll, + experimentalClientSideRenderingEnabled, + askAIEnabled, +}: { + entry: string; + userDefinedComponent: string; + outDir: string | null; + environment: 'development' | 'production'; + webpackOverride: WebpackOverrideFn; + onProgress?: (f: number) => void; + enableCaching?: boolean; + maxTimelineTracks: number | null; + keyboardShortcutsEnabled: boolean; + bufferStateDelayInMilliseconds: number | null; + remotionRoot: string; + poll: number | null; + askAIEnabled: boolean; + experimentalClientSideRenderingEnabled: boolean; +}): Promise<[string, RspackConfiguration]> => { + let lastProgress = 0; + + const define = new DefinePlugin( + getDefinePluginDefinitions({ + maxTimelineTracks, + askAIEnabled, + keyboardShortcutsEnabled, + bufferStateDelayInMilliseconds, + experimentalClientSideRenderingEnabled, + }) as unknown as Record, + ); + + const swcLoaderRule = { + loader: 'builtin:swc-loader', + options: { + jsc: { + parser: {syntax: 'typescript' as const, tsx: true}, + transform: { + react: { + runtime: 'automatic' as const, + development: environment === 'development', + refresh: environment === 'development', + }, + }, + }, + env: {targets: 'Chrome >= 85'}, + }, + }; + + const swcLoaderRuleJsx = { + loader: 'builtin:swc-loader', + options: { + jsc: { + parser: {syntax: 'ecmascript' as const, jsx: true}, + transform: { + react: { + runtime: 'automatic' as const, + development: environment === 'development', + refresh: environment === 'development', + }, + }, + }, + env: {targets: 'Chrome >= 85'}, + }, + }; + + // Rspack config is structurally compatible with webpack config at runtime, + // but the TypeScript types differ. Cast through `any` for the override. + const conf = (await webpackOverride({ + ...getBaseConfig(environment, poll), + ignoreWarnings: [ + /Circular dependency between chunks with runtime/, + /Critical dependency: the request of a dependency is an expression/, + /"__dirname" is used and has been mocked/, + ], + entry: [ + require.resolve('./setup-environment'), + userDefinedComponent, + require.resolve('../react-shim.js'), + entry, + ].filter(Boolean) as [string, ...string[]], + mode: environment, + plugins: + environment === 'development' + ? [ + new ReactRefreshPlugin({overlay: false}), + new rspack.HotModuleReplacementPlugin(), + define, + ] + : [ + new ProgressPlugin((p: number) => { + if (onProgress) { + if ((p === 1 && p > lastProgress) || p - lastProgress > 0.05) { + lastProgress = p; + onProgress(Number((p * 100).toFixed(2))); + } + } + }), + define, + ], + output: getOutputConfig(environment), + resolve: getResolveConfig(), + module: { + rules: [ + ...getSharedModuleRules(), + { + test: /\.tsx?$/, + use: [swcLoaderRule], + }, + { + test: /\.jsx?$/, + exclude: /node_modules/, + use: [swcLoaderRuleJsx], + }, + ], + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any)) as RspackConfiguration; + + const [hash, finalConf] = computeHashAndFinalConfig(conf, { + enableCaching, + environment, + outDir, + remotionRoot, + }); + return [hash, finalConf as unknown as RspackConfiguration]; +}; + +export const createRspackCompiler = (config: RspackConfiguration) => { + return rspack(config); +}; diff --git a/packages/bundler/src/shared-bundler-config.ts b/packages/bundler/src/shared-bundler-config.ts new file mode 100644 index 00000000000..e4f4e5ee9c0 --- /dev/null +++ b/packages/bundler/src/shared-bundler-config.ts @@ -0,0 +1,155 @@ +import {createHash} from 'node:crypto'; +import path from 'node:path'; +import ReactDOM from 'react-dom'; +import {NoReactInternals} from 'remotion/no-react'; +import {jsonStringifyWithCircularReferences} from './stringify-with-circular-references'; +import {getWebpackCacheName} from './webpack-cache'; + +if (!ReactDOM?.version) { + throw new Error('Could not find "react-dom" package. Did you install it?'); +} + +const reactDomVersion = ReactDOM.version.split('.')[0]; +if (reactDomVersion === '0') { + throw new Error( + `Version ${reactDomVersion} of "react-dom" is not supported by Remotion`, + ); +} + +export const shouldUseReactDomClient = + NoReactInternals.ENABLE_V5_BREAKING_CHANGES + ? true + : parseInt(reactDomVersion, 10) >= 18; + +export const getResolveConfig = () => ({ + extensions: ['.ts', '.tsx', '.web.js', '.js', '.jsx', '.mjs', '.cjs'], + alias: { + // Only one version of react + 'react/jsx-runtime': require.resolve('react/jsx-runtime'), + 'react/jsx-dev-runtime': require.resolve('react/jsx-dev-runtime'), + react: require.resolve('react'), + // Needed to not fail on this: https://github.com/remotion-dev/remotion/issues/5045 + 'remotion/no-react': path.resolve( + require.resolve('remotion'), + '..', + '..', + 'esm', + 'no-react.mjs', + ), + 'remotion/version': path.resolve( + require.resolve('remotion'), + '..', + '..', + 'esm', + 'version.mjs', + ), + remotion: path.resolve( + require.resolve('remotion'), + '..', + '..', + 'esm', + 'index.mjs', + ), + + '@remotion/media-parser/worker': path.resolve( + require.resolve('@remotion/media-parser'), + '..', + 'esm', + 'worker.mjs', + ), + // test visual controls before removing this + '@remotion/studio': require.resolve('@remotion/studio'), + 'react-dom/client': shouldUseReactDomClient + ? require.resolve('react-dom/client') + : require.resolve('react-dom'), + }, +}); + +export const getOutputConfig = (environment: 'development' | 'production') => ({ + hashFunction: 'xxhash64' as const, + filename: NoReactInternals.bundleName, + devtoolModuleFilenameTemplate: '[resource-path]', + assetModuleFilename: + environment === 'development' ? '[path][name][ext]' : '[hash][ext]', +}); + +export const getBaseConfig = ( + environment: 'development' | 'production', + poll: number | null, +) => { + const isBun = typeof Bun !== 'undefined'; + + return { + optimization: { + minimize: false, + }, + experiments: { + lazyCompilation: isBun + ? false + : environment === 'production' + ? false + : { + entries: false, + }, + }, + watchOptions: { + poll: poll ?? undefined, + aggregateTimeout: 0, + ignored: ['**/.git/**', '**/.turbo/**', '**/node_modules/**'], + }, + // Higher source map quality in development to power line numbers for stack traces + devtool: + environment === 'development' + ? ('source-map' as const) + : ('cheap-module-source-map' as const), + }; +}; + +export const getSharedModuleRules = () => [ + { + test: /\.css$/i, + use: [require.resolve('style-loader'), require.resolve('css-loader')], + type: 'javascript/auto' as const, + }, + { + test: /\.(png|svg|jpg|jpeg|webp|gif|bmp|webm|mp4|mov|mp3|m4a|wav|aac)$/, + type: 'asset/resource' as const, + }, + { + test: /\.(woff(2)?|otf|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/, + type: 'asset/resource' as const, + }, +]; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const computeHashAndFinalConfig = ( + conf: T, + options: { + enableCaching: boolean; + environment: 'development' | 'production'; + outDir: string | null; + remotionRoot: string; + }, +): [string, T] => { + const hash = createHash('md5') + .update(jsonStringifyWithCircularReferences(conf)) + .digest('hex'); + return [ + hash, + { + ...conf, + cache: options.enableCaching + ? { + type: 'filesystem', + name: getWebpackCacheName(options.environment, hash), + version: hash, + } + : false, + output: { + ...conf.output, + ...(options.outDir ? {path: options.outDir} : {}), + }, + context: options.remotionRoot, + }, + ]; +}; diff --git a/packages/bundler/src/webpack-config.ts b/packages/bundler/src/webpack-config.ts index 50cc8c96d95..6324b54373a 100644 --- a/packages/bundler/src/webpack-config.ts +++ b/packages/bundler/src/webpack-config.ts @@ -1,17 +1,19 @@ -import {createHash} from 'node:crypto'; -import path from 'node:path'; -import ReactDOM from 'react-dom'; -import {NoReactInternals} from 'remotion/no-react'; import type {Configuration} from 'webpack'; import webpack, {ProgressPlugin} from 'webpack'; import {CaseSensitivePathsPlugin} from './case-sensitive-paths'; +import {getDefinePluginDefinitions} from './define-plugin-definitions'; import type {LoaderOptions} from './esbuild-loader/interfaces'; import {ReactFreshWebpackPlugin} from './fast-refresh'; import {AllowDependencyExpressionPlugin} from './hide-expression-dependency'; import {IgnorePackFileCacheWarningsPlugin} from './ignore-packfilecache-warnings'; import {AllowOptionalDependenciesPlugin} from './optional-dependencies'; -import {jsonStringifyWithCircularReferences} from './stringify-with-circular-references'; -import {getWebpackCacheName} from './webpack-cache'; +import { + computeHashAndFinalConfig, + getBaseConfig, + getOutputConfig, + getResolveConfig, + getSharedModuleRules, +} from './shared-bundler-config'; import esbuild = require('esbuild'); export type WebpackConfiguration = Configuration; @@ -19,21 +21,6 @@ export type WebpackOverrideFn = ( currentConfiguration: WebpackConfiguration, ) => WebpackConfiguration | Promise; -if (!ReactDOM?.version) { - throw new Error('Could not find "react-dom" package. Did you install it?'); -} - -const reactDomVersion = ReactDOM.version.split('.')[0]; -if (reactDomVersion === '0') { - throw new Error( - `Version ${reactDomVersion} of "react-dom" is not supported by Remotion`, - ); -} - -const shouldUseReactDomClient = NoReactInternals.ENABLE_V5_BREAKING_CHANGES - ? true - : parseInt(reactDomVersion, 10) >= 18; - type Truthy = T extends false | '' | 0 | null | undefined ? never : T; function truthy(value: T): value is Truthy { @@ -80,39 +67,18 @@ export const webpackConfig = async ({ let lastProgress = 0; - const isBun = typeof Bun !== 'undefined'; - - const define = new webpack.DefinePlugin({ - 'process.env.MAX_TIMELINE_TRACKS': maxTimelineTracks, - 'process.env.ASK_AI_ENABLED': askAIEnabled, - 'process.env.KEYBOARD_SHORTCUTS_ENABLED': keyboardShortcutsEnabled, - 'process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS': + const define = new webpack.DefinePlugin( + getDefinePluginDefinitions({ + maxTimelineTracks, + askAIEnabled, + keyboardShortcutsEnabled, bufferStateDelayInMilliseconds, - 'process.env.EXPERIMENTAL_CLIENT_SIDE_RENDERING_ENABLED': experimentalClientSideRenderingEnabled, - }); + }), + ); const conf: WebpackConfiguration = await webpackOverride({ - optimization: { - minimize: false, - }, - experiments: { - lazyCompilation: isBun - ? false - : environment === 'production' - ? false - : { - entries: false, - }, - }, - watchOptions: { - poll: poll ?? undefined, - aggregateTimeout: 0, - ignored: ['**/.git/**', '**/.turbo/**', '**/node_modules/**'], - }, - // Higher source map quality in development to power line numbers for stack traces - devtool: - environment === 'development' ? 'source-map' : 'cheap-module-source-map', + ...getBaseConfig(environment, poll), entry: [ // Fast Refresh must come first, // because setup-environment imports ReactDOM. @@ -151,67 +117,11 @@ export const webpackConfig = async ({ new AllowDependencyExpressionPlugin(), new IgnorePackFileCacheWarningsPlugin(), ], - output: { - hashFunction: 'xxhash64', - filename: NoReactInternals.bundleName, - devtoolModuleFilenameTemplate: '[resource-path]', - assetModuleFilename: - environment === 'development' ? '[path][name][ext]' : '[hash][ext]', - }, - resolve: { - extensions: ['.ts', '.tsx', '.web.js', '.js', '.jsx', '.mjs', '.cjs'], - alias: { - // Only one version of react - 'react/jsx-runtime': require.resolve('react/jsx-runtime'), - 'react/jsx-dev-runtime': require.resolve('react/jsx-dev-runtime'), - react: require.resolve('react'), - // Needed to not fail on this: https://github.com/remotion-dev/remotion/issues/5045 - 'remotion/no-react': path.resolve( - require.resolve('remotion'), - '..', - '..', - 'esm', - 'no-react.mjs', - ), - 'remotion/version': path.resolve( - require.resolve('remotion'), - '..', - '..', - 'esm', - 'version.mjs', - ), - remotion: path.resolve( - require.resolve('remotion'), - '..', - '..', - 'esm', - 'index.mjs', - ), - - '@remotion/media-parser/worker': path.resolve( - require.resolve('@remotion/media-parser'), - '..', - 'esm', - 'worker.mjs', - ), - // test visual controls before removing this - '@remotion/studio': require.resolve('@remotion/studio'), - 'react-dom/client': shouldUseReactDomClient - ? require.resolve('react-dom/client') - : require.resolve('react-dom'), - }, - }, + output: getOutputConfig(environment), + resolve: getResolveConfig(), module: { rules: [ - { - test: /\.css$/i, - use: [require.resolve('style-loader'), require.resolve('css-loader')], - type: 'javascript/auto', - }, - { - test: /\.(png|svg|jpg|jpeg|webp|gif|bmp|webm|mp4|mov|mp3|m4a|wav|aac)$/, - type: 'asset/resource', - }, + ...getSharedModuleRules(), { test: /\.tsx?$/, use: [ @@ -227,10 +137,6 @@ export const webpackConfig = async ({ : null, ].filter(truthy), }, - { - test: /\.(woff(2)?|otf|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/, - type: 'asset/resource', - }, { test: /\.jsx?$/, exclude: /node_modules/, @@ -249,25 +155,11 @@ export const webpackConfig = async ({ ], }, }); - const hash = createHash('md5') - .update(jsonStringifyWithCircularReferences(conf)) - .digest('hex'); - return [ - hash, - { - ...conf, - cache: enableCaching - ? { - type: 'filesystem', - name: getWebpackCacheName(environment, hash), - version: hash, - } - : false, - output: { - ...conf.output, - ...(outDir ? {path: outDir} : {}), - }, - context: remotionRoot, - }, - ]; + + return computeHashAndFinalConfig(conf, { + enableCaching, + environment, + outDir, + remotionRoot, + }); }; diff --git a/packages/cli/src/benchmark.ts b/packages/cli/src/benchmark.ts index 9c8d94b7a7f..5d945c945e9 100644 --- a/packages/cli/src/benchmark.ts +++ b/packages/cli/src/benchmark.ts @@ -58,6 +58,7 @@ const { askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, + rspackOption, pixelFormatOption, browserExecutableOption, everyNthFrameOption, @@ -280,6 +281,7 @@ export const benchmarkCommand = async ( const keyboardShortcutsEnabled = keyboardShortcutsOption.getValue({ commandLine: parsedCli, }).value; + const rspack = rspackOption.getValue({commandLine: parsedCli}).value; const shouldCache = bundleCacheOption.getValue({ commandLine: parsedCli, }).value; @@ -355,6 +357,7 @@ export const benchmarkCommand = async ( experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }); diff --git a/packages/cli/src/bundle.ts b/packages/cli/src/bundle.ts index ff0e56b4a6b..77cfc4b9b4d 100644 --- a/packages/cli/src/bundle.ts +++ b/packages/cli/src/bundle.ts @@ -21,6 +21,7 @@ const { askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, + rspackOption, outDirOption, bundleCacheOption, } = BrowserSafeApis.options; @@ -75,6 +76,7 @@ export const bundleCommand = async ( const keyboardShortcutsEnabled = keyboardShortcutsOption.getValue({ commandLine: parsedCli, }).value; + const rspack = rspackOption.getValue({commandLine: parsedCli}).value; const shouldCache = bundleCacheOption.getValue({ commandLine: parsedCli, }).value; @@ -166,6 +168,7 @@ export const bundleCommand = async ( experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }); diff --git a/packages/cli/src/compositions.ts b/packages/cli/src/compositions.ts index 0b6e60766c2..4ce4de087f5 100644 --- a/packages/cli/src/compositions.ts +++ b/packages/cli/src/compositions.ts @@ -29,6 +29,7 @@ const { askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, + rspackOption, browserExecutableOption, userAgentOption, disableWebSecurityOption, @@ -136,6 +137,7 @@ export const listCompositionsCommand = async ( const keyboardShortcutsEnabled = keyboardShortcutsOption.getValue({ commandLine: parsedCli, }).value; + const rspack = rspackOption.getValue({commandLine: parsedCli}).value; const shouldCache = bundleCacheOption.getValue({ commandLine: parsedCli, }).value; @@ -172,6 +174,7 @@ export const listCompositionsCommand = async ( experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }); diff --git a/packages/cli/src/config/index.ts b/packages/cli/src/config/index.ts index 9075b66ed2b..55ddecf735d 100644 --- a/packages/cli/src/config/index.ts +++ b/packages/cli/src/config/index.ts @@ -112,6 +112,7 @@ const { overrideWidthOption, overrideFpsOption, overrideDurationOption, + rspackOption, outDirOption, webpackPollOption, imageSequenceOption, @@ -184,6 +185,12 @@ declare global { readonly setExperimentalClientSideRenderingEnabled: ( enabled: boolean, ) => void; + /** + * Enable experimental Rspack bundler instead of Webpack. + * @param enabled Boolean whether to enable the Rspack bundler + * @default false + */ + readonly setExperimentalRspackEnabled: (enabled: boolean) => void; /** * Set number of shared audio tags. https://www.remotion.dev/docs/player/autoplay#using-the-numberofsharedaudiotags-prop * @param numberOfAudioTags @@ -662,6 +669,7 @@ export const Config: FlatConfig = { setKeyboardShortcutsEnabled: keyboardShortcutsOption.setConfig, setExperimentalClientSideRenderingEnabled: experimentalClientSideRenderingOption.setConfig, + setExperimentalRspackEnabled: rspackOption.setConfig, setNumberOfSharedAudioTags: numberOfSharedAudioTagsOption.setConfig, setWebpackPollingInMilliseconds: webpackPollOption.setConfig, setShouldOpenBrowser: noOpenOption.setConfig, diff --git a/packages/cli/src/config/preview-server.ts b/packages/cli/src/config/preview-server.ts index dcced81201d..6b0c42e00bf 100644 --- a/packages/cli/src/config/preview-server.ts +++ b/packages/cli/src/config/preview-server.ts @@ -1,5 +1,8 @@ +import {BrowserSafeApis} from '@remotion/renderer/client'; import {parsedCli} from '../parsed-cli'; +const {portOption} = BrowserSafeApis.options; + let studioPort: number | undefined; let rendererPort: number | undefined; @@ -53,5 +56,7 @@ export const getRendererPortFromConfigFile = () => { }; export const getRendererPortFromConfigFileAndCliFlag = (): number | null => { - return parsedCli.port ?? rendererPort ?? null; + return ( + portOption.getValue({commandLine: parsedCli}).value ?? rendererPort ?? null + ); }; diff --git a/packages/cli/src/get-config-file-name.ts b/packages/cli/src/get-config-file-name.ts index d95eb05f8f1..789fc6640ac 100644 --- a/packages/cli/src/get-config-file-name.ts +++ b/packages/cli/src/get-config-file-name.ts @@ -1,28 +1,28 @@ +import {BrowserSafeApis} from '@remotion/renderer/client'; import {existsSync} from 'node:fs'; import path from 'node:path'; import {loadConfigFile} from './load-config'; import {Log} from './log'; import {parsedCli} from './parsed-cli'; +const {configOption} = BrowserSafeApis.options; + const defaultConfigFileJavascript = 'remotion.config.js'; const defaultConfigFileTypescript = 'remotion.config.ts'; export const loadConfig = (remotionRoot: string): Promise => { - if (parsedCli.config) { - const fullPath = path.resolve(process.cwd(), parsedCli.config); + const configFile = configOption.getValue({commandLine: parsedCli}).value; + if (configFile) { + const fullPath = path.resolve(process.cwd(), configFile); if (!existsSync(fullPath)) { Log.error( {indent: false, logLevel: 'error'}, - `You specified a config file location of "${parsedCli.config}" but no file under ${fullPath} was found.`, + `You specified a config file location of "${configFile}" but no file under ${fullPath} was found.`, ); process.exit(1); } - return loadConfigFile( - remotionRoot, - parsedCli.config, - fullPath.endsWith('.js'), - ); + return loadConfigFile(remotionRoot, configFile, fullPath.endsWith('.js')); } if (remotionRoot === null) { diff --git a/packages/cli/src/get-input-props.ts b/packages/cli/src/get-input-props.ts index 2953eb51b13..0297e229be7 100644 --- a/packages/cli/src/get-input-props.ts +++ b/packages/cli/src/get-input-props.ts @@ -1,19 +1,23 @@ import type {LogLevel, LogOptions} from '@remotion/renderer'; +import {BrowserSafeApis} from '@remotion/renderer/client'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import {Log} from './log'; import {parsedCli} from './parsed-cli'; +const {propsOption} = BrowserSafeApis.options; + export const getInputProps = ( onUpdate: ((newProps: Record) => void) | null, logLevel: LogLevel, ): Record => { - if (!parsedCli.props) { + const props = propsOption.getValue({commandLine: parsedCli}).value; + if (!props) { return {}; } - const jsonFile = path.resolve(process.cwd(), parsedCli.props); + const jsonFile = path.resolve(process.cwd(), props); try { if (fs.existsSync(jsonFile)) { const rawJsonData = fs.readFileSync(jsonFile, 'utf-8'); @@ -38,18 +42,14 @@ export const getInputProps = ( return JSON.parse(rawJsonData); } - return JSON.parse(parsedCli.props); + return JSON.parse(props); } catch { Log.error( {indent: false, logLevel}, 'You passed --props but it was neither valid JSON nor a file path to a valid JSON file. Provided value: ' + - parsedCli.props, - ); - Log.info( - {indent: false, logLevel}, - 'Got the following value:', - parsedCli.props, + props, ); + Log.info({indent: false, logLevel}, 'Got the following value:', props); Log.error( {indent: false, logLevel}, 'Check that your input is parseable using `JSON.parse` and try again.', diff --git a/packages/cli/src/parsed-cli.ts b/packages/cli/src/parsed-cli.ts index c78f8a1f1ae..7d3b6ca3133 100644 --- a/packages/cli/src/parsed-cli.ts +++ b/packages/cli/src/parsed-cli.ts @@ -68,6 +68,10 @@ const { forSeamlessAacConcatenationOption, isProductionOption, noOpenOption, + portOption, + propsOption, + configOption, + browserOption, } = BrowserSafeApis.options; export type CommandLineOptions = { @@ -104,7 +108,7 @@ export type CommandLineOptions = { [videoCodecOption.cliFlag]: TypeOfOption; [concurrencyOption.cliFlag]: TypeOfOption; timeout: number; - config: string; + [configOption.cliFlag]: TypeOfOption; ['public-dir']: string; [audioBitrateOption.cliFlag]: TypeOfOption; [videoBitrateOption.cliFlag]: TypeOfOption; @@ -119,7 +123,7 @@ export type CommandLineOptions = { output: string | undefined; [overwriteOption.cliFlag]: TypeOfOption; png: boolean; - props: string; + [propsOption.cliFlag]: TypeOfOption; quality: number; [jpegQualityOption.cliFlag]: TypeOfOption; frames: string | number; @@ -129,7 +133,7 @@ export type CommandLineOptions = { q: boolean; [logLevelOption.cliFlag]: TypeOfOption; help: boolean; - port: number; + [portOption.cliFlag]: TypeOfOption; [stillFrameOption.cliFlag]: TypeOfOption; [headlessOption.cliFlag]: TypeOfOption; [keyboardShortcutsOption.cliFlag]: TypeOfOption< @@ -150,7 +154,7 @@ export type CommandLineOptions = { [packageManagerOption.cliFlag]: TypeOfOption; [webpackPollOption.cliFlag]: TypeOfOption; [noOpenOption.cliFlag]: TypeOfOption; - ['browser']: string; + [browserOption.cliFlag]: TypeOfOption; ['browser-args']: string; [userAgentOption.cliFlag]: TypeOfOption; [outDirOption.cliFlag]: TypeOfOption; diff --git a/packages/cli/src/render-flows/render.ts b/packages/cli/src/render-flows/render.ts index 995f2a80440..c63c7c32356 100644 --- a/packages/cli/src/render-flows/render.ts +++ b/packages/cli/src/render-flows/render.ts @@ -126,6 +126,7 @@ export const renderVideoFlow = async ({ audioLatencyHint, imageSequencePattern, mediaCacheSizeInBytes, + rspack, askAIEnabled, experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, @@ -192,6 +193,7 @@ export const renderVideoFlow = async ({ audioLatencyHint: AudioContextLatencyCategory | null; imageSequencePattern: string | null; mediaCacheSizeInBytes: number | null; + rspack: boolean; askAIEnabled: boolean; experimentalClientSideRenderingEnabled: boolean; keyboardShortcutsEnabled: boolean; @@ -345,6 +347,7 @@ export const renderVideoFlow = async ({ experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }, ); diff --git a/packages/cli/src/render-flows/still.ts b/packages/cli/src/render-flows/still.ts index d18a3298002..e85fda2e2a8 100644 --- a/packages/cli/src/render-flows/still.ts +++ b/packages/cli/src/render-flows/still.ts @@ -84,6 +84,7 @@ export const renderStillFlow = async ({ offthreadVideoThreads, audioLatencyHint, mediaCacheSizeInBytes, + rspack, askAIEnabled, experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, @@ -124,6 +125,7 @@ export const renderStillFlow = async ({ chromeMode: ChromeMode; audioLatencyHint: AudioContextLatencyCategory | null; mediaCacheSizeInBytes: number | null; + rspack: boolean; askAIEnabled: boolean; experimentalClientSideRenderingEnabled: boolean; keyboardShortcutsEnabled: boolean; @@ -231,6 +233,7 @@ export const renderStillFlow = async ({ experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }, ); diff --git a/packages/cli/src/render-queue/process-still.ts b/packages/cli/src/render-queue/process-still.ts index 8a642d4b3e9..72dd4c27e6c 100644 --- a/packages/cli/src/render-queue/process-still.ts +++ b/packages/cli/src/render-queue/process-still.ts @@ -10,6 +10,7 @@ const { askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, + rspackOption, browserExecutableOption, bundleCacheOption, } = BrowserSafeApis.options; @@ -49,6 +50,7 @@ export const processStill = async ({ const shouldCache = bundleCacheOption.getValue({ commandLine: parsedCli, }).value; + const rspack = rspackOption.getValue({commandLine: parsedCli}).value; const fullEntryPoint = convertEntryPointToServeUrl(entryPoint); @@ -92,6 +94,7 @@ export const processStill = async ({ askAIEnabled, experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }); }; diff --git a/packages/cli/src/render-queue/process-video.ts b/packages/cli/src/render-queue/process-video.ts index a6618ae9b12..48cd17f981a 100644 --- a/packages/cli/src/render-queue/process-video.ts +++ b/packages/cli/src/render-queue/process-video.ts @@ -12,6 +12,7 @@ const { askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, + rspackOption, browserExecutableOption, bundleCacheOption, } = BrowserSafeApis.options; @@ -54,7 +55,9 @@ export const processVideoJob = async ({ const browserExecutable = browserExecutableOption.getValue({ commandLine: parsedCli, }).value; + const rspack = rspackOption.getValue({commandLine: parsedCli}).value; const fullEntryPoint = convertEntryPointToServeUrl(entryPoint); + await renderVideoFlow({ remotionRoot, browser: 'chrome', @@ -127,6 +130,7 @@ export const processVideoJob = async ({ experimentalClientSideRenderingOption.getValue({commandLine: parsedCli}) .value, keyboardShortcutsEnabled, + rspack, shouldCache, }); }; diff --git a/packages/cli/src/render.tsx b/packages/cli/src/render.tsx index bcdee69c71e..14019592554 100644 --- a/packages/cli/src/render.tsx +++ b/packages/cli/src/render.tsx @@ -48,6 +48,7 @@ const { askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, + rspackOption, pixelFormatOption, browserExecutableOption, everyNthFrameOption, @@ -222,6 +223,7 @@ export const render = async ( const keyboardShortcutsEnabled = keyboardShortcutsOption.getValue({ commandLine: parsedCli, }).value; + const rspack = rspackOption.getValue({commandLine: parsedCli}).value; const chromiumOptions: Required = { disableWebSecurity, @@ -250,6 +252,10 @@ export const render = async ( const shouldCache = bundleCacheOption.getValue({ commandLine: parsedCli, }).value; + const experimentalClientSideRenderingEnabled = + experimentalClientSideRenderingOption.getValue({ + commandLine: parsedCli, + }).value; await renderVideoFlow({ fullEntryPoint, @@ -321,10 +327,9 @@ export const render = async ( audioLatencyHint, imageSequencePattern, askAIEnabled, - experimentalClientSideRenderingEnabled: - experimentalClientSideRenderingOption.getValue({commandLine: parsedCli}) - .value, + experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }); }; diff --git a/packages/cli/src/setup-cache.ts b/packages/cli/src/setup-cache.ts index 517758fe312..136595ab081 100644 --- a/packages/cli/src/setup-cache.ts +++ b/packages/cli/src/setup-cache.ts @@ -35,6 +35,7 @@ export const bundleOnCliOrTakeServeUrl = async ({ experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }: { fullPath: string; @@ -58,6 +59,7 @@ export const bundleOnCliOrTakeServeUrl = async ({ experimentalClientSideRenderingEnabled: boolean; askAIEnabled: boolean; keyboardShortcutsEnabled: boolean; + rspack: boolean; shouldCache: boolean; }): Promise<{ urlOrBundle: string; @@ -102,6 +104,7 @@ export const bundleOnCliOrTakeServeUrl = async ({ experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }); @@ -130,6 +133,7 @@ export const bundleOnCli = async ({ experimentalClientSideRenderingEnabled, askAIEnabled, keyboardShortcutsEnabled, + rspack, shouldCache, }: { fullPath: string; @@ -153,6 +157,7 @@ export const bundleOnCli = async ({ experimentalClientSideRenderingEnabled: boolean; keyboardShortcutsEnabled: boolean; askAIEnabled: boolean; + rspack: boolean; shouldCache: boolean; }) => { const symlinkState: SymbolicLinksState = { @@ -217,6 +222,7 @@ export const bundleOnCli = async ({ publicPath, askAIEnabled, keyboardShortcutsEnabled, + rspack, }; const [hash] = await BundlerInternals.getConfig({ diff --git a/packages/cli/src/still.ts b/packages/cli/src/still.ts index 3caf73681c8..2d6390a8dba 100644 --- a/packages/cli/src/still.ts +++ b/packages/cli/src/still.ts @@ -30,6 +30,7 @@ const { askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, + rspackOption, browserExecutableOption, userAgentOption, disableWebSecurityOption, @@ -155,6 +156,7 @@ export const still = async ( const keyboardShortcutsEnabled = keyboardShortcutsOption.getValue({ commandLine: parsedCli, }).value; + const rspack = rspackOption.getValue({commandLine: parsedCli}).value; const shouldCache = bundleCacheOption.getValue({ commandLine: parsedCli, }).value; @@ -217,6 +219,7 @@ export const still = async ( experimentalClientSideRenderingOption.getValue({commandLine: parsedCli}) .value, keyboardShortcutsEnabled, + rspack, shouldCache, }); }; diff --git a/packages/cli/src/studio.ts b/packages/cli/src/studio.ts index 69d2b337695..9f9d706a853 100644 --- a/packages/cli/src/studio.ts +++ b/packages/cli/src/studio.ts @@ -17,19 +17,6 @@ import { removeJob, } from './render-queue/queue'; -const getPort = () => { - if (parsedCli.port) { - return parsedCli.port; - } - - const serverPort = ConfigInternals.getStudioPort(); - if (serverPort) { - return serverPort; - } - - return null; -}; - const { binariesDirectoryOption, publicDirOption, @@ -42,8 +29,11 @@ const { numberOfSharedAudioTagsOption, audioLatencyHintOption, ipv4Option, + rspackOption, webpackPollOption, noOpenOption, + portOption, + browserOption, } = BrowserSafeApis.options; export const studioCommand = async ( @@ -79,7 +69,10 @@ export const studioCommand = async ( process.exit(1); } - const desiredPort = getPort(); + const desiredPort = + portOption.getValue({commandLine: parsedCli}).value ?? + ConfigInternals.getStudioPort() ?? + null; const fullEntryPath = convertEntryPointToServeUrl(file); @@ -144,10 +137,19 @@ export const studioCommand = async ( const gitSource = getGitSource({remotionRoot, disableGitSource, logLevel}); + const useRspack = rspackOption.getValue({commandLine: parsedCli}).value; + + if (useRspack) { + Log.warn( + {indent: false, logLevel}, + 'Enabling experimental Rspack bundler.', + ); + } + const result = await StudioServerInternals.startStudio({ previewEntry: require.resolve('@remotion/studio/previewEntry'), browserArgs: parsedCli['browser-args'], - browserFlag: parsedCli.browser, + browserFlag: browserOption.getValue({commandLine: parsedCli}).value ?? '', logLevel, shouldOpenBrowser: !noOpenOption.getValue({commandLine: parsedCli}).value, fullEntryPath, @@ -182,6 +184,7 @@ export const studioCommand = async ( enableCrossSiteIsolation, askAIEnabled, forceNew: forceNewStudioOption.getValue({commandLine: parsedCli}).value, + rspack: useRspack, }); if (result.type === 'already-running') { diff --git a/packages/cloudrun/src/api/deploy-site.ts b/packages/cloudrun/src/api/deploy-site.ts index bddb8316abf..149f2c8b337 100644 --- a/packages/cloudrun/src/api/deploy-site.ts +++ b/packages/cloudrun/src/api/deploy-site.ts @@ -31,6 +31,7 @@ type Options = { keyboardShortcutsEnabled?: boolean; askAIEnabled?: boolean; experimentalClientSideRenderingEnabled?: boolean; + rspack?: boolean; }; type OptionalParameters = { @@ -110,6 +111,7 @@ export const internalDeploySiteRaw = async ({ renderDefaults: null, askAIEnabled: options?.askAIEnabled ?? true, keyboardShortcutsEnabled: options?.keyboardShortcutsEnabled ?? true, + rspack: options?.rspack ?? false, }), ]); diff --git a/packages/discord-poster/post.ts b/packages/discord-poster/post.ts index 1d8ba2346fe..2efc659bab3 100644 --- a/packages/discord-poster/post.ts +++ b/packages/discord-poster/post.ts @@ -1,15 +1,20 @@ const DISCORD_MAX_LENGTH = 2000; -const latestRelease = await fetch( - 'https://api.github.com/repos/remotion-dev/remotion/releases?per_page=1', -); +const tag = process.argv[2]; -const json = await latestRelease.json(); +const url = tag + ? `https://api.github.com/repos/remotion-dev/remotion/releases/tags/${tag}` + : 'https://api.github.com/repos/remotion-dev/remotion/releases?per_page=1'; + +const latestRelease = await fetch(url); + +const response = await latestRelease.json(); +const release = tag ? response : response[0]; const markdown = [ - `${json[0].tag_name} has been released!`, - `<:merge:909914451447259177> ${json[0].html_url}`, - ...json[0].body.split('\n').map((s: string) => { + `${release.tag_name} has been released!`, + `<:merge:909914451447259177> ${release.html_url}`, + ...release.body.split('\n').map((s: string) => { if (s.startsWith('## ')) { return s.replace('## ', '**<:love:989990489824559104> ') + '**'; } diff --git a/packages/docs/docs/bundle.mdx b/packages/docs/docs/bundle.mdx index 9e669b158ce..69efbd388e6 100644 --- a/packages/docs/docs/bundle.mdx +++ b/packages/docs/docs/bundle.mdx @@ -66,13 +66,17 @@ Specify a desired output directory. If no passed, the webpack bundle will be cre +### `rspack?` + +Whether to use [Rspack](https://rspack.dev) instead of Webpack as the bundler. Default `false`. + ### `keyboardShortcutsEnabled?` -A `boolean` specifying whether the Studio responds to the predefined keyboard shortcuts.. Default `true`. + ### `enableCaching?` -A `boolean` specifying whether Webpack caching should be enabled. Default `true`, it is recommended to leave caching enabled at all times since file changes should be recognized by Webpack nonetheless. + ### `publicPath?` @@ -88,7 +92,7 @@ The current working directory is the directory from which your program gets exec ### `publicDir?` -Set the directory in which the files that can be loaded using [`staticFile()`](/docs/staticfile) are located. By default it is the folder `public/` located in the [Remotion Root](/docs/terminology/remotion-root). If you pass a relative path, it will be resolved against the [Remotion Root](/docs/terminology/remotion-root). + ### `onPublicDirCopyProgress?` diff --git a/packages/docs/docs/cli/benchmark.mdx b/packages/docs/docs/cli/benchmark.mdx index dcbaba37eee..beb92871998 100644 --- a/packages/docs/docs/cli/benchmark.mdx +++ b/packages/docs/docs/cli/benchmark.mdx @@ -179,6 +179,10 @@ Inherited from [`npx remotion render`](/docs/cli/render#--audio-bitrate) +### `--experimental-rspack` + + + ### ~~`--ffmpeg-executable`~~ Removed in v4.0. Inherited from [`npx remotion render`](/docs/cli/render#--ffmpeg-executable) diff --git a/packages/docs/docs/cli/browser/index.mdx b/packages/docs/docs/cli/browser/index.mdx index f2ed162601d..61a55282b63 100644 --- a/packages/docs/docs/cli/browser/index.mdx +++ b/packages/docs/docs/cli/browser/index.mdx @@ -1,11 +1,11 @@ --- image: /generated/articles-docs-cli-browser-index.png title: npx remotion browser -crumb: "@remotion/cli" -sidebar_label: "browser" +crumb: '@remotion/cli' +sidebar_label: 'browser' --- -import { TableOfContents } from "./table-of-contents"; +import {TableOfContents} from './table-of-contents'; # npx remotion browser diff --git a/packages/docs/docs/cli/browser/table-of-contents.tsx b/packages/docs/docs/cli/browser/table-of-contents.tsx index 59fd4770e1a..fc6a53ec1e0 100644 --- a/packages/docs/docs/cli/browser/table-of-contents.tsx +++ b/packages/docs/docs/cli/browser/table-of-contents.tsx @@ -1,16 +1,16 @@ -import React from "react"; -import { Grid } from "../../../components/TableOfContents/Grid"; -import { TOCItem } from "../../../components/TableOfContents/TOCItem"; +import React from 'react'; +import {Grid} from '../../../components/TableOfContents/Grid'; +import {TOCItem} from '../../../components/TableOfContents/TOCItem'; export const TableOfContents: React.FC = () => { - return ( -
- - - browser ensure -
Ensure Remotion has a browser to render
-
-
-
- ); -}; \ No newline at end of file + return ( +
+ + + browser ensure +
Ensure Remotion has a browser to render
+
+
+
+ ); +}; diff --git a/packages/docs/docs/cli/bundle.mdx b/packages/docs/docs/cli/bundle.mdx index 9693cf2d54b..a5ac2b154eb 100644 --- a/packages/docs/docs/cli/bundle.mdx +++ b/packages/docs/docs/cli/bundle.mdx @@ -20,7 +20,7 @@ You may pass a [Serve URL](/docs/terminology/serve-url) or an [entry point](/doc ### `--config` -Specify a location for the Remotion config file. + ### `--log` @@ -41,3 +41,7 @@ Specify a location for the Remotion config file. ### `--disable-git-source` + +### `--experimental-rspack` + + diff --git a/packages/docs/docs/cli/compositions.mdx b/packages/docs/docs/cli/compositions.mdx index fe2a9d6d5d9..cc37695aba8 100644 --- a/packages/docs/docs/cli/compositions.mdx +++ b/packages/docs/docs/cli/compositions.mdx @@ -19,10 +19,7 @@ You may pass a [Serve URL](/docs/terminology/serve-url) or an [entry point](/doc ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. @@ -30,7 +27,7 @@ Inline JSON string isn't supported on Windows shells because it removes the `"` ### `--config` -Specify a location for the Remotion config file. + ### `--env-file` @@ -50,7 +47,7 @@ If you don't feel like passing command line flags every time, consider creating ### `--port` -[Set a custom HTTP server port to host the Webpack bundle](/docs/config#setport). If not defined, Remotion will try to find a free port. + ### `--public-dir` diff --git a/packages/docs/docs/cli/render.mdx b/packages/docs/docs/cli/render.mdx index 03ce7785b00..c731cc10bb8 100644 --- a/packages/docs/docs/cli/render.mdx +++ b/packages/docs/docs/cli/render.mdx @@ -22,10 +22,7 @@ Besides choosing a video and output location with the command line arguments, th ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. @@ -65,7 +62,7 @@ Inline JSON string isn't supported on Windows shells because it removes the `"` ### `--config` -Specify a location for the Remotion config file. + ### `--env-file` @@ -187,7 +184,7 @@ Disallows the renderer from doing rendering frames and encoding at the same time ### `--port` -[Set a custom HTTP server port that will be used to host the Webpack bundle](/docs/config#setrendererport). If not defined, Remotion will try to find a free port. + ### `--public-dir` @@ -249,6 +246,10 @@ Not to be confused with the [`--timeout` flag when deploying a Lambda function]( +### `--experimental-rspack` + + + ### `--for-seamless-aac-concatenation` diff --git a/packages/docs/docs/cli/still.mdx b/packages/docs/docs/cli/still.mdx index b745899b208..d2844c7a5ae 100644 --- a/packages/docs/docs/cli/still.mdx +++ b/packages/docs/docs/cli/still.mdx @@ -22,10 +22,7 @@ If `composition-id` is also not passed, Remotion will let you select a compositi ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. @@ -37,7 +34,7 @@ Inline JSON string isn't supported on Windows shells because it removes the `"` ### `--config` -Specify a location for the Remotion config file. + ### `--env-file` @@ -81,7 +78,7 @@ Sets the output file path, as an alternative to the `output-location` positional ### `--port` -[Set a custom HTTP server port to serve the Webpack bundle](/docs/config#setport). If not defined, Remotion will try to find a free port. + ### `--public-dir` @@ -143,6 +140,10 @@ Not to be confused with the [`--timeout` flag when deploying a Lambda function]( +### `--experimental-rspack` + + + ### ~~`--ffmpeg-executable`~~ _removed in v4.0_ diff --git a/packages/docs/docs/cli/studio.mdx b/packages/docs/docs/cli/studio.mdx index 82a0fc0dd81..7411636eaa3 100644 --- a/packages/docs/docs/cli/studio.mdx +++ b/packages/docs/docs/cli/studio.mdx @@ -19,12 +19,7 @@ You may pass an [entry point](/docs/terminology/entry-point) as an argument, oth ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -We don't recommend passing this flag when using the Studio - use [`defaultProps`](/docs/composition#defaultprops) instead. - -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. @@ -32,7 +27,7 @@ Inline JSON string isn't supported on Windows shells because it removes the `"` ### `--config` -Specify a location for the Remotion config file. + ### `--env-file` @@ -44,7 +39,7 @@ Specify a location for the Remotion config file. ### `--port` -[Set a custom HTTP server port to start the server on](/docs/config#setstudioport). If not defined, Remotion will try to find a free port. + ### `--public-dir` @@ -58,6 +53,10 @@ Specify a location for the Remotion config file. +### `--experimental-rspack` + + + ### `--webpack-poll` @@ -68,11 +67,13 @@ Specify a location for the Remotion config file. ### `--browser` -Specify the browser which should be used for opening tab - using the default browser by default. -Pass an absolute string or `"chrome"` to use Chrome. -If Chrome is selected as the browser and you are on macOS, Remotion will try to reuse an existing tab + + +You can also configure the browser via environment variables for backwards compatibility: -For backwards compatibility, the `BROWSER` environment variable is also supported. +- `BROWSER` behaves like the `--browser` flag. +- `BROWSER_ARGS` behaves like the `--browser-args` flag. +- Setting `BROWSER=none` disables auto-opening of the browser (equivalent to `--no-open`). ### `--browser-args` diff --git a/packages/docs/docs/client-side-rendering/limitations.mdx b/packages/docs/docs/client-side-rendering/limitations.mdx index 581dff16b68..d8be452cf7c 100644 --- a/packages/docs/docs/client-side-rendering/limitations.mdx +++ b/packages/docs/docs/client-side-rendering/limitations.mdx @@ -64,7 +64,7 @@ The `text-transform` property is supported. The `direction` HTML attribute is supported. The `writing-mode` property is not supported. The `text-decoration` property is not supported. -The `text-shadow` property is not supported. +The `text-shadow` property is supported. The `-webkit-text-stroke` property is not supported. ## Shadows diff --git a/packages/docs/docs/cloudrun/cli/render.mdx b/packages/docs/docs/cloudrun/cli/render.mdx index b769e5d6319..c0f83e4ea85 100644 --- a/packages/docs/docs/cloudrun/cli/render.mdx +++ b/packages/docs/docs/cloudrun/cli/render.mdx @@ -53,10 +53,7 @@ The [GCP region](/docs/cloudrun/region-selection) to select. For lowest latency, ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. diff --git a/packages/docs/docs/cloudrun/cli/still.mdx b/packages/docs/docs/cloudrun/cli/still.mdx index e394caf6491..14240113033 100644 --- a/packages/docs/docs/cloudrun/cli/still.mdx +++ b/packages/docs/docs/cloudrun/cli/still.mdx @@ -53,10 +53,7 @@ The [GCP region](/docs/cloudrun/region-selection) to select. For lowest latency, ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. diff --git a/packages/docs/docs/cloudrun/deploysite.mdx b/packages/docs/docs/cloudrun/deploysite.mdx index 09908d52862..b3e9e8a7c76 100644 --- a/packages/docs/docs/cloudrun/deploysite.mdx +++ b/packages/docs/docs/cloudrun/deploysite.mdx @@ -56,6 +56,10 @@ The bucket to where the website will be deployed. The bucket must have been crea Specify the subfolder in your Cloud Storage bucket that you want the site to deploy to. If you omit this property, a new subfolder with a random name will be created. If a site already exists with the name you passed, it will be overwritten. Can only contain the following characters: `0-9`, `a-z`, `A-Z`, `-`, `!`, `_`, `.`, `*`, `'`, `(`, `)` +### `logLevel?` + + + ### `options?` An object with the following properties: @@ -79,11 +83,11 @@ Allows to pass a custom webpack override. See [`bundle()` -> webpackOverride](/d #### `enableCaching?` -Whether webpack caching should be enabled. See [`bundle()` -> enableCaching](/docs/bundle#enablecaching) for more information. + #### `publicDir?` -Set the directory in which the files that can be loaded using [`staticFile()`](/docs/staticfile) are located. By default it is the folder `public/` located in the [Remotion Root](/docs/terminology/remotion-root) folder. If you pass a relative path, it will be resolved against the [Remotion Root](/docs/terminology/remotion-root). + #### `rootDir?` @@ -99,21 +103,19 @@ Ignore an error that gets thrown if you pass an entry point file which does not #### `keyboardShortcutsEnabled?` -_default: `true`_ - -Whether keyboard shortcuts should be enabled in the Studio. See [Config.setKeyboardShortcutsEnabled()](/docs/config#setkeyboardshortcutsenabled) for more information. + #### `askAIEnabled?` -_default: `true`_ - -Whether the Ask AI option should be enabled in the Studio. See [Config.setAskAIEnabled()](/docs/config#setaskaienabled) for more information. + #### `experimentalClientSideRenderingEnabled?` -_default: `false`_ + + +#### `rspack?` -Whether experimental client-side rendering should be enabled in the Studio. See [Config.setExperimentalClientSideRenderingEnabled()](/docs/config#setexperimentalclientsiderenderingenabled) for more information. + ## Return value diff --git a/packages/docs/docs/config.mdx b/packages/docs/docs/config.mdx index ce493f274cf..3a5c784a0ba 100644 --- a/packages/docs/docs/config.mdx +++ b/packages/docs/docs/config.mdx @@ -175,6 +175,18 @@ Config.setExperimentalClientSideRenderingEnabled(true); The [command line flag](/docs/cli/studio#--enable-experimental-client-side-rendering) `--enable-experimental-client-side-rendering` will take precedence over this option. +## `setExperimentalRspackEnabled()` + +Use [Rspack](https://rspack.dev) instead of Webpack as the bundler for the Studio. Default `false`. + +```ts twoslash title="remotion.config.ts" +import {Config} from '@remotion/cli/config'; +// ---cut--- +Config.setExperimentalRspackEnabled(true); +``` + +The [command line flag](/docs/cli/studio#--experimental-rspack) `--experimental-rspack` will take precedence over this option. + ## `setWebpackPollingInMilliseconds()` @@ -980,6 +992,18 @@ Config.setPublicLicenseKey('your-license-key'); The [command line flag](/docs/cli/studio#--public-license-key) `--public-license-key` will take precedence over this option. +## `setImageSequencePattern()` + + + +```ts twoslash title="remotion.config.ts" +import {Config} from '@remotion/cli/config'; +// ---cut--- +Config.setImageSequencePattern('frame_[frame]_custom.[ext]'); +``` + +The [command line flag](/docs/cli/render#--image-sequence-pattern) `--image-sequence-pattern` will take precedence over this option. + ## ~~`setQuality()`~~ Renamed to `setJpegQuality` in `v4.0.0`. @@ -1094,18 +1118,6 @@ Config.overrideWebpackConfig(async (currentConfiguration) => { }); ``` -### `setImageSequencePattern()` - - - -```ts twoslash title="remotion.config.ts" -import {Config} from '@remotion/cli/config'; -// ---cut--- -Config.setImageSequencePattern('frame_[frame]_custom.[ext]'); -``` - -The [command line flag](/docs/cli/render#--image-sequence-pattern) `--image-sequence-pattern` will take precedence over this option. - ## Old config file format In v3.3.39, a new config file format was introduced which flattens the options so they can more easily be discovered using TypeScript autocompletion. diff --git a/packages/docs/docs/lambda/cli/compositions.mdx b/packages/docs/docs/lambda/cli/compositions.mdx index 0faefd61943..4290f50b74b 100644 --- a/packages/docs/docs/lambda/cli/compositions.mdx +++ b/packages/docs/docs/lambda/cli/compositions.mdx @@ -66,10 +66,7 @@ You should use `npx remotion lambda compositions` if you cannot use [`npx remoti ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. @@ -77,7 +74,7 @@ Inline JSON string isn't supported on Windows shells because it removes the `"` ### `--config` -Specify a location for the Remotion config file. + ### `--env-file` diff --git a/packages/docs/docs/lambda/cli/functions.mdx b/packages/docs/docs/lambda/cli/functions.mdx index 9bee56febc1..669a537bd4b 100644 --- a/packages/docs/docs/lambda/cli/functions.mdx +++ b/packages/docs/docs/lambda/cli/functions.mdx @@ -17,4 +17,4 @@ You only need one function per AWS region and Remotion version. Suggested readin ## See also - [Do I need to deploy a function for each render?](/docs/lambda/faq#do-i-need-to-deploy-a-function-for-each-render) -- [Setup guide](/docs/lambda/setup) \ No newline at end of file +- [Setup guide](/docs/lambda/setup) diff --git a/packages/docs/docs/lambda/cli/functions/ls.mdx b/packages/docs/docs/lambda/cli/functions/ls.mdx index 095d423df47..5c5f83993ef 100644 --- a/packages/docs/docs/lambda/cli/functions/ls.mdx +++ b/packages/docs/docs/lambda/cli/functions/ls.mdx @@ -37,4 +37,4 @@ The [AWS region](/docs/lambda/region-selection) to select. ## `--quiet`, `-q` -Prints only the function names in a space-separated list. If no functions exist, prints `()` \ No newline at end of file +Prints only the function names in a space-separated list. If no functions exist, prints `()` diff --git a/packages/docs/docs/lambda/cli/functions/rm.mdx b/packages/docs/docs/lambda/cli/functions/rm.mdx index 670dea74452..f64b75f0a9a 100644 --- a/packages/docs/docs/lambda/cli/functions/rm.mdx +++ b/packages/docs/docs/lambda/cli/functions/rm.mdx @@ -35,4 +35,4 @@ The [AWS region](/docs/lambda/region-selection) to select. ## `--yes`, `-y` -Skips confirmation. \ No newline at end of file +Skips confirmation. diff --git a/packages/docs/docs/lambda/cli/functions/rmall.mdx b/packages/docs/docs/lambda/cli/functions/rmall.mdx index 26e4bbaab7b..1cc4d763c29 100644 --- a/packages/docs/docs/lambda/cli/functions/rmall.mdx +++ b/packages/docs/docs/lambda/cli/functions/rmall.mdx @@ -42,4 +42,4 @@ The [AWS region](/docs/lambda/region-selection) to select. ## `--yes`, `-y` -Skips confirmation. \ No newline at end of file +Skips confirmation. diff --git a/packages/docs/docs/lambda/cli/regions.mdx b/packages/docs/docs/lambda/cli/regions.mdx index 044338ace8e..bae3310a16f 100644 --- a/packages/docs/docs/lambda/cli/regions.mdx +++ b/packages/docs/docs/lambda/cli/regions.mdx @@ -14,12 +14,7 @@ npx remotion lambda regions
Show output -
-    eu-central-1 eu-west-1 eu-west-2 eu-west-3 eu-south-1 eu-north-1 us-east-1
-    us-east-2 us-west-1 us-west-2 af-south-1 ap-south-1 ap-east-1 ap-southeast-1
-    ap-southeast-2 ap-northeast-3 ap-northeast-1 ap-northeast-2 ca-central-1
-    me-south-1 sa-east-1
-  
+
eu-central-1 eu-west-1 eu-west-2 eu-west-3 eu-south-1 eu-north-1 us-east-1 us-east-2 us-west-1 us-west-2 af-south-1 ap-south-1 ap-east-1 ap-southeast-1 ap-southeast-2 ap-northeast-3 ap-northeast-1 ap-northeast-2 ca-central-1 me-south-1 sa-east-1
## Flags diff --git a/packages/docs/docs/lambda/cli/render.mdx b/packages/docs/docs/lambda/cli/render.mdx index 987ef428455..9331f5f3803 100644 --- a/packages/docs/docs/lambda/cli/render.mdx +++ b/packages/docs/docs/lambda/cli/render.mdx @@ -79,10 +79,7 @@ The [AWS region](/docs/lambda/region-selection) to select. Both project and func ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. diff --git a/packages/docs/docs/lambda/cli/sites.mdx b/packages/docs/docs/lambda/cli/sites.mdx index dabc986f465..16195e67781 100644 --- a/packages/docs/docs/lambda/cli/sites.mdx +++ b/packages/docs/docs/lambda/cli/sites.mdx @@ -10,4 +10,4 @@ The `npx remotion lambda sites` command allows to create, view and delete Remoti - [`create`](/docs/lambda/cli/sites/create) - [`ls`](/docs/lambda/cli/sites/ls) - [`rm`](/docs/lambda/cli/sites/rm) -- [`rmall`](/docs/lambda/cli/sites/rmall) \ No newline at end of file +- [`rmall`](/docs/lambda/cli/sites/rmall) diff --git a/packages/docs/docs/lambda/cli/sites/create.mdx b/packages/docs/docs/lambda/cli/sites/create.mdx index 77d3ca15992..e9250554507 100644 --- a/packages/docs/docs/lambda/cli/sites/create.mdx +++ b/packages/docs/docs/lambda/cli/sites/create.mdx @@ -86,4 +86,4 @@ Either `public` (default) or `no-acl` if you are not using ACL. Sites must have ## `--force-path-style` -Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. \ No newline at end of file +Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. diff --git a/packages/docs/docs/lambda/cli/sites/ls.mdx b/packages/docs/docs/lambda/cli/sites/ls.mdx index 7969edf8bd8..0c452b78512 100644 --- a/packages/docs/docs/lambda/cli/sites/ls.mdx +++ b/packages/docs/docs/lambda/cli/sites/ls.mdx @@ -28,7 +28,6 @@ Get a list of sites. The URL that is printed can be passed to the `render` comma - ## `--region` The [AWS region](/docs/lambda/region-selection) to select. Both project and function should be in this region. @@ -51,4 +50,4 @@ npx remotion lambda sites ls -q ## `--force-path-style` -Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. \ No newline at end of file +Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. diff --git a/packages/docs/docs/lambda/cli/sites/rm.mdx b/packages/docs/docs/lambda/cli/sites/rm.mdx index 36ad5059a9a..39ab89a1fb0 100644 --- a/packages/docs/docs/lambda/cli/sites/rm.mdx +++ b/packages/docs/docs/lambda/cli/sites/rm.mdx @@ -127,4 +127,4 @@ Specify a specific bucket name to be used. [This is not recommended](/docs/lambd ## `--force-path-style` -Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. \ No newline at end of file +Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. diff --git a/packages/docs/docs/lambda/cli/sites/rmall.mdx b/packages/docs/docs/lambda/cli/sites/rmall.mdx index b739a1970b1..f1ed906f290 100644 --- a/packages/docs/docs/lambda/cli/sites/rmall.mdx +++ b/packages/docs/docs/lambda/cli/sites/rmall.mdx @@ -126,4 +126,4 @@ Specify a specific bucket name to be used. [This is not recommended](/docs/lambd ## `--force-path-style` -Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. \ No newline at end of file +Passes `forcePathStyle` to the AWS S3 client. If you don't know what this is, you probably don't need it. diff --git a/packages/docs/docs/lambda/cli/still.mdx b/packages/docs/docs/lambda/cli/still.mdx index 67bfe43a050..52d8ce834b8 100644 --- a/packages/docs/docs/lambda/cli/still.mdx +++ b/packages/docs/docs/lambda/cli/still.mdx @@ -61,10 +61,7 @@ The [AWS region](/docs/lambda/region-selection) to select. Both project and func ### `--props` -[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli). -Must be a serialized JSON string (`--props='{"hello": "world"}'`) or a path to a JSON file (`./path/to/props.json`). -From the root component the props can be read using [`getInputProps()`](/docs/get-input-props). -You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata). + :::note Inline JSON string isn't supported on Windows shells because it removes the `"` character, use a file name instead. diff --git a/packages/docs/docs/lambda/deploysite.mdx b/packages/docs/docs/lambda/deploysite.mdx index efae1ff3574..3f01735ba8c 100644 --- a/packages/docs/docs/lambda/deploysite.mdx +++ b/packages/docs/docs/lambda/deploysite.mdx @@ -82,13 +82,13 @@ Allows to pass a custom webpack override. See [`bundle()` -> webpackOverride](/d #### `enableCaching?` -Whether webpack caching should be enabled. Default true. See [`bundle()` -> enableCaching](/docs/bundle#enablecaching) for more information. + #### `publicDir?` _available from v3.2.17_ -Set the directory in which the files that can be loaded using [`staticFile()`](/docs/staticfile) are located. By default it is the folder `public/` located in the [Remotion Root](/docs/terminology/remotion-root) folder. If you pass a relative path, it will be resolved against the [Remotion Root](/docs/terminology/remotion-root). + #### `rootDir?` @@ -108,21 +108,19 @@ Ignore an error that gets thrown if you pass an entry point file which does not #### `keyboardShortcutsEnabled?` -_default: `true`_ - -Whether keyboard shortcuts should be enabled in the Studio. See [Config.setKeyboardShortcutsEnabled()](/docs/config#setkeyboardshortcutsenabled) for more information. + #### `askAIEnabled?` -_default: `true`_ - -Whether the Ask AI option should be enabled in the Studio. See [Config.setAskAIEnabled()](/docs/config#setaskaienabled) for more information. + #### `experimentalClientSideRenderingEnabled?` -_default: `false`_ + + +#### `rspack?` -Whether experimental client-side rendering should be enabled in the Studio. See [Config.setExperimentalClientSideRenderingEnabled()](/docs/config#setexperimentalclientsiderenderingenabled) for more information. + ### `privacy?` diff --git a/packages/docs/docs/lambda/proxy.mdx b/packages/docs/docs/lambda/proxy.mdx index 161e5ab7827..eee54039c15 100644 --- a/packages/docs/docs/lambda/proxy.mdx +++ b/packages/docs/docs/lambda/proxy.mdx @@ -6,7 +6,7 @@ sidebar_label: Using a proxy crumb: 'Lambda' --- - +#Using a proxy with Remotion Lambda Remotion Lambda supports using HTTP/HTTPS proxies for all AWS API calls by accepting a `requestHandler` option that allows you to pass a custom AWS SDK request handler. diff --git a/packages/docs/docs/renderer/combine-chunks.mdx b/packages/docs/docs/renderer/combine-chunks.mdx index ce79c59f545..d2038c2a1b8 100644 --- a/packages/docs/docs/renderer/combine-chunks.mdx +++ b/packages/docs/docs/renderer/combine-chunks.mdx @@ -165,7 +165,11 @@ Metadata to add to the output file, in the format of key-value pairs. The function returns a Promise that resolves when the combining process is complete. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/combine-chunks.ts) -- [renderMedia()](/docs/renderer/render-media) +- [`renderMedia()`](/docs/renderer/render-media) diff --git a/packages/docs/docs/renderer/ensure-browser.mdx b/packages/docs/docs/renderer/ensure-browser.mdx index f9e7d91de16..9a394068dea 100644 --- a/packages/docs/docs/renderer/ensure-browser.mdx +++ b/packages/docs/docs/renderer/ensure-browser.mdx @@ -81,6 +81,10 @@ await ensureBrowser({ A promise with no value. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/ensure-browser.ts) diff --git a/packages/docs/docs/renderer/ensure-ffmpeg.mdx b/packages/docs/docs/renderer/ensure-ffmpeg.mdx index d30e6376efc..3b9486dbebf 100644 --- a/packages/docs/docs/renderer/ensure-ffmpeg.mdx +++ b/packages/docs/docs/renderer/ensure-ffmpeg.mdx @@ -5,7 +5,7 @@ title: ensureFfmpeg() crumb: '@remotion/renderer' --- - +# ensureFfmpeg() _Removed from v4.0_ diff --git a/packages/docs/docs/renderer/ensure-ffprobe.mdx b/packages/docs/docs/renderer/ensure-ffprobe.mdx index 38d7cad31c6..c42843ca5c4 100644 --- a/packages/docs/docs/renderer/ensure-ffprobe.mdx +++ b/packages/docs/docs/renderer/ensure-ffprobe.mdx @@ -5,8 +5,9 @@ title: ensureFfprobe() crumb: '@remotion/renderer' --- - +# ensureFfprobe() +_Part of the `@remotion/renderer` package._ _Removed from v4.0_ :::warning diff --git a/packages/docs/docs/renderer/extract-audio.mdx b/packages/docs/docs/renderer/extract-audio.mdx index 74f83835077..9f205fff932 100644 --- a/packages/docs/docs/renderer/extract-audio.mdx +++ b/packages/docs/docs/renderer/extract-audio.mdx @@ -7,10 +7,6 @@ crumb: '@remotion/renderer' # extractAudio() -:::note -This function is meant to be used **in Node.js applications**. It cannot run in the browser. -::: - Extracts the audio from a video source and saves it to the specified output path. It does not convert the audio to a different format. ## Example @@ -62,7 +58,11 @@ The path where the extracted audio will be saved. The file extension must match The function returns a `Promise`, which resolves once the audio extraction is complete. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/extract-audio.ts) -- [getVideoMetadata()](/docs/renderer/get-video-metadata) +- [`getVideoMetadata()`](/docs/renderer/get-video-metadata) diff --git a/packages/docs/docs/renderer/get-compositions.mdx b/packages/docs/docs/renderer/get-compositions.mdx index 01c56fea606..c0f321fc987 100644 --- a/packages/docs/docs/renderer/get-compositions.mdx +++ b/packages/docs/docs/renderer/get-compositions.mdx @@ -177,6 +177,10 @@ Returns a promise that resolves to an array of available compositions. Example v The `defaultProps` only get returned since v2.5.7. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/get-compositions.ts) diff --git a/packages/docs/docs/renderer/get-silent-parts.mdx b/packages/docs/docs/renderer/get-silent-parts.mdx index f24f14b8c24..3fa0aadd301 100644 --- a/packages/docs/docs/renderer/get-silent-parts.mdx +++ b/packages/docs/docs/renderer/get-silent-parts.mdx @@ -9,10 +9,6 @@ crumb: '@remotion/renderer' # getSilentParts() -:::note -This function is meant to be used **in Node.js applications**. It cannot run in the browser. -::: - Gets the silent parts of a video or audio in Node.js. Useful for cutting out silence from a video. ## Example @@ -86,7 +82,11 @@ An array of objects with the following properties: The time length of the media in seconds. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/get-silent-parts.ts) -- [getVideoMetadata()](/docs/renderer/get-video-metadata) +- [`getVideoMetadata()`](/docs/renderer/get-video-metadata) diff --git a/packages/docs/docs/renderer/get-video-metadata.mdx b/packages/docs/docs/renderer/get-video-metadata.mdx index c134144a71a..6d034447127 100644 --- a/packages/docs/docs/renderer/get-video-metadata.mdx +++ b/packages/docs/docs/renderer/get-video-metadata.mdx @@ -120,10 +120,14 @@ If the video has no audio track or is unknown to Remotion, it is `null`. Otherwi One of `yuv420p`, `yuyv422`, `rgb24`, `bgr24`, `yuv422p`, `yuv444p`, `yuv410p`, `yuv411p`, `yuvj420p`, `yuvj422p`, `yuvj444p`, `argb`, `rgba`, `abgr`, `bgra`, `yuv440p`, `yuvj440p`, `yuva420p`, `yuv420p16le`, `yuv420p16be`, `yuv422p16le`, `yuv422p16be`, `yuv444p16le`, `yuv444p16be`, `yuv420p9be`, `yuv420p9le`, `yuv420p10be`, `yuv420p10le`, `yuv422p10be`, `yuv422p10le`, `yuv444p9be`, `yuv444p9le`, `yuv444p10be`, `yuv444p10le`, `yuv422p9be`, `yuv422p9le`, `yuva420p9be`, `yuva420p9le`, `yuva422p9be`, `yuva422p9le`, `yuva444p9be`, `yuva444p9le`, `yuva420p10be`, `yuva420p10le`, `yuva422p10be`, `yuva422p10le`, `yuva444p10be`, `yuva444p10le`, `yuva420p16be`, `yuva420p16le`, `yuva422p16be`, `yuva422p16le`, `yuva444p16be`, `yuva444p16le`, `yuva444p`, `yuva422p`, `yuv420p12be`, `yuv420p12le`, `yuv420p14be`, `yuv420p14le`, `yuv422p12be`, `yuv422p12le`, `yuv422p14be`, `yuv422p14le`, `yuv444p12be`, `yuv444p12le`, `yuv444p14be`, `yuv444p14le`, `yuvj411p`, `yuv440p10le`, `yuv440p10be`, `yuv440p12le`, `yuv440p12be`, `yuv420p9`, `yuv422p9`, `yuv444p9`, `yuv420p10`, `yuv422p10`, `yuv440p10`, `yuv444p10`, `yuv420p12`, `yuv422p12`, `yuv440p12`, `yuv444p12`, `yuv420p14`, `yuv422p14`, `yuv444p14`, `yuv420p16`, `yuv422p16`, `yuv444p16`, `yuva420p9`, `yuva422p9`, `yuva444p9`, `yuva420p10`, `yuva422p10`, `yuva444p10`, `yuva420p16`, `yuva422p16`, `yuva444p16`, `yuva422p12be`, `yuva422p12le`, `yuva444p12be`, `yuva444p12le`, `unknown`. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/get-video-metadata.ts) - [Server-Side rendering](/docs/ssr) -- [getCompositions()](/docs/renderer/get-compositions) -- [renderStill()](/docs/renderer/stitch-frames-to-video) -- [renderMediaOnLambda()](/docs/lambda/rendermediaonlambda) +- [`getCompositions()`](/docs/renderer/get-compositions) +- [`renderStill()`](/docs/renderer/render-still) +- [`renderMediaOnLambda()`](/docs/lambda/rendermediaonlambda) diff --git a/packages/docs/docs/renderer/make-cancel-signal.mdx b/packages/docs/docs/renderer/make-cancel-signal.mdx index 758591bb298..0d891dee636 100644 --- a/packages/docs/docs/renderer/make-cancel-signal.mdx +++ b/packages/docs/docs/renderer/make-cancel-signal.mdx @@ -5,7 +5,9 @@ title: makeCancelSignal() crumb: '@remotion/renderer' --- - +# makeCancelSignal() + +_Part of the `@remotion/renderer` package._ This function returns a signal and a cancel function that allows to you cancel a render triggered using [`renderMedia()`](/docs/renderer/render-media), [`renderStill()`](/docs/renderer/render-still), [`renderFrames()`](/docs/renderer/render-frames) or [`stitchFramesToVideo()`](/docs/renderer/stitch-frames-to-video) . @@ -61,6 +63,10 @@ Calling `makeCancelSignal` returns an object with two properties: - `cancelSignal`: An object to be passed to one of the above mentioned render functions - `cancel`: A function you should call when you want to cancel the render. +## Compatibility + + + ## See also - [Source code for this component](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/make-cancel-signal.ts) diff --git a/packages/docs/docs/renderer/open-browser.mdx b/packages/docs/docs/renderer/open-browser.mdx index 6e135b04ea7..cbb13590a61 100644 --- a/packages/docs/docs/renderer/open-browser.mdx +++ b/packages/docs/docs/renderer/open-browser.mdx @@ -77,6 +77,10 @@ browser.close({silent: true}); If already closed or an operation is interrupted, an error is thrown. Setting the `silent` option to `true` will close the browser without generating an error. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/open-browser.ts) diff --git a/packages/docs/docs/renderer/render-frames.mdx b/packages/docs/docs/renderer/render-frames.mdx index aa540513aba..70b5dd8d9d7 100644 --- a/packages/docs/docs/renderer/render-frames.mdx +++ b/packages/docs/docs/renderer/render-frames.mdx @@ -326,12 +326,16 @@ A promise resolving to an object containing the following properties: - `frameCount`: `number` - describing how many frames got rendered. - `assetsInfo`: `RenderAssetInfo` - information that can be passed to `stitchFramesToVideo()` to mix audio. The shape of this object should be considered as Remotion internals and may change across Remotion versions. +## Compatibility + + + ## See also - [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/render-frames.ts) -- [renderMedia()](/docs/renderer/render-media) -- [bundle()](/docs/bundle) +- [`renderMedia()`](/docs/renderer/render-media) +- [`bundle()`](/docs/bundle) - [Server-Side rendering](/docs/ssr) -- [getCompositions()](/docs/renderer/get-compositions) -- [stitchFramesToVideo()](/docs/renderer/stitch-frames-to-video) -- [renderStill()](/docs/renderer/render-still) +- [`getCompositions()`](/docs/renderer/get-compositions) +- [`stitchFramesToVideo()`](/docs/renderer/stitch-frames-to-video) +- [`renderStill()`](/docs/renderer/render-still) diff --git a/packages/docs/docs/renderer/render-media.mdx b/packages/docs/docs/renderer/render-media.mdx index 30269d41bee..cfe45129a95 100644 --- a/packages/docs/docs/renderer/render-media.mdx +++ b/packages/docs/docs/renderer/render-media.mdx @@ -549,15 +549,20 @@ The return value is an object with the following properties: - `buffer`: If `outputLocation` is not specified or `null`, contains a buffer, otherwise `null`. - `slowestFrames`: An array of the 10 slowest frames in the shape of `{frame:, time: