mcpField
Y
yt2bb

yt2bb

github.com/agents365-ai创意与媒体97366 次安装2 周前更新
代码仓库

关于 yt2bb

yt2bb 是将 YouTube 视频或播放列表处理为适合发布到 Bilibili 的视频技能,可烧录中英双语字幕并生成 publish_info.md。流程涵盖下载、转录、翻译、字幕校验与样式设置、视频渲染和发布信息准备。

主要功能

  1. 01下载视频和播放列表
  2. 02转录并翻译字幕
  3. 03校验、检查并合并 SRT 文件
  4. 04用 ASS 设置双语字幕样式
  5. 05将字幕烧录到视频
  6. 06生成 Bilibili 发布信息

适用场景

  1. 01为发布到 Bilibili 准备 YouTube 视频
  2. 02为英文视频添加双语字幕
  3. 03将视频内容改编给中文受众
  4. 04生成视频上传所需信息

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/agents365-ai/365-skills --skill yt2bb

安装后在 Claude Code 中输入/yt2bb确认已加载。

附带文件srt_utils.py

详细介绍

yt2bb — YouTube 到 Bilibili 的视频再利用

概述

六步工作流:下载 → 转录 → 翻译 → 合并 → 烧录字幕 → 生成发布信息。生成的视频带有硬编码的中英双语字幕,并附带包含 Bilibili 上传元数据的 publish_info.md。

适用场景

  • 用户提供 YouTube URL(单个视频或播放列表),并希望获得可直接上传到 Bilibili 的版本
  • 用户需要将中英双语字幕烧录到视频中
  • 用户希望将英文视频内容重新制作,面向中文观众发布

快速参考

步骤工具命令输出
0. 更新git自动检查技能更新—
1. 下载yt-dlpyt-dlp --cookies-from-browser chrome -f ... -o ...{slug}.mp4
2. 转录whisper*先运行 srt_utils.py check-whisper,然后转录{slug}_{lang}.srt
2.5 验证srt_utils.pysrt_utils.py validate / fix{slug}_{lang}.srt(已修复)
3. 翻译AI感知 SRT 结构的分批翻译{slug}_zh.srt
4. 合并srt_utils.pysrt_utils.py merge ...{slug}_bilingual.srt
4.5 样式srt_utils.pysrt_utils.py to_ass --preset netflix|clean|glow{slug}_bilingual.ass
5. 烧录ffmpegffmpeg -c:v libx264 -vf ass=...{slug}_bilingual.mp4
6. 发布AI分析内容并生成元数据publish_info.md

确定技能目录

确定后续工作流步骤使用的 SKILL_DIR:

# Find the skill dir: a 'yt2bb' folder that actually contains SKILL.md.
# Works whether installed flat (~/.claude/skills/yt2bb) or pulled from this repo (skills/yt2bb).
SKILL_DIR="$(find ~/.claude/skills ~/.openclaw/skills ~/.hermes/skills ~/.pi/agent/skills ~/.agents/skills ~/myagents/myskills -type d -name 'yt2bb' -exec test -f '{}/SKILL.md' \; -print 2>/dev/null | head -1)"

工作流详情

步骤 1:下载

单个视频:

slug="video-name"  # or: slug=$(python3 "$SKILL_DIR/srt_utils.py" slugify "Video Title")
mkdir -p "${slug}"
yt-dlp --cookies-from-browser chrome \
  -f "bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]" \
  -o "${slug}/${slug}.mp4" "https://www.youtube.com/watch?v=VIDEO_ID"

播放列表 / 系列:

yt-dlp --cookies-from-browser chrome \
  -f "bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]" \
  -o "%(playlist_index)03d-%(title)s/%(playlist_index)03d-%(title)s.mp4" \
  "https://www.youtube.com/playlist?list=PLAYLIST_ID"

下载完成后,将每个文件夹重命名为简洁的 slug,然后依次对每个视频运行步骤 2–6。

  • -f "bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]":确保输出为 mp4,避免使用 webm
  • %(playlist_index)03d:使用零填充索引,以保留播放列表顺序
  • 如果 --cookies-from-browser 失败,请先导出 cookies——参见“故障排除”
步骤 2:转录

先运行环境检查,以检测你的平台并获取针对性推荐的 whisper 命令:

python3 "$SKILL_DIR/srt_utils.py" check-whisper

