关于 youtube-transcript
用于通过 yt-dlp 获取 YouTube 字幕的 Skill;字幕不可用时可提供 Whisper 转录选项,并指导检查、下载及转换字幕。
主要功能
- 01检查可用字幕轨道
- 02优先手动字幕,再用自动字幕
- 03提供 Whisper 转录备用方案
- 04将 VTT 字幕转换为纯文本
- 05下载音频或清理文件前征求确认
适用场景
- 01保存 YouTube 链接的视频字幕
- 02字幕缺失时获取视频文本
- 03生成便于阅读或分析的纯文本稿
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ michalparkola/ tapestry-skills --skill youtube-transcript安装后在 Claude Code 中输入/youtube-transcript确认已加载。
详细介绍
YouTube 字幕下载器
此技能可使用 yt-dlp 下载 YouTube 视频的字幕(字幕文本/隐藏式字幕)。
何时使用此技能
在用户执行以下操作时启用此技能:
- 提供 YouTube URL 并想获取字幕文本
- 请求“从 YouTube 下载字幕文本”
- 想“获取视频的隐藏式字幕”或“获取字幕”
- 请求“转录 YouTube 视频”
- 需要 YouTube 视频的文本内容
工作原理
优先顺序:
- 检查是否已安装 yt-dlp——如有需要则安装
- 列出可用字幕——查看实际可用的字幕
- 优先尝试手动字幕(
--write-sub)——质量最高 - 回退到自动生成的字幕(
--write-auto-sub)——通常可以获取 - 最后手段:使用 Whisper 转录——如果没有字幕(需要用户确认)
- 确认下载,并告知用户文件的保存位置
- 可选清理 VTT 格式(如果用户需要纯文本)
安装检查
重要:始终先检查是否已安装 yt-dlp:
which yt-dlp || command -v yt-dlp
如果尚未安装
根据系统尝试自动安装:
macOS(Homebrew):
brew install yt-dlp
Linux(apt/Debian/Ubuntu):
sudo apt update && sudo apt install -y yt-dlp
替代方案(pip,适用于所有系统):
pip3 install yt-dlp
# or
python3 -m pip install yt-dlp
如果安装失败:告知用户需要手动安装 yt-dlp,并提供 https://github.com/yt-dlp/yt-dlp#installation 中的安装说明。
检查可用字幕
在尝试下载之前,务必先执行此操作:
yt-dlp --list-subs "YOUTUBE_URL"
此命令会显示可用的字幕类型,不会下载任何内容。请查看:
- 手动字幕(质量更高)
- 自动生成的字幕(通常可以获取)
- 可用语言
下载策略
选项 1:手动字幕(首选)
先尝试此选项——质量最高,由人工创建:
yt-dlp --write-sub --skip-download --output "OUTPUT_NAME" "YOUTUBE_URL"
选项 2:自动生成的字幕(备用)
如果没有手动字幕:
yt-dlp --write-auto-sub --skip-download --output "OUTPUT_NAME" "YOUTUBE_URL"
这两个命令都会创建 .vtt 文件(WebVTT 字幕格式)。
选项 3:使用 Whisper 转录(最后手段)
仅在手动字幕和自动生成的字幕都不可用时使用。
步骤 1:显示文件大小并请求确认
# Get audio file size estimate
yt-dlp --print "%(filesize,filesize_approx)s" -f "bestaudio" "YOUTUBE_URL"
# Or get duration to estimate
yt-dlp --print "%(duration)s %(title)s" "YOUTUBE_URL"
重要:向用户显示文件大小,并询问:“没有可用字幕。我可以下载音频(约 X MB),并使用 Whisper 转录。要继续吗?”
继续之前请等待用户确认。
步骤 2:检查是否已安装 Whisper
command -v whisper
如果尚未安装,请询问用户:“尚未安装 Whisper。要通过 pip install openai-whisper 安装吗(模型需要约 1-3GB 空间)?此安装只需进行一次。”
安装之前请等待用户确认。
如果用户同意,则安装:
pip3 install openai-whisper
步骤 3:仅下载音频
yt-dlp -x --audio-format mp3 --output "audio_%(id)s.%(ext)s" "YOUTUBE_URL"
步骤 4:使用 Whisper 转录
# Auto-detect language (recommended)
whisper audio_VIDEO_ID.mp3 --model base --output_format vtt
# Or specify language if known
whisper audio_VIDEO_ID.mp3 --model base --language en --output_format vtt
模型选项(目前使用 base):
tiny- 速度最快,准确度最低(约 1GB)base- 平衡性较好(约 1GB)← 使用此模型small- 准确度更高(约 2GB)medium- 准确度很高(约 5GB)large- 准确度最高(约 10GB)
步骤 5:清理
转录完成后,询问用户:“转录完成!要删除音频文件以节省空间吗?”
如果用户同意:
rm audio_VIDEO_ID.mp3
获取视频信息
提取视频标题(用于文件名)
yt-dlp --print "%(title)s" "YOUTUBE_URL"
使用此命令根据视频标题创建有意义的文件名。清理标题,使其适用于文件系统:
- 将
/替换为- - 替换可能导致问题的特殊字符
- 可考虑使用经过清理的版本:
$(yt-dlp --print "%(title)s" "URL" | tr '/' '-' | tr ':' '-')
后期处理
转换为纯文本(推荐)
YouTube 自动生成的 VTT 文件中包含重复行,这是因为字幕会随着时间戳逐步显示,且彼此重叠。转换为纯文本时,务必在保留原始语序的同时去除重复内容。
python3 -c "
import sys, re
seen = set()
with open('transcript.en.vtt', 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:
clean = re.sub('<[^>]*>', '', line)
clean = clean.replace('&', '&').replace('>', '>').replace('<', '<')
if clean and clean not in seen:
print(clean)
seen.add(clean)
" > transcript.txt
使用视频标题完成后期处理
# Get video title
VIDEO_TITLE=$(yt-dlp --print "%(title)s" "YOUTUBE_URL" | tr '/' '_' | tr ':' '-' | tr '?' '' | tr '"' '')
# Find the VTT file
VTT_FILE=$(ls *.vtt | head -n 1)
# Convert with deduplication
python3 -c "
import sys, re
seen = set()
with open('$VTT_FILE', 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:
clean = re.sub('<[^>]*>', '', line)
clean = clean.replace('&', '&').replace('>', '>').replace('<', '<')
if clean and clean not in seen:
print(clean)
seen.add(clean)
" > "${VIDEO_TITLE}.txt"
echo "✓ Saved to: ${VIDEO_TITLE}.txt"
# Clean up VTT file
rm "$VTT_FILE"
echo "✓ Cleaned up temporary VTT file"
输出格式
- VTT 格式(
.vtt):包含时间戳和格式,适合视频播放器使用 - 纯文本(
.txt):仅包含文本内容,适合阅读或分析
提示
- 文件名格式为
{output_name}.{language_code}.vtt(例如,transcript.en.vtt) - 大多数 YouTube 视频都有自动生成的英语字幕
- 有些视频可能提供多种语言选项
- 如果没有自动字幕,请改用
--write-sub尝试获取手动字幕
完整工作流示例
VIDEO_URL="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# Get video title for filename
VIDEO_TITLE=$(yt-dlp --print "%(title)s" "$VIDEO_URL" | tr '/' '_' | tr ':' '-' | tr '?' '' | tr '"' '')
OUTPUT_NAME="transcript_temp"
# ============================================
# STEP 1: Check if yt-dlp is installed
# ============================================
if ! command -v yt-dlp &> /dev/null; then
echo "yt-dlp not found, attempting to install..."
if command -v brew &> /dev/null; then
brew install yt-dlp
elif command -v apt &> /dev/null; then
sudo apt update && sudo apt install -y yt-dlp
else
pip3 install yt-dlp
fi
fi
# ============================================
# STEP 2: List available subtitles
# ============================================
echo "Checking available subtitles..."
yt-dlp --list-subs "$VIDEO_URL"
# ============================================
# STEP 3: Try manual subtitles first
# ============================================
echo "Attempting to download manual subtitles..."
if yt-dlp --write-sub --skip-download --output "$OUTPUT_NAME" "$VIDEO_URL" 2>/dev/null; then
echo "✓ Manual subtitles downloaded successfully!"
ls -lh ${OUTPUT_NAME}.*
else
# ============================================
# STEP 4: Fallback to auto-generated
# ============================================
echo "Manual subtitles not available. Trying auto-generated..."
if yt-dlp --write-auto-sub --skip-download --output "$OUTPUT_NAME" "$VIDEO_URL" 2>/dev/null; then
echo "✓ Auto-generated subtitles downloaded successfully!"
ls -lh ${OUTPUT_NAME}.*
else
# ============================================
# STEP 5: Last resort - Whisper transcription
# ============================================
echo "⚠ No subtitles available for this video."
# Get file size
FILE_SIZE=$(yt-dlp --print "%(filesize_approx)s" -f "bestaudio" "$VIDEO_URL")
DURATION=$(yt-dlp --print "%(duration)s" "$VIDEO_URL")
TITLE=$(yt-dlp --print "%(title)s" "$VIDEO_URL")
echo "Video: $TITLE"
echo "Duration: $((DURATION / 60)) minutes"
echo "Audio size: ~$((FILE_SIZE / 1024 / 1024)) MB"
echo ""
echo "Would you like to download and transcribe with Whisper? (y/n)"
read -r RESPONSE
if [[ "$RESPONSE" =~ ^[Yy]$ ]]; then
# Check for Whisper
if ! command -v whisper &> /dev/null; then
echo "Whisper not installed. Install now? (requires ~1-3GB) (y/n)"
read -r INSTALL_RESPONSE
if [[ "$INSTALL_RESPONSE" =~ ^[Yy]$ ]]; then
pip3 install openai-whisper
else
echo "Cannot proceed without Whisper. Exiting."
exit 1
fi
fi
# Download audio
echo "Downloading audio..."
yt-dlp -x --audio-format mp3 --output "audio_%(id)s.%(ext)s" "$VIDEO_URL"
# Get the actual audio filename
AUDIO_FILE=$(ls audio_*.mp3 | head -n 1)
# Transcribe
echo "Transcribing with Whisper (this may take a few minutes)..."
whisper "$AUDIO_FILE" --model base --output_format vtt
# Cleanup
echo "Transcription complete! Delete audio file? (y/n)"
read -r CLEANUP_RESPONSE
if [[ "$CLEANUP_RESPONSE" =~ ^[Yy]$ ]]; then
rm "$AUDIO_FILE"
echo "Audio file deleted."
fi
ls -lh *.vtt
else
echo "Transcription cancelled."
exit 0
fi
fi
fi
# ============================================
# STEP 6: Convert to readable plain text with deduplication
# ============================================
VTT_FILE=$(ls ${OUTPUT_NAME}*.vtt 2>/dev/null || ls *.vtt | head -n 1)
if [ -f "$VTT_FILE" ]; then
echo "Converting to readable format and removing duplicates..."
python3 -c "
import sys, re
seen = set()
with open('$VTT_FILE', 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:
clean = re.sub('<[^>]*>', '', line)
clean = clean.replace('&', '&').replace('>', '>').replace('<', '<')
if clean and clean not in seen:
print(clean)
seen.add(clean)
" > "${VIDEO_TITLE}.txt"
echo "✓ Saved to: ${VIDEO_TITLE}.txt"
# Clean up temporary VTT file
rm "$VTT_FILE"
echo "✓ Cleaned up temporary VTT file"
else
echo "⚠ No VTT file found to convert"
fi
echo "✓ Complete!"
注意:此完整工作流会处理所有情况,并在每个决策点进行适当的错误检查并提示用户。
错误处理
常见问题及解决方案:
1. 未安装 yt-dlp
- 根据系统(Homebrew/apt/pip)尝试自动安装
- 如果安装失败,提供手动安装链接
- 继续操作前验证是否安装成功
2. 没有可用字幕
- 先列出可用字幕以确认
- 同时尝试
--write-sub和--write-auto-sub - 如果两者都失败,提供 Whisper 转录选项
- 显示文件大小,并在下载音频前征求用户确认
3. 视频无效或为私密视频
- 检查 URL 格式是否正确:
https://www.youtube.com/watch?v=VIDEO_ID - 有些视频可能是私密视频、受年龄限制或受地理位置限制
- 将 yt-dlp 返回的具体错误告知用户
4. Whisper 安装失败
- 可能需要系统依赖项(ffmpeg、rust)
- 提供备用方案:“使用以下命令手动安装:
pip3 install openai-whisper” - 检查可用磁盘空间(模型大小不一,所需空间为 1-10GB)
5. 下载中断或失败
- 检查互联网连接
- 确认磁盘空间充足
- 如果出现 SSL 问题,尝试使用
--no-check-certificate重试
6. 多种字幕语言
- 默认情况下,yt-dlp 会下载所有可用语言的字幕
- 可使用
--sub-langs en指定仅下载英语字幕 - 先使用
--list-subs列出可用字幕
最佳实践:
- ✅ 下载前始终先检查可用内容(
--list-subs) - ✅ 每个步骤完成后都要确认成功,再继续下一步
- ✅ 大型下载(音频文件、Whisper 模型)前先征求用户同意
- ✅ 处理完成后清理临时文件
- ✅ 清晰说明每个阶段正在进行的操作
- ✅ 妥善处理错误并提供有帮助的提示