Video Downloader β€” AI Agent Skill

2026-03-23
yt-dlpvideoskillX/TwitterYouTube

Video Downloader

Downloads videos from YouTube, X/Twitter, and 1000+ platforms via yt-dlp.

Tool

yt-dlp (/opt/homebrew/bin/yt-dlp) β€” open-source CLI video downloader.

Workflow

Step 1 β€” Probe (no download)

yt-dlp --print title --print duration_string --no-download "<URL>"

Confirms the video exists and is accessible. Returns title + duration.

Step 2 β€” Download

yt-dlp -f "best[ext=mp4]/best" --merge-output-format mp4 \
  -o "$HOME/Downloads/%(title).100s.%(ext)s" "<URL>"

Audio Only

yt-dlp -x --audio-format mp3 -o "$HOME/Downloads/%(title).100s.%(ext)s" "<URL>"

Quality Control

# List available formats first
yt-dlp -F "<URL>"

# Pick specific format by ID
yt-dlp -f 137+140 -o "$HOME/Downloads/%(title).100s.%(ext)s" "<URL>"

# Cap resolution
yt-dlp -f "best[height<=720][ext=mp4]/best[height<=720]" "<URL>"

Batch / Playlist

# YouTube playlist
yt-dlp -f "best[ext=mp4]/best" --merge-output-format mp4 \
  -o "$HOME/Downloads/%(playlist_title)s/%(title).100s.%(ext)s" "<PLAYLIST_URL>"

# Multiple URLs from file
yt-dlp -a urls.txt -f "best[ext=mp4]/best" --merge-output-format mp4 \
  -o "$HOME/Downloads/%(title).100s.%(ext)s"

Platform-Specific Notes

X/Twitter

yt-dlp has a built-in Twitter extractor. The download flow:

  1. Guest Token β€” requests a temporary guest token from X’s public API (no login needed)
  2. GraphQL API β€” queries X’s GraphQL endpoint for the tweet’s full data (including video URLs)
  3. m3u8 parsing β€” X hosts native videos as HLS streams (.m3u8); yt-dlp parses and selects the best quality
  4. Download β€” downloads the full stream and saves as MP4

Log shows this clearly:

[twitter] Extracting URL: https://x.com/...
[twitter] <id>: Downloading guest token
[twitter] <id>: Downloading GraphQL JSON
[twitter] <id>: Downloading m3u8 information

Two types of video on X:

Type How it works yt-dlp behavior
Native upload User uploads video directly to X. X transcodes & hosts via HLS. Uses [twitter] extractor β†’ GraphQL β†’ m3u8 β†’ download
YouTube embed User pastes a YouTube URL. X shows a preview card but video lives on YouTube. Uses [youtube] extractor β†’ standard YouTube download

How to tell: if yt-dlp log shows [twitter] extractor, it’s native. If [youtube], it’s an embed.

Native uploads > 2 min typically require X Premium.

YouTube

Most common platform. yt-dlp handles: - Age-restricted videos (may need cookies) - Live streams (use --live-from-start for full recording) - Shorts, playlists, channels

If a video requires login (age-gate, private):

yt-dlp --cookies-from-browser chrome "<URL>"

Other Supported Platforms

Vimeo, Twitch (VODs + clips), Bilibili, Instagram Reels, TikTok, Reddit, and 1000+ more. Same command pattern works β€” yt-dlp auto-detects the platform.

Error Handling

Error Cause Fix
ERROR: Unable to extract guest token X rate limiting or API change Wait and retry; or update yt-dlp
ERROR: Sign in to confirm your age Age-restricted YouTube Add --cookies-from-browser chrome
ERROR: Video unavailable Deleted, private, or geo-blocked Try VPN or confirm video exists
HTTP Error 403 Auth required or geo-block Try --cookies-from-browser chrome
Filename too long Title exceeds filesystem limit Already handled by .100s truncation

Output Format

After download, report to user:

βœ… Downloaded: <title>
- Duration: <HH:MM:SS>
- Size: <size>
- Location: ~/Downloads/<filename>

Only download with permission. Respect copyright and platform ToS. Personal/educational/fair use only.