此命令会自动检测操作系统、GPU(CUDA/Metal/CPU)、内存和已安装的后端,然后针对你的硬件推荐最佳后端和模型。如果无法检测内存,则会采用保守的备用方案,而不会假设设备内存不足。请使用它打印出的命令。

手动备用方案(openai-whisper,适用于所有平台):

src_lang="en"      # Change to ja/ko/es/etc. based on source video
whisper_model="medium"  # check-whisper recommends the best model for your hardware
whisper "${slug}/${slug}.mp4" \
  --model "$whisper_model" \
  --language "$src_lang" \
  --word_timestamps True \
  --condition_on_previous_text False \
  --output_format srt \
  --max_line_width 40 --max_line_count 1 \
  --output_dir "${slug}"
mv "${slug}/${slug}.srt" "${slug}/${slug}_${src_lang}.srt"

支持的后端:

后端适用场景安装
mlx-whispermacOS Apple Silicon(速度最快)pip install mlx-whisper
whisper-ctranslate2Windows/Linux CUDA,或 CPU(速度约快 4 倍)pip install whisper-ctranslate2
openai-whisper通用备用方案pip install openai-whisper

模型选择(由 check-whisper 自动推荐):

  • tiny — 快速草稿,准确度较低,适合 CPU(约 1 GB)
  • medium — 默认,兼顾速度与准确度(约 5 GB)
  • large-v3 — 准确度最高,推荐用于日语/韩语/中文源视频(约 10 GB)

注意:

  • --language:显式指定语言以避免误检测;支持 en、ja、ko、es 等
  • --word_timestamps True:获得更精确的字幕时间
  • --condition_on_previous_text False:防止产生幻觉式循环
  • 如果输出乱码或内容重复,请添加防幻觉参数——参见“故障排除”
步骤 2.5:验证与修复(可选)
python3 "$SKILL_DIR/srt_utils.py" validate "${slug}/${slug}_${src_lang}.srt"
# If issues found:
python3 "$SKILL_DIR/srt_utils.py" fix "${slug}/${slug}_${src_lang}.srt" "${slug}/${slug}_${src_lang}.srt"
第 3 步:翻译

读取 {slug}_{src_lang}.srt 并翻译成中文。关键规则:

这些规则参考了 Netflix 简体中文计时文本风格指南;请遵循这些规则,制作出可达到广播级质量的字幕。

  1. 保持 SRT 格式不变——索引编号和时间戳(--> 行)必须原样保留
  2. 条目一一对应——每个源条目必须恰好对应一个译文条目(数量相同)
  3. 优化底部字幕——尽可能让每条中文字幕保持 1 行,以便最终双语字幕在画面底部保持紧凑
  4. 每行最多 16 个全角字符(Netflix 简体中文规范)。优先控制在 12–16 个字符;如果字幕很短(< 1 s),则进一步压缩,确保阅读速度 ≤ 9 个字符/秒
  5. 酌情精简,不要机械删减——删除填充词、重复主语、语气较弱的感叹词和多余的客套话,再考虑删减关键信息
  6. 匹配字幕时长——字幕行应能在屏幕显示时间内轻松读完;如果字幕很短,则进一步压缩
  7. 中文字幕末尾不加标点——去掉句末的 。、!、?;仅在有助于理解时保留句中的 ,、、、;
  8. 字幕内使用全角中文标点(,。!?、;:);内层引号使用 「」,不要使用 "" 或 ''
  9. 数字和拉丁字符使用半角——数字、单位、产品名称和代码标识符均保持半角(GPT-4、30fps、2026);只有标点使用全角
  10. 每条字幕都是完整、独立的一行——每个显示行都应是完整句子或简短语义单元,绝不能是被截断的从句,就像电影或电视剧中的双语字幕一样。实际操作中:不要在功能词(的、了、吗、呢、吧、啊)后断行;不要将英语短语拆开;修饰语要与中心语放在一起
  11. 保持术语一致——技术术语、名称、产品名称和反复出现的短语在各批次中应采用相同译法。必要时维护一份行内术语表
  12. 灵活翻译,不要音译——优先保留语体、语气和意图,而非逐字对应;用自然的中文表达习语
  13. 每批翻译 10 条——以有效的 SRT 格式输出每批内容,然后继续翻译
  14. 不要合并或拆分条目——保持原有分段
  15. 保存为 {slug}/{slug}_zh.srt
