youtube-transcript - SKILL
·
name: youtube-transcript
description: “Fetch YouTube transcripts through DeepAPI or local fallback tooling and save clean text output.”
category: research
risk: safe
source: community
source_repo: davidondrej/skills
source_type: community
date_added: “2026-07-07”
author: davidondrej
tags: [youtube, transcripts, research]
tools: [claude, codex]
license: “MIT”
license_source: “https://github.com/davidondrej/skills/blob/main/LICENSE”
YouTube 转录(通过 DeepAPI,yt-dlp 回退)
何时使用
- 当用户要求获取 YouTube 转录、字幕、字幕文本或口语内容提取时使用。
- 当 DeepAPI 或本地回退工具可以安全获取转录时使用。
获取 YouTube 视频的转录并保存干净的原始 .txt 文件。主要路径是 DeepAPI POST /v1/scrape/youtube/transcript。它在服务端运行,因此避免了困扰 yt-dlp 的本地 IP 机器人标记问题。
保存位置
- 如果用户位于真实的项目/工作目录中 → 保存到那里。
- 否则(没有给定目录,或当前工作目录无意义)→ 保存到
~/Downloads。 - 始终将文件命名为
Channel_Title,空格替换为_(例如David_Ondrej_title_of_video.txt)。如果元数据不可用,回退到视频 ID。
主要路径 — DeepAPI
DEEPAPI_API_KEY 必须已经存在于环境中。不要读取 shell 启动文件或打印密钥:
test -n "$DEEPAPI_API_KEY" || { echo "DEEPAPI_API_KEY is not set"; exit 1; }
BASE=${DEEPAPI_API_BASE_URL:-https://deepapi.co}
运行抓取(保留幂等键;重试必须复用同一个键):
IDK=$(uuidgen)
curl -s --max-time 120 "$BASE/v1/scrape/youtube/transcript" \
-H "Authorization: Bearer $DEEPAPI_API_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"
jq -r '.debitMicrousd' /tmp/yt_transcript.json # cost (50000 = $0.05)
.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。 - HTTP 402
insufficient_credits(先告诉用户在 deepapi.co/credits 充值;只有他们不可用时才回退)。 - DeepAPI 请求
failed两次。
每次回退时都要告诉用户——回退意味着产品错过了一个真实用例。
回退路径 — yt-dlp(本地)
OUT="$(pwd)" # 如果当前工作目录无意义则为 ~/Downloads
META=$(yt-dlp --print "%(channel)s|%(title)s" --skip-download "URL")
NAME=$(echo "$META" | tr '| ' '__' | tr -cd '[:alnum:]_.-') # "Channel_Title",空格 -> _,去除不安全字符
yt-dlp --skip-download --write-subs --write-auto-subs \
--sub-langs "en.*" --sub-format json3 \
-o "$OUT/$NAME.%(ext)s" "URL"
- 如果
channel为 null,回退channel→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 可能需要在 PATH 上有
deno才能进行 YouTube 提取。 - 首次失败时:运行一次
yt-dlp -U,重试一次,然后停止。 - 429 / “Sign in to confirm you’re not a bot” = IP 被标记。停止——不要循环重试(会让情况更糟)。
- 除非用户明确要求,否则绝不回退到为 Whisper 下载音频。
输出
报告保存的路径;如果文本较短则打印出来。如果使用了 DeepAPI,还要以美元报告费用。
局限性
- 改编自
davidondrej/skills;在行动之前验证本地路径、工具、凭据和代理功能。 - 对于命令、远程访问、调度、浏览器自动化或文件更改工作流,先获得用户的明确批准并确认目标环境。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)