mcpField
A
audiogram

audiogram

github.com/iart-ai创意与媒体6779 次安装18 周前更新
代码仓库

关于 audiogram

Audiogram 是用于 Remotion 的 skill,可将音频片段制作成带字幕、波形、封面、标题和进度条的视频。它面向社交媒体内容创作者,以帧驱动音频可视化,并支持多种画面比例。

主要功能

  1. 01音频响应式均衡条或波形
  2. 02与帧同步的字幕
  3. 03封面、标题和进度条
  4. 04方形、竖屏和宽屏布局
  5. 05离线采样以便渲染

适用场景

  1. 01将播客精选片段制作成社交视频
  2. 02让旁白在静音动态中也易于理解
  3. 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–1visualizeAudio()音乐、活力感、“让柱子动起来”
平滑的示波器波形时域振幅,−1…1visualizeAudioWaveform()人声、播客、平静简约的风格

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:16Reels / TikTok / Shorts1080×1920留出更多垂直空间;字幕避开底部 18%(界面区域)
16:9YouTube、落地页嵌入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> + zod schema + 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(无声,但可证明动画效果)。

完成前:

  1. npx remotion still 在第 0 帧、中间帧和最后一帧均能正常渲染——没有错误,也没有缺失封面 / 音频资源。
  2. 每个已检查帧的条形 / 波形高度都与该处音频的振幅相符;屏幕上显示正确的字幕短句,且同步无误。
  3. 仅由帧驱动——不使用实时分析器 / Date.now() / Math.random() / 定时器;样本已离线写入。
  4. 每个已检查帧上的字幕都位于安全区域内(避开底部约 18% 的界面区域);封面图 + 标题 + 进度条均已显示。
  5. 编码完整 MP4,混入真实音频并确保能够播放;(可选)为 README 渲染 GIF。

参考文件

  • references/waveform-render.md — 两种视觉样式的完整可运行组件:镜像频率条均衡器和平滑的示波器波形(visualizeAudio / visualizeAudioWaveform)、包含封面图、标题、进度条和音频混入的完整五层音频可视化视频合成、2 的幂 / 平滑处理速查表,以及一个无需依赖项的 Web Audio + canvas 版本(可解码为逐帧样本数组)。最后附有构建 / 署名说明。

评论

支持 Markdown