第 4 步:合并
python3 "$SKILL_DIR/srt_utils.py" merge \
  "${slug}/${slug}_${src_lang}.srt" "${slug}/${slug}_zh.srt" "${slug}/${slug}_bilingual.srt"
第 4.25 步:Netflix 校验(推荐)

对合并后的双语 SRT 运行 lint,检查 validate 未覆盖的 Netflix 计时文本风格指南违规项,包括阅读速度(CPS)、每行长度、字幕间隔和行数。

python3 "$SKILL_DIR/srt_utils.py" lint "${slug}/${slug}_bilingual.srt"

默认值(均可通过标志覆盖):

规则阈值标志
阅读速度(英语)≤ 17 CPS--max-cps-en
阅读速度(简体中文)≤ 9 CPS--max-cps-zh
最短字幕时长833 ms(5/6 秒)--min-duration-ms
最长字幕时长7000 ms--max-duration-ms
最短字幕间隔83 ms(24 fps 下 2 帧)--min-gap-ms
每行最多字符数(英语)42--max-chars-en
每行最多字符数(中文,全角)16--max-chars-zh
每条字幕最多行数2—

严重性模型:

  • 错误(退出代码 2):时长超出限制、CPS 超限、每条字幕超过 2 行。这些问题会导致无法通过 Netflix 验收,应在烧录字幕前修复。
  • 警告(若无错误则退出代码为 0):每行长度、间隔过短。这些是建议项——可行时请予以处理,但不会阻止交付。

出现 CPS 错误时,问题几乎总是出在上游——返回第 3 步,重写不符合时间窗口要求的中文条目。不要通过延长字幕时长,使其超出源音频的语音时长来解决 CPS 问题。

便于 Agent 使用的输出:

python3 "$SKILL_DIR/srt_utils.py" lint "${slug}/${slug}_bilingual.srt" --format json

返回 {ok, error_count, warning_count, issues: [{index, code, severity, message}, ...]},以便进行程序化筛选。

步骤 4.5:样式 — 转换为 ASS

将双语 SRT 转换为 ASS 文件。ASS 支持逐行设置颜色、字体大小和发光效果,而这些效果无法通过 SRT 的 force_style 实现。布局规则:字幕始终位于底部。默认排列:中文在底部字幕堆叠的上行,英文在下行。这些预设经过调整,旨在确保字幕块易于阅读,同时降低与屏幕下方内容重叠的风险。

重要 — 继续之前请先询问。 向用户展示下方预设表格,并询问他们偏好哪种样式。不要擅自选择默认样式。如果用户没有偏好,请使用 clean。

可用预设:

预设效果适用场景
netflix纯白文字、细黑描边、柔和投影、无底框 — 参考 Netflix Timed Text Style Guide专业、广播级观感。纪录片、访谈、长内容,以及任何需要呈现“原生流媒体平台”质感的内容都适用。Linux 上搭配 --font "Source Han Sans SC",macOS 上搭配 "PingFang SC",可获得最接近 Netflix Sans 的观感
clean灰色底框上的黄色文字 — 金黄色中文 + 浅黄色英文,搭配半透明浅灰色背景适用于画面繁杂或亮度混杂的素材,作为可读性保障,避免 netflix 仅靠描边的文字在视觉上难以辨认。灰色底框可确保文字周围有清晰的对比区域
glow黄色中文 + 白色英文,并带彩色发光效果 — 亮黄色中文 + 白色英文、模糊的外发光、无底框适用于娱乐内容、Vlog 和节奏活跃的剪辑。最吸睛,但在明亮或繁杂的背景上效果最弱

向用户提问的示例:

字幕有三套样式可选:

  1. netflix — 纯白字体 + 细黑描边 + 柔和阴影(默认推荐,Netflix 专业观感,适合纪录片/访谈/长内容)
  2. clean — 黄色字体 + 灰色半透明底框(亮背景或花背景的兜底选项,底框保证对比度)
  3. glow — 黄色/白色字体 + 彩色外发光(更抢眼,适合娱乐/Vlog)
  4. 自定义 — 提供 .ass 样式文件,完全控制字体、颜色、大小(可用 Aegisub 可视化编辑)

选哪个?默认推荐 netflix;如果画面特别花哨或底部信息多,可改用 clean。

