mcpField
P
PrismPoster Creator Tools

PrismPoster Creator Tools

远程服务
prismposter.com媒体与设计14 天前更新

关于 PrismPoster Creator Tools

PrismPoster Creator Tools 是为视频和社交媒体创作者提供的 TypeScript 工具集,也包含本地 MCP 服务。它提供带来源的社交平台安全区域数据,以及字幕、编码、比例和媒体元数据处理功能。

主要功能

  1. 01计算画面比例与裁切方案
  2. 02查询平台尺寸及有来源的安全区域
  3. 03解析、转换和调整字幕时间
  4. 04计算码率、文件大小和时间码
  5. 05提取调色板并读取图像元数据
  6. 06检测 C2PA 与 AI 来源标记

适用场景

  1. 01为不同社交平台准备视频画幅
  2. 02转换或校准字幕文件
  3. 03估算满足文件大小限制的码率
  4. 04检查上传媒体中的来源信息

MCP 相关

该项目包含零运行依赖的 stdio MCP 服务,向 AI 客户端提供平台尺寸与安全区域、比例裁切、码率和字幕转换等只读工具。计算在本地执行,无网络请求。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://www.prismposter.com/api/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npm@prismposter/creator-tools1.0.0

工具

详细介绍

creator-tools

面向视频和社交媒体创作者的零依赖 TypeScript 工具:宽高比计算、敲击测节拍、字幕解析与转换、带有来源依据的各平台画面尺寸和安全区域、编码计算器、调色板提取、GIF 编码、图像元数据,以及 C2PA / AI 来源检测。

无运行时依赖。不进行网络调用。可在浏览器、Node 和 worker 中运行。返回的每个数值都可以手动核验;如果平台没有公布某个数值,工具会如实说明,而不会凭空编造。

npm install @prismposter/creator-tools

为什么要做这个项目

这些计算大多散落在互相引用的博客文章中,而且不少引用的数字都是错的。促成这个库诞生的一点是:**网上所有“TikTok 安全区域”像素表都是编造的。**TikTok 发布的是叠加模板,而非固定边距——被遮挡的区域会随画面尺寸、字幕长度和正在投放的广告格式而变化。不存在正确的固定值,因此这个库会返回 null 并解释原因,而不是提供一个看似合理的数字。

整个软件包都遵循这条原则:

  • **推导出的数值就应由计算得出。**宽度为 1080 的 9:16 画面,高度是 1920,因为这就是比例所决定的。测试套件会验证 social-sizes 中的每种尺寸是否符合其声明的比例。
  • **引用的数值会注明来源。**每个安全区域都链接到其数据来源的官方页面。safeAreaSourceUrl(placement) 会返回该 URL。
  • **未知也是一种值,而非空白。**未公布任何数据的平台会获得明确的 kind: 'unpublished',并附上原因。

模块

aspect-ratio

用于即将编码的画面的比例运算。处理非整数电影比例(2.39:1)的方式与处理 16:9 相同。

import {
  simplifyRatio, cropToRatio, padToRatio, alignToBlock,
} from '@prismposter/creator-tools/aspect-ratio';

simplifyRatio({ width: 1920, height: 1080 });   // { w: 16, h: 9 }

cropToRatio({ width: 1920, height: 1080 }, { w: 9, h: 16 });
// { result: { width: 608, height: 1080 },
//   removed: { top: 0, right: 656, bottom: 0, left: 656 },
//   areaKept: 0.3167 }

// Codecs want even dimensions; H.264 chroma subsampling makes an odd
// width an encoder error or a silent rescale.
alignToBlock({ width: 1081, height: 607 });      // { width: 1082, height: 608 }
alignToBlock({ width: 1080, height: 1920 }, 16); // { width: 1088, height: 1920 }

裁剪后多出的奇数像素始终分配到下边缘或右边缘。这是人为规定的,但能保持一致——如果每次调用时分配方式不同,一批片段最终就会出现一像素的错位。

social-sizes

各平台的画面尺寸和安全区域,以及对应来源。

import {
  getPlacement, frameSize, safeAreaPx, safeAreaBox, safeAreaSourceUrl,
} from '@prismposter/creator-tools/social-sizes';

