Communitygithub.com

Prismer-AI/PrismerCloud

用于处理 Remotion 合成、Studio、Player、@remotion 包、程序化视频渲染、字幕、媒体处理、地图以及 Remotion 和 Mediabunny 升级的任务。

PrismerCloud 是什么?

此技能提供了在 Prismer Cloud 环境中构建、维护和调试 Remotion 项目的全面指南和工作流程。它涵盖了从项目创建、组合管理、帧驱动动画、Studio 可编辑标记到资产处理、字幕、多媒体检查以及地图集成的方方面面。该技能强调确定性的、帧驱动的渲染方式,避免使用 CSS 过渡或定时器。它详细说明了如何与 Prismer 的工件和交付系统集成,以可靠地交付最终渲染的媒体文件。该技能支持多种平台,包括 Remotion Studio、Player、Lambda 以及 Vercel/Cloudflare 集成,并提供了明确的升级路径。它是一个用于程序化视频生成、媒体处理和字幕任务的权威参考,特别是在需要与 Remotion 和 Mediabunny 进行复杂交互的场景下。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Prismer-AI/PrismerCloud/tree/HEAD/sdk/cloud/catalog/skills/remotion

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Remotion

构建和维护 Remotion 项目,同时保留用户的更改。如果文件意外更改,除非用户另有确认,否则将其视为有意为之。

