如何在 Vercel Sandbox 中用 renderMediaOnVercel 渲染视频并上传到 Vercel Blob?

如何在 Vercel Sandbox 中用 renderMediaOnVercel 渲染视频并上传到 Vercel Blob? 如何在 Vercel Sandbox 中用 renderMediaOnVercel 渲染视频并上传到 Vercel Blob【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion当你想在 Vercel 上按需渲染 Remotion 视频又不想自己管理 Lambda 或 AWS 基础设施时remotion/vercel包提供了这条路径在 Vercel Sandbox 里渲染再把产物上传到 Vercel Blob 得到一个可公开访问的下载 URL。完整流程是四步createSandbox()创建沙箱 →addBundleToSandbox()拷贝你的 Remotion bundle →renderMediaOnVercel()渲染视频 →uploadToVercelBlob()上传到 Blob 存储。需要注意的是remotion/vercel目前是实验性包自 v4.0.426 起提供官方保留在移除警告提示前做破坏性变更的权利并且它要求vercel/sandbox作为 peer dependency。准备条件创建项目并连接 Blob 存储使用官方的 Next.js 模板起步npx create-videolatest --template vercel把项目推送到 Vercel然后在 Vercel 控制台的 Storage 下新建一个 Blob store 并连接到项目重新部署使配置生效。渲染上传依赖环境变量BLOB_READ_WRITE_TOKEN官方模板的渲染路由在未设置该变量时会直接抛出错误BLOB_READ_WRITE_TOKEN is not set. To fix this, go to vercel.com, log in, select Storage, click Create Database, select Blob, link it to your project, then add BLOB_READ_WRITE_TOKEN to your .env file.模板参考实现位于仓库的 template-vercel 渲染路由可以对照本文步骤逐行理解。完整渲染与上传流程以下代码展示了模板中同步渲染路径的核心逻辑省略了 SSE 进度推送部分四个 API 均从remotion/vercel导入import { addBundleToSandbox, createSandbox, renderMediaOnVercel, uploadToVercelBlob, } from remotion/vercel; // 1. 创建沙箱已预装系统库、compositor 和浏览器 const sandbox await createSandbox({ onProgress: async ({progress, message}) { console.log(${message} (${Math.round(progress * 100)}%)); }, }); // 2. 把 Remotion bundle 拷贝进沙箱 // bundleDir 是相对当前工作目录的路径 // bundle 可以用 npx remotion bundle 命令或 bundle() API 创建 await addBundleToSandbox({ sandbox, bundleDir: .remotion, }); // 3. 渲染视频产物留在沙箱内 const {sandboxFilePath, contentType} await renderMediaOnVercel({ sandbox, compositionId: MyComp, inputProps: {title: Hello World}, }); // 4. 上传到 Vercel Blob得到公开 URL const {url, size} await uploadToVercelBlob({ sandbox, sandboxFilePath, contentType, blobToken: process.env.BLOB_READ_WRITE_TOKEN!, access: public, }); console.log(Uploaded ${size} bytes to ${url}); // 5. 用完沙箱后必须 stop释放资源 await sandbox.stop();各步骤的判断依据renderMediaOnVercel()未设置detached时返回{sandboxFilePath, contentType}其中sandboxFilePath是视频在沙箱内的路径默认输出路径为/tmp/video.mp4contentType是 MIME 类型如video/mp4。把这两个值直接传给uploadToVercelBlob()即可无需手写路径。uploadToVercelBlob()返回{url, size}url是上传文件的公开下载 URLsize是字节数。拿到url即表示渲染产物已可公开访问。access只能是public或private默认private想让视频可直接播放就显式传access: public。blobPath参数可指定 Blob 内的目标路径如renders/abc.mp4省略时生成随机路径。沙箱资源与清理createSandbox()的可选参数resources分配给沙箱的资源类型继承自vercel/sandboxSDK每个 vCPU 对应 2048 MB 内存默认{vcpus: 4}timeoutInMillisecondsv4.0.452 起沙箱创建的最大允许时间默认3000005 分钟超时则中止创建。清理沙箱有两种方式手动调用sandbox.stop()或使用await using sandbox await createSandbox()让沙箱离开作用域时自动 stop。上面的示例代码在上传完成后即调用sandbox.stop()。长渲染detached 模式 进度轮询Vercel functions 最长可运行 800 秒而 Sandbox 的超时上限在 Hobby 计划为 45 分钟、Pro/Enterprise 为 5 小时。如果渲染时间可能超过函数时限用detached: true让启动渲染的路由立即返回再用getRenderProgress()轮询两者均自 v4.0.469 起提供// app/api/render/start/route.ts import {addBundleToSandbox, createSandbox, renderMediaOnVercel} from remotion/vercel; export async function POST() { const sandbox await createSandbox(); await addBundleToSandbox({ sandbox, bundleDir: /path/to/your/bundle, // 替换为你的 bundle 目录 }); const {sandboxId, cmdId} await renderMediaOnVercel({ sandbox, compositionId: MyComp, inputProps: {title: Hello World}, detached: true, vercelBlob: { blobToken: process.env.BLOB_READ_WRITE_TOKEN!, access: public, }, }); return Response.json({sandboxId, cmdId}); }// app/api/render/progress/route.ts import {getRenderProgress} from remotion/vercel; import {Sandbox} from vercel/sandbox; export async function GET(req: Request) { const url new URL(req.url); const sandboxId url.searchParams.get(sandboxId); const cmdId url.searchParams.get(cmdId); if (!sandboxId || !cmdId) { return Response.json({error: Missing sandboxId or cmdId}, {status: 400}); } const progress await getRenderProgress({sandboxId, cmdId}); if (progress.stage done || progress.stage error) { await Sandbox.get({sandboxId}) .then((sandbox) sandbox.stop()) .catch(() undefined); } return Response.json(progress); }detached 模式的关键约束设置detached: true后返回{sandboxId, cmdId, outputFile}vercelBlob参数在该模式下是必需的——因为启动渲染的路由在视频存在之前就已返回必须由沙箱内自行完成上传detachedSandboxTimeoutInMilliseconds可延长返回前沙箱的存活时间默认180000030 分钟getRenderProgress()的终态阶段有done渲染已上传到 Vercel Blob、error渲染失败、expired沙箱已不存在。文档说明收到done或error后应删除你应用里保存的渲染句柄沙箱本身会保持存活到配置的超时时间以便刷新后的页面仍能读到终态进度。限制与注意事项实验性包remotion/vercel的四个 API 都带有实验性警告接口可能变化。性能Sandbox 渲染发生在单台机器上而非分布式系统因此比 Lambda 慢沙箱内含 Chrome 和 FFmpeg启动需要几秒。并发上限Hobby 计划 10 个同时渲染Pro/Enterprise 2000 个。模板不含限流与缓存官方提示在把应用公开之前自行实现 rate limiting 和 caching并建议配置 Vercel Spend Management 控制成本。Blob 数据会持久保留Sandbox 快照、渲染视频和其他 Vercel Blob 数据会一直存在不再需要时应删除。渲染参数renderMediaOnVercel()还支持codec默认h264、frameRange、concurrency、timeoutInMilliseconds等与remotion/renderer一致的编码参数详见 renderMediaOnVercel() 文档 的参数列表。相关文档入口Rendering with Vercel Sandbox、remotion/vercel API 索引、createSandbox()、addBundleToSandbox()、uploadToVercelBlob()、getRenderProgress()。【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考