Production-ready FastAPI service for extracting media links from YouTube, Instagram, TikTok, and other supported sources.
- FastAPI-based async API
yt-dlpas the main universal extractor- Smart routing by URL
- Instagram priority chain:
instaloader -> gallery-dl -> yt-dlp - TikTok priority chain: custom no-watermark provider ->
yt-dlp - Standardized JSON response for every supported platform
- Streaming proxy endpoint for hotlink-protected media
- SEO-friendly web UI with animated landing pages
- Release-friendly file logging
GET /extract and POST /extract always return the same success shape:
{
"status": "success",
"provider": "youtube",
"metadata": {
"title": "Video title",
"author": "Channel name",
"duration": "03:33",
"thumbnail": "https://img.youtube.com/vi/.../maxresdefault.jpg",
"description": "Short description..."
},
"media": {
"video_mp4": [
{
"quality": "1080p",
"url": "https://...",
"size_bytes": 450892100,
"extension": "mp4",
"has_audio": false
}
],
"audio_only": [
{
"quality": "128kbps",
"url": "https://...",
"ext": "m4a",
"size_bytes": 12500000
}
],
"images": [],
"subtitles": [
{
"lang_code": "en",
"language": "English",
"url": "https://...",
"format": "vtt"
}
]
},
"config": {
"proxy_required": true,
"headers": {
"User-Agent": "Mozilla/5.0...",
"Referer": "https://www.youtube.com/"
},
"expires_at": 1711568647
}
}Release mode hides raw upstream extractor messages from clients.
{
"status": "error",
"code": "media_not_found",
"message": "Video topilmadi.",
"provider": "instagram",
"attempts": [],
"details": {}
}Full internal errors are written to error.txt.
GET /
Animated web UI for end users. Users can paste a media URL and instantly see available quality options, audio-only files, subtitles, images, and release-friendly errors.
SEO landing pages are also available:
/youtube-video-downloader/instagram-downloader/tiktok-video-downloader/facebook-video-downloader/x-video-downloader
SEO helper routes:
/sitemap.xml/robots.txt
GET /health
Health check.
GET /extract
Query params:
urlrequiredinclude_rawoptional, defaultfalse
Example:
curl "http://127.0.0.1:8000/extract?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ&include_raw=false"POST /extract
Example:
curl -X POST "http://127.0.0.1:8000/extract" \
-H "Content-Type: application/json" \
-d "{\"url\":\"https://www.instagram.com/p/XXXXXXXXXXX/\",\"include_raw\":false}"GET /stream
Proxy media through this server without saving the file to disk.
Examples:
curl -L "http://127.0.0.1:8000/stream?url=https%3A%2F%2Fwww.tiktok.com%2F%40user%2Fvideo%2F1234567890&item_index=1" -o media.bincurl -L "http://127.0.0.1:8000/stream?media_url=https%3A%2F%2Fcdn.example.com%2Fvideo.mp4&referer=https%3A%2F%2Fexample.com%2Fpost%2F1" -o media.binapp/main.pyFastAPI app, middleware, exception handlersapp/services/router.pysmart route selection and fallback chainapp/services/ytdlp_base.pysharedyt-dlpextraction logicapp/services/youtube_extractor.pygenericyt-dlpextractorapp/services/instagram_extractor.pyInstagram extractor chainapp/services/tiktok_extractor.pyTikTok extractor chainapp/services/response_mapper.pystandardized API mapping layerapp/services/stream_proxy.pystreaming proxy serviceapp/services/errors.pyerror classification and public error shapingapp/logging_config.pyrequest and error file loggers
Create .env from .env.example.
Important values:
DEBUG=falseREQUEST_TIMEOUT_SECONDS=20TIKTOK_API_BASE=https://www.tikwm.com/api/INSTAGRAM_SESSIONFILE=optionalINSTAGRAM_USERNAME=optionalINSTAGRAM_PASSWORD=optionalHTTP_USER_AGENT=optional custom user agent
Windows PowerShell:
python -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txtLinux/macOS:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtDo not use --reload for release.
Windows PowerShell:
.\.venv\Scripts\uvicorn app.main:app --host 0.0.0.0 --port 8000Linux/macOS:
./.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000Swagger UI:
http://127.0.0.1:8000/docs
Web UI:
http://127.0.0.1:8000/
Two log files are created in the project root:
log.txtevery incoming requesterror.txtfull internal extractor and server errors
This means clients only see clean public messages such as Video topilmadi., while the full upstream error remains available on the server.
- Some Instagram posts require authentication even when the URL itself is valid
- Signed CDN URLs may expire, so clients should use the response quickly
config.proxy_required=truemeans the safer option is using/streamDEBUGshould remainfalsein production
- Create
.env - Keep
DEBUG=false - Install dependencies from
requirements.txt - Start with
uvicorn app.main:app --host 0.0.0.0 --port 8000 - Verify
/health - Verify logs are being written to
log.txtanderror.txt
If you have any questions, feedback, or just want to say hi, feel free to reach out:
If you find this project helpful and want to support its further development, you can buy me a coffee:
Ethereum Network:
0x76b0c5ec2De0A7173bcf49839f331683dAe4E941
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.
Give a βοΈ if this project helped you!