@hyperframes / aws-lambda
用于HyperFrames分布式渲染的AWS Lambda适配器。船只三 共同的东西:
- 这个 λ处理程序 包裹了OSS
plan/renderChunk/assemble单个分派边界后面的原语步骤函数 会开车吗?src/handler.ts)。 - 一、 客户端SDK - - - - - -
renderToLambda,getRenderProgress,deploySite,再加上validateDistributedRenderConfig和computeRenderCost(src/sdk/)。 - 一个
aws-cdk-libL2构造 (HyperframesRenderStack), 提供相同的拓扑结构examples/aws-lambda/template.yaml在采用者自己的CDK应用程序(src/cdk/)。
处理程序ZIP和SAM模板仍然驱动维护程序运行的实际aws 烟流;SDK + CDK是采用者支持的公共界面。
体系结构
┌──────────────────────────────────────────────────────────────────┐
│ Step Functions state machine │
│ Plan → Map(N) RenderChunk → Assemble │
└──────────────────────────────────────────────────────────────────┘
│ dispatches by event.Action
▼
┌──────────────────────────────────────────────────────────────────┐
│ One Lambda function (this package's `dist/handler.zip`) │
│ handler.mjs │
│ ├─ Action="plan" → @hyperframes/producer/distributed │
│ ├─ Action="renderChunk" → @hyperframes/producer/distributed │
│ └─ Action="assemble" → @hyperframes/producer/distributed │
│ bin/ffmpeg — ffmpeg-static │
│ node_modules/@sparticuz/chromium/ — Lambda-optimised Chromium │
└──────────────────────────────────────────────────────────────────┘
│ pure functions over local paths
▼
┌──────────────────────────────────────────────────────────────────┐
│ S3 bucket — v1 plan tar or v2 manifest/blobs + chunks + output │
└──────────────────────────────────────────────────────────────────┘
处理程序将来自S3的输入下载到 /tmp称OSS是原始的,
将输出上传到S3,并返回一个适合的小JSON结果
在Step Functions的历史预算范围内(每个块低于200字节)。
规划运输选择
Plan v2是新渲染的默认版本。当 planProtocol 省略了,
renderToLambda 发送显式的 PlanProtocol: "v2" SDK和
已部署状态机同意:
await renderToLambda({
// ...bucket, state machine, project, and config...
});
V2从不重载 PlanS3Uri。计划者回来了
PlanV2ManifestS3Uri 和 PlanV2ArtifactS3Prefix;块工作器获取
只有清单选择的块工件,而汇编程序获取它的
自己的元数据和音频子集。blob是不可变的sha -256寻址
对象,在上传和下载时进行验证,并发布清单
最后的。未知协议和摘要不匹配是终端步骤函数
错误。单片v1传输仍然可用,但已弃用
通过传递实现兼容性 planProtocol: "v1" 明确。
更新订单
此默认值更改了应用程序行为,并且需要一个协调的
基础设施升级。的应用程序升级之前
renderToLambda:
- 暂停新的渲染,让现有的步骤函数执行耗尽。
- 重新部署Lambda处理程序和SAM模板或CDK构造 相同的新包版本。
- 继续渲染,然后升级应用程序/SDK依赖项。
网站是一个 sites/<id>/files.json 旧堆栈无法提供的文件列表
读,在任何计划协议下。在上传任何东西之前,
renderToLambda 读取状态机定义
(states:DescribeStateMachine),并以 STACK_TOO_OLD 当
Stack早于这种格式。如果不能首先重新部署基础设施,
在重新部署之前,将应用程序保持在以前的包版本上
完成了。重新部署后,早期版本的站点id仍然可以工作:
当 sites/<id>/files.json 是失踪,渲染使用该网站的
project.tar.gz.
Chrome运行时
该包支持两个Chromium源:
| 来源 | 默认的 | 大小 | 什么时候采摘 |
|---|---|---|---|
@sparticuz/chromium | 是 | ~70 MiB压缩 | λ。解压缩到 /tmp 在运行时;生态系统的其余部分已经将其用于无头铬-in- lambda。 |
捆绑 chrome-headless-shell | 否 | ~ 140 MiB | 回退。如果使用 @sparticuz/chromium 曾经滴 HeadlessExperimental.beginFrame 支持。 |
在构建时选择源代码:
bun run --cwd packages/aws-lambda build:zip
bun run --cwd packages/aws-lambda build:zip -- --source=chrome-headless-shell
处理程序读取 HYPERFRAMES_LAMBDA_CHROME_SOURCE 在引导。构建
脚本通过Lambda函数配置设置env var
examples/aws-lambda/template.yaml.
回归保护
HyperFrames的渲染器通过CDP驱动Chrome
HeadlessExperimental.beginFrame 命令—与K8s部署使用的路径相同。
Lambda适配器假定 @sparticuz/chromium的
chrome-headless-shell构建尊重BeginFrame。去证明(再证明)
(在每个版本中),该包附带一个Docker探测:
# Build the Lambda-like container and run the probe.
bun run --cwd packages/aws-lambda probe:beginframe:docker
探测靴 @sparticuz/chromium 内部
public.ecr.aws/lambda/nodejs:22 并断言CDP beginFrame 与
screenshot: true 返回一个PNG缓冲区。退出码0 =绿色;非零=
回落到捆绑铬头壳直接通过 --source=chrome-headless-shell.
构建ZIP
bun install # at the monorepo root
bun run --cwd packages/aws-lambda build:zip # → packages/aws-lambda/dist/handler.zip
bun run --cwd packages/aws-lambda verify:zip-size # CI gate
构建脚本包 src/handler.ts 通过esbuild, stage
@sparticuz/chromium 和 puppeteer-core 下 node_modules/复制
ffmpeg-static进 bin/,并将结果压缩。解压后的布局为
被设计成干净利落地提取到Lambda的 /var/task/.
verify:zip-size 执行:
- 解压缩≤248 MiB(内部预算;Lambda硬上限为250 MiB解压缩- AWS文档标记为“250 MB”,但使用二进制字节)
- 压缩≤150 MiB(内部预算;Lambda没有s3部署功能的硬压缩帽)
如果超出任何一个,则CI将使PR失败。
运行测试
bun run --cwd packages/aws-lambda test # unit tests (no Chrome)
bun run --cwd packages/aws-lambda probe:beginframe # local probe (Linux only)
使用SDK
在部署堆栈(通过下面的SAM模板、CDK构造)之后,或者 你自己的CFN选择),驱动渲染从节点:
import { deploySite, getRenderProgress, renderToLambda } from "@hyperframes/aws-lambda";
// One-time upload per project version.
const site = await deploySite({
projectDir: "./my-composition",
bucketName: "hyperframes-render-bucket",
});
// Start a render. Returns immediately — does NOT poll.
const handle = await renderToLambda({
siteHandle: site,
bucketName: site.bucketName,
stateMachineArn: "arn:aws:states:us-east-1:123:stateMachine:hyperframes-render",
config: {
fps: 30,
width: 1920,
height: 1080,
format: "mp4",
chunkSize: 240,
maxParallelChunks: 16,
runtimeCap: "lambda",
},
});
// Poll progress + cost on your own cadence.
const progress = await getRenderProgress({ executionArn: handle.executionArn });
console.log(progress.overallProgress, progress.costs.displayCost);
if (progress.status === "SUCCEEDED" && progress.outputFile) {
console.log("Render landed at", progress.outputFile.s3Uri);
}
renderToLambda 通过验证配置客户端
validateDistributedRenderConfig 抛出一个类型 InvalidConfigError
在步进函数开始执行之前,因此形状错误会出现
同步而不是不透明 ExecutionFailed 结果。
getRenderProgress 报告近似的每次渲染成本
(accruedSoFarUsd 加上一个格式化的 displayCost)衍生自Lambda
计费时长×内存× us-east-1按需速率加上Step
功能转换价格。数学是记录在
src/sdk/costAccounting.ts;数字是最好的选择,不包括S3
转移。
使用CDK构造
import { App, Stack } from "aws-cdk-lib";
import { HyperframesRenderStack } from "@hyperframes/aws-lambda/cdk";
const app = new App();
const stack = new Stack(app, "MyApp");
const render = new HyperframesRenderStack(stack, "Render", {
// optional: reservedConcurrency: 8,
// optional: lambdaMemoryMb: 10240,
// optional: chromeSource: "sparticuz",
});
// Re-export so an adopter app can wire dashboards / SNS topics.
new CfnOutput(stack, "RenderBucketName", { value: render.bucket.bucketName });
new CfnOutput(stack, "StateMachineArn", { value: render.stateMachine.stateMachineArn });
aws-cdk-lib 和 constructs 是 可选的对等依赖项: SDK-only
消费者不会在运行时拉出它们。构造本身从
@hyperframes/aws-lambda/cdk.
前方还有什么
hyperframes lambdaCLI(部署/站点创建/渲染/进度/销毁)- PR 6.5。- IAM引导子命令(
policies role | user | validate) -第6.9节。 - Lambda-local regression harness (
--mode=lambda-local) -第6.6页。 - 面向采用者的迁移指南——PR 6.8。