关于 baoyu-youtube-transcript
baoyu-youtube-transcript 是面向需要提取 YouTube 视频字幕的用户的命令行技能,可获取人工或自动生成的字幕。它通过 InnerTube API 获取内容,并在受阻时回退到 yt-dlp,还会缓存视频资料以便重新格式化。
主要功能
- 01下载人工或自动生成字幕
- 02支持多种视频链接和语言优先级
- 03输出 Markdown 文本或 SRT
- 04提取章节并按说话人处理
- 05缓存字幕、元数据和封面
适用场景
- 01将视频字幕保存为 Markdown
- 02为视频播放器生成 SRT 字幕
- 03查看视频可用的字幕语言
- 04按章节整理并标注说话人
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jimliu/ baoyu-skills --skill baoyu-youtube-transcript安装后在 Claude Code 中输入/baoyu-youtube-transcript确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
prompts/speaker-transcript.mdscripts/main.test.tsmain.tsshared.tsstorage.tstranscript.tstypes.tsyoutube.ts详细介绍
YouTube 字幕稿
下载 YouTube 视频的字幕(字幕/隐藏式字幕)。支持人工创建和自动生成的字幕。无需 API 密钥或浏览器——直接使用 YouTube 的 InnerTube API,并在 YouTube 屏蔽直接 API 访问时自动回退到 yt-dlp。
首次运行时获取视频元数据和封面图片,并缓存原始数据,以便快速重新格式化。
脚本目录
脚本位于 scripts/ 子目录中。{baseDir} = 此 SKILL.md 所在目录的路径。解析 ${BUN_X} 运行时:如果已安装 bun,则使用 bun;如果有 npx,则使用 npx -y bun;否则建议安装 bun。将 {baseDir} 和 ${BUN_X} 替换为实际值。
| 脚本 | 用途 |
|---|---|
scripts/main.ts | 字幕下载 CLI |
用法
# Default: markdown with timestamps (English)
${BUN_X} {baseDir}/scripts/main.ts <youtube-url-or-id>
# Specify languages (priority order)
${BUN_X} {baseDir}/scripts/main.ts <url> --languages zh,en,ja
# Without timestamps
${BUN_X} {baseDir}/scripts/main.ts <url> --no-timestamps
# With chapter segmentation
${BUN_X} {baseDir}/scripts/main.ts <url> --chapters
# With speaker identification (requires AI post-processing)
${BUN_X} {baseDir}/scripts/main.ts <url> --speakers
# SRT subtitle file
${BUN_X} {baseDir}/scripts/main.ts <url> --format srt
# Translate transcript
${BUN_X} {baseDir}/scripts/main.ts <url> --translate zh-Hans
# List available transcripts
${BUN_X} {baseDir}/scripts/main.ts <url> --list
# Force re-fetch (ignore cache)
${BUN_X} {baseDir}/scripts/main.ts <url> --refresh
选项
| 选项 | 描述 | 默认值 |
|---|---|---|
<url-or-id> | YouTube URL 或视频 ID(可指定多个) | 必填 |
--languages <codes> | 语言代码,按优先级顺序以逗号分隔 | en |
--format <fmt> | 输出格式:text、srt | text |
--translate <code> | 翻译为指定的语言代码 | |
--list | 列出可用字幕,而不获取字幕 | |
--timestamps | 为每段添加 [HH:MM:SS → HH:MM:SS] 时间戳 | 开启 |
--no-timestamps | 禁用时间戳 | |
--chapters | 根据视频说明进行章节分段 | |
--speakers | 输出带有说话人识别元数据的原始字幕稿 | |
--exclude-generated | 跳过自动生成的字幕 | |
--exclude-manually-created | 跳过人工创建的字幕 | |
--refresh | 强制重新获取,忽略缓存数据 | |
-o, --output <path> | 保存到指定文件路径 | 自动生成 |
--output-dir <dir> | 基础输出目录 | youtube-transcript |
可选环境变量
| 变量 | 描述 |
|---|---|
YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER | 回退时传递给 yt-dlp --cookies-from-browser,例如 chrome、safari、firefox 或 chrome:Profile 1 |
输入格式
以下任一格式均可用作视频输入:
- 完整 URL:
https://www.youtube.com/watch?v=dQw4w9WgXcQ - 短 URL:
https://youtu.be/dQw4w9WgXcQ - 嵌入式 URL:
https://www.youtube.com/embed/dQw4w9WgXcQ - Shorts URL:
https://www.youtube.com/shorts/dQw4w9WgXcQ - 视频 ID:
dQw4w9WgXcQ
输出格式
| 格式 | 扩展名 | 描述 |
|---|---|---|
text | .md | 带有 frontmatter(含 description)、标题、摘要,以及可选目录/封面/时间戳/章节/说话人的 Markdown |
srt | .srt | 供视频播放器使用的 SubRip 字幕格式 |
输出目录
youtube-transcript/
├── .index.json # Video ID → directory path mapping (for cache lookup)
└── {channel-slug}/{title-full-slug}/
├── meta.json # Video metadata (title, channel, description, duration, chapters, etc.)
├── transcript-raw.json # Raw transcript snippets from YouTube API (cached)
├── transcript-sentences.json # Sentence-segmented transcript (split by punctuation, merged across snippets)
├── imgs/
│ └── cover.jpg # Video thumbnail
├── transcript.md # Markdown transcript (generated from sentences)
└── transcript.srt # SRT subtitle (generated from raw snippets, if --format srt)
{channel-slug}:频道名称的 kebab-case 格式{title-full-slug}:完整视频标题的 kebab-case 格式
--list 模式仅输出到 stdout(不保存文件)。
缓存
首次获取时,脚本会保存:
meta.json— 视频元数据、章节、封面图片路径、语言信息transcript-raw.json— YouTube API 返回的原始转录片段({ text, start, duration }[])transcript-sentences.json— 按句子分段的转录文本({ text, start: "HH:mm:ss", end: "HH:mm:ss" }[]),按句末标点(.?!…。?!等)拆分,按字符长度按比例分配时间戳,并合并中日韩文字imgs/cover.jpg— 视频缩略图
同一视频的后续运行会使用缓存数据(不会发起网络请求)。使用 --refresh 强制重新获取。如果请求的语言不同,缓存会自动刷新。
当 YouTube 在直接 InnerTube 路径上返回反机器人或拦截响应时,脚本会使用其他客户端身份重试,然后在可用时回退到 yt-dlp。如果需要回退但 yt-dlp 不可用,Agent 应自行决定如何让 yt-dlp 可用并继续,而不是把安装决定推给用户。
SRT 输出(--format srt)由 transcript-raw.json 生成。文本/Markdown 输出使用 transcript-sentences.json,以保留自然的句子边界。
工作流
用户提供 YouTube URL 并希望获取转录文本时:
- 如果用户未指定语言,先使用
--list运行,以显示可用选项 - 运行脚本时始终用单引号括住 URL — zsh 会将
?视为通配符,因此未加引号的 YouTube URL 会导致“no matches found”:使用'https://www.youtube.com/watch?v=ID' - 默认使用
--chapters --speakers运行,以获取最丰富的输出(章节 + 说话人识别) - 脚本会自动保存缓存数据和输出文件,并打印文件路径
- 对于
--speakers模式:脚本保存原始文件后,按照下面的说话人识别工作流进行后处理并添加说话人标签
用户只想要封面图片或元数据时,使用任意选项运行脚本也会缓存 meta.json 和 imgs/cover.jpg。
重新格式化同一视频时(例如,先生成文本,再生成 SRT),会重复使用缓存数据,无需重新获取。
章节与说话人工作流
章节(--chapters)
脚本会从视频描述中解析章节时间戳(例如 0:00 Introduction),按章节边界分割转录文本,将片段归组为易读的段落,并保存为带目录的 .md 文件。无需进一步处理。
如果描述中没有章节时间戳,转录文本会按组归并为段落,不带章节标题。
说话人识别(--speakers)
说话人识别需要 AI 处理。脚本会输出一个原始 .md 文件,其中包含:
- 带有视频元数据(标题、频道、日期、封面、描述、语言)的 YAML frontmatter
- 视频描述(用于提取说话人姓名)
- 描述中的章节列表(如果有)
- SRT 格式的原始转录文本(已预先计算起止时间戳,节省 token)
脚本保存原始文件后,启动一个子 Agent(为提高成本效益,可使用 Sonnet 等成本较低的模型)来处理说话人识别:
- 读取已保存的
.md文件 - 读取提示词模板
{baseDir}/prompts/speaker-transcript.md - 按照提示词处理原始转录文本:
- 使用视频元数据识别说话人(标题 → 嘉宾,频道 → 主持人,描述 → 姓名)
- 根据对话流程、问答模式和上下文线索检测说话人轮次
- 划分章节(如果有描述中的章节则使用;否则根据主题变化创建章节)
- 使用
**Speaker Name:**标签、段落分组(2-4 句)和[HH:MM:SS → HH:MM:SS]时间戳进行格式化
- 用处理后的转录文本覆盖
.md文件(保留 YAML frontmatter)
使用 --speakers 时,会默认启用 --chapters — 处理后的输出始终包含章节划分。
错误情况
| 错误 | 含义 |
|---|---|
| 已禁用字幕稿 | 视频完全没有字幕 |
| 未找到字幕稿 | 不提供所请求的语言 |
| 视频不可用 | 视频已删除、设为私有或受到地区限制 |
| IP 被屏蔽 | 请求过多,请稍后再试 |
| 有年龄限制 | 视频需要登录以进行年龄验证 |
| 检测到机器人 | 脚本会重试其他客户端,然后使用 yt-dlp;如果缺少回退工具,Agent 应自行解决,否则如果仍然失败,请尝试设置 YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER=safari(或使用你的浏览器) |