Paste YouTube links or drag local files → get one merged video. Optionally upload the result straight to your YouTube channel.
Merge Video is a self-hosted service with a web UI, Telegram bot, and REST API. It uses a reliable two-pass merge pipeline (normalize → concat) that handles mixed resolutions, codecs, and 50+ files without errors.
| Feature | Description |
|---|---|
| 🔗 YouTube URLs | Paste links — videos downloaded via yt-dlp through residential proxy and merged |
| 📁 Local Upload | Drag & drop files from your computer |
| 🎚️ 3 Quality Modes | Compact (CRF 23), High Quality (CRF 18), Lossless (no re-encode) |
| 📐 Smart Resolution | Auto-detects minimum resolution across files, no upscaling |
| Upload merged result directly to your YouTube channel via OAuth | |
| 📧 Email Notifications | Status updates via Gmail API (start, success, error) |
| 🤖 Telegram Bot | Send URLs → pick quality → get result in chat |
| 📱 Mobile-Friendly | Responsive web UI, works on any device |
git clone https://github.com/maximosovsky/merge-video.git
cd merge-video/backend
cp .env.example .env
pip install -r requirements.txt
uvicorn main:app --port 8000Open http://localhost:8000 in your browser.
🤖 Run Telegram Bot
cd bot
cp .env.example .env
pip install -r requirements.txt
python main.py⚙️ Environment Variables
cp .env.example .env| Variable | Description | Required |
|---|---|---|
GOOGLE_CLIENT_ID |
OAuth2 client ID | Yes |
GOOGLE_CLIENT_SECRET |
OAuth2 client secret | Yes |
GOOGLE_REDIRECT_URI |
OAuth2 callback URL | Yes |
BASE_URL |
Backend public URL | Yes |
BOT_TOKEN |
Telegram bot token | Bot only |
BACKEND_URL |
Backend URL for bot API calls | Bot only |
PROXY_URL |
SOCKS5h residential proxy for YouTube downloads | YouTube mode |
| Layer | Technology |
|---|---|
| Backend | Python 3.11, FastAPI, uvicorn |
| Video download | yt-dlp + PySocks (via residential proxy) |
| Video merge | ffmpeg (two-pass: normalize → concat demuxer) |
| YouTube upload | google-api-python-client, OAuth2 |
| Gmail API (OAuth2) | |
| TG Bot | aiogram 3 (polling mode) |
| Website | HTML, CSS, vanilla JS |
| Bot deploy | Fly.io Free Tier |
| Backend deploy | Alibaba ECS Singapore |
merge-video/
├── backend/
│ ├── main.py # FastAPI app + static serving
│ ├── video.py # Download → normalize → merge
│ ├── auth.py # YouTube/Gmail OAuth2
│ ├── jobs.py # Async job queue
│ └── config.py # Environment config
├── bot/
│ ├── main.py # Telegram bot (polling)
│ ├── Dockerfile # Fly.io container
│ └── fly.toml # Fly.io config
├── site/
│ ├── index.html # Landing + merge app (SPA)
│ └── style.css # Mobile-first styles
└── deploy/
├── nginx.conf # Reverse proxy
├── merge-video.service # Backend systemd unit
└── setup.sh # VPS setup script
- Two-pass merge pipeline
- YouTube upload via OAuth
- Email notifications (Gmail API)
- Telegram bot (Fly.io)
- Backend deploy (Alibaba ECS)
- DNS —
merge-video.osovsky.com - SSL — certbot + HTTPS
- Google Console — production redirect URIs
- Telegram Bot — connected to production backend
- Residential proxy (Decodo) for YouTube downloads
- End-to-end production test (YouTube URLs → proxy → merge → upload → email)
Fork → feature/name → PR
Maxim Osovsky. Licensed under MIT.