video について
videoは、動画やポッドキャストのリンクから字幕を取得または音声を文字起こしし、構造化された要約を作るスキルです。複数のメディアサービスや直接リンクに対応し、文字起こしと要点整理に役立ちます。
主な機能
- 01字幕の取得または音声の文字起こし
- 02複数の動画・ポッドキャストソースに対応
- 03長時間音声の分割と順次文字起こし
- 04メディア種別に応じた要約の生成
- 05文字起こしエラーやレート制限への対応
活用シーン
- 01YouTubeやBilibili動画の要約
- 02ポッドキャストの章ごとの要約と要点整理
- 03字幕のないメディア音声の文字起こし
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ ibigqiang/ feedgrab --skill videoインストール後、Claude Code で/videoを入力して読み込まれたか確認します。
詳細
動画・ポッドキャスト要約スキル
動画/ポッドキャストのリンクを送信すると、完全な文字起こしと構造化された要約を取得できます
対応プラットフォーム
| プラットフォーム | 種類 | 字幕 | Whisper による文字起こし |
|---|---|---|---|
| YouTube | 動画 | ✅ | ✅ |
| Bilibili | 動画 | ✅ | ✅ |
| X/Twitter | 動画 | ❌ | ✅ |
| Xiaoyuzhou (小宇宙) | ポッドキャスト | ❌ | ✅ |
| Apple Podcasts | ポッドキャスト | ❌ | ✅ |
| 直接リンク(mp3/mp4/m3u8) | 任意 | ❌ | ✅ |
トリガー
メディア URL が検出されると自動的にトリガーされます:
- YouTube:
youtube.com、youtu.be - Bilibili:
bilibili.com、b23.tv - X/Twitter:
x.com、twitter.com(動画付きの投稿) - Xiaoyuzhou:
xiaoyuzhoufm.com - Apple Podcasts:
podcasts.apple.com - 直接リンク:
.mp3、.mp4、.m3u8、.m4a、.webm
パイプライン
ステップ 0:メディアの種類を検出
| URL パターン | 種類 | パイプライン |
|---|---|---|
xiaoyuzhoufm.com/episode/ | ポッドキャスト | → ステップ 1b(Xiaoyuzhou) |
podcasts.apple.com | ポッドキャスト | → ステップ 1c(Apple) |
bilibili.com、b23.tv | 動画 | → ステップ 1d(Bilibili API) |
.mp3、.m4a の直接リンク | 音声 | → ステップ 2b(直接ダウンロード) |
| その他 | 動画 | → ステップ 1a(字幕抽出) |
ステップ 1a:動画 — 字幕を抽出
rm -f /tmp/media_sub*.vtt /tmp/media_audio.mp3 /tmp/media_transcript*.json /tmp/media_segment_*.mp3 2>/dev/null || true
# YouTube (prefer English, fallback Chinese)
yt-dlp --skip-download --write-auto-sub --sub-lang "en,zh-Hans" -o "/tmp/media_sub" "VIDEO_URL"
# Bilibili
yt-dlp --skip-download --write-auto-sub --sub-lang "zh-Hans,zh" -o "/tmp/media_sub" "VIDEO_URL"
字幕を確認:
ls /tmp/media_sub*.vtt 2>/dev/null
- 字幕あり → VTT コンテンツを読み込み、ステップ 3 に進みます
- 字幕なし → ステップ 2a(音声をダウンロード)
ステップ 1b:Xiaoyuzhou (小宇宙) — 音声 URL を抽出
AUDIO_URL=$(curl -sL -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
"EPISODE_URL" \
| grep -oE 'https://media\.xyzcdn\.net/[^"]+\.(m4a|mp3)' \
| head -1)
echo "Audio URL: $AUDIO_URL"
curl -L -o /tmp/media_audio.mp3 "$AUDIO_URL"
→ ステップ 2b
ステップ 1c:Apple Podcasts — yt-dlp 経由
yt-dlp -f "ba[ext=m4a]/ba/b" --extract-audio --audio-format mp3 --audio-quality 5 \
-o "/tmp/media_audio.%(ext)s" "APPLE_PODCAST_URL"
→ ステップ 2b
ステップ 1d:Bilibili — API から音声ストリームを直接取得
BV="BV1xxxxx"
curl -s "https://api.bilibili.com/x/web-interface/view?bvid=$BV" \
-H "User-Agent: Mozilla/5.0" -H "Referer: https://www.bilibili.com/" \
| python3 -c "import json,sys; d=json.load(sys.stdin)['data']; print(f\"Title: {d['title']}\nDuration: {d['duration']}s\nCID: {d['cid']}\")"
CID=<CID from previous step>
AUDIO_URL=$(curl -s "https://api.bilibili.com/x/player/playurl?bvid=$BV&cid=$CID&fnval=16&qn=64" \
-H "User-Agent: Mozilla/5.0" -H "Referer: https://www.bilibili.com/" \
| python3 -c "import json,sys; print(json.load(sys.stdin)['data']['dash']['audio'][0]['baseUrl'])")
curl -L -o /tmp/media_audio.m4s \
-H "User-Agent: Mozilla/5.0" -H "Referer: https://www.bilibili.com/" "$AUDIO_URL"
ffmpeg -y -i /tmp/media_audio.m4s -acodec libmp3lame -q:a 5 /tmp/media_audio.mp3
→ ステップ 2b
ステップ 2a:動画 — 音声をダウンロード(字幕がない場合)
yt-dlp --cookies-from-browser chrome -f "ba[ext=m4a]/ba/b" --extract-audio --audio-format mp3 --audio-quality 5 \
-o "/tmp/media_audio.%(ext)s" "VIDEO_URL"
ステップ 2b:音声サイズを確認して分割
FILE_SIZE=$(stat -f%z /tmp/media_audio.* 2>/dev/null || stat -c%s /tmp/media_audio.* 2>/dev/null)
echo "File size: $FILE_SIZE bytes"
- ≤ 25MB → ステップ 2c(直接文字起こし)
- > 25MB → 10 分ごとのセグメントに分割:
DURATION=$(ffprobe -v error -show_entries format=duration -of csv=p=0 /tmp/media_audio.* | head -1)
SEGMENT_SEC=600
SEGMENTS=$(python3 -c "import math; print(math.ceil(float('$DURATION')/$SEGMENT_SEC))")
for i in $(seq 0 $((SEGMENTS-1))); do
START=$((i * SEGMENT_SEC))
ffmpeg -y -i /tmp/media_audio.* -ss $START -t $SEGMENT_SEC -acodec libmp3lame -q:a 5 \
"/tmp/media_segment_${i}.mp3" 2>/dev/null
done
各セグメントについて、ステップ 2c を順次呼び出します(並列実行すると Groq で 524 タイムアウトが発生します)
ステップ 2c:Whisper による文字起こし
前提条件:GROQ_API_KEY 環境変数
if [ -z "$GROQ_API_KEY" ]; then
echo "❌ GROQ_API_KEY not set. Get one at: https://console.groq.com/keys"
exit 1
fi
curl -s -X POST "https://api.groq.com/openai/v1/audio/transcriptions" \
-H "Authorization: Bearer $GROQ_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F "file=@AUDIO_FILE" \
-F "model=whisper-large-v3-turbo" \
-F "response_format=verbose_json" \
-F "language=zh" \
> /tmp/media_transcript.json
python3 -c "import json; print(json.load(open('/tmp/media_transcript.json'))['text'])"
ステップ 3:構造化された要約
動画(≤20 分):
- 概要(1~2 文)
- 要点(箇条書き 3~5 項目)
- 注目すべき引用(ある場合)
- アクション項目(該当する場合)
ポッドキャスト(>20 分):
- 概要(2~3 文)
- チャプター要約(トピックごとに分割)
- 要点(箇条書き 5~8 項目)
- 注目すべき引用
- アクション項目(該当する場合)
エラー処理
| 状況 | 対応 |
|---|---|
| 字幕なし、かつ GROQ_API_KEY なし | API キーを設定するようユーザーに案内 |
| 音声が 25MB 超 | ffmpeg で分割(1 セグメント 10 分)、順次文字起こし |
| ポッドキャストが 2 時間超 | ユーザーに警告し、続行前に確認 |
| Groq 524 タイムアウト | 並列実行しない — 順次文字起こしし、間に 5~8 秒待機 |
| Groq 429 レート制限 | retry-after ヘッダーの指定時間待機してから再試行 |
| yt-dlp の Bilibili 412 | 代わりに Bilibili API を使用(ステップ 1d) |
| yt-dlp の YouTube ボット検出 | --cookies-from-browser chrome を追加 |
| Spotify のリンク | 非対応(DRM 保護のため) |
依存関係
yt-dlp:動画のダウンロード+字幕抽出ffmpeg:音声変換+分割curl:音声ダウンロード、API 呼び出しGROQ_API_KEY:Whisper による文字起こし(https://console.groq.com/keys で無料取得)
コメント
Markdown 対応