资讯动态

@remotion/vercel:在 Vercel Sandbox 中渲染 Remotion 视频的完整技术解析

发布时间:2026/9/8 19:43:30 来源:尧图企业网站定制
remotion/vercel在 Vercel Sandbox 中渲染 Remotion 视频的完整技术解析【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion本文围绕 Remotion 仓库中的remotion/vercel包packages/vercel/README.md展开讲解如何在 Vercel Sandbox 中创建渲染环境、上传项目 Bundle、执行视频/静帧渲染、跟踪进度并把产物上传到 Vercel Blob 的完整链路所有结论均基于仓库内 packages/vercel/src/index.ts 等源码。包定位与公开 APIremotion/vercel的官方定位是“Render Remotion videos on Vercel Sandbox”在 Vercel Sandbox 上渲染 Remotion 视频当前仓库内版本为4.0.521License 为 Remotion License见 packages/vercel/package.json。它依赖remotion/renderer与remotion并以vercel/sandbox 1.0.0作为 peer dependency开发中固定使用1.6.0配套vercel/blob2.3.0。从 src/index.ts 的导出清单看该包对外暴露 6 个运行时 API 和一批类型导出类型作用createSandbox函数创建一个安装好系统依赖、JS 依赖、headless 浏览器与渲染脚本的沙箱addBundleToSandbox函数把本地remotion bundle产物递归上传进沙箱renderMediaOnVercel函数在沙箱内渲染视频支持常规与 detached 两种模式renderStillOnVercel函数在沙箱内渲染单帧静图getRenderProgress函数轮询 detached 渲染任务的文件式进度uploadToVercelBlob函数把沙箱内产物上传到 Vercel Blob返回 URL类型导出typeVercelSandbox、RenderProgress、VercelBlobUploadOptions、ChromiumOptions、Codec等大部分自 types.ts 与remotion/renderer再导出安装与版本约束README 给出的安装方式npm install remotion/vercel --save-exact两条必须遵守的版本约束来自 README 与 package.json所有remotion与remotion/*包必须对齐同一版本需去掉版本号前的^使用精确版本vercel/sandbox是 peer dependency调用方需自行安装1.0.0。另外从沙箱初始化逻辑看包内渲染脚本由构建产物generated/*-script注入包内部通过remotion/version读取版本号在沙箱内以精确版本安装remotion/rendererVERSION与remotion/compositor-linux-x64-gnuVERSION见 internals/install-js-dependencies.ts也就是说沙箱内的渲染器版本永远与本地remotion/vercel版本一致这也是“版本必须对齐”这条约束的底层原因。createSandbox一步准备一个可渲染沙箱createSandbox是整个流程的入口完整实现在 src/create-sandbox.ts。签名与默认值createSandbox({ onProgress?, // (update: {progress, message}) void | Promisevoid resources {vcpus: 4}, // Vercel Sandbox 的 resources 参数默认 4 vCPU timeoutInMilliseconds 5 * 60 * 1000, // 沙箱创建/初始化超时默认 5 分钟 } {})它返回VercelSandbox——即Sandbox AsyncDisposable定义见 types.ts意味着可以用await using语法自动停止沙箱创建时通过 internals/disposable.ts 给沙箱挂了[Symbol.asyncDispose]dispose 时调用sandbox.stop()。沙箱的准备工作按两个加权阶段推进onProgress的进度权重系统依赖 75%、下载浏览器 25%创建沙箱runtime: node24即 Node 24 运行时安装系统依赖75%通过sudo dnf install安装 headless Chromium 在 Amazon Linux 2023 上运行所需的一组库nss、atk、at-spi2-atk、cups-libs、libdrm、libXcomposite、libXdamage、libXrandr、mesa-libgbm、alsa-lib、pango、gtk3以及补丁工具链patchelf、zstd、binutils见 internals/install-system-dependencies.ts。进度是通过统计命令 stdout 行数源码注释说明经验值为 272 行线性估算的安装 JS 依赖在沙箱内执行pnpm i remotion/renderer remotion/compositor-linux-x64-gnu vercel/blob版本锁定为当前包版本修补 compositorVercel Sandbox 的 Amazon Linux 2023 自带 glibc 2.34而 Remotion 的 compositor 二进制要求 glibc 2.35。internals/patch-compositor.ts 会下载 Ubuntu 22.04 的libc6 2.35deb 包主源为 Launchpad备用源为 remotion.media解压后用patchelf把remotion二进制的动态链接指向捆绑的 glibc。源码注释明确指出Remotion 并不官方支持 glibc 2.34但可以通过这种方式打补丁且只有remotion二进制需要修补ffmpeg/ffprobe在 glibc 2.34 下工作正常下载 headless 浏览器25%写入并执行ensure-browser.mjs以 JSON 日志形式回报browser-progress百分比见 internals/install-browser.ts写入渲染脚本向沙箱写入package.json{type: module}以及render-video.mjs、render-still.mjs、upload-blob.mjs三个脚本后续渲染命令直接调用它们。addBundleToSandbox上传项目 Bundle渲染前需要把npx remotion bundle生成的静态产物传进沙箱。src/add-bundle-to-sandbox.ts 的addBundleToSandbox({sandbox, bundleDir})行为如下递归读取bundleDir下所有文件统一转成 POSIX 分隔路径先在沙箱内按祖先目录逐一mkDir再批量writeFiles上传所有文件统一放在沙箱内的remotion-bundle/目录下常量REMOTION_SANDBOX_BUNDLE_DIR见 internals/add-bundle.ts。渲染时浏览器加载的 URL 因此固定为/vercel/sandbox/remotion-bundle目录创建或文件上传失败时经由 internals/format-sandbox-error.ts 重新抛出带操作上下文如“upload N bundle file(s)”的错误便于定位。renderMediaOnVercel渲染视频完整实现在 src/render-media-on-vercel.ts。这是一个通过重载区分两种模式的函数常规模式detached缺省或false阻塞等待渲染结束返回{sandboxFilePath, contentType}产物留在沙箱文件系统中等待后续uploadToVercelBlobdetached 模式detached: true必须同时提供vercelBlob: {blobToken, access, blobPath?}立即返回{sandboxId, cmdId, outputFile}由沙箱后台继续渲染并用getRenderProgress轮询结果。完整参数与默认值以下参数表全部来自源码中解构默认值参数默认值说明sandbox必填createSandbox返回的沙箱实例compositionId必填目标 Composition 的 idinputProps必填传给 Composition 的 propsoutputFile/tmp/video.mp4沙箱内输出路径codech264视频编码类型Codec自remotion/renderer再导出crfnull恒定质量因子imageFormat/pixelFormatnull帧图像格式与像素格式envVariables{}注入渲染进程的环境变量frameRangenull只渲染指定帧区间everyNthFrame1抽帧渲染步长proResProfilenullProRes 档位chromiumOptions{}附加 Chromium 启动参数scale1输出缩放比例preferLosslessfalse偏好无损编码enforceAudioTrackfalse强制包含音轨disallowParallelEncodingfalse禁止并行编码concurrencynull并发帧数metadatanull写入容器的元数据licenseKeynullRemotion 企业授权密钥videoBitrate/audioBitrate/encodingMaxRate/encodingBufferSizenull码率相关类型Bitratemutedfalse静音输出numberOfGifLoopsnullGIF 循环次数x264Preset/gopSizenullH.264 预设与 GOP 大小colorSpacedefault色彩空间jpegQuality80JPEG 帧质量audioCodecnull音频编码logLevelinfo日志级别timeoutInMilliseconds30000浏览器/Composition 打开超时forSeamlessAacConcatenationfalseAAC 无缝拼接separateAudioTonull单独输出音频文件路径hardwareAccelerationdisable硬件加速开关沙箱环境默认关闭offthreadVideoCacheSizeInBytes/mediaCacheSizeInBytes/offthreadVideoThreadsnull离屏视频缓存与线程sampleRate48000音频采样率detachedfalse是否后台渲染detachedSandboxTimeoutInMilliseconds30 * 60 * 1000detached 模式下沙箱超时延长时长30 分钟底层执行方式函数把上述参数组装成renderConfig其中强制写死了几个与本地渲染不同的字段chromeMode: headless-shell、browserExecutable: null、binariesDirectory: null、repro: false以及serveUrl: /vercel/sandbox/remotion-bundle。随后const renderCmd await sandbox.runCommand({ cmd: node, args: [render-video.mjs, JSON.stringify(renderConfig)], detached: true, env: vercelBlob ? {BLOB_READ_WRITE_TOKEN: vercelBlob.blobToken} : undefined, });即把整个渲染配置作为 JSON 传给沙箱内的render-video.mjs脚本脚本内部再调用remotion/renderer完成渲染并以 JSON 行形式把进度打到 stdout。常规模式下客户端逐行解析stdout日志非 JSON 的行直接忽略把opening-browser、selecting-composition、render-progress三个阶段透传给onProgress最后wait()等待命令结束退出码非 0 时抛出Render failed: stderr stdout。detached 模式则先sandbox.extendTimeout(detachedSandboxTimeoutInMilliseconds)延长沙箱寿命然后立即返回{sandboxId, cmdId, outputFile}供后续轮询。renderStillOnVercel渲染静帧实现在 src/render-still-on-vercel.ts参数更精简参数默认值outputFile/tmp/still.pngframe0imageFormatpng类型StillImageFormatjpegQuality80scale1logLevelinfotimeoutInMilliseconds30000chromiumOptions/envVariables{}/{}offthreadVideoCacheSizeInBytes/mediaCacheSizeInBytes/offthreadVideoThreads/licenseKey均可选执行方式与视频渲染一致node render-still.mjs jsonConfig同样以 JSON 行协议回报opening-browser、selecting-composition、done携带size与contentType成功返回{sandboxFilePath, contentType}。getRenderProgress轮询 detached 任务detached 模式下的进度追踪实现在 src/get-render-progress.ts。它不依赖命令句柄而是按“文件 命令状态”双通道读取Sandbox.get({sandboxId})重新附着沙箱失败即返回{stage: expired}sandbox.getCommand(cmdId)获取渲染命令对象识别sandbox_stopped一类错误码同样归为expired读取沙箱内固定路径/vercel/sandbox/progress.json沙箱内渲染脚本把最新进度写在这里文件不存在且命令尚未退出时返回{stage: starting, overallProgress: 0}文件存在但命令退出码非 0 时收集stderr/stdout组装错误信息返回error。返回值是联合类型RenderProgresstypes.ts覆盖完整生命周期starting → opening-browser → selecting-composition → render-progress → (detached 时沙箱内自动) uploading → done | error | expired其中done携带{url, size, contentType, overallProgress}——detached 模式下沙箱内的渲染脚本会使用BLOB_READ_WRITE_TOKEN直接把产物上传到 Vercel Blob因此done里的url就是可直接下载的产物地址。uploadToVercelBlob上传产物到 Blob常规模式渲染完产物只存在于沙箱文件系统中需要显式上传。src/upload-to-vercel-blob.ts 的uploadToVercelBlob({sandbox, sandboxFilePath, blobPath?, contentType, blobToken, access})blobPath缺省时自动生成renders/{uuid}{原文件扩展名}在沙箱内执行node upload-blob.mjs jsonConfig沙箱内已装好vercel/blobSDK从 stdout 的type: doneJSON 消息中取回{url, size}access为public | private类型VercelBlobAccess。典型端到端工作流把上述 API 串起来一个完整的服务端渲染流程大致如下基于仓库内各函数的真实签名编写import { addBundleToSandbox, createSandbox, renderMediaOnVercel, uploadToVercelBlob, } from remotion/vercel; // 1. 创建并初始化沙箱可 await using 自动清理 await using sandbox await createSandbox({ onProgress: ({progress, message}) console.log(progress, message), resources: {vcpus: 4}, }); // 2. 上传 npx remotion bundle 的产物如 out/remotion await addBundleToSandbox({sandbox, bundleDir: out/remotion}); // 3. 渲染视频常规模式 const {sandboxFilePath, contentType} await renderMediaOnVercel({ sandbox, compositionId: MyComp, inputProps: {title: Hello}, codec: h264, scale: 1, onProgress: ({stage, overallProgress}) console.log(stage, overallProgress), }); // 4. 上传到 Vercel Blob 并拿到 URL const {url, size} await uploadToVercelBlob({ sandbox, sandboxFilePath, contentType, blobToken: process.env.BLOB_READ_WRITE_TOKEN!, access: public, }); console.log(url, size);长任务或需要跨进程追踪时改用 detached 模式const {sandboxId, cmdId, outputFile} await renderMediaOnVercel({ sandbox, compositionId: MyComp, inputProps: {title: Hello}, detached: true, vercelBlob: { blobToken: process.env.BLOB_READ_WRITE_TOKEN!, access: public, blobPath: renders/hello.mp4, }, }); // 在任意时机甚至另一个进程中轮询 const progress await getRenderProgress({sandboxId, cmdId}); // progress.stage: starting | opening-browser | ... | done | expired适用前提与限制综合源码可以归纳出该包的使用前提与限制部署前需要确认平台假设沙箱初始化脚本围绕node24运行时 Amazon Linux 2023dnf包管理、glibc 2.34 补丁路径编写compositor 修补逻辑只处理node_modules/remotion/compositor-linux-x64-gnu即当前实现面向 Linux x64 沙箱环境浏览器固定为 headless-shellrenderConfig中chromeMode被硬编码为headless-shell且browserExecutable、binariesDirectory恒为null无法指定自托管 Chromiumdetached 模式强依赖 Vercel Blobdetached: true时缺少vercelBlob会直接抛错The vercelBlob option is required when detached is set to true.且沙箱默认只自动延长 30 分钟超时DEFAULT_DETACHED_SANDBOX_TIMEOUT超长渲染需自行调大detachedSandboxTimeoutInMilliseconds版本一致性是硬约束沙箱内渲染器版本取自本地remotion/version本地remotion/remotion/*版本不一致会导致行为不确定因此 README 要求所有包使用--save-exact的同一版本。小结remotion/vercel把“打包 → 沙箱环境准备 → 渲染 → 产物分发”拆成了 6 个职责单一、可组合的 APIcreateSandbox负责一个开箱即用的 Node 24 渲染沙箱含系统依赖、glibc 2.35 补丁与 headless-shell 下载addBundleToSandbox负责 Bundle 分发renderMediaOnVercel/renderStillOnVercel负责以 JSON 配置驱动的无头渲染getRenderProgress与uploadToVercelBlob分别覆盖异步进度追踪与产物上传。对于需要在无状态云端按需生成视频的 Remotion 项目这是一条不依赖长期 GPU 实例的轻量渲染路径实现细节可直接在 packages/vercel/src/ 下按上述文件名查阅。【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价