关于 youtube-intro-outro
youtube-intro-outro 是用于 Remotion 的 skill,可制作可复用的品牌化 YouTube 片头和片尾视频。它帮助创作者制作符合平台时长和布局限制、由帧驱动的动画。
主要功能
- 01品牌化片头与片尾作品
- 02Logo 动效与音频冲击帧同步
- 03符合结束画面安全区域的布局
- 04基于 brand 属性的可复用模板
- 05静帧与 MP4 验证
适用场景
- 01制作简短的频道 Logo 片头
- 02围绕 YouTube 结束画面元素设计片尾
- 03为多个频道渲染风格一致的片头片尾
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iart-ai/ youtube-video-skills --skill youtube-intro-outro安装后在 Claude Code 中输入/youtube-intro-outro确认已加载。
附带文件README.mdreferences/intro-outro.md
详细介绍
YouTube 片头与片尾
为频道的每个视频打造前后呼应的两段动态效果:3-5s 的品牌片头(用 Logo 动效告诉观众“这是我的频道”),以及片尾,最后约 20s 用于承载 YouTube 可点击的结束画面元素(订阅按钮 + 下一个视频)。两者都必须遵守平台的硬性限制——片头时长会影响观众留存率;片尾布局必须避开 YouTube 叠加的界面元素——并且都应做成可复用模板,只需更换品牌即可。
适用场景
- 频道片头 / 开场短片 / Logo 动效(在内容开始前,用 3-5s 展示频道标识)。
- 片尾 / 结束画面 / 片尾卡片(最后约 20s,包含订阅按钮 + 下一个视频卡片)。
- 可复用的品牌模板:替换名称、Logo、颜色、音效,并重新导出。
两条硬性规则(平台要求,非个人偏好)
- 片头控制在 3-5s,Logo 展示 1-2s。 时长超过 5s 会导致可量化的观众流失,进而影响视频在算法中的表现。片头用于确认频道身份,然后迅速让位给内容。
- 片尾必须包含 ≥20s 的静止、安静布局,且视频总时长 ≥25s。 YouTube 只允许在最后 5-20s 显示结束画面元素,而且视频必须至少 25s。设计片尾底板时要考虑这些元素的位置——不要在它们下方放置自己的内容。
片头:Logo 动效
Logo 动效在约 3.5s 内分为三个节拍:蓄势(通过动态营造张力)、冲击(Logo 随音效重击瞬间显现为完整形态)和收稳(轻微过冲后平稳停下)。品牌标志必须恰好落在声音的冲击帧上,而不是接近该帧。
| 节拍 | 时间范围 | 作用 |
|---|---|---|
| 蓄势 | 0-0.8s | 呼啸 / 渐强;Logo 尚不可辨认 |
| 冲击 | ~0.8s | Logo 随音效重击瞬间完整显现 + 白色闪光 |
| 收稳 | 0.8-1.2s | 过冲后平稳停下;标语渐显 |
| 停留 | 1.2-3.5s | 品牌清晰可见,然后切入内容 |
import {useCurrentFrame, useVideoConfig, spring, interpolate, Img, Audio, staticFile} from "remotion";
export const LogoSting = ({brand}) => {
const frame = useCurrentFrame();
const {fps} = useVideoConfig();
const IMPACT = Math.round(0.8 * fps); // logo lands here, on the sting hit
// overshoot scale: springs up past 1, settles to 1 (the "snap")
const scale = spring({frame: frame - IMPACT, fps, config: {damping: 9, mass: 0.5}, from: 1.18, to: 1});
const logoOpacity = frame < IMPACT ? 0 : 1;
const flash = interpolate(frame - IMPACT, [0, 6], [0.9, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
return (
<div style={{flex: 1, background: brand.bg, display: "flex", alignItems: "center", justifyContent: "center"}}>
<Audio src={staticFile(brand.sting)} /> {/* impact of this file must sit at 0.8s */}
<Img src={staticFile(brand.logo)} style={{width: 420, opacity: logoOpacity, transform: `scale(${scale})`}} />
<div style={{position: "absolute", inset: 0, background: "#fff", opacity: flash}} />
</div>
);
};
spring 从 1.18→1 的过冲本身就是那一下显现;白色 flash 在 6 帧内淡出,强化冲击感。调整音频,让音量最大的瞬态落在第 IMPACT 帧。完整构图、CSS/GSAP 变体,以及如何在任何音效中找到冲击帧,请参阅 references/intro-outro.md。
片尾:遵循 YouTube 元素区域限制的结束画面布局
大多数片尾的问题都出在这里:创作者把 Logo 或文字放在 YouTube 将要显示订阅按钮的位置。将画面视为三等分。YouTube 的可点击元素位于右侧三分之二;自己的品牌标识、频道名称和任何人像摄像头画面都应放在左侧三分之一。避开角落和底部——移动端进度条和界面会覆盖这些区域。
| 元素 | 原生尺寸 | 预留位置(1920×1080) |
|---|---|---|
| 订阅 / 频道圆形头像 | 294×294 | 右侧、垂直方向大致居中,超出画面边缘 |
| 下一个视频卡片(缩略图) | 615×345 | 右上方或右侧中央 |
| 播放列表 / 链接卡片 | 294×294 | 与视频卡片并排 |
| 自有品牌元素(Logo、名称) | — | 仅限左侧三分之一,靠上对齐 |
在片尾底板上绘制占位框,标出动态元素将出现的位置,以便围绕它们进行构图;然后在 YouTube Studio 中将真实元素覆盖上去(使用其网格和“吸附到元素”功能)。
import {useCurrentFrame, interpolate, Img, staticFile} from "remotion";
// 1920×1080 outro plate. Left third = brand; right two-thirds = YouTube element zones (drawn as guides).
export const EndScreen = ({brand}) => {
const frame = useCurrentFrame();
const fade = interpolate(frame, [0, 18], [0, 1], {extrapolateRight: "clamp"});
const zone = {position: "absolute", border: "2px dashed rgba(255,255,255,.25)", borderRadius: 12};
return (
<div style={{flex: 1, background: brand.bg, opacity: fade}}>
{/* LEFT THIRD: your brand — safe from YouTube's overlays */}
<div style={{position: "absolute", left: 80, top: 90, width: 560}}>
<Img src={staticFile(brand.logo)} style={{width: 220}} />
<div style={{color: brand.fg, font: "700 56px Inter", marginTop: 24}}>{brand.name}</div>
<div style={{color: brand.accent, font: "500 30px Inter", marginTop: 8}}>Subscribe for more →</div>
</div>
{/* RIGHT TWO-THIRDS: leave these empty; YouTube draws the live elements here */}
<div style={{...zone, width: 615, height: 345, right: 90, top: 110}} /> {/* next-video card */}
<div style={{...zone, width: 294, height: 294, right: 250, bottom: 150, borderRadius: 999}} /> {/* subscribe circle */}
</div>
);
};
仅在预览版本中显示虚线参考线;最终渲染时移除参考线,让底板保持干净,并有意让右侧保持安静。片尾可以静止展示品牌,也可以在完整的 20s 内循环播放细微动效,但不能让任何内容与卡片争夺注意力。
可复用的品牌模板
两种构图都读取同一个 brand 属性——不硬编码名称、颜色、Logo 或音频。替换对象(或传入 --props),即可通过同一套代码为不同频道重新设计片头和片尾。
// brand.json — the only thing that changes per channel
{ "name": "PixelForge", "logo": "logo.png", "sting": "sting.mp3",
"bg": "#0B0B14", "fg": "#FFFFFF", "accent": "#7C5CFF" }
# render intro + outro for every brand file in /brands
for f in brands/*.json; do
name=$(basename "$f" .json)
npx remotion render Intro "out/${name}-intro.mp4" --props="$f"
npx remotion render Outro "out/${name}-outro.mp4" --props="$f"
done
在模板中固定字体、布局和时长,让 20 个频道在结构上保持一致,只呈现不同的品牌标识。
输出检查清单
- 片头 ≤5 秒;约 2 秒时 logo 清晰可读;logo 出现时刻与音频冲击帧精确对齐。
- 片尾保持布局 ≥20 秒;视频总时长 ≥25 秒,以便允许添加结束画面元素。
- 片尾右侧三分之二保持留白,供 YouTube 放置元素;自有品牌内容仅放在左侧三分之一。
- 距离任一边缘约 10% 范围内以及底部 UI 区域内都不要放置重要内容。
- 规划的结束画面元素最多 4 个(1 个视频 + 订阅是点击率最高的布局)。
- 所有文字/颜色/logo/音频均来自
brandprop——一个模板,适用于多个频道。
交付与验证(渲染静帧 → MP4)
打包的辅助脚本(
scripts/):使用scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png拼接静帧,然后使用scripts/probe-mp4.sh out.mp4 [WxH] [fps]检查编码结果。参见scripts/README.md。
这是重型工作:交付物是实际的 MP4 片段(片头 + 片尾)。编码前,先以静帧形式验证 logo 出现时刻和结束画面的安全区域——如果音效落后或提前一帧,或 logo 被盖在 YouTube 绘制订阅按钮的位置,要等完整渲染后才发现,代价会很高。
输出要求:
- 一个 Remotion 项目,注册了两个合成(
<Composition>+ zodschema+defaultProps),所有动画均由帧驱动——不使用Date.now()/Math.random()/ 定时器。 - 将音效冲击预先烘焙到帧中(
IMPACT = Math.round(0.8 * fps)),不在运行时检测;音频通过<Audio src={staticFile()}>添加,确保导出文件包含音效。 - 交付物 = 渲染后的
out/*-intro.mp4+out/*-outro.mp4以及项目,方便用户通过brandprop 更换品牌样式并重新导出。
验证流程——渲染静帧 → 检查 → 编码。
# 1. Frame-exact stills WITH SHIPPED brand props (not just defaultProps).
# Intro: windup / impact / settle. Outro: fade-in / held end-screen plate.
npx remotion still Intro out/i-windup.png --frame=12 --props=./brand.json
npx remotion still Intro out/i-impact.png --frame=24 --props=./brand.json # = round(0.8*fps)
npx remotion still Intro out/i-settle.png --frame=40 --props=./brand.json
npx remotion still Outro out/o-end.png --frame=N --props=./brand.json
# 2. Inspect each PNG — fidelity (logo readable + captions/tagline correct; on the impact
# frame the logo is full-scale and the flash fires) AND artifacts (end-screen elements
# inside YouTube safe zones — branding in the LEFT third only, right two-thirds quiet,
# nothing within ~10% of any edge or in the bottom UI band; no off-canvas text/overflow).
# 3. Only once the stills check out, encode both plates:
npx remotion render Intro out/intro.mp4 --props=./brand.json
npx remotion render Outro out/outro.mp4 --props=./brand.json
- 明确验证冲击帧(logo 突然放大至完整尺寸,白色闪光逐渐消退)——音效必须与该帧同步,而非出现在附近。
- 最终渲染时移除虚线结束画面参考线;确认右侧三分之二有意留白。
- README 演示:
npx remotion render Intro out/demo.gif --codec=gif。
完成前:
npx remotion still在片头的蓄势/冲击/稳定阶段以及片尾的保持画面均可正常渲染——无错误、无缺失的 logo/音效素材。- 冲击帧上的 logo 为完整尺寸且清晰可读;片头 ≤5 秒,片尾保持 ≥20 秒(视频总时长 ≥25 秒)。
- 仅使用帧驱动——音效冲击预先烘焙到帧中;不使用
Date.now()/Math.random()/ 定时器。 - 结束画面元素均位于 YouTube 安全区域内——品牌内容放在左侧三分之一,右侧三分之二留白;底部 UI 区域内或距离边缘约 10% 范围内均无内容。
- 两个 MP4 均已编码并混入音效,且可正常播放;所有文字/颜色/logo/音频均来自
brandprop;(可选)为 README 渲染 GIF。
参考文件
references/intro-outro.md— 片头和片尾的完整可运行 Remotion 合成、CSS/GSAP logo 音效变体、适用于 16:9 的精确结束画面坐标图及 1080×1920 的说明、查找音效冲击帧并使揭示效果与之同步的方法,以及包含批量渲染流程的 brand prop 架构。