const reels = getPlacement('instagram-reels')!;
frameSize(reels);           // { width: 1080, height: 1920 }
safeAreaPx(reels);          // { top: 269, bottom: 672, left: 65, right: 65 }
safeAreaBox(reels);         // { width: 950, height: 979 }
safeAreaSourceUrl(reels);   // Meta's Reels ads-guide page

const tiktok = getPlacement('tiktok-video')!;
safeAreaPx(tiktok);         // null — and that is the correct answer
tiktok.safeArea.reason;     // explains why no fixed table can be right

Meta 公布的 Reels 和 Stories 安全区域为顶部 14%、底部 35%、左右各 6%。在 1080×1920 的画面上,分别是 269 / 672 / 65 px。底部占三分之一不是笔误。

safeAreaPx 返回 null 是有意义的——应向用户说明“该平台未公布固定安全区域”。不要用零替代,也不要借用其他平台的数据。

subtitles

支持 SRT、WebVTT 和 ASS/SSA 的解析、转换与时间编辑。所有格式都会先转换为统一的中性 Cue 结构,而不是直接在格式之间互转:否则六种格式需要三十个转换器,而每个转换器都可能悄悄采用不同的舍入规则。

import { convert, parse, shift, scale, deoverlap }
  from '@prismposter/creator-tools/subtitles';

const { output, warnings } = convert(srtText, 'vtt');

// Fix subtitles authored against a different frame rate.
scale(parse(srtText).cues, 23.976 / 25);

// Nudge everything 500ms later; cues pushed before zero clamp to zero.
shift(cues, 500);

// Clip overlaps so only one cue is ever on screen.
deoverlap(cues);

解析过程具有容错性:格式错误的区块会产生警告并被跳过,不会因此丢失文件中其他 899 条字幕。支持处理 UTF-8 BOM 和 CRLF 行尾。会移除 VTT 的 NOTE / STYLE 区块和内联标签(<v Roger>、<i>),也会移除 ASS 覆盖区块({\an8})。

ASS 使用厘秒,因此往返转换 ASS 格式时,精度会损失到 10 ms 以下。convert() 会在 warnings 中告知你这一点,而不是让你事后才发现。

tempo

敲击测节拍,以及编辑时间线所需的节拍计算。

import { estimateTempo, beatMs, noteMs, beatGrid, snapToBeat }
  from '@prismposter/creator-tools/tempo';

estimateTempo(tapTimestamps);
// { bpm: 128.02, taps: 16, spreadMs: 8.4, discarded: 1 }

beatMs(120);                              // 500
noteMs(120, 'quarter', { triplet: true }); // 333.333
beatGrid(120, 10_000);                     // [0, 500, 1000, … 10000]
snapToBeat(480, 120);                      // { timeMs: 500, deltaMs: 20 }

估算器取滑动窗口内的中位数,而非平均值。敲击序列有两种情况会让平均值表现不佳:用户寻找节拍时,最初几次敲击会偏晚;漏敲一次则会产生约为真实周期两倍的间隔。异常值会依据中位数剔除,因为平均值早已被拖偏,足以让错误间隔落入容差范围。

spreadMs 会告知你结果的可信程度——低于约 20 ms 表示敲击节奏稳定,高于 60 ms 则说明估算结果不够可靠。beatGrid 会根据每个位置的索引计算数值,而非累加,因此长序列不会产生漂移。

encoding

文件大小、比特率、时间码和帧数。

import { fileSizeBytes, targetBitrateKbps, bitsPerPixel, toDropFrame }
  from '@prismposter/creator-tools/encoding';

fileSizeBytes(60, 8_000);          // 60_000_000 bytes
targetBitrateKbps(120, 50_000_000); // kbps to hit a 50 MB cap
bitsPerPixel(1920, 1080, 30, 8_000); // 0.1286
toDropFrame(1_800, 29.97);           // '00:01:00;02'

单位约定,仅说明一次:比特率使用十进制(1 Mbps = 1,000,000 位/秒,所有编码器和平台规范都是如此),文件大小使用二进制 (1 MiB = 1,048,576 字节,所有操作系统的报告方式都是如此)。混用两者 正是在线计算器结果相差约 5% 的原因。formatBytesBinary 和 formatBytesDecimal 是两个独立函数,因此始终明确选择所用单位。

