youtube-intro-outro

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

YouTube Intro & Outro

YouTube 片头与片尾

Build the two pieces of motion that bracket every video on a channel: a 3-5s branded intro (logo sting that says "this is my channel") and an outro whose last ~20s host YouTube's clickable end-screen elements (subscribe + next video). Both must respect hard platform constraints — intro length affects retention; outro layout must dodge YouTube's overlaid UI — and both should be one reusable template where only the brand changes.
为频道中的每个视频制作首尾两段动态内容:一段3-5秒的品牌化片头(展示频道标识的标志动画,传递“这是我的频道”的信息),以及一段片尾,其最后约20秒包含YouTube可点击的结束画面元素(订阅按钮+下一集视频卡片)。两者都必须遵守平台的严格限制——片头时长会影响观众留存率;片尾布局必须避开YouTube的叠加UI——并且都应是仅需替换品牌元素即可复用的模板。

When to use

使用场景

  • Channel intro / bumper / logo sting (a 3-5s identity hit before content).
  • Outro / end screen / end card (the last ~20s with subscribe + next-video cards).
  • A reusable brand template: swap name, logo, colors, sting, and re-export.
  • 频道片头/短片头/标志动画(内容开始前1个3-5秒的身份展示片段)。
  • 片尾/结束画面/结束卡片(最后约20秒包含订阅+下一集视频卡片的片段)。
  • 可复用品牌模板:替换名称、标志、配色、音频特效后重新导出。

Two hard rules (platform, not taste)

两条硬性规则(平台要求,非审美偏好)

  1. Keep the intro 3-5s, the logo hit 1-2s. Anything longer than 5s causes measurable viewer drop-off, which hurts the video in the algorithm. The intro confirms the channel and gets out of the way.
  2. The outro must be ≥20s of held, quiet layout, and the video ≥25s total. YouTube only allows end-screen elements in the final 5-20s, and the video must be at least 25 seconds long. Design the outro plate around where those elements land — never put your own content under them.
  1. 片头时长控制在3-5秒,标志展示时长1-2秒。 超过5秒会导致明显的观众流失,进而影响视频在算法中的表现。片头只需确认频道身份,然后尽快过渡到内容。
  2. 片尾必须包含至少20秒的固定安静布局,且视频总时长≥25秒。 YouTube仅允许在视频最后5-20秒添加结束画面元素,且视频总时长必须至少25秒。设计片尾模板时要围绕这些元素的位置进行布局——绝对不要将自有内容放在这些元素下方。

Intro: the logo sting

片头:标志动画

A sting is three beats in ~3.5s: a windup (motion building tension), an impact (logo snaps to full on the audio hit), and a settle (micro-overshoot relaxing to rest). The brand mark must land exactly on the sound's impact frame, not near it.
BeatWindowJob
Windup0-0.8swhoosh / build; logo not yet readable
Impact~0.8slogo snaps to full on the audio hit + a white flash
Settle0.8-1.2sovershoot relaxes to rest; tagline fades in
Hold1.2-3.5sbrand legible, then cut to content
jsx
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
overshooting from 1.18→1 is the snap; the white
flash
decaying over 6 frames sells the impact. Align the audio so its loudest transient sits on frame
IMPACT
. See
references/intro-outro.md
for the full composition, a CSS/GSAP variant, and how to find the impact frame in any sting.
一个标准的标志动画在约3.5秒内分为三个节拍:蓄力(营造张力的动态效果)、冲击(标志在音频特效的峰值帧瞬间完全显示)、稳定(微过冲后恢复到静止状态)。品牌标志必须精准落在音频特效的峰值帧,而非近似位置。
节拍时间区间作用
蓄力0-0.8秒呼啸/渐强效果;标志暂不可读
冲击~0.8秒标志在音频峰值帧瞬间完全显示 + 白色闪屏效果
稳定0.8-1.2秒过冲效果恢复静止;标语渐入
保持1.2-3.5秒品牌标识清晰可见,随后切入内容
jsx
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);            // 标志在此帧落地,对应音频特效峰值

  // 过冲缩放:弹簧效果从1.18过渡到1(实现“瞬间弹出”效果)
  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)} />        {/* 此音频文件的峰值必须位于0.8秒处 */}
      <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

Outro: end-screen layout that respects YouTube's element zones

片尾:符合YouTube元素区域的结束画面布局