# Netflix-grade default (white + outline + soft shadow), ZH on top
python3 "$SKILL_DIR/srt_utils.py" to_ass \
  "${slug}/${slug}_bilingual.srt" "${slug}/${slug}_bilingual.ass" \
  --preset netflix

# Gray-box fallback for busy backgrounds, EN on top
python3 "$SKILL_DIR/srt_utils.py" to_ass \
  "${slug}/${slug}_bilingual.srt" "${slug}/${slug}_bilingual.ass" \
  --preset clean --top en

# Vibrant glow (B站 entertainment style)
python3 "$SKILL_DIR/srt_utils.py" to_ass \
  "${slug}/${slug}_bilingual.srt" "${slug}/${slug}_bilingual.ass" \
  --preset glow

自定义样式文件 — 如需完全控制样式,可提供包含自定义 [V4+ Styles] 区段的外部 .ass 文件。文件中必须包含名为 EN 和 ZH 的样式,否则 to_ass 会在前期校验时失败并报错。你可以使用 Aegisub 直观地设计样式并导出。

python3 "$SKILL_DIR/srt_utils.py" to_ass \
  "${slug}/${slug}_bilingual.srt" "${slug}/${slug}_bilingual.ass" \
  --style-file my_styles.ass

也可以在 .ass 文件中添加 ; en_tag= 和 ; zh_tag={\blur5} 注释行,为每种语言注入 ASS 覆盖标签。

字体 — 省略 --font 可根据操作系统自动选择最佳的已安装中日韩字体;传入 --font 可覆盖自动选择结果(使用 --style-file 时会忽略此选项):

平台自动选择
macOSPingFang SC
LinuxNoto Sans CJK SC(已安装字体中的最佳选择)
WindowsMicrosoft YaHei

其他选项:

  • --top zh|en — 指定哪种语言位于底部字幕堆叠的上行(默认:zh)
  • --res WxH — 视频分辨率(默认:1920x1080)
  • --fade <ms> — 淡入/淡出时长,单位为毫秒(默认 150;0 表示禁用)。使用柔和的电影式淡入淡出,而非硬切
  • --reflow — 将每条字幕拆分为完整句子行(规则 10),确保显示的每一行都不是被截断的片段
  • --safe-area <frac> — 底部保留区域占画面高度的比例(默认 0.06),避免字幕遮挡平台界面或进度条

所有预设的可读性说明:

  • 预设始终在底部对齐;不会自动移至顶部
  • 字体大小、描边和垂直边距会随 --res 缩放,确保 720p 和 1080p 下的视觉平衡相近
  • 如果必须确保字幕在每个镜头中都位于底部,clean 是最安全的选择
步骤 5:烧录字幕

使用 ass= 滤镜(不要使用 subtitles=)——所有样式都来自 ASS 文件。

ffmpeg -i "${slug}/${slug}.mp4" \
  -vf "ass='${slug}/${slug}_bilingual.ass'" \
  -c:v libx264 -crf 23 -preset medium \
  -c:a copy "${slug}/${slug}_bilingual.mp4"
  • -c:v libx264 -crf 23:在画质良好与文件大小合理之间取得平衡
  • -preset medium:平衡速度与压缩效果(需要更快编码时可使用 fast)
  • 无需 force_style — 样式已嵌入 ASS 文件中
步骤 6:生成发布信息

根据视频内容(来自 {slug}_{src_lang}.srt 和 {slug}_zh.srt),生成 {slug}/publish_info.md。

此文件中的所有内容都必须使用中文(面向 Bilibili 观众)。

# Publish Info

## Source
{YouTube URL}

## Titles (5 variants)
1. {Suspense/question style — spark curiosity}
2. {Data/achievement driven — emphasize results}
3. {Controversial/opinion style — spark discussion}
4. {Tutorial/practical style — emphasize utility}
5. {Emotional/relatable style — connect with audience}

## Tags
{~10 comma-separated keywords covering topic, technology, domain}

## Description
{3-5 sentences summarizing core content and highlights}

## Chapter Timestamps
00:00 {chapter name}
...

生成规则:

  • 标题风格需符合 Bilibili 惯例:语气轻松,设置悬念,灵活使用符号(【】、?、!)
  • 标签应同时涵盖中英文关键词,以便用户发现
  • 从 {slug}_bilingual.srt 中提取主题转换点的时间戳
  • 描述需要有吸引力的开头——前两句话决定用户是否会展开阅读

输出结构

