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>"
-f "best[ext=mp4]/best"β highest quality MP4; falls back to best available--merge-output-format mp4β ensures final output is MP4.100sin template β truncates title to 100 chars (avoids filesystem issues)- Default save path:
~/Downloads/
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:
- Guest Token β requests a temporary guest token from Xβs public API (no login needed)
- GraphQL API β queries Xβs GraphQL endpoint for the tweetβs full data (including video URLs)
- m3u8 parsing β X hosts native videos as HLS streams
(
.m3u8); yt-dlp parses and selects the best quality - 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>
Copyright
Only download with permission. Respect copyright and platform ToS. Personal/educational/fair use only.