This is where most outros fail: creators put a logo or text exactly where YouTube will stamp a subscribe button. Treat the frame as two thirds. YouTube's clickable elements live on the right two thirds; keep your own branding, channel name, and any face-cam in the left third. Stay away from corners and the bottom — the mobile progress bar and UI overlap there.
ElementNative sizeWhere to leave room (1920×1080)
Subscribe / channel circle294×294right side, vertically centered-ish, off the edge
Next-video card (thumbnail)615×345upper-right or center-right
Playlist / link card294×294pair beside the video card
Your branding (logo, name)left third only, top-aligned
Render placeholders in your outro plate where the live elements will sit, so you compose around them — then position the real elements over them in YouTube Studio (use its grid + "snap to element").
jsx
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>
  );
};
Ship the dashed guides only in a preview build; the final render drops them, leaving a clean plate whose right side is intentionally quiet. The outro itself can hold a static brand or loop a subtle motion for the full 20s — but nothing that competes for attention with the cards.
这是大多数片尾的失败之处:创作者会将标志或文字放在YouTube将显示订阅按钮的位置。将画面视为三等分。YouTube的可点击元素位于右侧三分之二区域;将自有品牌标识、频道名称和任何摄像头画面放在左侧三分之一区域。远离角落和底部——移动设备的进度条和UI会在此处重叠。
元素原生尺寸预留空间位置(1920×1080分辨率)
订阅按钮/频道头像294×294右侧,大致垂直居中,贴近边缘
下一集视频卡片(缩略图)615×345右上或中右区域
播放列表/链接卡片294×294与视频卡片配对放置
自有品牌(标志、名称)仅左侧三分之一区域,顶部对齐
在片尾模板中渲染占位符,标记出实际元素将放置的位置,以便围绕这些位置进行构图——然后在YouTube Studio中使用网格和“对齐元素”功能将真实元素放在占位符上方。
jsx
import {useCurrentFrame, interpolate, Img, staticFile} from "remotion";

// 1920×1080分辨率的片尾模板。左侧三分之一为品牌区域;右侧三分之二为YouTube元素区域(用虚线标记)。
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}}>
      {/* 左侧三分之一:自有品牌区域——不受YouTube叠加层影响 */}
      <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>

      {/* 右侧三分之二:留空;YouTube将在此渲染实际元素 */}
      <div style={{...zone, width: 615, height: 345, right: 90, top: 110}} />        {/* 下一集视频卡片 */}
      <div style={{...zone, width: 294, height: 294, right: 250, bottom: 150, borderRadius: 999}} /> {/* 订阅头像 */}
    </div>
  );
};
仅在预览版本中保留虚线引导线;最终渲染时移除它们,得到右侧区域特意留白的干净模板。片尾可以是静态品牌展示,也可以是持续20秒的细微循环动态——但不能与卡片争夺注意力。

Reusable brand template

可复用品牌模板

Both compositions read a single
brand
prop — no hardcoded names, colors, logos, or audio. Swap the object (or pass
--props
) to re-skin every channel intro/outro from one codebase.
js
// brand.json — the only thing that changes per channel
{ "name": "PixelForge", "logo": "logo.png", "sting": "sting.mp3",
  "bg": "#0B0B14", "fg": "#FFFFFF", "accent": "#7C5CFF" }
bash
undefined
两个合成组件都读取单个
brand
属性——没有硬编码的名称、配色、标志或音频。替换该对象(或传递
--props
参数)即可从同一个代码库为不同频道重新设计片头/片尾。
js
// brand.json — 每个频道唯一需要修改的文件
{ "name": "PixelForge", "logo": "logo.png", "sting": "sting.mp3",
  "bg": "#0B0B14", "fg": "#FFFFFF", "accent": "#7C5CFF" }
bash
// 为/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个频道的片头片尾在结构上保持一致,仅品牌标识不同。

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

Keep fonts, layout, and timing fixed in the template so 20 channels stay structurally consistent and only the brand identity differs.
  • 片头时长≤5秒;标志在约2秒时清晰可读;标志展示精准落在音频峰值帧。
  • 片尾包含≥20秒的固定布局;视频总时长≥25秒,以支持添加结束画面元素。
  • 片尾右侧三分之二区域留白,用于放置YouTube元素;自有品牌仅位于左侧三分之一区域。
  • 重要内容远离任何边缘约10%的范围,也不放在底部UI区域。
  • 规划最多4个结束画面元素(1个视频卡片+订阅按钮是点击率最高的布局)。
  • 所有文字/配色/标志/音频均来自
    brand
    属性——一个模板,适配多个频道。

Output checklist

交付与验证(渲染静帧→MP4)

  • Intro ≤5s; logo readable by ~2s; logo hit lands exactly on the audio impact frame.
  • Outro is ≥20s of held layout; total video ≥25s so end-screen elements are allowed.
  • Right two-thirds of the outro left quiet for YouTube's elements; own branding in the left third only.
  • Nothing important within ~10% of any edge or in the bottom UI band.
  • Up to 4 end-screen elements planned (1 video + subscribe is the highest-CTR layout).
  • Every text/color/logo/audio comes from the
    brand
    prop — one template, many channels.
