baoyu-youtube-transcript

baoyu-youtube-transcript

热门

根据 YouTube 视频 URL 或 ID 下载视频字幕/转录文本和封面图片。支持多语言、翻译、章节分割和说话人识别。缓存原始数据以便快速重新格式化。当用户要求“获取 YouTube 转录”、“下载字幕”、“获取字幕”、“YouTube字幕”、“YouTube封面”、“视频封面”、“video thumbnail”、“video cover image”,或提供 YouTube URL 并希望提取转录文本或封面图片时使用。

2.3万Star
2606Fork
更新于 2026/6/18
SKILL.md
readonly只读
name
baoyu-youtube-transcript
description

根据 YouTube 视频 URL 或 ID 下载视频字幕/转录文本和封面图片。支持多语言、翻译、章节分割和说话人识别。缓存原始数据以便快速重新格式化。当用户要求“获取 YouTube 转录”、“下载字幕”、“获取字幕”、“YouTube字幕”、“YouTube封面”、“视频封面”、“video thumbnail”、“video cover image”,或提供 YouTube URL 并希望提取转录文本或封面图片时使用。

version
1.1.0

YouTube Transcript

从 YouTube 视频下载转录文本(字幕/隐藏式字幕)。支持手动创建和自动生成的字幕。无需 API 密钥或浏览器——直接使用 YouTube 的 InnerTube API,并在 YouTube 阻止直接 API 路径时自动回退到 yt-dlp

首次运行时获取视频元数据和封面图片,缓存原始数据以便快速重新格式化。

脚本目录

脚本位于 scripts/ 子目录中。{baseDir} = 此 SKILL.md 文件所在的目录路径。解析 ${BUN_X} 运行时:如果安装了 bunbun;如果 npx 可用 → npx -y bun;否则建议安装 bun。将 {baseDir}${BUN_X} 替换为实际值。

脚本 用途
scripts/main.ts 转录下载命令行工具

用法

# 默认:带时间戳的 Markdown(英语)
${BUN_X} {baseDir}/scripts/main.ts <youtube-url-or-id>

# 指定语言(优先级顺序)
${BUN_X} {baseDir}/scripts/main.ts <url> --languages zh,en,ja

# 不带时间戳
${BUN_X} {baseDir}/scripts/main.ts <url> --no-timestamps

# 带章节分割
${BUN_X} {baseDir}/scripts/main.ts <url> --chapters

# 带说话人识别(需要 AI 后处理)
${BUN_X} {baseDir}/scripts/main.ts <url> --speakers

# SRT 字幕文件
${BUN_X} {baseDir}/scripts/main.ts <url> --format srt

# 翻译转录
${BUN_X} {baseDir}/scripts/main.ts <url> --translate zh-Hans

# 列出可用的转录
${BUN_X} {baseDir}/scripts/main.ts <url> --list

# 强制重新获取(忽略缓存)
${BUN_X} {baseDir}/scripts/main.ts <url> --refresh

选项

选项 描述 默认值
<url-or-id> YouTube URL 或视频 ID(允许多个) 必需
--languages <codes> 语言代码,逗号分隔,按优先级顺序 en
--format <fmt> 输出格式:textsrt 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,例如 chromesafarifirefoxchrome:Profile 1

输入格式

接受以下任意格式作为视频输入:

  • 完整 URL:https://www.youtube.com/watch?v=dQw4w9WgXcQ
  • 短 URL:https://youtu.be/dQw4w9WgXcQ
  • 嵌入 URL:https://www.youtube.com/embed/dQw4w9WgXcQ
  • 短视频 URL:https://www.youtube.com/shorts/dQw4w9WgXcQ
  • 视频 ID:dQw4w9WgXcQ

输出格式

格式 扩展名 描述
text .md 带前置元数据(包括 description)、标题、摘要、可选目录/封面/时间戳/章节/说话人的 Markdown
srt .srt 用于视频播放器的 SubRip 字幕格式

输出目录

