mcpField
Y
youtube-transcript

youtube-transcript

github.com/michalparkola生産性564866 回インストール33 週間前に更新
リポジトリ

youtube-transcript について

yt-dlpでYouTubeの字幕を取得するスキルです。字幕がない場合はWhisperによる文字起こしを提示し、確認からダウンロード、変換までを案内します。

主な機能

  1. 01利用可能な字幕の確認
  2. 02手動字幕を優先し自動字幕へ切替
  3. 03Whisperによる文字起こしの提示
  4. 04VTT字幕のテキスト変換
  5. 05音声取得やファイル削除前の確認

活用シーン

  1. 01YouTube動画の字幕保存
  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 モデル)の前にユーザーに確認します
  • ✅ 処理後に一時ファイルを削除します
  • ✅ 各段階で何が行われているかを明確に伝えます
  • ✅ 役立つメッセージを添えて、エラーに適切に対処します

コメント