关于 youtube-transcript
youtube-transcript 是一项获取 YouTube 视频字幕并保存为纯文本的技能,优先使用 DeepAPI,失败时可改用 yt-dlp,也可提取带时间信息的字幕片段。
主要功能
- 01通过 DeepAPI 获取字幕
- 02使用 yt-dlp 作为备用方案
- 03保存清理后的字幕文本
- 04提取带时间信息的字幕片段
- 05指定字幕语言
适用场景
- 01将视频字幕保存到项目目录
- 02生成用于审阅的字幕文本
- 03获取带时间戳的字幕片段
- 04DeepAPI 不可用时继续获取字幕
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ davidondrej/ skills --skill youtube-transcript安装后在 Claude Code 中输入/youtube-transcript确认已加载。
详细介绍
YouTube 字幕转录(通过 DeepAPI,yt-dlp 作为后备方案)
获取 YouTube 视频的字幕转录,并保存为干净的原始 .txt 文件。首选方式是 DeepAPI POST /v1/scrape/youtube/transcript。该操作在服务端运行,因此可避免 yt-dlp 常见的本地 IP 机器人标记问题。
保存位置
- 如果用户当前在一个实际的项目/工作目录中 → 保存到该目录。
- 否则(未指定目录,或当前工作目录不合适)→ 保存到
~/Downloads。 - 文件名始终使用
Channel_Title,并将空格替换为_(例如:David_Ondrej_title_of_video.txt)。如果无法获取元数据,则使用视频 ID。
首选方式 — DeepAPI
从环境变量中读取密钥;设置过程会将其写入 ~/.deepapi/env。切勿执行 source ~/.zshrc(会导致 shell 出错,退出码为 126):
[ -n "$DEEPAPI_API_KEY" ] || . ~/.deepapi/env
KEY=$DEEPAPI_API_KEY
BASE=${DEEPAPI_API_BASE_URL:-https://deepapi.co}
运行抓取操作(保留 Idempotency-Key;重试时必须使用同一个值):
IDK=$(uuidgen)
curl -s --max-time 120 "$BASE/v1/scrape/youtube/transcript" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDK" \
-d '{"url": "VIDEO_URL", "maxCostUsd": "0.05", "waitForFinishSecs": 60}' \
> /tmp/yt_transcript.json
- 非英语视频:在请求体中添加
"language": "de"(或其他语言代码)。 status: running→ 等待next.afterSecs指定的时间,然后运行curl "$BASE$(jq -r '.next.path' /tmp/yt_transcript.json)" -H "Authorization: Bearer $KEY",直到状态变为succeeded或failed。
提取文本并保存:
jq -r '.status' /tmp/yt_transcript.json # succeeded | running | failed
jq -r '.output[0].text' /tmp/yt_transcript.json > "$OUT/$NAME.txt"
.output[0].segments 还包含带时间戳的片段(startSecs、durationSecs、text),如果用户需要时间戳可使用这些内容。output 为空表示视频没有字幕;告知用户,不要重试。
要生成 Channel_Title 文件名,可使用 yt-dlp --print "%(channel)s|%(title)s" --skip-download "URL" 快速获取元数据;如果失败,则使用视频 ID。
何时改用 yt-dlp
- 未设置
DEEPAPI_API_KEY,且~/.deepapi/env不存在。 - HTTP 402
insufficient_credits(告知用户先前往 deepapi.co/credits 充值;只有在用户无法充值时才改用后备方案)。 - DeepAPI 请求连续两次
failed。
每次改用后备方案时都要告知用户——这意味着 DeepAPI 未能满足一个实际使用场景。
后备方案 — yt-dlp(本地)
OUT="$(pwd)" # or ~/Downloads if cwd makes no sense
META=$(yt-dlp --print "%(channel)s|%(title)s" --skip-download "URL")
NAME=$(echo "$META" | tr '| ' '__' | tr -cd '[:alnum:]_.-') # "Channel_Title", spaces -> _, strip unsafe chars
yt-dlp --skip-download --write-subs --write-auto-subs \
--sub-langs "en.*" --sub-format json3 \
-o "$OUT/$NAME.%(ext)s" "URL"
- 如果
channel为 null,则依次改用uploader→uploader_id。 --skip-download= 仅获取字幕。--write-subs+--write-auto-subs= 优先使用人工字幕,无可用时再使用自动字幕。- 始终使用
json3,绝不使用 VTT/SRT——自动生成的 VTT 会将每行重复两次(滚动字幕)。
将 json3 展平为原始文本:
python3 - "$OUT" <<'PY'
import json, html, re, glob, sys, pathlib
f = glob.glob(sys.argv[1] + "/*.json3")
if not f: sys.exit("no json3 file")
data = json.load(open(f[0], encoding="utf-8"))
parts = ["".join(s.get("utf8","") for s in e.get("segs") or []) for e in data.get("events", [])]
txt = re.sub(r"\s+", " ", html.unescape(" ".join(p.strip() for p in parts if p.strip()))).strip()
out = pathlib.Path(f[0]).with_suffix(".txt")
out.write_text(txt, encoding="utf-8"); print(out)
PY
yt-dlp 失败处理
- 非英语/语言未知:先运行
yt-dlp --list-subs "URL",然后设置--sub-langs。 - 较新版本的 yt-dlp 可能需要将
deno添加到 PATH,才能提取 YouTube 内容。 - 首次失败时:运行一次
yt-dlp -U,重试一次,然后停止。 - 429 / "Sign in to confirm you're not a bot" = IP 已被标记。立即停止——不要循环重试(情况会更糟)。
- 除非用户明确要求,否则绝不改为下载音频并使用 Whisper。
输出
报告保存路径;如果文本较短,则打印文本。除非用户询问,否则不要报告费用。
评论
支持 Markdown