Lightweight service to download video and audio from YouTube, Instagram, Telegram, TikTok, and more.
π Tech Stack:
- PHP 8 π
- Symfony 7 πΌ
- EasyAdmin 4 π οΈ
- Docker π³
- PostgreSQL π
- Redis π
- RabbitMQ π
- yt-dlp β‘
- p3sdev/php-ytdlp-wrapper π¦
- botman/botman π€
This program is strictly for lawful personal use. You must not use it to download, distribute, or otherwise process copyrighted material without explicit permission from the rights holder. Any use that violates YouTube's terms of service, applicable laws, or thirdβparty rights is prohibited. By using this program, you accept full responsibility for your actions and agree that the authors and contributors are not liable for any misuse or resulting violations.
- π§ Ubuntu 22.04
- π³ Docker 28.5.2
- π¦ Docker compose v2.38.1
- βοΈ GNU Make 4.3
-
Initialize new application:
make init
Remarks: During initialization, all env files (project and Docker) are generated automatically. If they are missing, run
make env-setup. -
Restart application:
make restart
-
Stop application:
make stop
-
Setup database (if needed):
make db-setup
-
Start queue worker (if needed):
make supervisor-start
-
Create admin user by console command:
make docker-php php bin/console app:user-add <username> [password]
-
Run tests:
make test -
Run tests with coverage:
make test-coverage
-
List of all available 'make' commands:
make help -
Useful URLs:
- Health check:
GET http://host.tld/health - Admin dashboard:
GET http://host.tld/admin
Generated during make init (or make env-setup). Defaults below are from docker/.env.example:
- Xdebug:
XDEBUG_INSTALL=false,XDEBUG_MODE=off,XDEBUG_CLIENT_HOST=host.docker.internal,XDEBUG_CLIENT_PORT=9003
Set XDEBUG_INSTALL=true and XDEBUG_MODE=debug in your docker env file (created from docker/.env.example), then restart the stack:
make build
make restart- Initialize:
- Enable the bot in .env.local:
TELEGRAM_BOT_ENABLED=true - Set your bot token:
TELEGRAM_BOT_TOKEN=change_me_please - Set the public host URL:
TELEGRAM_HOST_URL=https://host.tld - Register the webhook:
make telegram-bot-hook
- To remove the webhook:
make telegram-bot-unhook
- Enable the bot in .env.local:
- Commands:
/start - start bot
All API endpoints are prefixed with /api/v1 and require a Bearer token, except the login endpoint.
Request
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "admin@admin.local",
"password": "admin123456"
}
Response
{
"token": "<jwt>"
}
Add the JWT token to the Authorization header:
Authorization: Bearer <jwt>
GET /api/v1/auth/me
Authorization: Bearer <jwt>
JWT is stateless, so logout just tells the client to discard the token:
POST /api/v1/auth/logout
Authorization: Bearer <jwt>
POST /api/v1/download/create
Authorization: Bearer <jwt>
Content-Type: application/json
{
"url": "https://example.com",
"quality": "best" // best|moderate|poor|audio
}
GET /api/v1/source?order=desc
Authorization: Bearer <jwt>
GET /api/v1/source/{id}/download
Authorization: Bearer <jwt>
DELETE /api/v1/source/{id}
Authorization: Bearer <jwt>
All API endpoints are prefixed with /api/v2. The login endpoint returns a JWT plus a refresh token. Use the JWT for authenticated requests. When the JWT expires, call refresh to get a new pair.
Request
POST /api/v2/auth/login
Content-Type: application/json
{
"email": "admin@admin.local",
"password": "admin123456"
}
Response
{
"token": "<jwt>",
"refresh_token": "<refresh_token>",
"refresh_token_expires_at": "2026-01-31T12:00:00+00:00"
}
Add the JWT token to the Authorization header:
Authorization: Bearer <jwt>
Request
POST /api/v2/auth/refresh
Content-Type: application/json
{
"refresh_token": "<refresh_token>"
}
Response
{
"token": "<jwt>",
"refresh_token": "<refresh_token>",
"refresh_token_expires_at": "2026-01-31T12:00:00+00:00"
}
GET /api/v2/auth/me
Authorization: Bearer <jwt>
POST /api/v2/auth/logout
Authorization: Bearer <jwt>
POST /api/v2/download/create
Authorization: Bearer <jwt>
Content-Type: application/json
{
"url": "https://example.com",
"quality": "best" // best|moderate|poor|audio
}
GET /api/v2/source?order=desc
Authorization: Bearer <jwt>
GET /api/v2/source/{id}/download
Authorization: Bearer <jwt>
DELETE /api/v2/source/{id}
Authorization: Bearer <jwt>
- Admin dashboard
- Background video downloads (queues)
- Download statistics counter
- Download status notifications
- Tests coverage
- Health check endpoint
- YouTube cache/cookies optimization (avoid anti-bot detection)
- Telegram bot integration
- REST API implementation
- Playlist special characters fix
- Refactor to services
- Setup automation script
- Own yt-dlp wrapper implementation





