/SKILL.md
A smart YouTube video downloader with multiple strategies, auto-retry, intelligent cookie management, and subtitle support
npx skillsauth add lxmxhh/cc-skill-youtube-download youtube-downloadInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
一个智能的 YouTube 视频下载工具,支持多种下载策略,自动重试直到成功
当用户触发这个 Skill 时,按照以下流程执行:
使用 AskUserQuestion 工具询问用户:
视频质量:
是否下载字幕:
输出目录:
检查必需的工具是否已安装:
# 检查 Python 环境
python --version
# 检查 yt-dlp(推荐安装完整版)
python -m yt_dlp --version
# 检查 EJS 脚本是否已安装
python -c "import yt_dlp_ejs; print('EJS scripts installed:', yt_dlp_ejs.__version__)"
# 检查 Node.js(用于解密 n 参数)
node --version
如果缺少工具,按以下步骤安装:
安装完整的 yt-dlp(包含 EJS 脚本):
# 推荐:安装完整版(包含 JavaScript 解密支持)
pip install -U "yt-dlp[default]"
# 或者基础版(不推荐,会遇到 n 参数解密问题)
pip install yt-dlp
安装 Node.js(如果未安装):
brew install nodesudo apt install nodejs 或 sudo yum install nodejs验证安装:
# 测试 n 参数解密功能
python -m yt_dlp --js-runtimes node --list-formats "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# 应该看到 [jsc:node] 日志,表示解密功能正常
使用多种策略依次尝试,直到成功:
python -m yt_dlp \
--js-runtimes node \
--format "bestvideo[ext=mp4][height<=1080]+bestaudio[ext=m4a]/best[ext=mp4]/best" \
--merge-output-format mp4 \
--output "%(title)s.%(ext)s" \
"<youtube_url>"
python -m yt_dlp \
--cookies "./cookies.txt" \
--js-runtimes node \
--format "bestvideo[ext=mp4][height<=1080]+bestaudio[ext=m4a]/best[ext=mp4]/best" \
--merge-output-format mp4 \
--output "%(title)s.%(ext)s" \
"<youtube_url>"
注意: 使用策略 2 前确保已安装 yt-dlp[default] 完整包:
pip install -U "yt-dlp[default]"
# 尝试 Chrome
yt-dlp --cookies-from-browser chrome --format "..." "<youtube_url>"
# 失败则尝试 Firefox
yt-dlp --cookies-from-browser firefox --format "..." "<youtube_url>"
# 失败则尝试 Edge
yt-dlp --cookies-from-browser edge --format "..." "<youtube_url>"
yt-dlp --proxy "http://proxy:port" --format "..." "<youtube_url>"
yt-dlp --format "best" "<youtube_url>"
在下载过程中显示:
示例输出:
🎬 正在下载: 视频标题
策略: 使用 Chrome 浏览器 Cookies
[████████████████░░░░░░░░] 67.8%
已下载: 234 MB / 345 MB
速度: 5.2 MB/s
剩余时间: 00:21
验证文件:
格式转换(如果需要):
下载字幕(如果用户选择):
生成元数据文件:
向用户展示:
示例输出:
✅ 下载成功!
📁 文件信息:
标题: 为什么大多数人的努力都是无效的?
路径: ./为什么大多数人的努力都是无效的?.mp4
大小: 535 MB
时长: 26:02
分辨率: 1920x1080
🎯 下载策略: 使用 Chrome 浏览器 Cookies
📝 字幕文件:
- 为什么大多数人的努力都是无效的?.zh-Hans.vtt (简体中文)
- 为什么大多数人的努力都是无效的?.zh-Hant.vtt (繁体中文)
- 为什么大多数人的努力都是无效的?.en.vtt (英文)
💡 快速预览:
open "./为什么大多数人的努力都是无效的?.mp4"
Cookie 文件位置: ~/.claude/skills/youtube-download/cookies.txt
Cookie 优先级:
Cookie 过期检测:
MP4 优先策略:
# 第一优先:MP4 视频 + M4A 音频
bestvideo[ext=mp4][height<=1080]+bestaudio[ext=m4a]
# 第二优先:最佳 MP4
best[ext=mp4][height<=1080]
# 第三优先:任何最佳格式
best[height<=1080]
# 最后:任何格式
best
常见错误和解决方案:
| 错误信息 | 原因 | 解决方案 | |---------|------|---------| | "n challenge solving failed" | JavaScript 运行时未配置或 EJS 脚本缺失 | 见下方 "n 参数解密问题" 详细解决方案 | | "Sign in to confirm you're not a bot" | Cookie 无效/缺失 | 切换到浏览器 Cookie 提取 | | "Video unavailable" | 视频被删除或私有 | 提示用户检查 URL | | "This video is age restricted" | 年龄限制 | 必须使用有效 Cookie | | "HTTP Error 429: Too Many Requests" | 请求过多 | 等待或使用代理 | | "No video formats found" | 地区限制 | 使用代理 |
问题描述:
当出现 WARNING: [youtube] n challenge solving failed: Some formats may be missing 错误时,表示 yt-dlp 无法解密 YouTube 的 n 参数,导致无法获取视频格式。
根本原因:
完整解决方案:
安装完整的 yt-dlp 包(包含 EJS 脚本):
pip install -U "yt-dlp[default]"
这会安装以下关键组件:
yt-dlp-ejs: JavaScript 挑战解决脚本brotli: 用于解压缩pycryptodomex: 加密支持确保已安装 Node.js:
# 检查 Node.js 版本(需要 ≥20.0.0)
node --version
如果未安装,访问 https://nodejs.org 下载安装
使用正确的命令参数:
python -m yt_dlp \
--cookies cookies.txt \
--js-runtimes node \
--output "%(title)s.%(ext)s" \
--write-auto-sub \
--sub-langs "zh-Hans,zh-Hant,en" \
"<youtube_url>"
关键参数说明:
--js-runtimes node: 明确启用 Node.js 作为 JavaScript 运行时--cookies cookies.txt: 使用本地 cookies 文件进行身份验证--js-runtimes node:/path/to/node验证解密成功: 当看到以下日志时,表示解密成功:
[youtube] [jsc:node] Solving JS challenges using node
其他可选的 JavaScript 运行时: 如果 Node.js 不可用,可以尝试:
--js-runtimes deno--js-runtimes bun--js-runtimes quickjs替代方案 - 使用远程 EJS 脚本: 如果不想安装完整包,可以临时下载 EJS 脚本:
python -m yt_dlp \
--remote-components ejs:npm \
--js-runtimes node \
"<youtube_url>"
配置文件方式(推荐): 将参数添加到 yt-dlp 配置文件避免每次手动输入:
创建/编辑 ~/.config/yt-dlp/config (Linux/Mac) 或 %APPDATA%\yt-dlp\config.txt (Windows):
--js-runtimes node
测试解密功能:
# 测试命令,应该能看到 [jsc:node] 日志
python -m yt_dlp --js-runtimes node --list-formats "<youtube_url>"
使用 yt-dlp 的进度钩子实时更新:
如果用户提供多个 URL:
核心下载脚本,实现智能重试机制:
def download_with_strategies(url, quality, output_dir):
"""
使用多种策略依次尝试下载
返回:成功使用的策略和文件路径
"""
strategies = [
('direct', download_direct),
('cookies_file', download_with_cookies_file),
('browser_chrome', download_from_browser_chrome),
('browser_firefox', download_from_browser_firefox),
('browser_edge', download_from_browser_edge),
('fallback', download_fallback)
]
for strategy_name, strategy_func in strategies:
try:
result = strategy_func(url, quality, output_dir)
return strategy_name, result
except Exception as e:
print(f"❌ 策略 {strategy_name} 失败: {e}")
continue
raise Exception("所有下载策略都失败了")
检查和管理 Cookies:
def check_cookies_validity(cookies_path):
"""检查 cookies 文件是否有效"""
# 尝试使用 cookies 获取视频信息
# 如果失败,返回 False
def export_cookies_from_browser(browser_name):
"""从浏览器导出 cookies"""
# 使用 yt-dlp 的内置功能
# 保存到 cookies.txt
格式转换工具:
def convert_to_mp4(input_path, output_path):
"""
将任何视频格式转换为 MP4
使用 FFmpeg
"""
根据视频信息给出建议:
支持播放列表和多个 URL:
# 播放列表
yt-dlp --yes-playlist "<playlist_url>"
# 多个 URL
# 从文件读取 URLs
如果下载中断:
--continue 参数记录下载历史:
~/.claude/skills/youtube-download/history.json{
"default_quality": "1080p",
"default_output_dir": "~/Downloads/YouTube",
"auto_download_subtitles": false,
"preferred_subtitle_languages": ["zh-Hans", "zh-Hant", "en"],
"cookies_path": "./cookies.txt",
"max_concurrent_downloads": 3,
"enable_download_history": true,
"auto_convert_to_mp4": true
}
用户: /youtube-download https://youtube.com/watch?v=xxxxx
助手:
- 询问质量选项(选择:最高质量)
- 询问是否下载字幕(选择:是)
- 开始下载(策略1失败 -> 策略2成功)
- 显示结果
用户: /youtube-download 下载这个播放列表 <playlist_url>
助手:
- 检测到播放列表
- 显示播放列表信息(23个视频)
- 询问是否全部下载
- 并发下载(3个同时)
用户: /youtube-download <url>
助手:
- 策略1失败(需要登录)
- 策略2失败(cookies过期)
- 策略3成功(从Chrome提取新cookies)
- 自动保存新cookies供下次使用
当用户触发此 Skill 时:
核心价值:
让我们开始吧!
content-media
Summarize or extract text/transcripts from URLs, podcasts, and local files (great fallback for “transcribe this YouTube/video”).
content-media
QQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
content-media
Summarize or extract text/transcripts from URLs, podcasts, and local files (great fallback for “transcribe this YouTube/video”).
content-media
QQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。