丢帧时间码跳过的是标签,而非帧:每分钟开始时都会省略编号 00 和 01, 但每十分钟一次除外。这样才能让 29.97 时间码与实际时间保持一致;不丢帧时间码 每小时会偏差约 3.6 秒。


palette

中值切割颜色量化,以及在其返回的颜色上放置文本时所需的对比度计算。

import { extractPalette, toHex, readableTextOn } from '@prismposter/creator-tools/palette';

const swatches = extractPalette(pixels, 5);  // pixels: { r, g, b }[]
swatches.map(toHex);                          // ['#1b2430', '#3f6d8e', ...]
readableTextOn(swatches[0]);                  // { onColour: 'black' | 'white', ratio: 8.7 }

选择的切分位置是主导轴上最宽的间隙,而非像素数量的中位数。教科书式的中值切分会让每个色框包含相同数量的像素,这对于照片来说恰恰是错误的:大片纯色天空会被反复细分,而小块高饱和度点缀色——设计师真正想要的那种颜色——则会与相邻颜色取平均后消失。按间隙切分就能保留它。

如果源图像的不同颜色少于请求的色块数,返回的色块就会更少。用相近颜色填充结果,只会得到一份无法如实反映图像的调色板。

provenance

这个文件是否带有来源信息?其中是否表明该素材由 AI 生成?

import { inspectProvenance } from '@prismposter/creator-tools/provenance';

inspectProvenance(bytes);
// { hasC2paManifest: true, hasIptcSourceType: true, hasProvenance: true,
//   declaresAiGenerated: true, declaresCapture: false,
//   digitalSourceTypes: ['.../digitalsourcetype/trainedAlgorithmicMedia'],
//   assertionLabels: ['c2pa.actions.v2', 'c2pa.claim.v2'],
//   manifestOffset: 41, signatureVerified: false }

目前有两种标记,常常被混为一谈:

  1. C2PA 清单——JUMBF 容器中的加密签名内容凭证。
  2. IPTC 数字来源类型——普通的 XMP/EXIF 字符串,没有任何签名,任何人都可以用 exiftool 写入。

文件可能带有其中一种、两种,或两种都没有。之所以分别报告,是因为它们的证明力截然不同;许多“AI 检测器”的介绍却把第二种说得仿佛是第一种。

它不会验证签名。signatureVerified 始终为 false,这是有意为之。要证明清单有效,需要完整的 C2PA 信任列表和证书链验证——这正是 c2patool 和 c2pa-node 的用途;如果你要判断可信度,就应该使用它们。此处回答的是一个成本更低的问题,而那些工具对于这个问题又显得过于强大;在无法携带原生二进制文件的无服务器运行时中,这个问题往往也无从解决:是否存在凭证?它声称了什么? 当你在处理上传队列、只把值得关注的文件转交给真正的验证器时,这正是你需要的检查。

**清单存在,不代表清单可信。**任何人都可以用自签名证书签署任何内容,包括谎言。

image-metadata

读取文件对自身的描述——更重要的是,留意它何时什么也没说。

import { readImageMetadata, isStripped } from '@prismposter/creator-tools/image-metadata';

const meta = readImageMetadata(bytes);
meta.format;   // 'jpeg' | 'png' | 'webp' | 'gif' | ...
meta.fields;   // parsed EXIF / XMP / text fields
isStripped(meta);

大多数平台在上传时都会剥除元数据,因此没有元数据的图像才是常态,并非可疑情况。isStripped 的存在就是为了让你能向用户解释这一点,而不是给他们显示一张空表。

gif

动画 GIF 编码器:全局调色板、LZW、子块,应有尽有。

import { encodeGif, buildGlobalPalette, indexFrame } from '@prismposter/creator-tools/gif';

const palette = buildGlobalPalette(frames, 256);
const bytes = encodeGif({ width, height, palette, frames });

GIF 最多支持 256 种颜色,且所有帧共用一个全局调色板,因此量化器比编码器更重要——这也是它沿用 palette 的中值切割算法,而不另行实现的原因。

mcp(Model Context Protocol 服务)

