A modern, community-driven alternative to yt-dlp. Built from scratch for simplicity, speed, and extensibility.
- 🚀 Lightweight: Minimal dependencies, just requests library
- 🔄 Modern API: Uses YouTube's official innertube API
- 🛠 Simple Architecture: Easy to understand and contribute to
- 📦 Fast Installation: No complex build process
- 🔧 Maintainable: Built with modern Python practices
- 👥 Community First: Designed for community contributions
This repository is participating in Hacktoberfest 2025! We welcome contributions from the community.
- Check out our CONTRIBUTING.md guide
- Look for issues labeled with
hacktoberfestorgood first issue - Fork the repository and create your branch
- Make your changes and submit a pull request
- Wait for review and address any feedback
Please ensure you read our Code of Conduct before contributing.
pip install ytsnap# Basic download
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID"
# Custom output filename
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" output.mp4
# Download specific quality
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" video.mp4 --quality 720p
# Download by itag
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" video.mp4 --itag 18
# Use proxies from file (bypass rate limits)
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" video.mp4 --proxy-file proxies.txt
# Use single proxy
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" video.mp4 --proxy "http://127.0.0.1:8080"
# Use authenticated proxy
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" video.mp4 --proxy "http://user:pass@proxy.com:8080"# Download entire playlist (auto-detects playlist URL)
ytsnap "https://www.youtube.com/playlist?list=PLxxx"
# Download playlist with custom output directory
ytsnap "https://www.youtube.com/playlist?list=PLxxx" --output-dir "./my_playlist"
# Download playlist with specific quality
ytsnap "https://www.youtube.com/playlist?list=PLxxx" --output-dir "./downloads" --quality 720p
# Download playlist with custom concurrency
ytsnap "https://www.youtube.com/playlist?list=PLxxx" --output-dir "./downloads" --concurrency 5
# Download playlist with proxies
ytsnap "https://www.youtube.com/playlist?list=PLxxx" --output-dir "./downloads" --proxy-file proxies.txtfrom youtube_downloader import YouTubeDownloader, PlaylistDownloader, ProxyManager, ProxyConfig
# === Single Video Download ===
downloader = YouTubeDownloader("https://www.youtube.com/watch?v=VIDEO_ID")
# Get available formats
formats = downloader.get_formats()
for fmt in formats:
print(f"itag={fmt['itag']} quality={fmt['quality']} size={fmt['filesize']}")
# Download video (auto-selects best format)
downloader.download("video.mp4")
# Download specific quality
downloader.download("video_720p.mp4", quality="720p")
# Download by itag
downloader.download("video.mp4", itag=18)
# Use proxy manager to bypass rate limits
proxy_manager = ProxyManager.from_file("proxies.txt")
downloader = YouTubeDownloader("https://www.youtube.com/watch?v=VIDEO_ID", proxy_manager=proxy_manager)
downloader.download("video_with_proxy.mp4")
# === Playlist Download ===
playlist_url = "https://www.youtube.com/playlist?list=PLxxx"
# Initialize playlist downloader
playlist_downloader = PlaylistDownloader(playlist_url, concurrency=3)
# Get list of videos in playlist
videos = playlist_downloader.get_videos()
print(f"Found {len(videos)} videos in playlist")
# Download entire playlist
stats = playlist_downloader.download(output_dir="./downloads")
# Download playlist with specific quality
stats = playlist_downloader.download(output_dir="./downloads", quality="720p")
# Download playlist with custom callbacks
def on_start(video):
print(f"Starting download: {video['title']}")
def on_complete(video, output_file):
print(f"Completed: {video['title']} -> {output_file}")
def on_error(video, error):
print(f"Error downloading {video['title']}: {error}")
stats = playlist_downloader.download(
output_dir="./downloads",
on_video_start=on_start,
on_video_complete=on_complete,
on_error=on_error
)
# Use single proxy
proxy_config = ProxyConfig(host="127.0.0.1", port=8080, scheme="http")
proxy_manager = ProxyManager(proxies=[proxy_config])
playlist_downloader = PlaylistDownloader(playlist_url, proxy_manager=proxy_manager)
playlist_downloader.download("playlist_videos")- ✅ No yt-dlp dependency
- ✅ Uses YouTube's innertube API
- ✅ Multiple quality options
- ✅ Progress tracking
- ✅ Both CLI and library usage
- ✅ Video and audio formats
- ✅ Fast and lightweight
- ✅ Proxy support (HTTP, HTTPS, SOCKS4, SOCKS5)
- ✅ Proxy rotation to bypass rate limits
- ✅ Automatic failover and health checking
- ✅ Proxy authentication support
- ✅ Playlist download support with parallel downloading
- ✅ Resume support - skips already downloaded videos
- ✅ Configurable concurrency for playlist downloads
ytsnap includes robust proxy support to bypass rate limiting and distribute requests across multiple IPs.
- HTTP/HTTPS proxies
- SOCKS4/SOCKS4A proxies
- SOCKS5 proxies
- Authenticated proxies (username:password)
- ✅ Automatic proxy rotation
- ✅ Health checking and failure tracking
- ✅ Automatic failover on rate limits (429 errors)
- ✅ Support for proxy lists from files
- ✅ Time-based and round-robin rotation
Create a file (e.g., proxies.txt) with one proxy per line:
http://127.0.0.1:8080
https://proxy.example.com:8443
socks5://127.0.0.1:1080
http://username:password@proxy.example.com:8080
# Use proxy file
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" output.mp4 --proxy-file proxies.txt
# Use single proxy
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" output.mp4 --proxy "http://127.0.0.1:8080"
# Use SOCKS5 proxy
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" output.mp4 --proxy "socks5://127.0.0.1:1080"
# Disable health checking
ytsnap "https://www.youtube.com/watch?v=VIDEO_ID" output.mp4 --proxy-file proxies.txt --no-health-checkfrom youtube_downloader import YouTubeDownloader, ProxyManager, ProxyConfig
# Load proxies from file
proxy_manager = ProxyManager.from_file("proxies.txt")
# Initialize downloader with proxy manager
downloader = YouTubeDownloader(url, proxy_manager=proxy_manager)
downloader.download("video.mp4")
# Create custom proxy configuration
proxy_config = ProxyConfig(
host="127.0.0.1",
port=8080,
scheme="http",
username="user", # optional
password="pass" # optional
)
proxy_manager = ProxyManager(proxies=[proxy_config])
downloader = YouTubeDownloader(url, proxy_manager=proxy_manager)
downloader.download("video.mp4")Uses YouTube's official innertube API with Android client credentials to fetch direct CDN URLs without signature decryption complexity.
We welcome contributions! Please see our Contributing Guide for details.
- 🐛 Bug fixes
- ✨ New features
- 📝 Documentation improvements
- 🧪 Test coverage
- 🎨 Code quality improvements
MIT