
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
asyncyt
Advanced tools
AsyncYT is a fully async, high-performance media downloader for 1000+ websites powered by yt-dlp and ffmpeg.
It comes with auto binary setup, progress tracking, playlist support, search, and clean API models using pydantic.
await‑ready.yt-dlp and ffmpeg automatically if not found, with update support and resume-capable downloads.EncodingConfig model — translated directly into yt-dlp --postprocessor-args flags, no separate FFmpeg process needed.VideoConvertor, ExtractAudio, Merger, VideoRemuxer) depending on your config.VideoInfo results.pydantic model with schema extras and field-level docs.youtu.be, /shorts/, and /embed/ URLs automatically.yt-dlp and ffmpeg (auto-downloaded if not present)pip install asyncyt
import asyncio
from asyncyt import AsyncYT, DownloadConfig, Quality
from asyncyt.exceptions import AsyncYTBase
async def main():
downloader = AsyncYT()
await downloader.setup_binaries()
config = DownloadConfig(quality=Quality.HD_720P)
info = await downloader.get_video_info("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
print(f"Downloading: {info.title}")
filename = await downloader.download(info.url, config)
print(f"Downloaded to: {filename}")
asyncio.run(main())
For more examples check the Examples folder.
AsyncYT exposes a rich EncodingConfig model that gives you full control over how FFmpeg processes your media. It maps directly onto yt-dlp's --postprocessor-args / --ppa flags — no extra FFmpeg invocations.
from asyncyt import AsyncYT, DownloadConfig, Quality, VideoFormat
from asyncyt.encoding import EncodingConfig, VideoEncodingConfig, AudioEncodingConfig
from asyncyt.enums import VideoCodec, AudioCodec, Preset, PixelFormat
config = DownloadConfig(
quality=Quality.HD_1080P,
video_format=VideoFormat.MP4,
embed_metadata=True,
embed_thumbnail=True,
encoding=EncodingConfig(
video=VideoEncodingConfig(
codec=VideoCodec.H264,
crf=20,
preset=Preset.SLOW,
pixel_format=PixelFormat.YUV420P,
),
audio=AudioEncodingConfig(
codec=AudioCodec.AAC,
bitrate="192k",
),
overwrite=True,
),
)
| Field | Type | Description |
|---|---|---|
codec | VideoCodec | FFmpeg video codec (e.g. libx264, hevc_nvenc) |
crf | int (0–63) | Constant Rate Factor — quality vs. size. Mutually exclusive with bitrate. |
bitrate | str | Target video bitrate, e.g. "2M", "800k" |
maxrate | str | Max bitrate cap for VBV, e.g. "4M" |
bufsize | str | VBV buffer size, e.g. "8M" |
preset | Preset | Encoding speed preset (ultrafast … placebo) |
tune | TuneOption | x264/x265 tune (film, animation, grain …) |
pixel_format | PixelFormat | Output pixel format (yuv420p, yuv420p10le …) |
width | int | Output width in pixels (aspect ratio preserved when height omitted) |
height | int | Output height in pixels (aspect ratio preserved when width omitted) |
fps | int | float | Force output frame rate |
extra_args | List[str] | Raw FFmpeg video args appended verbatim |
| Field | Type | Description |
|---|---|---|
codec | AudioCodec | FFmpeg audio codec (e.g. aac, libmp3lame, libopus) |
bitrate | str | Target audio bitrate, e.g. "192k", "320k" |
quality | int (0–10) | VBR quality (codec-specific scale) |
sample_rate | int | Output sample rate in Hz, e.g. 44100, 48000 |
channels | AudioChannels | Output channel layout (MONO, STEREO, SURROUND_5_1 …) |
extra_args | List[str] | Raw FFmpeg audio args appended verbatim |
| Field | Type | Description |
|---|---|---|
video | VideoEncodingConfig | Video encoding settings |
audio | AudioEncodingConfig | Audio encoding settings |
overwrite | bool | Pass -y to FFmpeg to overwrite existing output files |
extra_global_args | List[str] | Raw FFmpeg global args, e.g. ["-threads", "4"] |
Pass any async or sync callable as progress_callback to receive live DownloadProgress updates:
from asyncyt import AsyncYT, DownloadConfig
from asyncyt.basemodels import DownloadProgress
from asyncyt.enums import ProgressStatus
async def on_progress(p: DownloadProgress):
if p.status == ProgressStatus.DOWNLOADING:
print(f"[Download] {p.percentage:.1f}% {p.speed} ETA {p.eta}s")
elif p.status == ProgressStatus.ENCODING:
print(f"[Encode] {p.encoding_percentage:.1f}% fps={p.encoding_fps} speed={p.encoding_speed}")
elif p.status == ProgressStatus.MERGING:
print("[Merging streams...]")
elif p.status == ProgressStatus.COMPLETED:
print("Done!")
downloader = AsyncYT()
await downloader.setup_binaries()
await downloader.download("https://youtu.be/dQw4w9WgXcQ", progress_callback=on_progress)
| Field | Description |
|---|---|
id | Download ID (SHA-256 hash of URL + config) |
url | Download URL |
title | Video title |
status | Current phase (downloading, encoding, merging, remuxing, completed …) |
percentage | Download progress 0–100 |
downloaded_bytes | Bytes downloaded so far |
total_bytes | Total bytes expected |
speed | Download speed string, e.g. "3.20MiB/s" |
eta | Estimated seconds remaining |
encoding_percentage | FFmpeg encode progress 0–100 |
encoding_fps | Frames per second during encoding |
encoding_speed | Encoding speed multiplier, e.g. "2.50x" |
encoding_frame | Current frame being encoded |
encoding_bitrate | Current output bitrate during encode |
encoding_size | Output size so far during encode |
encoding_time | Elapsed encode time as HH:MM:SS.mmm |
results = await downloader.search("Eminem - Mockingbird", max_results=5)
for video in results:
print(video.title, video.url, video.duration)
from asyncyt.basemodels import PlaylistRequest, DownloadConfig
from asyncyt.enums import Quality
request = PlaylistRequest(
url="https://www.youtube.com/playlist?list=PL...",
config=DownloadConfig(quality=Quality.HD_720P),
max_videos=20,
)
response = await downloader.download_playlist(request=request)
print(f"Downloaded {response.successful_downloads} of {response.total_videos}")
print("Failed:", response.failed_downloads)
| Field | Default | Description |
|---|---|---|
output_path | "./downloads" | Output directory (created automatically) |
quality | Quality.BEST | Video quality setting |
audio_format | None | Audio format for extraction |
video_format | None | Video container format |
extract_audio | False | Extract audio only |
embed_subs | False | Embed subtitles in video |
write_subs | False | Write subtitle files |
subtitle_lang | "en" | Subtitle language code |
write_thumbnail | False | Download thumbnail |
embed_thumbnail | False | Embed thumbnail in file |
embed_metadata | True | Embed metadata |
write_info_json | False | Write yt-dlp info JSON |
write_live_chat | False | Download live chat |
custom_filename | None | Custom yt-dlp output template |
cookies_file | None | Path to cookies file |
proxy | None | Proxy URL |
rate_limit | None | Rate limit e.g. "1M" or "500K" |
retries | 3 | Number of retries (0–10) |
fragment_retries | 3 | Fragment retries (0–10) |
custom_options | {} | Extra yt-dlp options as key→value dict |
encoding | None | EncodingConfig for fine-grained FFmpeg control |
| Enum | Values (examples) |
|---|---|
Quality | BEST, WORST, AUDIO_ONLY, VIDEO_ONLY, HD_720P, HD_1080P, UHD_4K, UHD_8K … |
VideoFormat | MP4, MKV, WEBM, AVI, MOV, FLV, GIF |
AudioFormat | MP3, AAC, FLAC, OPUS, OGG, WAV, ALAC … |
VideoCodec | H264, H265, VP9, AV1, H264_NVENC, HEVC_NVENC, H264_QSV … |
AudioCodec | AAC, MP3, OPUS, FLAC, ALAC, AC3, COPY … |
Preset | ULTRAFAST, FAST, MEDIUM, SLOW, VERYSLOW, PLACEBO … |
TuneOption | FILM, ANIMATION, GRAIN, FASTDECODE, ZEROLATENCY … |
PixelFormat | YUV420P, YUV420P10LE, YUV444P, RGB24, RGBA … |
AudioChannels | MONO, STEREO, SURROUND_5_1, SURROUND_7_1 |
ProgressStatus | DOWNLOADING, ENCODING, MERGING, REMUXING, COMPLETED … |
All exceptions extend AsyncYTBase.
| Exception | When raised |
|---|---|
DownloadAlreadyExistsError | A download with the same ID is already running |
DownloadNotFoundError | Attempting to cancel a download that doesn't exist |
DownloadGotCanceledError | A download was cancelled |
YtdlpDownloadError | yt-dlp exited with a non-zero return code |
YtdlpSearchError | yt-dlp search failed |
YtdlpGetInfoError | yt-dlp failed to retrieve video info |
YtdlpPlaylistGetInfoError | yt-dlp failed to retrieve playlist info |
from asyncyt.exceptions import AsyncYTBase, YtdlpDownloadError
try:
await downloader.download(url, config)
except YtdlpDownloadError as e:
print(f"yt-dlp failed (code {e.error_code}):\n{e.output}")
except AsyncYTBase as e:
print(f"AsyncYT error: {e}")
AsyncYT supports 1000+ websites through yt-dlp, including:
See full list of supported sites →
Contributions are welcome! Feel free to open an issue or pull request.
MIT © MahiroX36
FAQs
A fully asynchronous media downloader for 1000+ websites, powered by yt-dlp and FFmpeg
We found that asyncyt demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.