关于 audiogram
Audiogram 是用于 Remotion 的 skill,可将音频片段制作成带字幕、波形、封面、标题和进度条的视频。它面向社交媒体内容创作者,以帧驱动音频可视化,并支持多种画面比例。
主要功能
- 01音频响应式均衡条或波形
- 02与帧同步的字幕
- 03封面、标题和进度条
- 04方形、竖屏和宽屏布局
- 05离线采样以便渲染
适用场景
- 01将播客精选片段制作成社交视频
- 02让旁白在静音动态中也易于理解
- 03用响应式均衡条或波形呈现音乐
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iart-ai/ youtube-video-skills --skill audiogram安装后在 Claude Code 中输入/audiogram确认已加载。
附带文件README.mdreferences/waveform-render.md
详细介绍
Audiogram
将一段音频剪辑——播客精彩片段、配音或引言——制作成一段简短的字幕视频,让人在静音的信息流中停下滚动。动态元素(波形或均衡器柱)表明“这里有声音”,字幕为静音观看的 80% 用户传达内容,而封面图 + 标题 + 进度条则构成完整、有品牌感的画面。
适用场景
- 用于 Reels / TikTok / Shorts / 信息流帖子的播客音频片段或引言。
- 需要添加视觉画面才能作为视频发布的配音或旁白。
- 以响应式波形/柱状图为主角的音乐或其他音频。
防止 90% 错误的一条规则
所有柱高都要根据当前帧计算,绝不要使用实时分析器循环。 实时 AnalyserNode + requestAnimationFrame 读取的是“此刻正在播放的内容”,但视频渲染器会以不同于实时播放的速度绘制帧,且帧的顺序也可能不同,因此波形会不同步或冻结。正确做法是先将整个文件解码为振幅采样,然后将显示值计算为帧的纯函数。在 Remotion 中,这就是 useAudioData() + visualizeAudio();在普通 canvas 中,则是通过 decodeAudioData() 将音频解码到采样数组,再按帧索引取值。
import { useAudioData, visualizeAudio } from "@remotion/media-utils";
import { useCurrentFrame, useVideoConfig } from "remotion";
const audioData = useAudioData(staticFile("episode.mp3"));
if (!audioData) return null; // still loading
const { fps } = useVideoConfig();
const bars = visualizeAudio({
audioData,
frame: useCurrentFrame(),
fps,
numberOfSamples: 32, // MUST be a power of two
}); // → Float array, length 32, each 0–1, low freq → high freq
两种波形渲染方式
| 外观 | 数据 | API | 最适合 |
|---|---|---|---|
| 均衡器柱状图 | 频谱,取值范围 0–1 | visualizeAudio() | 音乐、活力感、“让柱子动起来” |
| 平滑的示波器波形 | 时域振幅,−1…1 | visualizeAudioWaveform() | 人声、播客、平静简约的风格 |
visualizeAudio 返回的频率值从左侧的低频到右侧的高频排列。要创建居中均衡器,请取前 N 个柱并围绕中间镜像,让低音位于中心。numberOfSamples 必须是 2 的幂(16/32/64);想要粗犷、有品牌感的效果,可使用 16–32;想要细致的频谱,可使用 64 以上。完整的柱状图和示波器组件请参见 references/waveform-render.md。
长音频文件:不要加载整集内容
useAudioData() 会将整个文件读入内存——对于 30–90 秒的剪辑没问题,但处理完整一集时会很慢且占用大量内存。对于较长的音频,请先剪辑,或使用 useWindowedAudioData();它会通过 HTTP 范围请求,仅获取当前帧附近的音频。
import { useWindowedAudioData } from "@remotion/media-utils";
const { audioData } = useWindowedAudioData(
staticFile("full-episode.mp3"),
fps,
/* windowInSeconds */ 10,
);
最佳实践:渲染前先剪辑出音频片段(≤90s)。精简的片段更适合作为社交媒体素材,渲染负担也更轻。
布局
完整的 audiogram 由五个叠放的图层组成。将它们固定在指定区域,这样同一构图就能适配各种宽高比。
| 图层 | 作用 | 说明 |
|---|---|---|
| 背景 | 品牌色 / 柔和渐变 / 模糊封面 | 不能过于繁杂,以免干扰字幕 |
| 封面图 + 标题 | 说明人物/内容 | 顶部区域放置小方形封面 + 单集/节目标题 |
| 波形 / 柱状图 | 表明音频内容的动态效果 | 位于中央区域,是画面焦点 |
| 字幕 | 为静音观看者传达内容 | 高对比度,一次显示一条简短短语 |
| 进度条 | 显示剪辑的播放进度 | 细条,根据 frame / durationInFrames 驱动 |
// progress bar — a pure function of frame, no audio needed
const { durationInFrames } = useVideoConfig();
const progress = useCurrentFrame() / durationInFrames; // 0 → 1
<div style={{ width: `${progress * 100}%`, height: 6, background: "#fff" }} />
与语音同步的字幕
字幕不可或缺——大多数信息流视频都是静音播放的,而带字幕的视频能更长时间地吸引注意力。通过转录步骤生成词语/短语时间点(Whisper / @remotion/captions parseSrt),然后一次显示一条简短短语,并在其起始帧切换。逐词显示、突出显示当前词语,以及 SRT/JSON 时间点等实现细节属于 caption-animation 技能——字幕图层应使用该技能,而不是在这里重复实现。本技能负责将字幕轨道放入 audiogram 布局,并确保它与波形使用相同的音频时钟同步。
社交媒体画幅适配
先在中心安全区域内设计,再重新适配画幅——不要加黑边。
| 画幅 | 用途 | 分辨率 | 布局 |
|---|---|---|---|
| 1:1 | 信息流帖子 | 1080×1080 | 封面 + 标题置顶,波形居中,字幕位于下三分之一处 |
| 9:16 | Reels / TikTok / Shorts | 1080×1920 | 留出更多垂直空间;字幕避开底部 18%(界面区域) |
| 16:9 | YouTube、落地页嵌入 | 1920×1080 | 波形宽而低,字幕居中 |
让片段静音和有声时都能播放:波形 + 字幕必须能在静音时讲完整个故事,而用户点击后则播放实际音轨。务必加入真实音频 <Audio src={...} />,确保导出文件带有声音。
输出检查清单
- 条形 / 波形高度是
useCurrentFrame()的纯函数——没有实时分析器循环。 numberOfSamples是 2 的幂;居中的条形围绕中点镜像排列。- 片段修剪至 ≤90s;若源文件较长,则使用
useWindowedAudioData()。 - 包含字幕,具有高对比度,并与同一音频时钟同步(通过 caption-animation)。
- 渲染封面图 + 标题 + 进度条;进度 =
frame / durationInFrames。 - 混入真实音频(
<Audio>);静音时仍能读懂故事。 - 从一个合成生成 1:1 + 9:16(如有需要,也生成 16:9),关键内容位于安全区域内。
交付与验证(渲染静帧 → 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。
这是 HEAVY 级别:交付物必须是真正的 MP4(混入音频),且波形必须由数据驱动——任意帧上的波形形状都必须与该时刻的音频相符。在花费资源进行完整编码前,先将几帧渲染为静帧并进行验证。
输出要求:
- 一个已注册音频可视化视频的 Remotion 项目(
<Composition>+ zodschema+defaultProps),所有动画均由帧驱动——不使用Date.now()/Math.random()/ 定时器,且不使用实时分析器。 - 离线将振幅 / 波形样本写入 props(或通过
useAudioData解码一次)——切勿在渲染时分析音频;无头渲染没有实时音频时钟。 - 交付物 = 渲染好的
out/*.mp4(通过<Audio src={staticFile()}>混入音频)以及项目本身,方便用户用新音频 / 字幕重新渲染。
验证流程——渲染静帧 → 检查 → 编码。
# 1. Frame-exact stills at start / mid / end, WITH SHIPPED PROPS (not just defaultProps)
npx remotion still Audiogram out/f-start.png --frame=0 --props=./props.json
npx remotion still Audiogram out/f-mid.png --frame=N --props=./props.json
npx remotion still Audiogram out/f-end.png --frame=N-1 --props=./props.json # last = durationInFrames-1
# 2. Inspect each PNG — fidelity (waveform/bar heights match the audio's amplitude at
# that exact time; the right caption phrase is on screen and synced) AND artifacts
# (missing cover art, caption off-canvas / under the bottom UI band, bar overflow).
# 3. Only once the stills check out, encode the full video (audio muxed):
npx remotion render Audiogram out/audiogram.mp4 --props=./props.json
- 波形由数据驱动——完整渲染前,在几帧上验证振幅 + 字幕同步,以便及时发现不同步的问题,避免长时间编码后才发现。
- 使用
npx remotion compositions读取durationInFrames/fps并选择结束帧。 - README 演示:
npx remotion render Audiogram out/demo.gif --codec=gif(无声,但可证明动画效果)。
完成前:
npx remotion still在第 0 帧、中间帧和最后一帧均能正常渲染——没有错误,也没有缺失封面 / 音频资源。- 每个已检查帧的条形 / 波形高度都与该处音频的振幅相符;屏幕上显示正确的字幕短句,且同步无误。
- 仅由帧驱动——不使用实时分析器 /
Date.now()/Math.random()/ 定时器;样本已离线写入。 - 每个已检查帧上的字幕都位于安全区域内(避开底部约 18% 的界面区域);封面图 + 标题 + 进度条均已显示。
- 编码完整 MP4,混入真实音频并确保能够播放;(可选)为 README 渲染 GIF。
参考文件
references/waveform-render.md— 两种视觉样式的完整可运行组件:镜像频率条均衡器和平滑的示波器波形(visualizeAudio/visualizeAudioWaveform)、包含封面图、标题、进度条和音频混入的完整五层音频可视化视频合成、2 的幂 / 平滑处理速查表,以及一个无需依赖项的 Web Audio + canvas 版本(可解码为逐帧样本数组)。最后附有构建 / 署名说明。