@prismposter/creator-tools 提供零依赖的 MCP stdio 服务,让 AI 助手(Claude Desktop、Cursor、Windsurf、Cline)能够查询经过验证的平台安全区域、纵横比裁切、比特率和字幕格式转换,而不会凭空编造像素尺寸。

添加到 claude_desktop_config.json 或 .cursor/mcp.json:

{
  "mcpServers": {
    "prismposter-creator-tools": {
      "command": "npx",
      "args": ["-y", "@prismposter/creator-tools"]
    }
  }
}

提供的 MCP 工具(均为只读工具,执行纯本地计算并提供输出架构):

  • get_social_media_placement — 某个版位的画面尺寸、以像素为单位的安全区域内边距、可用框和第一方文档 URL(instagram-reels、youtube-shorts、tiktok-video 等),以及针对源尺寸的裁切/加黑边方案
  • list_social_media_placements — 列出所有版位或某个平台的版位,供浏览和比较
  • check_safe_area — 检查字幕、徽标或按钮框是否位于某个版位的安全区域内,以及超出各边缘多少像素;TikTok 会说明原因并返回 unknown
  • calculate_aspect_ratio — 简化任意比例、对齐到编解码器块,并计算任意目标比例的中心裁切/加黑边方案
  • estimate_video_bitrate — 编码后文件大小(字节、MiB、MB)、符合大小上限的比特率,以及每像素比特密度
  • convert_subtitles — 在 SRT、WebVTT 和 ASS/SSA 之间转换,支持格式检测和时间偏移
  • estimate_tempo — 根据点击时间戳计算 BPM,或计算已知 BPM 对应的节拍和小节长度

调用错误会返回 MCP 工具错误(isError: true),错误消息会说明如何修正,例如提供未知版位的有效 ID。

托管版本运行于 https://www.prismposter.com/api/mcp(Streamable HTTP,无需安装)。 它使用 prismposter.com 更大的版位数据集作答(也接受网站使用的 camelCase ID),比特率工具接受 videoKbps 和 targetCapMb,仅转换 SRT 和 WebVTT,并新增 get_prismposter_capabilities 工具。 这两个版本都已列入官方 MCP Registry,名称为 com.prismposter/creator-tools。

设计规则

  1. 纯函数,无副作用,无 I/O。 所有操作均为同步且确定性的。
  2. 无效输入返回 null,不会抛出异常。 这些函数处理的是文本输入,用户输入一半就停下很常见,并非异常情况。
  3. 只在边界处进行一次舍入。 尺寸以整像素表示,因为编码器需要这样的值。
  4. null 表示“没有可用答案”,且始终可以与零区分。
  5. 错误的类型仍会抛出异常。 规则 2 针对的是用户可能输入的值,并不意味着调用方把字符串传给读取字节的函数时,函数就应该猜测调用方的意图。

开发

npm install
npm test          # 173 tests
npm run typecheck
npm run build

欢迎贡献 — 请参阅 CONTRIBUTING.md。新增常量的门槛是要有第一方来源;新增函数的门槛是要有一个没有它就会失败的测试。

同样的数学逻辑,也可以作为浏览器工具使用

此处的每个模块都为一个免费工具提供支持,访问 prismposter.com/tools 即可使用——无需账户,也无需 上传或提供电子邮件。如果你想直接获取答案,而不是函数,请从这里开始:

宽高比计算器BPM 节拍器字幕转换器
社交媒体尺寸Instagram 帖子尺寸视频计算器
调色板提取器图像元数据查看器视频转 GIF
视频帧提取器视频裁剪图像人声消除器
热门视频复刻镜头清单模板歌词生成器
视频比特率计算器SRT 字幕清理器YouTube 缩略图预览器

维护者

PrismPoster 是一个 AI 内容工作空间,包含图像、视频、复刻、角色和音乐工作室,它们共享同一个项目、素材库和一条真正能完成的时间线。

这个库是该产品中枯燥的那一半:工作室底层的算术逻辑。我们将其提取出来,是因为它确实可以复用,而且字幕解析器并非竞争优势。provenance 则出于相反的原因而存在——在媒体产品中构建 AI 披露功能,让我们认识到 C2PA 工具链还不完善;而缺失的恰恰是一个不依赖任何依赖项的存在性检查。

许可证

MIT © PrismLabs OÜ

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。