mcpField
V
video

video

github.com/ibigqiangProductivity62274 installsUpdated 6d ago
Repository

About video

video is a digest skill for video and podcast links that extracts subtitles or transcribes audio, then produces a structured summary. It covers several media platforms and direct media links, for people who need transcripts and organized takeaways.

Key features

  1. 01Extract subtitles or transcribe audio
  2. 02Support multiple video and podcast sources
  3. 03Split and sequentially transcribe long audio
  4. 04Generate summaries by media type
  5. 05Handle transcription errors and rate limits

Use cases

  1. 01Summarize YouTube or Bilibili videos
  2. 02Get chapter summaries and takeaways from podcasts
  3. 03Transcribe media audio without subtitles

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/ibigqiang/feedgrab --skill video

After installing, type/videoin Claude Code to confirm it loaded.

Details

From the project README

Video & Podcast Digest Skill

Send a video/podcast link → get full transcript + structured summary

Supported Platforms

PlatformTypeSubtitlesWhisper Transcription
YouTubeVideo✅✅
BilibiliVideo✅✅
X/TwitterVideo❌✅
Xiaoyuzhou (小宇宙)Podcast❌✅
Apple PodcastsPodcast❌✅
Direct links (mp3/mp4/m3u8)Any❌✅

Trigger

Auto-triggered when a media URL is detected:

  • YouTube: youtube.com, youtu.be
  • Bilibili: bilibili.com, b23.tv
  • X/Twitter: x.com, twitter.com (tweets with video)
  • Xiaoyuzhou: xiaoyuzhoufm.com
  • Apple Podcasts: podcasts.apple.com
  • Direct: .mp3, .mp4, .m3u8, .m4a, .webm

Pipeline

Step 0: Detect Media Type
URL PatternTypePipeline
xiaoyuzhoufm.com/episode/Podcast→ Step 1b (Xiaoyuzhou)
podcasts.apple.comPodcast→ Step 1c (Apple)
bilibili.com, b23.tvVideo→ Step 1d (Bilibili API)
.mp3, .m4a direct linkAudio→ Step 2b (direct download)
OtherVideo→ Step 1a (subtitle extraction)
Step 1a: Video — Extract Subtitles
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"

Check for subtitles:

ls /tmp/media_sub*.vtt 2>/dev/null
  • Has subtitles → Read VTT content, skip to Step 3
  • No subtitles → Step 2a (download audio)
Step 1b: Xiaoyuzhou (小宇宙) — Extract Audio 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"

→ Step 2b

Step 1c: Apple Podcasts — via 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"

→ Step 2b

Step 1d: Bilibili — API Direct Audio Stream
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

→ Step 2b

Step 2a: Video — Download Audio (when no subtitles)
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"
Step 2b: Check Audio Size & Segment
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 → Step 2c (transcribe directly)
  • > 25MB → Split into 10-minute segments:
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

→ Call Step 2c for each segment sequentially (parallel triggers Groq 524 timeout)

Step 2c: Whisper Transcription

Prerequisite: GROQ_API_KEY environment variable

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'])"
Step 3: Structured Summary

Video (≤20 min):

  1. Overview (1-2 sentences)
  2. Key Points (3-5 bullet points)
  3. Notable Quotes (if any)
  4. Action Items (if applicable)

Podcast (>20 min):

  1. Overview (2-3 sentences)
  2. Chapter Summary (segmented by topic)
  3. Key Points (5-8 bullet points)
  4. Notable Quotes
  5. Action Items (if applicable)

Error Handling

SituationAction
No subtitles + no GROQ_API_KEYPrompt user to set API key
Audio >25MBffmpeg segment (10min/segment), transcribe sequentially
Podcast >2 hoursWarn user, confirm before proceeding
Groq 524 timeoutDo NOT parallelize — transcribe sequentially, sleep 5-8s between
Groq 429 rate limitWait for retry-after header, then retry
yt-dlp Bilibili 412Use Bilibili API instead (Step 1d)
yt-dlp YouTube bot detectionAdd --cookies-from-browser chrome
Spotify linksNot supported (DRM protected)

Dependencies

  • yt-dlp: video download + subtitle extraction
  • ffmpeg: audio conversion + segmentation
  • curl: audio download, API calls
  • GROQ_API_KEY: Whisper transcription (free at https://console.groq.com/keys)

Comments

Markdown supported