youtube-transcript/
├── .index.json                          # 视频 ID → 目录路径映射(用于缓存查找)
└── {channel-slug}/{title-full-slug}/
    ├── meta.json                        # 视频元数据(标题、频道、描述、时长、章节等)
    ├── transcript-raw.json              # 来自 YouTube API 的原始转录片段(已缓存)
    ├── transcript-sentences.json        # 按句子分割的转录(按标点分割,跨片段合并)
    ├── imgs/
    │   └── cover.jpg                    # 视频缩略图
    ├── transcript.md                    # Markdown 转录(从句子生成)
    └── transcript.srt                   # SRT 字幕(从原始片段生成,如果使用 --format srt)
  • {channel-slug}:频道名称的短横线命名形式
  • {title-full-slug}:完整视频标题的短横线命名形式

--list 模式仅输出到标准输出(不保存文件)。

缓存

首次获取时,脚本保存:

  • 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 不可用,代理应自行决定如何使 yt-dlp 可用并继续,而不是将安装决定推给用户。

SRT 输出(--format srt)从 transcript-raw.json 生成。文本/Markdown 输出使用 transcript-sentences.json 以获得自然的句子边界。

工作流程

当用户提供 YouTube URL 并希望获取转录时:

  1. 如果用户未指定语言,首先使用 --list 运行以显示可用选项
  2. 运行脚本时始终对 URL 使用单引号——zsh 将 ? 视为通配符,因此未加引号的 YouTube URL 会导致“no matches found”:使用 'https://www.youtube.com/watch?v=ID'
  3. 默认:使用 --chapters --speakers 运行以获得最丰富的输出(章节 + 说话人识别)
  4. 脚本自动保存缓存数据 + 输出文件并打印文件路径
  5. 对于 --speakers 模式:脚本保存原始文件后,按照下面的说话人识别工作流程进行后处理,添加说话人标签

当用户仅需要封面图片或元数据时,使用任何选项运行脚本也会缓存 meta.jsonimgs/cover.jpg

当重新格式化同一视频时(例如,先文本后 SRT),会重用缓存数据——无需重新获取。

章节与说话人工作流程

章节(--chapters

脚本从视频描述中解析章节时间戳(例如 0:00 Introduction),按章节边界分割转录,将片段分组为可读段落,并保存为带目录的 .md 文件。无需进一步处理。

如果描述中没有章节时间戳,则转录以分组段落形式输出,不带章节标题。

说话人识别(--speakers

说话人识别需要 AI 处理。脚本输出一个原始的 .md 文件,包含:

  • YAML 前置元数据,包含视频元数据(标题、频道、日期、封面、描述、语言)
  • 视频描述(用于提取说话人名称)
  • 来自描述中的章节列表(如果有)
  • 原始转录,采用 SRT 格式(预计算开始/结束时间戳,节省 token)

脚本保存原始文件后,生成一个子代理(使用较便宜的模型如 Sonnet 以节省成本)来处理说话人识别:

  1. 读取保存的 .md 文件
  2. 读取 {baseDir}/prompts/speaker-transcript.md 中的提示模板
  3. 按照提示处理原始转录:
    • 使用视频元数据识别说话人(标题 → 嘉宾,频道 → 主持人,描述 → 名称)
    • 从对话流程、问答模式和上下文线索中检测说话人切换
    • 分割为章节(如果可用则使用描述中的章节,否则根据主题转换创建)
    • 使用 **Speaker Name:** 标签、段落分组(2-4 句)和 [HH:MM:SS → HH:MM:SS] 时间戳格式化
  4. 用处理后的转录覆盖 .md 文件(保留 YAML 前置元数据)

当使用 --speakers 时,隐含 --chapters——处理后的输出始终包含章节分割。

错误情况

错误 含义
Transcripts disabled 视频没有任何字幕
No transcript found 请求的语言不可用
Video unavailable 视频已删除、设为私密或区域限制
IP blocked 请求过多,请稍后重试
Age restricted 视频需要登录进行年龄验证
bot detected 脚本会重试备用客户端,然后使用 yt-dlp;如果回退工具缺失,代理应自行解决,否则如果仍然失败,尝试 YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER=safari(或你的浏览器)