工作流程

  1. 检查 package.json、锁文件、现有合成、当前差异以及 npx remotion versions。重用包管理器和项目结构;将所有 remotion / @remotion/* 包保持在一个确切的版本上。
  2. 确认所请求的输出:合成/源更改、Studio 预览、渲染的媒体、嵌入式 Player 或渲染服务。
  3. 实现确定性、帧驱动的视觉效果,并保持渲染输入可序列化。
  4. 在 Studio 中预览。仅当用户请求媒体文件时才渲染。
  5. 使用 ffprobe 验证渲染的媒体,并检查代表性帧。
  6. 报告更改的文件、预览/渲染证据以及交付回执。在 Prismer 中,松散的沙盒路径不是已交付的结果。

Prismer 工件和交付合同

当用户请求渲染媒体时,将最终文件写入 $PRISMER_ARTIFACTS_DIR(调度 <artifacts_dir>)。将项目脚手架、帧、探针和其他中间文件放在 $PRISMER_SCRATCH_DIR 或现有项目树下。然后,将每个请求的最终文件精确交付一次:

cloud deliver "$PRISMER_ARTIFACTS_DIR/launch-video.mp4"

写入或渲染文件并不会附加它。成功的 cloud deliver 回执是交付的仲裁者。除非用户请求,否则不要交付预览帧、临时音频或重复编码。如果不存在调度工件目录,则将结果保留在用户批准的项目输出路径中,并报告交付不可用,而不是凭空捏造一个回执。

项目创建和合成

不要在不空的项目上进行脚手架搭建。当没有合适的项目存在时,确认 Node.js 和 Git 可用,然后运行:

npx create-video@latest --yes --blank --no-tailwind my-video
cd my-video
npm install

使用有意义的目录名称。仅当用户要求或项目已经使用 Tailwind 时才添加它。在继续之前,检查生成的清单、配置和全局 CSS:生成器版本即使请求了 --no-tailwind,也可能仍然发出 Tailwind 依赖和导入。仅当项目不使用它们时才移除它们,并保持 Remotion 包版本对齐。

在 Prismer 沙盒镜像中,对每个可能安装或调用缺失包的命令(包括脚手架搭建、npm ci、remotion add、探针和渲染)使用命令作用域的可写 npm 缓存:

npm_config_cache="${PRISMER_SCRATCH_DIR:-/tmp}/npm-cache" npm ci

不要为了绕过沙盒所有权不匹配而更改用户的全局 npm 配置。

保持静态合成元数据内联:

<Composition
  id="LaunchVideo"
  component={LaunchVideo}
  durationInFrames={300}
  fps={30}
  width={1920}
  height={1080}
  defaultProps={{title: 'Launch day'}}
/>

仅当持续时间、尺寸或属性确实依赖于输入、远程数据或媒体检查时才使用 calculateMetadata()。保持 defaultProps 内联,以便 Studio 可以将属性编辑保存回代码。对于多场景视频,使用命名的 <Sequence> 边界,并从单个 fps 感知的计划中推导所有时序。

帧驱动动画

使用 useCurrentFrame()、interpolate()、弹簧或缓动来驱动渲染动画。不要使用 CSS 过渡、CSS 动画、挂钟定时器或 Tailwind 动画工具;它们不是确定性渲染。

import {
  AbsoluteFill,
  Easing,
  Interactive,
  interpolate,
  useCurrentFrame,
  useVideoConfig,
} from 'remotion';

export const Hero = () => {
  const frame = useCurrentFrame();
  const {fps} = useVideoConfig();

  return (
    <AbsoluteFill style={{justifyContent: 'center', alignItems: 'center'}}>
      <Interactive.Div
        name="Hero title"
        style={{
          opacity: interpolate(frame, [0, fps], [0, 1], {
            extrapolateLeft: 'clamp',
            extrapolateRight: 'clamp',
            easing: Easing.bezier(0.16, 1, 0.3, 1),
          }),
          scale: interpolate(frame, [0, fps], [0.9, 1], {
            extrapolateLeft: 'clamp',
            extrapolateRight: 'clamp',
            easing: Easing.spring({damping: 200}),
            output: 'perceptual-scale',
          }),
          fontSize: 88,
        }}
      >
        Launch day
      </Interactive.Div>
    </AbsoluteFill>
  );
};

优先使用单独的 scale、translate 和 rotate CSS 属性,而不是组合的 transform 字符串。除非有意外推,否则要夹紧有限动画的两端。

Studio 可编辑标记

使用 Interactive.* 来处理 HTML 和 SVG 元素,这些元素在 Studio 中应该可以被选中、拖动、调整大小、旋转、设置样式或添加关键帧。<Img> 已经是可交互的。

  • 为每个交互元素提供一个简短、硬编码、描述性的 name。
  • 将一次性文本直接放在元素内部。
  • 当 Studio 写回很重要时,保持样式对象、interpolate() 范围、输出、缓动和外推内联。
  • 只从 useVideoConfig() 解构支持的值,例如 fps、width、height 和 durationInFrames。
  • 避免在可编辑的关键帧范围内部使用提取的样式常量、对象展开、计算出的效果数组和任意变量。

对于自定义组件,在实现之前,查阅当前官方 Remotion 文档中的 make-component-interactive API。

资产、媒体和时序

将本地资产放在 public/ 中,并使用 staticFile() 引用它们:

import {Audio, Video} from '@remotion/media';
import {AnimatedImage, CanvasImage, staticFile} from 'remotion';

export const MediaLayer = () => (
  <>
    <Video src={staticFile('clip.mp4')} />
    <Audio src={staticFile('music.mp3')} />
    <CanvasImage src={staticFile('logo.png')} />
    <AnimatedImage src={staticFile('sticker.gif')} />
  </>
);

当基于 Chrome 的动画图像路径不合适时,使用 @remotion/gif。使用 npx remotion add <package> 安装生态系统包,以使 Remotion 包版本保持一致。

对于可重现的沙盒渲染,优先使用本地或内容寻址的媒体。不要将 cookie、承载令牌、签名 URL 或地图凭证嵌入源文件或组合属性中。对于异步资产、字体、字幕和地图瓦片,使用 delayRender() / continueRender() 与 cancelRender() 配对,以便在失败时明确失败,而不是挂起到超时。

在支持的组件上使用 from、durationInFrames 和 trimBefore。将不支持的组件包装在 <Sequence> 中:

<Sequence name="Product demo" from={2 * fps} durationInFrames={6 * fps}>
  <Video src={staticFile('demo.mp4')} trimBefore={1 * fps} />
</Sequence>

将媒体持续时间与预期的可用片段匹配。将场景时序保持在一个计划中,以免过渡意外重叠或留下空白帧。

对于效果,使用能产生镜头的最简单技术:

  1. HTML、SVG 和 CSS。
  2. 元素上的 Remotion 效果或 HtmlInCanvas 包装器。
  3. 仅当前两种方法无法产生时才使用自定义效果或着色器。

保持效果数组稳定。渲染单独的元素,而不是有條件地更改效果数组的形状。

字幕和多媒体检查

将字幕规范化为 Remotion 的 Caption[] 形状,并将摄入时间戳保持为毫秒:

import type {Caption} from '@remotion/captions';

const caption: Caption = {
  text: 'Hello',
  startMs: 0,
  endMs: 800,
  timestampMs: null,
  confidence: null,
};

仅在使用组合 fps 的组合边界处将毫秒转换为帧。在可用时保留单词时序,将字幕分组为可读页面,从帧时钟进行动画,并在实际输出尺寸下验证换行和安全区域。

对于 SRT,使用当前的 @remotion/captions 解析器,而不是编写时间戳解析器。在实现字幕之前,确认 parse-srt、createTikTokStyleCaptions 和所选转录提供商的当前 API。

对于音频可视化,使用 @remotion/media-utils 配合帧窗口音频数据;切勿从实时分析器驱动条形或波形。对于图表和文本动画,首先计算最终几何形状,然后使用基于帧的裁剪、不透明度或变换来显示它,以便条形、标签和字形布局保持稳定。

使用 Mediabunny 进行浏览器端持续时间、尺寸、裁剪、旋转、元数据和容器处理。在使用不熟悉的 API 之前,阅读 https://mediabunny.dev/llms.txt。保持 mediabunny 和 @mediabunny/* 版本与项目的 Remotion 版本兼容。

地图

为镜头选择一种技术:

技术使用场景
准备好的光栅确定性静态/卫星图像配合动画叠加就足够了。
Mapbox需要精美的样式、地球渲染或 3D 建筑物。
MapLibre首选不需要 Mapbox API 密钥的开源矢量运行时。
MapTiler托管样式或地理注释适合该项目。
CesiumJS需要地形、全球范围 3D 或飞行相机运动。

切勿提交地图凭证。确认图像、图块和样式的许可和归属。在帧捕获之前,等待图块、图像、字体和相机初始化。从 Remotion 帧时钟驱动相机运动,当可重复性很重要时,保持地理输入本地或内容寻址,并在实际渲染环境中验证无头 Chromium/WebGL。

Studio、渲染和验证

启动 Studio,而不打开外部浏览器:

npx remotion studio --no-open

使用打印的 URL。直接在 /<composition-id> 打开合成,例如 http://localhost:3000/LaunchVideo。

有用的 Studio 标志:

参数目的
--log=<level>设置 error、warn、info 或 verbose。
--port=<number>请求特定端口。
--force-new为同一项目和端口启动另一个实例。

对于快速的确定性布局检查,渲染一帧:

npx remotion still LaunchVideo out.png --scale=0.25 --frame=30

在 30 fps 下,第 30 帧是一秒。当现有的可视化测试已经提供足够证据时,跳过此项。

在渲染之前,验证 CLI 能看到预期的合成:

npx remotion versions
npx remotion compositions

默认情况下让 Remotion 管理其兼容的浏览器。Prismer 镜像也可能带有 Playwright 浏览器,但其存在不是兼容性保证:完整的 Chrome 二进制文件可能在沙盒崩溃策略下失败,而更新的无头 Shell 可能通过静态渲染但无法完成多帧渲染。仅对镜像拥有的、版本配对的、已通过相邻帧渲染测试的可执行文件传递 --browser-executable。切勿搜索整个文件系统以查找浏览器,也不要将成功启动视为兼容性证据。

仅当用户请求媒体文件时才渲染:

npx remotion render LaunchVideo out.mp4 --codec=h264
npx remotion still LaunchVideo out.png --frame=0

Prismer 沙盒提供 Node 和 FFmpeg,Remotion 在项目缓存中管理兼容的浏览器。优先使用 H.264 视频加 AAC 音频的 MP4 格式以实现广泛播放,除非需要透明度或无损输出。将可写 npm 缓存覆盖范围限定到每个命令:

npm_config_cache=/tmp/npm-cache npx remotion render LaunchVideo out.mp4 --codec=h264

对于 CJK 内容,显式加载并等待固定字体;不要仅依赖系统后备字体系列存在。检查相邻的编码帧以及单独的静态图像:无头渲染器可能生成正确的静态图像,而回退字体在完整渲染期间可能闪烁或丢失字形。

将媒体检查视为交付的仲裁者:

ffprobe -v error \
  -show_entries format=duration:stream=codec_name,width,height \
  -of compact out.mp4

确认持续时间、尺寸、编解码器和预期的音频流。检查代表性帧,包括动画或文本密集部分中的几个相邻帧,或在可能时播放结果。成功的渲染命令本身不是交付证据。如果孤立的静态图像是正确的,但编码渲染有部分或闪烁的帧,则使用程序化的 renderStill() API,用一个捆绑的服务 URL 和一个浏览器实例来输出经过验证的帧序列,然后使用沙盒 FFmpeg 组装。不要循环 CLI 并为每一帧重新捆绑;报告回退并再次探测组装的文件。

Player、编辑器和渲染服务

使用 Remotion 的 <Player> 进行交互式 React 预览。保持合成可同时用于 Player 和渲染路径;不要分叉视觉逻辑。

按工作负载选择渲染架构:

  • 浏览器/客户端渲染用于有限、用户本地的工作。
  • 用于受控服务器的 Node worker 和队列。
  • Remotion Lambda 用于 AWS 原生弹性渲染。
  • 当匹配托管平台和已安装的 Remotion 版本时,使用当前的官方 Vercel 或 Cloudflare 集成。

重要的渲染应该是异步的:返回一个作业 ID,公开进度和失败,持久化存储输出,并使重试具有幂等性。

对于编辑器,显式建模合成属性和时间轴状态。保持渲染输入可序列化和版本化,验证不受信任的属性,限制远程资产访问,并将预览状态与持久项目状态分开。

Remotion 的渲染表面是 React。对于 Vue、Angular 或 Svelte 宿主,使用当前的官方集成,并保持 React 合成边界显式,而不是依赖于记忆化的启动器。

当前文档和升级

优先使用当前的官方文档,而不是记忆化的 API。将 .md 附加到 Remotion 文档 URL 以获取 Markdown,例如:

https://www.remotion.dev/docs/sequence.md

Remotion 文档搜索可以

…

[截断以进行翻译]

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能