FireRed-OpenStoryline智能音乐卡点:如何做到BPM节拍分析与情绪驱动的BGM推荐
【免费下载链接】FireRed-OpenStorylineFireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language interaction, LLM-powered planning, and precise tool orchestration. It facilitates transparent, human-in-the-loop creation with reusable Style Skills for consistent, professional storytelling.项目地址: https://gitcode.com/gh_mirrors/fi/FireRed-OpenStoryline
FireRed-OpenStoryline是一个开源 AI 视频剪辑 Agent,它能听懂你的自然语言需求,自动搜索素材、生成文案,并根据视频情绪智能推荐 BGM、精准卡点。本文带你拆解它的两大核心技术:基于 librosa 的BPM 节拍分析,以及由多模态模型驱动的情绪化 BGM 推荐流程,让你明白"AI 音乐卡点"背后到底发生了什么。
🎵 智能 BGM 推荐:从"听懂情绪"到"选出曲子"
整个推荐链路分为三步,核心实现在 select_bgm.py 中的SelectBGMNode:
第 1 步:给曲库打"情绪标签"
推荐的前提是系统"懂"你的每一首 BGM。项目提供了一键批量打标签脚本 omni_bgm_label.py,它会扫描resource/bgms目录下的 mp3/wav 文件,调用 Qwen3-Omni 多模态大模型"听"完每首音乐后输出结构化标签:
- scene(场景):Vlog、Travel、Relaxing、Emotion、Cafe、Food……
- genre(曲风):Pop、Electronic、Rock、Jazz、Chinese Style……
- mood(情绪):Dynamic、Chill、Happy、Sorrow、Romantic、Inspirational……
- description(一句话描述):例如"轻松愉快的电子乐,适合旅行或日常 Vlog"
标签体系定义在提示词 omni_bgm_label.md 中,结果写入meta.json。脚本用文件 MD5 做增量识别——没改过的歌不会重复打标,省 token 又高效。
第 2 步:向量召回 + 标签过滤
当你在对话里说"来一首治愈系纯音乐"时,系统先走全量向量召回:recall.py 把候选音乐与用户请求做语义相似度匹配,再由 element_filter.py 按场景、曲风、情绪等标签做 include/exclude 过滤,快速收敛出最贴切的一批候选曲。
第 3 步:LLM 终选——有且只有一条
候选列表和用户需求一起送入大模型做最终裁决。系统提示词 select_bgm/zh/system.md 要求"返回有且只有一条最适合的 json",采样参数 temperature=0.1,保证结果稳定。如果模型输出解析失败,还有降级策略:直接取候选列表第一条,保证流程不中断。
🥁 BPM 节拍分析:卡点是如何算出来的
选完曲子,analyze_music_metrics()会对音频做一套信号分析,产出卡点所需的"音乐指纹":
| 指标 | 计算方式 | 作用 |
|---|---|---|
| bpm | librosa.beat.beat_track+ onset envelope | 每分钟节拍数,节拍间隔的基准 |
| beats | 重音拍检测(毫秒时间戳列表) | 卡点的"落点" |
| energy_mean | RMS 均值 | 音乐整体能量 |
| dynamic_range_db | 10%~95% 分位数差 | 动态范围 |
其中重音拍(accent beats)的计算_compute_accent_beats藏着不少工程细节:
- 打击乐分离:先用
librosa.effects.percussive抽出打击乐成分,让鼓点更突出; - 局部归一化:用 8 拍滑动窗口做局部均值归一,防止"副歌太响"导致重音全挤在响段落;
- 局部峰值约束:只保留比前后拍都强的拍,避免一段平台期被整体选中;
- 最小间隔抑制:按强度排序后做贪心抑制,相邻拍不会同时入选。
最终输出形如[1250, 3500, 5750, ...]的毫秒级重音时间戳列表,存进beats字段。
⏱️ 卡点落地的关键:时间轴按拍分配时长
节拍数据的真正价值在 plan_timeline.py。当use_beats=True时,_allocate_clip_durations_using_beats()会让每个片段的时长对齐节拍间隔——画面切换恰好落在重音上,这就是你看到的"卡点"效果。
还有两层贴心兜底:
- 如果
beats为空,则回退用bpm推算均匀节拍间隔; - 如果 BPM 也缺失,则切换为无节拍分配策略
_allocate_clip_durations_without_beats。
相关采样参数(sample_rate、hop_length、frame_length)都可以在 config.py 中调整。
🛠️ 三步搭建你的私有 BGM 卡点库
- 把私有音乐文件放入
resource/bgms目录(官方教程见 docs/source/zh/guide.md); - 运行打标签脚本:
python -m scripts.omni_bgm_label- 重启 MCP 服务,之后只需一句话:"选一首适合夜晚咖啡馆氛围的 BGM,卡点剪辑"。
❓ 常见问题
Q: 没有配 API Key 时还能用 BGM 推荐吗?A: 可以。脚本会跳过新文件的打标(已有标签仍生效),推荐链路本身仍可运行。
Q: 卡点不准怎么办?A: 先检查选曲是否电子/鼓点明显的曲风;再检查 config.py 中select_bgm的采样与帧参数;纯氛围曲本身重音稀疏,建议关闭use_beats改用自由时长分配。
Q: 想复刻同一套选曲风格?A: 项目支持把完整剪辑逻辑保存为 Style Skill,下次换素材直接复用,实现批量同款产出。
📁 核心文件速查
- BGM 选择与 BPM 分析节点:src/open_storyline/nodes/core_nodes/select_bgm.py
- 时间轴卡点分配:src/open_storyline/nodes/core_nodes/plan_timeline.py
- 向量召回工具:src/open_storyline/utils/recall.py
- 曲库批量打标脚本:scripts/omni_bgm_label.py
- 选择提示词:prompts/tasks/select_bgm/zh/
- 官方使用指南:docs/source/zh/guide.md
从"听懂情绪"到"算准拍子",FireRed-OpenStoryline 用多模态理解 + 信号分析 + LLM 裁决的组合拳,把过去需要逐帧对拍的卡点工作变成了一句话的事。
【免费下载链接】FireRed-OpenStorylineFireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language interaction, LLM-powered planning, and precise tool orchestration. It facilitates transparent, human-in-the-loop creation with reusable Style Skills for consistent, professional storytelling.项目地址: https://gitcode.com/gh_mirrors/fi/FireRed-OpenStoryline
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考