内容
╔══════════════════════════════════════════════════════╗
║ ║
║ ████████ ████████ ██ ██ ██████ ████████ ████ ║
║ ██ ██ ███ ███ ██ ██ ██ ██ ║
║ ██████ ██████ ██ ██ ██ ██████ ██████ ██ ██ ║
║ ██ ██ ██ ██ ██ ██ ██ ██ ║
║ ██ ██ ██ ██ ██ ████████ ████ ║
║ ║
║ ██████ ████████ ██ ██ ██████ ████████ ██████ ║
║ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ║
║ ██████ ██████ ██ ██ ██ ██ ██ ██████ ██████ ║
║ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ║
║ ██ ██ ████████ ██ ██ ██████ ████████ ██ ██ ║
║ ║
║ ██████ ██████ ████ ║
║ ██ ██ ██ ██ ██ ██ ║
║ ██████ ██████ ██ ██ ║
║ ██ ██ ██ ██ ██ ║
║ ██ ██ ██ ████ ║
║ ║
║ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░ 8 WRKRS ║
║ GPU: AUTO DASHBOARD: LIVE CONCAT: INSTANT ║
╚══════════════════════════════════════════════════════╝
# ffmpeg-render-pro
[](https://www.npmjs.com/package/ffmpeg-render-pro)
[](LICENSE)
[](https://github.com/beeswaxpat/ffmpeg-render-pro)
[](https://nodejs.org/)
[](https://modelcontextprotocol.io)
并行视频渲染,带有实时仪表盘、GPU 自动检测、检查点系统和流复制连接。包括一个 MCP 服务器、一个 Claude Code 技能和一个 CLI。
由 [Beeswax Pat](https://github.com/beeswaxpat) 构建 · 永久免费和开源
## 功能
- **并行渲染**:将帧分成 N 个工作线程,零重新编码连接
- **GPU 自动检测**:探测 NVENC、VideoToolbox、AMF、VA-API、QSV,1 帧验证
- **实时仪表盘**:在浏览器中自动打开,显示每个工作线程的进度、FPS 图表、ETA
- **检查点系统**:长渲染的快速转发开销减少 93%
- **色彩分级**:5 种内置预设(noir、warm、cool、cinematic、vintage)加自定义过滤器
- **音频合并**:视频 + 音频合并,音量归一化,无视频重新编码
- **确定性输出**:种子 RNG 确保并行工作线程生成的结果与顺序结果相同
- **MCP 服务器**:模型上下文协议服务器,带有 7 种工具,与 Claude Code、Claude Desktop 和任何 MCP 客户端配合使用
- **跨平台**:Windows、macOS、Linux。任何 GPU 或仅 CPU。需要 Node.js >= 18 加 ffmpeg。
## v1.5.0 新增功能
可靠性和代理集成。完全向后兼容:每个 CLI 命令、API 签名、MCP 工具名称、工作线程合约和检查点文件格式均与 1.4.x 版本兼容。
- **检查点恢复精确**。`generateCheckpoints` 保存的状态比其标签多一帧,因此检查点恢复的工作线程渲染一帧,与顺序渲染不同步。重新生成 1.5.0 之前创建的检查点目录,以获取修复。
- **VA-API 在 Linux 上实际工作**。探测和编解码器参数现在包括设备初始化和 `hwupload`;以前,Linux 上的每个 AMD/Intel GPU 都静默地回落到 CPU。
- **VideoToolbox 质量映射修复**(它被反转),并且每个编码器现在都使用其真实的生产参数进行验证,因此 Intel Mac 在检测时回落到 CPU,而不是在渲染时失败。
- **`concatSegments` 验证段兼容性**(编解码器、分辨率、fps、像素格式)与 ffprobe 在连接之前;不匹配的输入用于生成静默损坏的输出。
- **MCP 服务器是代理原生**:结构化输出和输出模式在每个工具上,进度通知,干净的取消,一个新的 `get_worker_template` 工具和保证的协议卫生(stdout 仅携带 JSON-RPC 帧)。
- 新的 `renderParallel` 选项:`signal`(AbortSignal)和 `quiet`(字节干净的 stdout)。失败的工作线程的帧范围自动重试一次,并且在实时仪表盘上显示错误。
- 新的 CLI 标志 `--crf` 和 `--encoder-preset`;`FFMPEG_RENDER_PRO_FFMPEG` / `FFMPEG_RENDER_PRO_FFPROBE` 环境变量支持不在 PATH 上的 ffmpeg 安装。
- 分数 fps x 时长不再将帧降低为浮点错误(25fps x 4.6s 渲染 115 帧,而不是 114)。
- 81 个测试增长到 12 个套件中的 241 个,加上 GitHub Actions 测试矩阵(Ubuntu/Windows/macOS x Node 18/20/22),使用真实的 ffmpeg 安装。
查看 [CHANGELOG.md](CHANGELOG.md) 获取完整列表。
## 要求
- **Node.js** >= 18
- **ffmpeg** 已安装并在 PATH 上(或通过环境变量指向)
### 使用不在 PATH 上的 ffmpeg
每个 ffmpeg 和 ffprobe 调用在其调用时都会从两个环境变量中解析其二进制文件:
```bash
# ffmpeg 可执行文件的完整路径(每个渲染、评分、合并、连接、探测时使用)
FFMPEG_RENDER_PRO_FFMPEG=/opt/ffmpeg/bin/ffmpeg
# 可选:ffprobe 的完整路径。当未设置且 FFMPEG_RENDER_PRO_FFMPEG 已设置时,
# 如果存在,ffmpeg 旁边的 ffprobe 将自动使用。
FFMPEG_RENDER_PRO_FFPROBE=/opt/ffmpeg/bin/ffprobe
```
因为变量在调用时读取(从不缓存模块加载),所以像 MCP 服务器这样的长期进程在不重启的情况下会接收到更改。错误消息在找不到二进制文件时会提及这些变量。第三个变量 `FFMPEG_RENDER_PRO_CACHE_DIR` 覆盖 GPU 检测缓存目录(默认 `~/.ffmpeg-render-pro`)。
## 安装
```bash
# 全局安装为您提供 ffmpeg-render-pro 和 ffmpeg-render-pro-mcp 二进制文件
npm install -g ffmpeg-render-pro
# 或直接克隆仓库
git clone https://github.com/beeswaxpat/ffmpeg-render-pro.git
cd ffmpeg-render-pro
```
## 快速入门
```bash
# 系统信息(工作线程、RAM、CPU、ffmpeg 版本)
ffmpeg-render-pro info
# 探测硬件编码器
ffmpeg-render-pro detect-gpu
# 5 秒基准渲染(仪表盘自动打开,网址为 http://127.0.0.1:8080)
ffmpeg-render-pro benchmark
# 更长的渲染,自定义分辨率
ffmpeg-render-pro benchmark --duration=30 --width=1080 --height=1920 --fps=30
# 强制 CPU / GPU 编码
ffmpeg-render-pro detect-gpu --cpu
ffmpeg-render-pro detect-gpu --gpu
```
## CLI
```bash
ffmpeg-render-pro info # 系统快照
ffmpeg-render-pro detect-gpu # 探测硬件编码器
ffmpeg-render-pro render <worker.js> # 使用工作线程脚本渲染
ffmpeg-render-pro benchmark # 快速 5 秒测试渲染
ffmpeg-render-pro version # 打印已安装的版本
```
`render` 和 `benchmark` 的仪表盘控制标志:`--no-dashboard`(完全禁用),`--no-open`(提供但不打开浏览器),`--port=8080`,和 `--linger-ms=30000`(仪表盘在完成后的保持时间;`0` 立即退出)。运行不带参数的 `ffmpeg-render-pro` 以获取完整的标志引用。
`render` 和 `benchmark` 的质量标志:`--crf=NN`(0-51,较低为较高质量)和 `--encoder-preset=NAME`(任何 x264 预设名称:从 ultrafast 到 placebo)。两者都通过 `workerData.codecArgs` 传递给工作线程;捆绑的工作线程遵循它们,自定义工作线程也可以。
标志验证:未知标志在标准错误上打印警告,执行继续(脚本保持向前兼容),但无法解析的值(如 `--fps=abc`)或超出范围的 `--crf=99` 以清晰的错误退出,而不是静默渲染为默认值。
已安装的二进制文件:`ffmpeg-render-pro`(此 CLI)和 `ffmpeg-render-pro-mcp`(MCP 服务器)。MCP 服务器的旧别名 `ffmpeg-render-mcp` 也存在,并永久保留,以便旧的 MCP 配置永远不会中断。
## API
```js
const {
renderParallel, // 核心:并行渲染引擎
createEncoder, // 将原始帧传输到 ffmpeg
detectGPU, // 跨平台 GPU 检测
getConfig, // 自动调整工作线程,编解码器选择
computeTotalFrames, // fps/时长对的浮点安全帧数
concatSegments, // 流复制段连接(默认验证)
colorGrade, // 应用色彩分级(预设或自定义)
mergeAudio, // 合并视频 + 音频
startDashboard, // 实时进度仪表盘
ProgressTracker, // 每个工作线程的进度 + 仪表盘 JSON 写入器
saveCheckpoint, // 检查点序列化
loadCheckpoint, // 检查点恢复
getEncoderIO, // 编码器配方分为输入参数/过滤器/输出参数
getCodecArgs, // 编码器配方为一个扁平的参数数组
getEncoderCandidates, // 平台的编码器候选按优先级顺序
validateEncoder, // 使用生产参数的 1 帧探测一个编码器
ffmpegBin, // 已解析的 ffmpeg 二进制文件(环境变量感知)
ffprobeBin, // 已解析的 ffprobe 二进制文件(环境变量感知)
} = require('ffmpeg-render-pro');
```
### renderParallel(options)
主要入口点。将渲染分散到工作线程,显示实时仪表盘,并生成最终的 MP4。
```js
const controller = new AbortController();
await renderParallel({
workerScript: './my-worker.js', // 您的帧生成器
outputPath: './output.mp4',
width: 1920,
height: 1080,
fps: 60,
duration: 60, // 秒
title: 'My Render',
autoOpen: true, // 在浏览器中自动打开仪表盘
maxWorkers: 8, // 自动工作线程数量上限(覆盖 workerCount)
dashboardLingerMs: 0, // 0 = 立即解析;CLI 默认保持 30 秒
signal: controller.signal, // 可选:中止停止工作线程 + 清理临时文件
quiet: false, // true 保持 stdout 字节干净(状态转到 stderr)
});
```
宽度和高度必须为偶数(管道编码 `yuv420p`)。对于库使用,设置 `dashboardLingerMs: 0` 以便调用在不保持进程打开的情况下解析。`renderParallel` 解析为 `{ outputPath, elapsed, totalFrames, avgFps }`。在环境中设置 `FFMPEG_RENDER_PRO_DEBUG=1` 以获取错误时的完整堆栈跟踪。
每个渲染中都内置了可靠性行为:
- **中止**:传递 `AbortSignal` 作为 `signal`。调用 `abort()` 停止所有工作线程,删除临时文件,并拒绝带有错误(其 `name` 为 `'AbortError'`)的承诺。
- **静默模式**:`quiet: true` 将所有状态行路由到 stderr 并禁用终端进度表,因此 stdout 保持字节干净以用于协议(这是 MCP 服务器运行的方式)。仪表盘 JSON 文件仍被写入。
- **一次重试**:失败的工作线程的帧范围被重新生成一次(到新的段路径),然后渲染失败;在 stderr 上,警告名称为工作线程和尝试次数。
- **输出验证**:连接后,一个廉价的 ffprobe 元数据读取在 stderr 上警告,如果输出比请求的短。它从不使渲染失败,并且在 ffprobe 丢失时保持沉默。
- **故障表面**:发生错误时,仪表盘显示红色 RENDER FAILED 横幅(并且浏览器选项卡标题更改为 FAILED),而不是冻结在最后一个良好状态。
`workerCount` 选项是一个请求,而不是保证:渲染器永远不会生成比帧更多的工作线程,因此短渲染可能会使用较少的工作线程。自动检测上限为 `maxWorkers`(默认 8),空闲 RAM 和 CPU 核心数减 2。
### 编码器帮助程序
`getCodecArgs(encoder, { crf, cq, preset })` 返回 11 个受支持的编码器(libx264、NVENC、VideoToolbox、AMF、VA-API、QSV 在 H.264 和 HEVC 变体中)的完整生产参数数组。对于 VA-API,该数组包括设备初始化和 `-vf format=nv12,hwupload` 对,因为编码器无法在没有它们的情况下运行。
`getEncoderIO(encoder, opts)` 返回相同的配方,分为 `{ inputArgs, filter, outputArgs }`。如果您构建自己的 `-vf` 链(色彩分级、缩放),请将 `getEncoderIO().filter` 合并到该链中,而不是传递两个 `-vf` 标志:ffmpeg 只接受每个流的最后一个 `-vf`,而静默地丢弃其他标志。这也适用于具有 VA-API 编码器的 `colorGrade`;保留默认的 `libx264` 进行分级,或通过 `getEncoderIO` 自己组成调用。
`computeTotalFrames(fps, duration)` 是渲染器本身使用的浮点安全帧数(25fps x 4.6s 正确得出 115,而不是 114)。
`ProgressTracker` 接受一个 `terminalStream` 构造函数选项(默认 `process.stdout`;传递 `null` 以禁用终端表),并具有一个 `fail(message)` 方法,该方法为仪表盘写入一个终端 `error` 阶段。
### 编写工作线程
工作线程通过 `workerData` 接收帧范围,并将原始 BGRA 帧传输到 ffmpeg:
```js
const { workerData, parentPort } = require('worker_threads');
const { spawn } = require('child_process');
const { width, height, fps, startFrame, endFrame, segmentPath, workerId } = workerData;
async function main() {
// 生成 ffmpeg 编码器(环境变量感知,备用 PATH)
const ffmpeg = spawn(process.env.FFMPEG_RENDER_PRO_FFMPEG || 'ffmpeg', [
'-y', '-f', 'rawvideo', '-pixel_format', 'bgra',
'-video_size', `${width}x${height}`, '-framerate', String(fps),
'-i', 'pipe:0',
'-c:v', 'libx264', '-preset', 'fast', '-crf', '20',
'-pix_fmt', 'yuv420p', '-movflags', '+faststart',
segmentPath,
], { stdio: ['pipe', 'pipe', 'pipe'] });
// 保留最后 8KB 的 ffmpeg stderr:它在失败时携带错误消息,
// 并且无限缓冲区在长渲染中无限制增长。
let stderrTail = '';
ffmpeg.stderr.on('data', (c) => { stderrTail = (stderrTail + c).slice(-8192); });
// 捕获 stdin 错误(当 ffmpeg 在管道中死亡时为 EPIPE)并跟踪
// 从早期关闭侦听器退出,以便最终等待不会附加“关闭”
//,否则会无限期挂起。
let streamError = null;
ffmpeg.stdin.on('error', (err) => { if (!streamError) streamError = err; });
let closed = false;
let closeCode = null;
ffmpeg.on('close', (code) => { closed = true; closeCode = code; });
const frameSize = width * height * 4; // BGRA
const buffer = Buffer.alloc(frameSize);
// 管道的峰值水位标记下的帧可以按引用排队,
// 即使 write() 返回 true,小帧必须在写入前复制。
// 更大的帧保持零复制重用:write() 返回 false,排干等待
// 确保在缓冲区再次被突变之前完全刷新。
const copyFrames = frameSize < 64 * 1024;
for (let f = startFrame; f < endFrame; f++) {
if (streamError || closed) {
const cause = streamError ? streamError.message : ` exited early with code ${closeCode}`;
throw new Error(`ffmpeg encode failed (${cause}): ${stderrTail.slice(-500)}`);
}
renderMyFrame(f, buffer); // 用你的帧数据填充缓冲区(BGRA)
// 带反压写入
const ok = ffmpeg.stdin.write(copyFrames ? Buffer.from(buffer) : buffer);
if (!ok) await new Promise((r) => ffmpeg.stdin.once('drain', r));
// 报告进度
const done = f - startFrame + 1;
parentPort.postMessage({
type: 'progress', workerId,
pct: (done / (endFrame - startFrame)) * 100,
fps: 0, frame: done, eta: 0,
});
}
// 关闭编码器;从捕获的状态中解析,如果它已经退出。
ffmpeg.stdin.end();
await new Promise((resolve, reject) => {
const finish = (code) => (code === 0
? resolve()
: reject(new Error(`ffmpeg exited ${code}: ${stderrTail.slice(-500)}`)));
if (closed) return finish(closeCode);
ffmpeg.once('close', finish);
});
parentPort.postMessage({ type: 'done', workerId });
}
main().catch((err) => {
parentPort.postMessage({ type: 'error', workerId, error: err.message });
});
```
查看 `examples/basic-worker.js` 获取完整强化参考工作线程(其排水等待也唤醒于错误/关闭,它从不发布 `done` 后 `error`,并遵循 `workerData.codecArgs`)。MCP `get_worker_template` 工具返回此合约以及完整参考源。
**工作线程数据**(通过 `worker_threads` 的 `workerData` 注入):`width`、`height`、`fps`、`seed`、`startFrame`、`endFrame`、`segmentPath`、`workerId`、`totalFrames`,以及您在 `renderParallel({ workerData })` 中传递的任何内容。
**工作线程发布给父进程的消息**,通过 `parentPort.postMessage(...)`:
| 消息 | 何时 | 字段 |
|---------|------|--------|
| `{ type: 'progress' }` | 编码过程中定期 | `workerId`、`pct`、`fps`、`frame`、`eta` |
| `{ type: 'fast-forward-start' }` | 可选,在快进到 `startFrame` 之前 | `workerId`、`frames` |
| `{ type: 'done' }` | 完全写入分段后 | `workerId` |
| `{ type: 'error' }` | 失败时 | `workerId`、`error` |
每个工作线程将其帧范围写入 `segmentPath`;渲染器流复制连接这些分段。
## 后处理 API
直接使用这些 API,或通过 CLI 和 MCP 工具使用。视频在可能的情况下进行流复制,因此不会有质量损失。
```javascript
const { colorGrade, mergeAudio, concatSegments } = require('ffmpeg-render-pro');
// 使用内置预设进行色彩分级(noir、warm、cool、cinematic、vintage)
await colorGrade({ inputPath: 'raw.mp4', outputPath: 'graded.mp4', preset: 'cinematic' });
// ...或自定义 ffmpeg -vf 过滤器链
await colorGrade({ inputPath: 'raw.mp4', outputPath: 'graded.mp4', filter: 'eq=contrast=1.08:saturation=0.9', crf: 18 });
// 在分级过程中保留音轨(默认情况下会去除音频)
await colorGrade({ inputPath: 'final.mp4', outputPath: 'graded.mp4', preset: 'noir', keepAudio: true });
// 合并音频:视频进行流复制,音频编码为 AAC。loop 和 loudnorm 是可选的。
await mergeAudio({ videoPath: 'graded.mp4', audioPath: 'track.mp3', outputPath: 'final.mp4', bitrate: 320, loop: true, normalize: true });
// 连接相同编解码器、相同分辨率的片段(瞬间完成)
await concatSegments(['part-000.mp4', 'part-001.mp4'], 'joined.mp4');
// 输入已知是均匀的?跳过 ffprobe 探测:
await concatSegments(['part-000.mp4', 'part-001.mp4'], 'joined.mp4', { validate: false });
```
默认情况下,`concatSegments` 会使用 ffprobe 探测每个输入(每个片段启动一个进程),并在运行 ffmpeg 之前拒绝编解码器、分辨率、帧率或像素格式不匹配的情况。因为 ffmpeg 本身接受不匹配的输入并会静默地写入损坏的文件。传递 `{ validate: false }` 以跳过探测。当 ffprobe 未安装时,会跳过检查并显示 stderr 警告;缺失和零字节片段始终会被拒绝。
## 检查点(长渲染)
对于多小时的渲染,预先生成状态快照,以便每个工作线程仅重放自最近检查点以来的帧,而不是从帧 0 开始。
```javascript
const { generateCheckpoints, loadCheckpoint, restoreCheckpoint } = require('ffmpeg-render-pro');
// 一次更新:推进系统并每隔 `interval` 帧快照
generateCheckpoints({ systems, totalFrames: 432000, fps: 60, checkpointDir: './.checkpoints', interval: 60000 });
// 在工作线程中:跳转到 startFrame 处的最近快照
const cp = loadCheckpoint('./.checkpoints', startFrame);
if (cp) {
const resumeFrame = restoreCheckpoint(cp, systems); // 返回快照的帧数
// 从 resumeFrame 到 startFrame 进行快速推进,然后渲染
}
```
`systems` 是一个命名模块的对象,每个模块实现 `getState()` 和 `setState()`(以及 `generateCheckpoints` 的 `update(dt)`)。键 `_frame` 和 `_timestamp` 是保留的检查点元数据;不要将系统命名为其中之一。
标记为帧 F 的检查点包含恰好 F 个 `update()` 调用,与上述快速推进约定相匹配。1.5.0 之前编写的检查点嵌入了一个额外的更新(状态领先一帧);重新生成旧检查点目录以恢复完全相同的保证。文件格式本身保持不变。
## 模块
| 模块 | 目的 |
|--------|---------|
| `parallel-renderer` | N-工作线程池,带有进度跟踪 |
| `encoder` | 原始帧管道,带有反压的 ffmpeg |
| `gpu-detect` | 跨平台硬件编码器发现 + 验证 |
| `config` | 根据分辨率、RAM、CPU 自动调整工作线程 |
| `concat` | 流复制段连接(瞬间完成) |
| `color-grade` | ffmpeg 视频过滤器预设 + 自定义链 |
| `audio-merge` | 视频 + 音频合并,支持 loudnorm |
| `dashboard-server` | 零依赖 HTTP 服务器,自动打开浏览器 |
| `progress` | 每个工作线程的终端 + JSON 进度跟踪 |
| `checkpoint` | 长期渲染的状态序列化 |
| `ffmpeg-bin` | ffmpeg/ffprobe 二进制解析(环境变量感知) |
## 基准测试
运行您自己的:
```bash
node examples/render-test.js --duration=5
node examples/render-test.js --duration=30
node examples/render-test.js --duration=60 --width=1080 --height=1920
```
## 测试
```bash
npm test # 烟雾测试 + MCP 测试 + 端到端渲染
npm run test:smoke # 仅烟雾测试
npm run test:mcp # 仅 MCP 服务器测试
npm run test:e2e # 使用 ffprobe + framemd5 验证的真实渲染
# 关注单元测试(零依赖,直接运行):
node test/checkpoint.test.js # 检查点保存/加载/恢复 + 偏移回归
node test/concat.test.js # 验证,引用(空格/撇号),列表文件路径
node test/gpu-detect.test.js # 缓存生命周期 + 所有 11 个编码器的参数
node test/dashboard.test.js # HTTP 服务器 + ProgressTracker JSON 契约
node test/cli.test.js # 标志解析和验证
node test/ffmpeg-bin.test.js # FFMPEG_RENDER_PRO_FFMPEG / _FFPROBE 解析
node test/renderer.test.js # 故障注入:工作线程错误/抛出/静默退出/重试/中止
node test/encoder.test.js # createEncoder 反压 + 错误路径
node test/audio-merge.test.js # mergeAudio 环路/归一化路径
```
一个零依赖测试套件,12 个文件中包含 241 个测试(1.4.0 中有 81 个)。覆盖范围包括模块导出、输入验证、仪表盘路径安全性(遍历 + 空字节 + 双重编码向量)、检查点语义、连接验证、GPU 缓存生命周期、CLI 解析、环境变量二进制解析、渲染器故障注入(包括静默 stdout 卫生)和编码器反压。MCP 测试套件运行 22 个检查,包括通过 stdio 进行的真实渲染、进度通知、完整的 stdout 协议卫生审计和服务器.json 漂移保护。端到端测试套件渲染真实视频并检查编解码器、尺寸、精确帧数、种子确定性(种子 0 字节相同,跨运行 framemd5,种子 1 不同)、连接、色彩分级和音频合并;如果机器上没有 ffmpeg,它会干净地跳过。CI 在 Ubuntu、Windows 和 macOS 上运行测试套件,针对 Node 18、20 和 22 以及真实的 ffmpeg 安装。
## MCP 服务器
ffmpeg-render-pro 包含一个带有 7 种工具的模型上下文协议(MCP)服务器。与 Claude Code、Claude Desktop 和任何 MCP 客户端一起工作。
### 添加到 Claude Code
```bash
# 在全局安装 ffmpeg-render-pro 后,MCP 二进制文件位于您的 PATH 中:
claude mcp add --transport stdio ffmpeg-render-pro -- ffmpeg-render-pro-mcp
# 或在没有全局安装的情况下(使用 npx):
claude mcp add --transport stdio ffmpeg-render-pro -- npx --yes --package=ffmpeg-render-pro ffmpeg-render-pro-mcp
```
### 添加到 Claude Desktop
将以下内容添加到您的 `claude_desktop_config.json` 中:
```json
{
"mcpServers": {
"ffmpeg-render-pro": {
"command": "ffmpeg-render-pro-mcp"
}
}
}
```
或者,如果您不想全局安装:
```json
{
"mcpServers": {
"ffmpeg-render-pro": {
"command": "npx",
"args": ["--yes", "--package=ffmpeg-render-pro", "ffmpeg-render-pro-mcp"]
}
}
}
```
### MCP 工具
| 工具 | 描述 |
|------|-------------|
| `detect_gpu` | 探测硬件编码器(NVENC、VideoToolbox、AMF、VA-API、QSV) |
| `system_info` | 显示 CPU 核心、RAM、推荐的工作线程、ffmpeg 版本 |
| `render_video` | 并行渲染,带有实时仪表盘、进度通知和取消 |
| `get_worker_template` | 返回工作线程契约和捆绑的参考工作线程源 |
| `color_grade` | 应用预设(noir、warm、cool、cinematic、vintage)或自定义过滤器 |
| `merge_audio` | 结合视频 + 音频,带有响度归一化 |
| `concat_videos` | 流复制连接多个视频(瞬间完成,默认验证) |
每个工具的完整输入模式(参数名称、类型、默认值、运行时最小/最大值限制)通过 `tools/list` 在运行时发布。每个工具还声明了一个 `outputSchema`,并在文本旁边返回 `structuredContent`,因此结果可以作为键入的 JSON 解析,而无需正则表达式。注释标记了四个写入者(`render_video`、`color_grade`、`merge_audio`、`concat_videos`)为破坏性(它们会覆盖 `output_path` 如果存在),以及三个探测为只读。
在连接代理时需要注意的行为:
- **进度通知**:当客户端发送 `progressToken` 时,`render_video` 每 2 秒发出 `notifications/progress`,以及开始和结束帧。客户端应启用 `resetTimeoutOnProgress`,以便长时间渲染不会达到请求超时。
- **取消**:客户端取消会干净地中止渲染;工作线程停止,临时文件被删除。
- **默认帧率**:`render_video` 默认帧率为 30;CLI `render` 命令默认为 60。
- **GPU 探测缓存**:`detect_gpu` 和 `system_info` 在 `~/.ffmpeg-render-pro` 中缓存探测结果 7 天(使用 `FFMPEG_RENDER_PRO_CACHE_DIR` 覆盖目录)。
- **协议卫生**:stdout 仅携带 JSON-RPC 帧;所有库和控制台输出都路由到 stderr,渲染在静默模式下自动运行。
- **缺少 ffmpeg**:每个工具都返回一个可行的错误,指出安装页面和 `FFMPEG_RENDER_PRO_FFMPEG` 环境变量,而不是原始的 spawn 错误。
## AI 代理
使用 `claude mcp add` 一行命令或上面的 Claude Desktop JSON 将服务器连接起来。然后,工作配方是:
1. `detect_gpu` 以确认硬件加速(可选但便宜;缓存 7 天)。
2. `get_worker_template` 以获取工作线程契约和捆绑的参考工作线程。其 `templatePath` 可直接用作测试场景的 `worker_script`,或根据返回的契约编写自定义工作线程。
3. `render_video` 带有 `dashboard: false` 和 `auto_open: false`,用于无头运行(stdout 卫生自动)。传递 `progressToken` 以获取实时进度。
4. `color_grade` 和/或 `merge_audio` 用于后处理。
5. `concat_videos` 以连接多个输出(默认情况下验证)。
每个响应都包含与工具的 `outputSchema` 匹配的 `structuredContent`,因此解析 JSON 而不是抓取文本。npm tarball 提供了现成的 Claude Code 技能(参见下一个部分关于复制路径的内容)和一个 `llms.txt` 取向文件,供代理使用。
## Claude Code 技能
此软件包包含一个现成的 Claude Code 技能(在 npm tarball 和存储库中提供)。要安装它,请将技能文件夹复制到您的 Claude 技能目录中:
```bash
# 从存储库克隆(macOS / Linux)
cp -r .claude/skills/ffmpeg-render-pipeline ~/.claude/skills/
# 从存储库克隆(Windows)
xcopy .claude\skills\ffmpeg-render-pipeline %USERPROFILE%\.claude\skills\ffmpeg-render-pipeline\ /E /I
# 从全局 npm 安装(macOS / Linux)
cp -r "$(npm root -g)/ffmpeg-render-pro/.claude/skills/ffmpeg-render-pipeline" ~/.claude/skills/
```
安装后,Claude Code 将在您要求使用 ffmpeg 渲染视频或音频时自动使用该技能。
## 安全注意事项
- **仪表盘服务器仅绑定到 `127.0.0.1`。** 它永远不会被您的网络上的其他机器访问。
- **无遥测,无电话,无 CDN 加载。** 仪表盘完全使用本地文件和系统字体运行。
- **MCP 服务器是一种本地文件系统工具。** 当连接到 AI 代理时,它将渲染、读取和写入当前用户可以访问的任何文件。像对待其他文件系统工具一样对待它:仅与受信任的代理一起运行,并考虑在使用不受信任的提示时限制进程的工作目录。
- **`render_video` 以当前用户的完全权限执行给定的工作线程脚本。** 工作线程脚本是任意 Node 代码,在工作线程中运行;仅运行您编写或信任的脚本。同样适用于库中的 `renderParallel`。
- **自定义过滤器字符串是文件访问。** ffmpeg `-vf` 过滤器可以通过 `movie=` 和 `subtitles=` 等源读取本地文件,因此传递给 `color_grade`/`colorGrade` 的自定义 `filter` 可以引用磁盘上的文件。像对待文件路径一样对待来自不受信任的代理或用户的过滤器输入。
- **流复制连接使用 `os.tmpdir()` 下的临时文件。** 您传递的输出路径仍然会按原样写入,因此请确保您的输出路径是您想要的位置。
## 更新日志
请参阅 [CHANGELOG.md](CHANGELOG.md) 以获取完整的发布历史记录。
## 许可证
MIT
## 作者
[Beeswax Pat](https://github.com/beeswaxpat)
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器