关于 Convertrilo
Convertrilo 是用于提交和管理视频编码任务的 TypeScript SDK,并附带命令行工具。它适合需要在脚本、CI 或 Agent 工作流中调用 Convertrilo API 的开发者,支持多种来源、输出目标及任务管理操作。
主要功能
- 01创建和查询编码任务
- 02视频文件夹批量导入
- 03保存编码预设与输出目标
- 04支持 VMAF 优化编码
- 05管理 Webhook 与投递记录
- 06幂等创建及文件清理
适用场景
- 01在 CI 或定时任务中编码视频
- 02将 S3 文件夹视频批量排入编码
- 03将编码结果交付至 S3 或 Google Drive
- 04从脚本检查任务状态或取消任务
MCP 相关
软件包包含 stdio MCP 服务 convertrilo-mcp,可将视频编码任务操作接入 Agent 和工作流。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
5收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| fps | number | 否 | |
| codec | enum | 否 | h264 | h265 | av1 |
| passes | enum | 否 | 1 | 2 |
| preset | enum | 否 | fast | standard | slow |
| quality | enum | 否 | good | better | best |
| webhook | string | 否 | |
| metadata | object | 否 | |
| optimize | enum | 否 | none | vmaf |
| outputS3 | object | 否 | |
| outputS3.key | string | 否 | |
| outputS3.bucket | string | 是 | |
| outputS3.region | string | 否 | |
| outputS3.endpoint | string | 否 | |
| outputS3.accessKeyId | string | 否 | |
| outputS3.forcePathStyle | boolean | 否 | |
| outputS3.secretAccessKey | string | 否 | |
| priority | enum | 否 | normal | high |
| container | enum | 否 | mp4 | mkv | webm | mov |
| sourceUrl | string | 是 | 可读取的源视频 URL。 |
| externalId | string | 否 | |
| resolution | enum | 否 | 480p | 720p | 1080p | 1440p | 2160p |
| vmafTarget | number | 否 | |
| idempotencyKey | string | 否 |
详细介绍
Convertrilo TypeScript SDK
适用于 Convertrilo API 的类型安全客户端。
VMAF 和编码轮次
请求 optimize: "vmaf" 时,Convertrilo 会进行 VMAF 采样,并执行一次优化后的最终编码。为保持向后兼容,仍接受提供的 passes: 2 值,但 API 实际使用并计费的有效轮次为一次。
定价响应会公开 requestedPasses 和 effectivePasses。新的集成应在使用 VMAF 时设置 passes: 1。
安装
pnpm add @convertrilo/sdk
该软件包目前面向提供全局 fetch 的现代 Node.js 运行时。如果你的运行时不提供 fetch,请向客户端传入 fetchImpl。
CLI 和 MCP 自动化
该软件包包含两个可执行的自动化工具:
export CONVERTRILO_API_KEY="cvr_..."
convertrilo encode https://example.com/input.mp4 \
--codec h264 \
--resolution 1080p \
--audio-policy transcode-aac \
--frame-rate-policy cap \
--scale-policy no-upscale \
--quality better \
--wait \
--json
convertrilo-mcp
脚本、CI、cron 和本地操作请使用 convertrilo。Agent 和工作流集成请将 convertrilo-mcp 用作 stdio MCP 服务。
运行 convertrilo login 或 convertrilo init 可在本地保存 API 密钥;也可以不带参数运行 convertrilo,启动交互式编码向导。等待中的命令默认会显示终端进度,并确保 --json 输出干净,便于脚本使用。
可通过以下命令获取 Shell 补全代码片段:
convertrilo completion zsh
请参阅 docs/CLI-AND-MCP.md,了解命令、MCP 客户端配置、S3 输出示例、VMAF、双轮编码、状态、取消和余额工作流。
如果你想要最简单的终端操作指南,请从 docs/CLI-QUICKSTART.md 开始。
客户端配置请参阅 docs/MCP-QUICKSTART.md。
MCP 注册表元数据位于 server.json。
创建客户端
import { ConvertriloClient } from "@convertrilo/sdk";
const client = new ConvertriloClient({
baseUrl: "https://api.convertrilo.com",
apiKey: process.env.CONVERTRILO_API_KEY,
});
服务器到服务器集成请使用 API 密钥。浏览器应用应调用你自己的后端,再由后端调用 Convertrilo。
示例
examples/ 目录包含主要集成路径的入门脚本:
node-url-to-cdn.ts- 编码公开 URL,并获取签名的 CDN 下载 URLnode-url-to-s3.ts- 编码公开 URL,并将结果上传到 S3/S3 兼容存储google-drive-byo-token.ts- 使用客户自有服务账号将输出上传到 Google Drivefolder-ingest-s3.ts- 为 S3 前缀中的每个视频排队创建一个编码作业idempotency.ts- 安全地重试createJob和createJobsBulkwebhook-receiver-hmac.ts- 在 Node 接收器中验证托管 Webhook 的 HMAC 签名
本地 SDK 冒烟测试使用 .env,但已发布的 SDK 用户应通过自己的服务器环境提供凭据。不要将 Convertrilo API 密钥或客户存储令牌放入前端代码。
如需了解完整的服务器到服务器操作指南,涵盖 URL、S3、文件夹导入、Google Drive 服务账号、轮询和 Webhook,请参阅 docs/API-INTEGRATION-GUIDE.md。
幂等作业创建
从后端重试创建调用时,请使用幂等键。使用相同请求正文重复使用同一个键,会返回原始响应,而不会创建重复作业。
const job = await client.createJob({
externalId: "upload-123",
metadata: { customerId: "cus_123" },
codec: "h264",
resolution: "1080p",
fps: 30,
}, {
idempotencyKey: "job-upload-123",
});
const batch = await client.createJobsBulk({
jobs: [
{
externalId: "batch-42:clip-1",
codec: "h264",
resolution: "1080p",
fps: 30,
sourceS3: { bucket: "source", key: "clip-1.mp4" },
},
],
settings: { confirm: true },
}, {
idempotencyKey: "bulk-batch-42",
});
作业文件清理
作业进入终止状态后,请删除托管的上传和输出对象:
await client.cancelJob(jobId); // required first for created, queued, or running jobs
const result = await client.deleteJobFiles(jobId);
console.log(result.objectsDeleted, result.jobRetained);
作业记录和计费历史仍可供审计。活动作业会返回稳定的 job_active 错误,直到作业被取消。
已保存的编码预设
保存可重复使用的编码设置,而不存储源 URL、存储凭据或输出密钥:
const preset = await client.createEncodePreset({
name: "Default 1080p web MP4",
settings: {
codec: "h264",
resolution: "1080p",
fps: 30,
preset: "standard",
bitrateTier: "medium",
passes: 1,
policy: "fastest",
container: "mp4",
quality: "better",
optimize: "none",
vmafTarget: 93,
audioPolicy: "transcode-aac",
frameRatePolicy: "cap",
scalePolicy: "no-upscale",
},
});
const { presets } = await client.getEncodePresets();
已保存的输出目标
保存可重复使用的交付目标,而不在目标本身存储原始存储密钥。S3 目标会引用加密保存的 S3 凭据:
const destination = await client.createOutputDestination({
name: "Customer uploads bucket",
config: {
type: "s3",
credentialId: "0f5a7f2b-4ff2-45d4-b76f-1f7b6e98d4d1",
keyPrefix: "processed/",
},
});
const { destinations } = await client.getOutputDestinations();
URL 源到 CDN 输出
const job = await client.onDemandEncode({
sourceUrl: "https://example.com/input.mp4",
externalId: "customer-video-123",
metadata: {
customerId: "cus_123",
workflow: "daily-compression",
},
codec: "h264",
resolution: "1080p",
quality: "better",
audioPolicy: "transcode-aac",
frameRatePolicy: "cap",
scalePolicy: "no-upscale",
}, {
idempotencyKey: "encode-customer-video-123",
});
let finalStatus;
while (true) {
finalStatus = await client.onDemandStatus(job.jobId);
if (finalStatus.status === "success") break;
if (finalStatus.status === "failed") {
throw new Error(finalStatus.failureMessage || "Encoding failed");
}
await new Promise((resolve) => setTimeout(resolve, 5000));
}
console.log(finalStatus.downloadUrl);
console.log(finalStatus.requestedExecution);
console.log(finalStatus.effectiveExecution);
console.log(finalStatus.sourceProbe?.color);
console.log(finalStatus.outputProbe);
终端用户可以通过以下命令查看同一份报告:
convertrilo status JOB_ID --json
convertrilo wait JOB_ID --json
URL 源到 S3 输出
const job = await client.onDemandEncode({
sourceUrl: "https://example.com/input.mp4",
codec: "h264",
resolution: "1080p",
outputS3: {
bucket: "customer-output-bucket",
key: "encoded/input-1080p.mp4",
region: "us-east-1",
accessKeyId: process.env.CUSTOMER_S3_ACCESS_KEY_ID,
secretAccessKey: process.env.CUSTOMER_S3_SECRET_ACCESS_KEY,
},
});
console.log(job.jobId);
对于 S3 兼容服务,请传入 endpoint,通常还应设置 forcePathStyle: true。
URL 源转换为 Google Drive 输出
对于无头 API 集成,请保存一个客户自有的 Google 服务账号,之后即可重复使用。 使用 Google Shared Drive 作为输出位置,并将返回的服务账号邮箱添加为成员, 授予其创建文件的权限。
const credential = await client.createGoogleDriveCredential({
name: "Production Drive",
serviceAccount: JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT_JSON!),
});
const job = await client.onDemandEncode({
sourceUrl: "https://example.com/input.mp4",
codec: "h264",
resolution: "1080p",
outputGoogleDrive: {
folderId: "GOOGLE_DRIVE_FOLDER_ID",
fileName: "input-1080p.mp4",
credentialId: credential.id,
},
});
console.log(job.jobId);
Dashboard 的 Google Picker 授权与 SDK 自动化相互独立。
文件夹导入
在 S3 前缀中为每个视频排入一个任务:
const batch = await client.onDemandIngestFolder({
externalIdPrefix: "batch-2026-06-09",
metadata: {
customerId: "cus_123",
workflow: "folder-compression",
},
sourceS3: {
bucket: "customer-source-bucket",
prefix: "incoming/",
region: "us-east-1",
accessKeyId: process.env.CUSTOMER_S3_ACCESS_KEY_ID,
secretAccessKey: process.env.CUSTOMER_S3_SECRET_ACCESS_KEY,
},
outputDestination: "s3",
outputS3: {
bucket: "customer-output-bucket",
prefix: "encoded/",
region: "us-east-1",
accessKeyId: process.env.CUSTOMER_S3_ACCESS_KEY_ID,
secretAccessKey: process.env.CUSTOMER_S3_SECRET_ACCESS_KEY,
},
codec: "h264",
maxFiles: 25,
resolution: "1080p",
}, {
idempotencyKey: "folder-batch-2026-06-09",
});
for (const job of batch.jobs || []) {
console.log(job.jobId, job.externalId, job.fileName);
}
使用 maxFiles 限制从文件夹中发现并排入队列的视频数量。
在 Google Drive 文件夹中为每个视频排入一个任务:
const batch = await client.onDemandIngestFolder({
sourceGoogleDrive: {
folderId: "SOURCE_FOLDER_ID",
credentialId: credential.id,
},
outputDestination: "google-drive",
outputGoogleDrive: {
folderId: "OUTPUT_FOLDER_ID",
credentialId: credential.id,
},
codec: "h264",
maxFiles: 25,
resolution: "1080p",
});
for (const job of batch.jobs || []) {
console.log(job.jobId, job.fileName);
}
每个 worker 启动时,Convertrilo 会使用加密的服务账号凭据生成短时有效的 Google 令牌。
使用 client.onDemandStatus(jobId) 轮询每个返回的 jobId。
Webhook 投递历史
托管的 webhook 使用 HMAC 签名。你可以测试 webhook 并检查近期的投递尝试:
await client.testWebhook(webhookId);
const history = await client.getWebhookDeliveries(webhookId);
for (const delivery of history.deliveries || []) {
console.log(delivery.status, delivery.statusCode, delivery.event);
}
重新生成类型
SDK 类型根据 openapi.yaml 生成。
pnpm run generate
pnpm run build
生成脚本使用 --default-non-nullable false,因此 OpenAPI 默认值在 TypeScript 请求体中仍为可选项。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。