mcpField
Y
youtube-transcript

youtube-transcript

github.com/michalparkola生产力564866 次安装33 周前更新
代码仓库

关于 youtube-transcript

用于通过 yt-dlp 获取 YouTube 字幕的 Skill;字幕不可用时可提供 Whisper 转录选项,并指导检查、下载及转换字幕。

主要功能

  1. 01检查可用字幕轨道
  2. 02优先手动字幕,再用自动字幕
  3. 03提供 Whisper 转录备用方案
  4. 04将 VTT 字幕转换为纯文本
  5. 05下载音频或清理文件前征求确认

适用场景

  1. 01保存 YouTube 链接的视频字幕
  2. 02字幕缺失时获取视频文本
  3. 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 视频的文本内容

工作原理

优先顺序:
  1. 检查是否已安装 yt-dlp——如有需要则安装
  2. 列出可用字幕——查看实际可用的字幕
  3. 优先尝试手动字幕(--write-sub)——质量最高
  4. 回退到自动生成的字幕(--write-auto-sub)——通常可以获取
  5. 最后手段:使用 Whisper 转录——如果没有字幕(需要用户确认)
  6. 确认下载,并告知用户文件的保存位置
  7. 可选清理 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('&amp;', '&').replace('&gt;', '>').replace('&lt;', '<')
            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('&amp;', '&').replace('&gt;', '>').replace('&lt;', '<')
            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('&amp;', '&').replace('&gt;', '>').replace('&lt;', '<')
            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 模型)前先征求用户同意
  • ✅ 处理完成后清理临时文件
  • ✅ 清晰说明每个阶段正在进行的操作
  • ✅ 妥善处理错误并提供有帮助的提示

评论

支持 Markdown