aytube
Extract direct YouTube stream URLs — without yt-dlp, pytube, or any external tool.
Fully custom implementation from scratch. Supports video/audio quality selection, cookies, proxies, and automatic rate-limit handling.
Version: 2.1.0 | Python: 3.10+ | License: MIT
Features
- Any URL format — watch, shorts, embed, youtu.be
- Video quality — 4K, 1080p, 720p, 480p, 360p, best, worst
- Audio only — high/medium/low quality (opus, m4a)
- Cookie support — Netscape-format cookies for age-restricted videos
- Proxy support — HTTP/HTTPS proxies
- Automatic retry on rate-limit (429/403/503)
- Modern cipher — AES-128-CTR signature decryption via Node.js worker
- Zero heavy dependencies — only stdlib + Node.js (for cipher only)
- Stream verification — confirms URLs have real bytes
Installation
# From PyPI
pip install aytube
# From source
pip install -e .
Requirements:
- Python 3.10+
- Node.js (for signature cipher decryption on modern YouTube)
Quick Start
from aytube import get_stream_url
# Basic usage
result = get_stream_url("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
print(result.url) # Direct playable stream URL
print(result.quality) # e.g. "2160p"
print(result.size) # File size in bytes
print(result.title) # Video title
# Quality selection
result = get_stream_url(url, quality="1080p")
# Audio only
result = get_stream_url(url, audio_only=True, quality="high")
# With cookies (for age-restricted / rate-limited videos)
result = get_stream_url(url, cookies_file="/path/to/cookies_file")
# With proxy
result = get_stream_url(url, proxy="http://127.0.0.1:8080")
CLI Usage
# List formats
aytube list "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# Download
aytube download "https://www.youtube.com/watch?v=dQw4w9WgXcQ" -q 1080p
# Get stream URL
aytube get "https://www.youtube.com/watch?v=dQw4w9WgXcQ" -q 720p
# Audio only
aytube download "https://www.youtube.com/watch?v=dQw4w9WgXcQ" --audio
# Search
aytube search "lofi hip hop" --max-results 5
# With cookies
aytube download "URL" -c cookies_file -q 1080p
# With proxy
aytube download "URL" -p "http://127.0.0.1:8080"
# Batch download
aytube batch urls.txt -q 720p
# Setup wizard
aytube setup
CLI Options
| Option | Description |
|---|---|
-q, --quality QUALITY |
Quality: best/1080p/720p/480p/360p/audio |
-a, --audio |
Audio only |
-o, --output OUTPUT |
Output file path |
-c, --cookies COOKIES |
Cookies file (Netscape format) |
-p, --proxy PROXY |
HTTP/HTTPS proxy URL |
-f, --format FORMAT |
Format itag (137, 251, etc.) |
-N, --max-results N |
Max search results |
API Reference
get_stream_url(url, cookies_file=None, proxy=None, quality=None, audio_only=False, verify=True, timeout=30)
Extract a playable stream URL from a YouTube video.
Parameters:
url— Any YouTube URL (watch, shorts, embed, youtu.be)quality— Target quality:"1080p","720p","480p","360p","4k","best","worst"audio_only— Return audio-only stream (opus/m4a)cookies_file— Netscape-format cookies for age-restricted videosproxy— HTTP/HTTPS proxy URLverify— Verify URL is accessible before returning
Returns: StreamResult with .url, .quality, .container, .size, .title, .itag
list_formats(url, cookies_file=None, proxy=None)
List all available stream formats with URLs.
get_metadata(url, cookies_file=None, proxy=None)
Get video metadata without extracting stream URL.
download(url, quality="best", audio_only=False, output=None, cookies_file=None, proxy=None)
Download a video to a file.
from aytube import get_stream_url, list_formats, download, get_metadata
# Get stream URL
result = get_stream_url("https://youtube.com/watch?v=VIDEO_ID", quality="1080p")
# List all formats
formats = list_formats("https://youtube.com/watch?v=VIDEO_ID")
# Get metadata
meta = get_metadata("https://youtube.com/watch?v=VIDEO_ID")
print(meta["title"], meta["duration"])
# Download
path = download("https://youtube.com/watch?v=VIDEO_ID", quality="1080p")
Examples
Video Quality Selection
r = get_stream_url(url, quality="1080p")
print(f"1080p: {r.quality} {r.size:,} bytes")
Audio Only
r = get_stream_url(url, audio_only=True, quality="high")
print(f"{r.quality} audio: {r.container} {r.audio_codec} {r.size:,} bytes")
With Cookies
result = get_stream_url(
"https://www.youtube.com/watch?v=VIDEO_ID",
cookies_file="/path/to/cookies_file",
quality="1080p",
)
Batch Processing
urls = ["https://youtube.com/watch?v=ID1", "https://youtube.com/watch?v=ID2"]
for url in urls:
try:
r = get_stream_url(url, quality="720p")
print(f"{r.title[:40]}: {r.size:,} bytes")
except Exception as e:
print(f"Failed: {e}")
How It Works
- URL Parsing — Extracts video ID from any YouTube URL format
- Page Fetch — Downloads watch page HTML with cookie/proxy support. Auto-retries with cookies on HTTP 429/403/503
- Player Response — Parses
ytInitialPlayerResponseJSON from HTML - Cipher Detection — Checks for encrypted
signatureCipherfields - Key Extraction — Extracts AES cipher key from player JS
- Signature Decryption — AES-128-CTR with zero counter (symmetric encrypt=decrypt)
- URL Construction — Builds adaptive format URLs with correct itag and signature
- Quality Selection — Picks best format matching quality preference (prefers mp4 + known sizes)
- Verification — Uses
contentLengthfrom YouTube, falls back to HTTP Range HEAD
Rate Limits
YouTube rate-limits unauthenticated requests. To avoid this:
- Provide
cookies_file— authenticated sessions get higher rate limits - Auto-retry — aytube automatically retries rate-limited requests with cookies
- Innertube fallback — HTML URLs that get 403 automatically fall back to innertube
# Recommended:
result = get_stream_url(url, cookies_file="cookies_file")
Supported Itags
| Itag | Quality | Container | Codec | Type |
|---|---|---|---|---|
| 401 | 2160p | mp4 | av01 | video-only |
| 313 | 2160p | webm | vp9 | video-only |
| 400 | 1440p | mp4 | av01 | video-only |
| 308 | 1440p | webm | vp9 | video-only |
| 299 | 1080p | mp4 | avc | video-only |
| 303 | 1080p | webm | vp9 | video-only |
| 137 | 1080p | mp4 | avc | video-only |
| 248 | 1080p | webm | vp9 | video-only |
| 136 | 720p | mp4 | avc | video-only |
| 247 | 720p | webm | vp9 | video-only |
| 135 | 480p | mp4 | avc | video-only |
| 244 | 480p | webm | vp9 | video-only |
| 18 | 360p | mp4 | avc+mp4a | muxed |
| 134 | 360p | mp4 | avc | video-only |
| 140 | audio | mp4 | mp4a.40.2 | audio-only |
| 251 | audio | webm | opus | audio-only |
| 250 | audio | webm | opus | audio-only |
| 249 | audio | webm | opus | audio-only |
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aytube-2.1.0.tar.gz.
File metadata
- Download URL: aytube-2.1.0.tar.gz
- Upload date:
- Size: 52.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
935033ff52479cdf9ccf5081149f24e2653eb2eeb3170ca36741e2f420a71640
|
|
| MD5 |
20407d9d03b858b09296cc58c5d62325
|
|
| BLAKE2b-256 |
fb7026d76125579339ea9efa048a93bef9b76eac3dc96a6c55dc6e6731cb0e55
|
File details
Details for the file aytube-2.1.0-py3-none-any.whl.
File metadata
- Download URL: aytube-2.1.0-py3-none-any.whl
- Upload date:
- Size: 58.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1695ddfcf59d0a18b48414aaac6cd04cec01e240f0a619b229fa3929474bedc
|
|
| MD5 |
98fbe9c722f51611443f3f7364f82161
|
|
| BLAKE2b-256 |
9d5349bb4088fe7ac382de0ef3b6f5944c01f07e50a0878adc615faa607f63b3
|