打包辅助工具
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模板(片头+片尾)。在编码前先验证标志展示和结束画面安全区域的静帧——如果标志展示差一帧对齐,或者标志放在了YouTube显示订阅按钮的位置,在完整渲染后再修改会非常耗时。
输出约定:
  • 一个注册了两个合成组件的Remotion项目(包含
    <Composition>
    + zod
    schema
    +
    defaultProps
    ),所有动态效果均由帧驱动——不使用
    Date.now()
    /
    Math.random()
    / 计时器。
  • 音频特效峰值帧已固化(
    IMPACT = Math.round(0.8 * fps)
    ),而非运行时检测;音频通过
    <Audio src={staticFile()}>
    引入,确保导出文件包含音频特效。
  • 交付物 = 渲染好的
    out/*-intro.mp4
    +
    out/*-outro.mp4
    以及项目源码,以便用户通过
    brand
    属性重新设计并重新导出。
验证流程——渲染静帧→检查→编码。
bash
undefined

Deliver & verify (rendered stills → MP4)

1. 使用实际品牌属性(而非仅defaultProps)渲染精准帧的静帧。

片头:蓄力/冲击/稳定帧。 片尾:淡入/固定结束画面帧。

Packaged helper (
scripts/
): tile your stills with
scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png
, then assert the encode with
scripts/probe-mp4.sh out.mp4 [WxH] [fps]
. See
scripts/README.md
.
This is HEAVY tier: the deliverables are real MP4 plates (intro + outro). Verify the logo hit and the end-screen safe zones as stills before encoding — a sting that lands a frame off, or a logo stamped where YouTube draws its subscribe button, is expensive to discover after a full render.
Output contract:
  • A Remotion project with both compositions registered (
    <Composition>
    + zod
    schema
    +
    defaultProps
    ), all motion frame-driven — no
    Date.now()
    /
    Math.random()
    / timers.
  • Sting impact baked to the frame (
    IMPACT = Math.round(0.8 * fps)
    ), not detected at runtime; audio via
    <Audio src={staticFile()}>
    so the export carries the sting.
  • Deliverable = the rendered
    out/*-intro.mp4
    +
    out/*-outro.mp4
    plus the project, so the user can re-skin via the
    brand
    prop and re-export.
Verify loop — render stills → inspect → encode.
bash
undefined
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

1. Frame-exact stills WITH SHIPPED brand props (not just defaultProps).

2. 检查每张PNG的保真度(标志清晰可读+字幕/标语正确;冲击帧上标志完全显示且闪屏效果触发)

Intro: windup / impact / settle. Outro: fade-in / held end-screen plate.

以及布局合理性(结束画面元素位于YouTube安全区域内——品牌仅在左侧三分之一区域,右侧三分之二留白,

重要内容远离边缘约10%范围或底部UI区域;无超出画布的文字/内容)。

3. 仅当静帧检查通过后,再编码两个模板:

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
npx remotion render Intro out/intro.mp4 --props=./brand.json npx remotion render Outro out/outro.mp4 --props=./brand.json

- 明确验证**冲击帧**(标志完全显示,白色闪屏正在衰减)——音频特效必须精准落在该帧,而非近似位置。
- 最终渲染时移除片尾的虚线引导线;验证右侧三分之二区域是否特意留白。
- README演示:`npx remotion render Intro out/demo.gif --codec=gif`。

**完成前检查:**
1. `npx remotion still`能成功渲染片头的蓄力/冲击/稳定帧和片尾的固定布局帧——无错误,无缺失的标志/音频特效资源。
2. 冲击帧上标志完全显示且清晰可读;片头时长≤5秒,片尾固定布局时长≥20秒(视频总时长≥25秒)。
3. 仅由帧驱动——音频特效峰值帧已固化;不使用`Date.now()` / `Math.random()` / 计时器。
4. 结束画面元素位于YouTube安全区域内——品牌在左侧三分之一区域,右侧三分之二留白,无内容在底部UI区域或边缘约10%范围内。
5. 两个MP4文件均已正确编码并包含音频特效;所有文字/配色/标志/音频均来自`brand`属性;(可选)已渲染GIF用于README。

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

- Verify the **impact frame** explicitly (logo snapped to full, white flash decaying) — the sting must land *on* it, not near it.
- Drop the dashed end-screen guides for the final render; verify the right two-thirds is intentionally quiet.
- README demo: `npx remotion render Intro out/demo.gif --codec=gif`.

**Before you finish:**
1. `npx remotion still` renders cleanly at windup/impact/settle (intro) and the held plate (outro) — no errors, no missing logo/sting assets.
2. On the impact frame the logo is full-scale and legible; intro ≤5s, outro ≥20s held (video ≥25s total).
3. Frame-driven only — sting impact baked to a frame; no `Date.now()` / `Math.random()` / timers.
4. End-screen elements land inside YouTube safe zones — branding in the left third, right two-thirds quiet, nothing in the bottom UI band or within ~10% of an edge.
5. Both MP4s encoded with the sting muxed in and play; every text/color/logo/audio comes from the `brand` prop; (optional) GIF rendered for the README.
  • references/intro-outro.md
    — 片头和片尾的完整可运行Remotion合成代码、CSS/GSAP版标志动画变体、16:9分辨率的精确结束画面坐标图及1080×1920分辨率的注意事项、查找音频特效峰值帧并同步标志展示的方法,以及包含批量渲染流程的品牌属性schema。

Reference files

  • references/intro-outro.md
    — the full runnable Remotion compositions for both intro and outro, a CSS/GSAP logo-sting variant, an exact end-screen coordinate map for 16:9 and notes for 1080×1920, the method for finding an audio sting's impact frame and syncing the reveal to it, and the brand-prop schema with the batch render pipeline.