write-post-event-highlight-reel-script
将活动笔记转化为社交平台用的简短回顾脚本。
基于弹幕与字幕分析,自动提取高能片段并合成带转场的视频。
openclaw skills install @volc-ai-mediakit/ai-mediakit-videoedit命令、参数、文件名以原文为准
AI 视频智能剪辑技能。输入视频文件路径(支持多个),可选弹幕文件路径,可选字幕文件路径,
结合弹幕与字幕内容理解视频上下文,根据用户编辑请求自动提取对应时间段(如“提取所有精彩片段”、“剪掉解释 xxx 的部分”),进行拼接并添加转场效果,最后使用 FFmpeg 合成输出视频。
当用户提及“视频剪辑”、“按弹幕剪视频”、“提取弹幕精彩片段”、“视频片段拼接”、“弹幕分析剪辑”、“从弹幕中找亮点”、“智能剪辑”时,此技能必须被触发。
version: v1.0.1
---------------
该技能通过分析弹幕和字幕内容,帮助用户理解视频上下文,根据编辑请求自动提取并拼接视频片段,并使用 FFmpeg 完成转场效果及最终合成。
.mp4、.flv、.mkv 等。.srt / .ass / .json 格式字幕文件,与视频文件一一对应,按顺序排列;无字幕的视频请留空。注意:字幕和弹幕是理解视频内容的唯一依据。若某视频未提供字幕和弹幕,则无法理解其内容,仅能执行用户明确给出的时间段指令。
在执行任何操作前,需确认运行环境满足要求。
验证命令:
python --version
ffmpeg -version 2>&1 | head -1
ffprobe -version 2>&1 | head -1
node --version验收标准与修复指南:
| 依赖项 | 最低要求 | 验证方法 | 未满足时的安装命令 |
|---|---|---|---|
| Python | 3.9+ | python --version | 参见下方说明 |
| ffmpeg | 任意版本 | ffmpeg -version | macOS: brew install ffmpeg · Linux: sudo apt install ffmpeg · Windows: [ffmpeg.org](https://ffmpeg.org/download.html) |
| ffprobe | 与 ffmpeg 一同安装 | ffprobe -version | 随 ffmpeg 一起安装,无需单独操作 |
| Node.js | 18+ | node --version | macOS: brew install node · 或访问 [nodejs.org](https://nodejs.org/) |
Python 安装说明(如版本不满足):
brew install python@3.11sudo apt install python3.11pyenv install 3.11 && pyenv global 3.11文字特效渲染依赖(Remotion)安装:
检查是否存在 byted-ai-mediakit-videoedit/template/node_modules:
ls byted-ai-mediakit-videoedit/template/node_modules/@remotion/renderer 2>/dev/null && echo "已安装" || echo "需要安装"若未安装,请执行:
cd byted-ai-mediakit-videoedit/template && npm install安装耗时约 1-2 分钟,完成后目录中将出现 node_modules。后续对话中若已存在则跳过此步骤。
处理规则:
在开始分析前,需逐一确认每段视频是否具备字幕或弹幕:
| 视频 | 是否有字幕 | 是否有弹幕 | 可理解性 |
|---|---|---|---|
| video_A.mp4 | ✅ | — | 智能分析:可基于内容语义理解视频,支持“找亮点”“找出场介绍”等语义类请求 |
| video_B.mp4 | — | ✅ | 降级智能分析:通过弹幕推断内容,准确性低于字幕 |
| video_C.mp4 | — | — | 仅支持显式指令:无法理解内容,仅可按用户提供的精确时间段进行剪辑 |
“仅支持显式指令”视频的处理规则:
- 明确的时间片段,或
- 字幕文件或弹幕文件
运行解析脚本,将弹幕和字幕转换为基于时间线的文字摘要,用于视频内容分析。
单个视频(含字幕 + 弹幕):
python byted-ai-mediakit-videoedit/scripts/parse_media_info.py \
--video ep1.mp4 \
--danmaku ep1.xml \
--subtitle ep1.srt \
--output /tmp/media_timeline.json**单个视频(仅含字幕 —— 省略 --danmaku):**
python byted-ai-mediakit-videoedit/scripts/parse_media_info.py \
--video ep1.mp4 \
--subtitle ep1.srt \
--output /tmp/media_timeline.json**多个视频(为每段视频重复 --video/--danmaku/--subtitle 参数):**
python byted-ai-mediakit-videoedit/scripts/parse_media_info.py \
--video ep1.mp4 --danmaku ep1.xml --subtitle ep1.srt \
--video ep2.mp4 --danmaku ep2.xml \
--output /tmp/media_timeline.json重要提示:仅对包含字幕或弹幕的视频运行此脚本。 未同时具备字幕和弹幕的视频不会被传入该脚本,其时间段将由用户提供。
可选参数:
--interval 5:弹幕摘要的时间间隔(秒),默认值为 5--top-danmaku 10:每个时间区间内最频繁的弹幕数量,默认值为 10--include-danmaku:强制在输出中包含弹幕摘要(即使已有字幕);仅当用户明确要求参考弹幕时才添加此参数(需为该视频提供 --danmaku 文件)--video 可省略,若仅传入 --danmaku 或仅传入 --subtitle(脚本使用文件基础名作为视频标识符);**建议显式指定 --video 并使用真实路径**,以确保 JSON 中的 video_file 与后续剪辑步骤匹配--danmaku 可省略,若视频已有字幕;每个视频必须至少包含弹幕或字幕之一--subtitle 可省略,若视频仅有弹幕脚本根据以下规则自动决定输出内容(无需 Claude 额外判断):
| 输入情况 | 写入时间线的内容 | 输出模式 |
|---|---|---|
有字幕,未加 --include-danmaku | 仅字幕条目 | subtitle_only |
| 无字幕 | 仅弹幕时间区间摘要 | danmaku_only |
有字幕且加 --include-danmaku | 字幕 + 弹幕摘要 | subtitle_and_danmaku |
输出文件的顶层字段 content_mode 表示当前模式,Claude 可直接根据该字段确认时间线中包含的内容类型。
脚本输出为 JSON 格式的时间线,弹幕不会逐条写出,而是按时间区间汇总。时间线中包含两类记录:
弹幕时间区间摘要(type = danmaku_summary):
{
"time": 25.0,
"time_start": 25.0,
"time_end": 30.0,
"type": "danmaku_summary",
"total_count": 38,
"density": 456.0,
"top_danmaku": [
{"text": "666", "count": 12},
{"text": "哈哈哈", "count": 8}
],
"video_file": "ep1.mp4"
}字幕条目(type = subtitle,完整保留):
{
"time": 27.3,
"end_time": 30.1,
"type": "subtitle",
"text": "这一波操作太丝滑了",
"video_file": "ep1.mp4"
}顶层字段说明:
videos:各视频的统计信息及其对应的高光峰值列表density_peaks:跨所有视频的全局高光峰值(包含 video_file 和 top_danmaku 字段)summary.peak_times:前 5 个高光时段的简要信息(包含位置、密度、代表性弹幕)读取 /tmp/media_timeline.json,结合用户的剪辑需求,推断需要提取的时间片段列表。
前置检查:跳过无法分析的视频
在内容分析前,仅处理步骤 0 中确定为“智能分析”的视频。对于“仅显式指令”的视频,跳过分析,直接使用用户提供的时间值作为剪辑的 start/end。
分析策略:
首要原则:根据字幕确定内容理解方式
| 情况 | 内容理解方法 |
|---|---|
| 存在字幕文件 | 仅阅读字幕以理解视频内容,忽略弹幕数据(除非用户明确要求参考弹幕) |
| 不存在字幕文件 | 仅阅读弹幕摘要(danmaku_summary)以理解视频内容及高光时刻 |
| 用户明确表示“参考弹幕” | 无论是否有字幕,均同时阅读字幕和弹幕 |
Skill: AI MEDIAKIT VIDEO EDIT
Version: 1.0.2
Chunk: 3/6
原因说明:字幕是视频音频内容的精确记录,直接表达视频语义;弹幕则是观众的即时反应,包含大量噪声(如刷屏、无关内容)。当存在字幕时,弹幕信息的边际收益较低,且会消耗大量上下文资源。
type=danmaku_summary 类型的条目,根据 density(每分钟数量)判断热度density_peaks 已预先识别出密度最高的时间段,可直接作为高光候选区间top_danmaku 列表推断该时间段内的视频内容或情绪倾向"www"、"哈哈"、"666"、"awsl"、"绝了"、"牛"、"真的假的"、"名场面""笑死"、"可怜")需结合上下文进行判断video_file 字段,分析时必须区分不同视频的时间线,不可混用时间偏移start/end 时,仅使用对应记录 video_file 的字幕或弹幕数据video_file 字段必须与时间线来源视频一致1. 定位候选区间:根据字幕关键词或弹幕密度(用户请求时)确定大致兴趣范围
2. 对齐开始时间:找到候选区间起始前最近的一条字幕的 time;若开头语义不完整(如出现“而且”、“但是”等连接词),则继续向前推进
3. 对齐结束时间:找到候选区间结束之后最近的一条字幕的 end_time,确保最后一句语义完整
4. 检查完整性:确认剪辑覆盖的字幕内容具备完整语义(不以逗号、过渡词或不完整分句结尾)
字幕记录包含
time(起始秒数)和end_time(结束秒数),可直接用于边界对齐。
{
"clips": [
{
"video_file": "/path/to/video.mp4",
"start": 125.3,
"end": 142.8,
"reason": "Danmaku density peak, lots of '666' and '绝了' danmaku, corresponding subtitles show player completed difficult operation"
}
],
"transition": "fade",
"normalize_audio": true,
"output_path": "/tmp/output_cut.mp4"
}
normalize_audio默认值为false,仅在用户明确确认后执行。对于多个剪辑,可启用两遍 EBU R128 音量归一化(目标 -16 LUFS / -1.5 dBTP),以消除不同视频源之间的音量差异。单个剪辑无需此操作。
若用户明确指定了转场效果,则直接采用。若未指定,则根据对弹幕和字幕的理解,推断最合适的转场效果,遵循以下逻辑:
| 内容特征 | 推荐转场效果 | 判断依据 |
|---|---|---|
| 弹幕以“哈哈”“666”“牛”“绝了”等激动词汇为主,节奏快 | none | 硬切更能匹配高光时刻的冲击感 |
| 游戏/体育比赛类内容,弹幕中大量出现“冲”“gkd”“打” | wipeleft 或 wiperight | 水平擦除具有动态感和方向性 |
| 知识讲解/教程/评测类字幕,内容偏理性 | dissolve | 淡入淡出过渡自然,不突兀,适合信息密集型内容 |
| 情绪化/Vlog/生活类内容,弹幕包含“好看”“感动”“治愈” | fade | 淡入淡出柔和,具有情感延续性 |
| 分步操作教程(如“第1步”“第2步”等) | slideup 或 slidedown | 垂直滑动具有进度感 |
| 高能量/混剪/强剪辑感内容,弹幕含“燃”“热血”“混剪” | zoomin | 镜头推进感强烈,增强视觉冲击力与节奏感 |
| 影视化/戏剧性内容,大场景切换 | circleopen | 圆形打开具有电影质感,适合戏剧性场景转换 |
| 科技/数字/游戏亮点内容,弹幕含“数字”“代码”“科技” | pixelize | 像素化溶解具有赛博朋克风格,契合科技主题 |
| 活动/派对/演唱会类,快速多场景切换 | radial | 径向扫掠具有舞台感,适合多场景快速切换 |
| 旅行/风景/城市探索类,场景推移 | smoothleft | 平滑左移过渡自然流畅,符合空间位移感受 |
| 混合内容或难以判断 | fade | 最通用的备选方案 |
推理完成后,应在回复中告知用户所选转场效果及其原因,便于用户确认或调整。
完成分析与转场选择后,必须以表格形式向用户展示完整编辑计划,在执行前必须等待用户明确确认,否则不得调用 cut_and_merge.py。
计划展示格式:
以下是根据您的需求整理的编辑计划,请确认后再开始合成:
# 视频源 时间段 时长 内容描述 - ------ ------ ---- -------- 1 xxx.mp4 01:29 → 01:57 28s 外观开场:首次介绍外观 + 色系评分 2 yyy.mp4 02:46 → 03:03 17s 边框工艺变化介绍 3 zzz.mp4 03:01 → 03:19 18s 三大外观风格细节 转场效果: dissolve(溶解) · 时长 0.8s · 原因:知识讲解/评测类内容适合平滑过渡
预计总时长: 约 63 秒
音量归一化: 是否启用 EBU R128 音量归一化?此步骤需对每段视频进行两遍响度分析,耗时较长(每分钟视频额外增加约 30–60 秒),但可消除不同视频源之间的音量差异。请告知是否需要启用。
是否确认执行?如需调整某段的时间、删除或替换某段内容,请告知。
支持的修改类型(用户反馈后更新计划,重新展示并等待确认):
确认信号识别规则: 当用户回复“好的”“确认”“可以”“执行”“开始”“没问题”等表示同意的词语时,视为编辑计划已确认;但音量归一化需单独明确回复后方可执行。
音量归一化确认规则:
normalize_audio: true,执行归一化normalize_audio: false,跳过用户确认计划后,将最终计划写入 /tmp/clips.json,运行编辑脚本:
python byted-ai-mediakit-videoedit/scripts/cut_and_merge.py \
--clips-json /tmp/clips.json \
--output /path/to/output.mp4默认过渡时长为 1 秒,可通过在 clips JSON 中设置 transition_duration 字段(单位:秒)进行覆盖。
脚本执行顺序:提取片段 → 音量归一化(两遍 loudnorm,仅当用户确认启用时执行)→ 分辨率归一化(添加黑边)→ 过渡合并 → 输出最终视频。
视频编辑完成后,询问用户是否需要添加文字特效:
视频编辑已完成。是否需要为最终视频添加文字特效?(例如弹幕爆发动画、UP主名片、章节标题、金句卡片等)
若用户选择不添加,跳至步骤 9 显示结果。若选择添加,执行以下流程:
基于步骤 3 解析的字幕/弹幕数据,结合剪辑列表,推断每个片段内容对应的特效。
时间轴转换规则(关键):
特效时间戳以最终视频为准,需从原始视频时间转换:
transition_duration × (N-1) 秒)clip_N 在最终视频中的起始时间 + (T - S)特效类型选择指南:
| 触发条件 | 推荐特效 | 说明 |
|---|---|---|
| 弹幕密度高峰(高能区间) | danmakuBursts | 使用 top_danmaku 实现浮动弹幕,highlight 填入出现频率最高的词 |
| 弹幕包含 "666"/"绝了"/"牛"/"神操作" | keyPhrases(强调) | 在画面顶部或底部显示该词语 |
| 字幕中包含金句 | quotes | 显示在底部或侧边 |
| 最终视频开头 0-3 秒或明显段落分界处 | chapterTitles | 显示主题,如“精彩时刻合集” |
| UP 主或嘉宾首次出现 | lowerThirds | 显示姓名/身份条 |
特效配置格式(时间单位:毫秒,相对于最终视频):
{
"theme": "douyin",
"videoInfo": {"width": 1920, "height": 1080},
"chapterTitles": [
{"title": "精彩时刻", "subtitle": "弹幕高能合集", "startMs": 0, "durationMs": 3000}
],
"keyPhrases": [
{"text": "666", "style": "emphasis", "position": "top", "startMs": 8500, "endMs": 10500}
],
"danmakuBursts": [
{"messages": ["666", "哈哈哈", "绝了", "牛啊", "名场面"], "highlight": "名场面", "startMs": 12000, "durationMs": 3000}
],
"lowerThirds": [
{"name": "UP主昵称", "role": "游戏区", "company": "bilibili", "startMs": 500, "durationMs": 5000}
],
"quotes": [
{"text": "这波操作太丝滑了", "author": "— 弹幕金句", "position": "bottom", "startMs": 25000, "durationMs": 4000}
]
}可选主题: douyin(默认,适用于 Bilibili/游戏场景)、notion(知识/复习类)、cyberpunk(科技/赛博风)、aurora(渐变流光)、apple(极简风格)
以表格形式展示所有建议特效,等待用户明确确认后才开始渲染:
# 类型 最终视频时间 内容 主题 - ---- ------------ ---- ---- 1 章节标题 0s – 3s “精彩时刻” douyin 2 文字特效 8.5s – 10.5s “666”(强调) douyin 3 弹幕爆发 12s – 15s 5 条弹幕,高亮="名场面" douyin 确认后,将渲染特效并合成至视频(耗时约 1-3 分钟)。确认?
ffprobe -v quiet -select_streams v:0 \
-show_entries stream=width,height -of json /path/to/output_cut.mp4将获取到的 width / height 填入 effects_config.json 的 videoInfo 字段,并保存至 /tmp/effects_config.json。
# 注意:必须先切换到模板目录,render.mjs 使用相对路径定位入口文件
cd byted-ai-mediakit-videoedit/template && node render.mjs \
--config=/tmp/effects_config.json \
--out-dir=/tmp/effects渲染成功后,每行输出 ✅ xxx-N -> /tmp/effects/xxx-N.mov。
python byted-ai-mediakit-videoedit/scripts/video_effects.py \
/path/to/output_cut.mp4 \
/tmp/effects_config.json \
/tmp/effects \
/path/to/output_final.mp4完成处理后:
output_final.mp4,不含特效的 output_cut.mp4)<i> 为根节点,<d> 为弹幕节点)brew install ffmpeg(macOS)或 apt install ffmpeg(Linux)node_modules(执行 npm install),确认 Node.js 版本 ≥ 18/tmp/effects/ 目录中是否存在对应的 .mov 文件,确认特效渲染步骤已成功完成--video;每个视频索引对应提供 --danmaku 和/或 --subtitle,顺序一致(可通过省略末尾参数隐式补全:例如两个视频可使用 --subtitle s1 --subtitle s2 而不加 --danmaku)。每个视频至少需有一个文本源.ass 格式,程序会自动提取纯文本内容,并忽略样式信息已收录 1 个 Skill