mcpField
Y
youtube-transcript

youtube-transcript

github.com/ovachiever创意与媒体5656 次安装48 周前更新
代码仓库

关于 youtube-transcript

使用 yt-dlp 获取 YouTube 视频字幕或文本稿的技能。它会先检查字幕并优先采用人工字幕;没有字幕时,才在用户确认后提供 Whisper 转录。

主要功能

  1. 01检查可用字幕语言
  2. 02优先人工字幕,其次自动字幕
  3. 03在无字幕时提供 Whisper 转录
  4. 04保存 VTT 或纯文本稿
  5. 05下载音频或安装前征求确认

适用场景

  1. 01从 YouTube 链接提取字幕
  2. 02选择可用的字幕语言
  3. 03为无字幕视频生成文本
  4. 04将 VTT 字幕整理为去重文本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ovachiever/droid-tings --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