{slug}/
├── {slug}.mp4              # Source video
├── {slug}_{src_lang}.srt   # Source language subtitles
├── {slug}_zh.srt           # Chinese subtitles
├── {slug}_bilingual.srt    # Merged bilingual
├── {slug}_bilingual.mp4    # Final output
└── publish_info.md         # Bilibili upload metadata

工具:srt_utils.py

python3 "$SKILL_DIR/srt_utils.py" merge en.srt zh.srt output.srt          # Merge bilingual
python3 "$SKILL_DIR/srt_utils.py" merge --dry-run en.srt zh.srt output.srt # Pre-check without writing
python3 "$SKILL_DIR/srt_utils.py" validate input.srt                       # Check timing issues
python3 "$SKILL_DIR/srt_utils.py" fix input.srt output.srt                 # Fix timing/overlaps (multi-pass)
python3 "$SKILL_DIR/srt_utils.py" slugify "Video Title"                    # Generate slug
python3 "$SKILL_DIR/srt_utils.py" to_ass input.srt output.ass              # Convert to styled ASS (default: clean, ZH on top)
python3 "$SKILL_DIR/srt_utils.py" to_ass --dry-run input.srt output.ass    # Pre-check without writing
python3 "$SKILL_DIR/srt_utils.py" to_ass input.srt output.ass --preset glow --top en
python3 "$SKILL_DIR/srt_utils.py" to_ass input.srt output.ass --style-file custom.ass  # User-defined styles
python3 "$SKILL_DIR/srt_utils.py" check-whisper                    # Detect platform, recommend whisper backend + model

常见错误

  • 条目数不匹配:默认情况下合并会失败——请修复翻译,或使用 --pad-missing 补齐
  • 未找到字体:请确保已安装 PingFang SC(macOS 默认字体),或使用替代字体(参见故障排查)

故障排查

yt-dlp:Cookie 身份验证失败

--cookies-from-browser chrome 要求关闭 Chrome(或使用配置文件快照)。如果失败:

# Export cookies once, then reuse the file
yt-dlp --cookies-from-browser chrome --cookies cookies.txt --skip-download "URL"
yt-dlp --cookies cookies.txt -f "bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]" -o "${slug}/${slug}.mp4" "URL"

对于 429 / 速率限制错误,请添加 --sleep-interval 3 --max-sleep-interval 8。

whisper:语言错误或出现幻觉循环

症状:重复短语、乱码字符,或尽管音频清晰,生成的 SRT 几乎为空。

whisper "${slug}/${slug}.mp4" \
  --model medium \
  --language "$src_lang" \
  --condition_on_previous_text False \
  --no_speech_threshold 0.6 \
  --logprob_threshold -1.0 \
  --compression_ratio_threshold 2.0 \
  --output_format srt \
  --output_dir "${slug}"

如果仍然误判语言,音频中可能有长时间静音或非语音片段——请添加 --vad_filter True 将其过滤掉。

ffmpeg:未找到字体 / 中文字符显示为方框

在 to_ass 步骤(步骤 4.5)中通过 --font 指定正确的字体。ASS 文件会嵌入字体名称,因此 ffmpeg 在烧录时需要已安装该字体。

平台字体安装方式
macOSPingFang SC预装
LinuxNoto Sans CJK SCsudo apt install fonts-noto-cjk
Linux(替代)WenQuanYi Micro Heisudo apt install fonts-wqy-microhei
WindowsMicrosoft YaHei预装

使用正确的 --font 参数重新生成 ASS 文件,然后重新运行烧录步骤。

隐私与数据流

  • 浏览器 Cookie:步骤 1 使用 yt-dlp --cookies-from-browser chrome 访问有年龄限制或私有视频。此操作会在本地读取 Chrome Cookie——不会将 Cookie 发送到 YouTube 自身服务器以外的任何地方。若要避免此操作,请先将 Cookie 导出到文件(参见上方的故障排查)。
  • 转录文本与翻译:步骤 3(翻译)和步骤 6(发布信息)由对话中的 AI Agent 完成。转录文本会发送给 Agent 所使用的模型 / 服务(例如 Claude API)。如果视频包含敏感内容,请在这些步骤中使用本地模型。
  • 无遥测:srt_utils.py 不会发出网络请求。所有处理(SRT 解析、合并、ASS 生成、硬件检测)均完全在本地进行。

评论

支持 Markdown