- Kotlin 43.8%
- TypeScript 41%
- Go 10.2%
- CSS 3.9%
- Shell 0.5%
- Other 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| android-app | ||
| android-tv | ||
| backend | ||
| doc | ||
| frontend | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| CHANGELOG.md | ||
| cookies.example.txt | ||
| docker-compose.yml | ||
| Dockerfile | ||
| launch.sh | ||
| LICENSE | ||
| README-SYNOLOGY.md | ||
| README.md | ||
| SECURITY.md | ||
| ship.sh | ||
| start.sh | ||
| stop.sh | ||
| subscriptions-proof.png | ||
| supervisord.conf | ||
| youtube-integration-knowledge.md | ||
🎬 KV-Tube
Your own private, self-hosted, ad-free YouTube portal with Android TV.
Stream 4K videos, skip sponsors, synchronize watch history, and listen in the background without Google tracking.
🌐 Language / Ngôn ngữ: 🇬🇧 English • 🇻🇳 Tiếng Việt
Quick Start • Why KV-Tube? • Features • Architecture • Synology NAS • Star History
⚡ Why KV-Tube?
The official YouTube experience is overwhelmed with unskippable ads, sponsored segments, and opaque recommendation algorithms that harvest your viewing telemetry.
KV-Tube delivers a clean, home-hosted sanctuary for video streaming:
| Capability | 🎬 KV-Tube | 📱 Official YouTube | 🌐 Invidious Web | 🟣 Piped |
|---|---|---|---|---|
| Advertisements | ❌ 100% Ad-Free | ⚠️ Heavy Ads | ❌ Ad-free | ❌ Ad-free |
| Sponsor Skipping | ✅ Built-in SponsorBlock | ❌ No | ⚠️ Instance dependent | ⚠️ Instance dependent |
| Dislike Counts | ✅ Return YouTube Dislike (RYD) | ❌ Removed | ⚠️ Basic | ⚠️ Basic |
| Native Android TV App | ✅ Kotlin Compose + D-Pad | ⚠️ Official TV app | ❌ Web browser only | ❌ Unofficial |
| Background Audio & PWA | ✅ Yes (Screen off playback) | ⚠️ Premium Paywall | ⚠️ Web browser | ⚠️ Web browser |
| Synology 1-Click Setup | ✅ Docker Container Manager | ❌ Cloud only | ⚠️ Complex stack | ⚠️ Complex stack |
| Tracking & Telemetry | Zero Google Tracking | Massive telemetry | Zero | Zero |
🇬🇧 English
On this page: What is KV-Tube? • Features • Quick Start • Synology NAS • How It Works • Data Flow • Other Deployments • Configuration • Apps • Developers
📖 What is KV-Tube?
KV-Tube is a website you host yourself that looks and works like YouTube — but without ads, without tracking, and under your control.
With KV-Tube you can:
- 🔍 Search & watch any YouTube video
- 🔔 Subscribe to channels and get your own feed
- 🚫 Skip ads & sponsors automatically (built-in SponsorBlock)
- 📜 Save watch history on your server — not Google's
- 📱 Watch on phone, TV, tablet via apps or browser
- 🎵 Listen in the background with screen locked
💡 In short: think "Netflix-style YouTube front page, running at home".
✨ Features
| Feature | What it means for you | |
|---|---|---|
| 🎞️ | Adaptive playback | Quality from 144p up to 4K, playback speed, subtitles |
| 🔔 | Subscriptions & channels | Follow any channel, rich channel pages, infinite feed |
| 🔍 | Fast search | Search videos, channels and playlists with filters |
| 📜 | Watch history | Resume where you left off, on every device |
| 🚫 | No ads & no sponsors | SponsorBlock segments skipped, dislike counts shown (RYD) |
| 🎵 | Background audio + PWA | Keep listening when the screen is off, installable as an app |
| 🌓 | Dark / Light / System theme | Trending region selectable per user |
| 📥 | Downloads | Save videos as MP4 — Low (≤360p), Recommended (≤1080p), Best |
| 🔐 | Invidious account sync | Sync subscriptions, feed and history across devices |
| 📱 | Native Android app | Kotlin + Material 3, offline downloads, auto-update |
| 📺 | Native Android TV app | Remote-friendly UI (D-pad), HLS/DASH playback |
🖼️ See all features in detail (click to expand)
- Adaptive Video Playback — HLS and DASH streaming with adaptive quality selector, variable playback speeds and subtitle support.
- Watch History & Feed — Automatically tracked history and a personalized feed, always in sync.
- Subscriptions & Channels — Channel pages with banners, avatars, subscriber counts and infinite-scrolling video lists.
- Full-Text Search — Fast search across videos, channels and playlists with category filter chips.
- Background Audio & PWA — Installable PWA with full-screen experience and offline UI caching.
- Themes & Region Tuning — Dark, Light and System themes; trending region per user (persisted in cookie).
- Comments & Engagement — Real YouTube comments, like/dislike counts via Return YouTube Dislike, automatic segment skipping powered by SponsorBlock.
- Server & Client Downloads — MP4 downloads with live progress and 3 quality tiers.
- Invidious Account Sync — Sync subscriptions, feed and watch history across devices, with import/export support.
- Fast & Self-cleaning — Stream signature decryption via companion, aggressive caching, multi-client fallback, automated temp-file purging.
🚀 Quick Start
One recipe file + one command. That's it.
mkdir -p kv-tube && cd kv-tube
curl -O https://raw.githubusercontent.com/vndangkhoa/kv-tube/main/docker-compose.yml
docker compose up -d
Then open:
| What | Address |
|---|---|
| 🎬 KV-Tube (the website) | http://localhost:3241 |
| 🔌 Invidious API (backend) | http://localhost:7601 |
⚠️ Watching from another device (phone, laptop)? Edit
NEXT_PUBLIC_INVIDIOUS_URLindocker-compose.ymland replace127.0.0.1with your server's IP, e.g.http://192.168.1.10:7601, then rundocker compose up -dagain.
This starts 4 containers that work together (explained below in How It Works).
🖥️ Setting Up on a Synology NAS
Using a Synology NAS? Two options:
| Option | Best for | Guide |
|---|---|---|
| 👶 Beginner guide | First time with Docker, GUI only, no terminal | README-SYNOLOGY.md (bilingual EN/VI) |
| 🛠️ Full guide | Comfortable with SSH, wants HTTPS/reverse proxy, troubleshooting | Main deployment section below |
Quick version for DSM 7.2+:
- Install Container Manager from Package Center
- Create folder
/docker/kv-tubein File Station, putdocker-compose.ymlinside - Container Manager → Project → Create → point to that folder
- Open
http://NAS-IP:3241🎉
(Prefer a native Package Center app? Try the community KV-Tube SPK package.)
🏗️ How It Works (Architecture)
KV-Tube is not one big program. It's 4 small containers cooperating:
| Container | Plain words | Port |
|---|---|---|
| kv-tube-ui | The website you watch on (Next.js) | 3241 |
| invidious | The middleman that talks to YouTube for you (no ads/tracking) | 7601 |
| invidious-db | A small database remembering channels, playlists, tokens | internal |
| companion | Helper that unlocks the real video streams | internal |
(A legacy all-in-one Go backend also exists for single-container setups — see Other Ways to Deploy.)
🔀 Data Flow
flowchart TD
subgraph Clients["Client Applications"]
WEB["Browser / PWA<br/>React 19 + Tailwind"]
MOBILE["Android Mobile App<br/>Compose + ExoPlayer + WorkManager"]
TV["Android TV App<br/>Compose for TV + Media3"]
end
subgraph KVT["KV-Tube Frontend — Next.js 16 (:3241)"]
RSC["Server Components<br/>Home · Watch · Channel · Search · Feed"]
API["API Handlers & Proxies<br/>/api/invidious · /api/download<br/>/api/media-proxy · /api/channel-avatar"]
end
subgraph INV["Invidious Backend Stack (internal network)"]
CORE["invidious Core<br/>(:7601 / internal :3000)"]
DB[("invidious-db<br/>PostgreSQL 16")]
COMP["companion<br/>signature decryptor (:8282)"]
end
YT[("YouTube Servers")]
SB["SponsorBlock API"]
RYD["Return YouTube Dislike API"]
WEB -->|"SSR & client fetch"| KVT
MOBILE -->|"API & stream extraction"| CORE
TV -->|"Direct API / Invidious"| CORE
RSC -->|"Internal HTTP"| CORE
API -->|"Proxy HTTP"| CORE
CORE --> DB
CORE --> COMP
COMP -->|"Signature Decryption"| YT
CORE -->|"Scrapes Metadata & Streams"| YT
WEB -.-> SB
WEB -.-> RYD
MOBILE -.-> SB
Reading the diagram, simply:
- Your device asks kv-tube-ui (the website) for a video
- kv-tube-ui asks invidious behind the scenes
- invidious fetches metadata from YouTube, decrypting stream signatures via companion
- Video plays on your device — ads and tracking never enter the picture
📦 Other Ways to Deploy
Classic All-in-One (single container)
Prefer everything inside one container (Go/Gin backend + Next.js + yt-dlp)? No Invidious needed:
git clone https://github.com/vndangkhoa/kv-tube.git
cd kv-tube
docker build -t kv-tube:latest .
docker run -d -p 3241:3000 -p 8080:8080 -v ./data:/app/data kv-tube:latest
Pre-built Images
| Image | Contents | Use it for |
|---|---|---|
kv-tube-ui (~485 MB) |
Next.js frontend only | The recommended 4-container stack (docker-compose.yml) |
kv-tube (~1.1 GB) |
Frontend + Go backend + yt-dlp + ffmpeg | Classic all-in-one mode |
Available on Docker Hub (vndangkhoa/kv-tube[-ui]:latest), GHCR (ghcr.io/vndangkhoa/...) and Forgejo (git.khoavo.myds.me/vndangkhoa/...).
Source Repositories
- GitHub: https://github.com/vndangkhoa/kv-tube
- Forgejo: https://git.khoavo.myds.me/vndangkhoa/kv-tube
⚙️ Configuration
Most people don't need to change anything. Common tweaks go in docker-compose.yml.
Frontend (kv-tube service / frontend/.env)
| Variable | Default | Meaning |
|---|---|---|
INVIDIOUS_URL |
http://invidious:3000 |
Internal address between containers — leave as-is |
NEXT_PUBLIC_INVIDIOUS_URL |
http://127.0.0.1:7601 |
Where browsers find Invidious. Change 127.0.0.1 to your server IP for other devices to work |
INVIDIOUS_TOKEN / NEXT_PUBLIC_INVIDIOUS_TOKEN |
empty | Optional session token for private feeds/history sync |
NEXT_PUBLIC_SITE_URL |
https://youtube.khoavo.myds.me |
Public site URL (used for share previews) |
NEXT_PUBLIC_SPONSORBLOCK_URL |
https://sponsor.ajay.app |
SponsorBlock API endpoint |
NEXT_PUBLIC_RYD_URL |
https://returnyoutubedislikeapi.com |
Return YouTube Dislike API endpoint |
Trending region defaults to
VN; each user can change it in-app (saved in a cookie).
Legacy Go Backend (backend/.env) — all-in-one mode only
| Variable | Default | Meaning |
|---|---|---|
PORT |
8080 |
Backend listening port |
KVTUBE_DATA_DIR |
./data |
SQLite database + cache folder |
GIN_MODE |
release |
release or debug |
CORS_ALLOWED_ORIGINS |
http://localhost:3000,... |
Allowed origins, comma-separated, or * |
RATE_LIMIT_RATE / _INTERVAL / _BURST |
300 / 1m / 120 |
Per-IP rate limiting |
YTDLP_PROXY |
empty | Optional HTTP/SOCKS5 proxy for yt-dlp |
YTDLP_COOKIES |
empty | Path to cookies.txt (needed for comments, bypasses bot-check) |
FORCE_IPV6 |
unset | 1 force IPv6, 0 disable, unset = auto-probe |
YTDLP_AUTO_UPDATE |
true |
Auto-update yt-dlp daily |
📱 Mobile & TV Apps
Two native Android apps are included (Kotlin + Jetpack Compose):
| App | Highlights | Compatibility |
|---|---|---|
📲 Phone/Tablet (android-app/) |
Material 3, background audio, on-device MP4 downloads (NewPipeExtractor + WorkManager), download manager, auto-update | Android 5.0+ |
📺 Android TV (android-tv/) |
Compose for TV, D-pad remote navigation, HLS/DASH playback, connects to your Invidious instance | Android 7.0+ |
Build them yourself:
cd android-app && ./gradlew assembleDebug # phone APK
cd android-tv && ./gradlew :app:assembleDebug # TV APK
adb install -r app/build/outputs/apk/debug/app-debug.apk
💻 For Developers
./launch.sh dev # frontend + backend with hot reload
./launch.sh prod # production mode
./stop.sh # stop everything
Manual:
cd frontend && npm install && npm run dev # Next.js on :3000
cd backend && go run main.go # Go backend on :8080
💖 Support the Project
KV-Tube is free, open source and ad-free. If it saves you from ads, consider supporting development:
Every contribution helps keep the servers running. Thank you! ❤️
🤝 Contributing
Contributions are always welcome!
- Fork the repository
- Create a branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'feat: add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
Distributed under the MIT License. See LICENSE.
🇻🇳 Tiếng Việt
📖 KV-Tube là gì?
KV-Tube là một trang web bạn tự lưu trữ — nhìn và dùng giống YouTube nhưng không quảng cáo, không theo dõi, và nằm dưới sự kiểm soát của bạn.
Với KV-Tube bạn có thể:
- 🔍 Tìm & xem bất kỳ video YouTube nào
- 🔔 Đăng ký kênh và có bảng tin riêng
- 🚫 Tự động bỏ quảng cáo & phân đoạn tài trợ (tích hợp SponsorBlock)
- 📜 Lưu lịch sử xem trên máy chủ của bạn — không phải của Google
- 📱 Xem trên điện thoại, TV, tablet qua ứng dụng hoặc trình duyệt
- 🎵 Nghe nhạc nền khi khóa màn hình
💡 Tóm gọn: hãy nghĩ "trang YouTube phong cách Netflix, chạy ngay tại nhà".
✨ Tính năng
| Tính năng | Lợi ích cho bạn | |
|---|---|---|
| 🎞️ | Phát video thích ứng | Chất lượng từ 144p đến 4K, đổi tốc độ phát, phụ đề |
| 🔔 | Đăng ký kênh & trang kênh | Theo dõi mọi kênh, feed cuộn vô hạn |
| 🔍 | Tìm kiếm nhanh | Tìm video, kênh, playlist kèm bộ lọc |
| 📜 | Lịch sử xem | Tiếp tục nơi bạn đã dừng, trên mọi thiết bị |
| 🚫 | Không quảng cáo & sponsor | Tự bỏ phân đoạn SponsorBlock, hiện số dislike (RYD) |
| 🎵 | Nhạc nền + PWA | Nghe tiếp khi tắt màn hình, cài như ứng dụng |
| 🌓 | Giao diện Tối / Sáng / Hệ thống | Chọn khu vực thịnh hành theo từng người dùng |
| 📥 | Tải video | Lưu MP4 — Thấp (≤360p), Đề xuất (≤1080p), Tốt nhất |
| 🔐 | Đồng bộ tài khoản Invidious | Đồng bộ đăng ký kênh, feed, lịch sử giữa các thiết bị |
| 📱 | Ứng dụng Android gốc | Kotlin + Material 3, tải offline, tự cập nhật |
| 📺 | Ứng dụng Android TV gốc | Giao diện thân thiện remote (D-pad), phát HLS/DASH |
🚀 Bắt đầu nhanh
Một file công thức + một câu lệnh. Xong.
mkdir -p kv-tube && cd kv-tube
curl -O https://raw.githubusercontent.com/vndangkhoa/kv-tube/main/docker-compose.yml
docker compose up -d
Sau đó mở:
| Cái gì | Địa chỉ |
|---|---|
| 🎬 KV-Tube (trang web) | http://localhost:3241 |
| 🔌 API Invidious (backend) | http://localhost:7601 |
⚠️ Xem từ thiết bị khác (điện thoại, laptop)? Sửa
NEXT_PUBLIC_INVIDIOUS_URLtrongdocker-compose.yml, thay127.0.0.1bằng IP máy chủ, ví dụhttp://192.168.1.10:7601, rồi chạy lạidocker compose up -d.
Lệnh trên khởi động 4 container phối hợp với nhau (giải thích ở phần Kiến trúc).
🖥️ Cài đặt trên Synology NAS
Dùng NAS Synology? Có 2 lựa chọn:
| Lựa chọn | Phù hợp với | Hướng dẫn |
|---|---|---|
| 👶 Hướng dẫn cho người mới | Lần đầu dùng Docker, chỉ cần giao diện, không cần terminal | README-SYNOLOGY.md (song ngữ Anh/Việt) |
| 🛠️ Hướng dẫn đầy đủ | quen SSH, muốn HTTPS/reverse proxy, xử lý lỗi | Phần triển khai bên dưới |
Bản rút gọn cho DSM 7.2+:
- Cài Container Manager từ Trung tâm gói
- Tạo thư mục
/docker/kv-tubetrong File Station, đưadocker-compose.ymlvào trong - Container Manager → Project → Create → trỏ tới thư mục đó
- Mở
http://IP-NAS:3241🎉
(Thích cài như ứng dụng Package Center? Dùng gói KV-Tube SPK do cộng đồng duy trì.)
🏗️ Kiến trúc hoạt động
KV-Tube không phải một chương trình lớn mà là 4 container nhỏ phối hợp:
| Container | Vai trò | Cổng |
|---|---|---|
| kv-tube-ui | Trang web bạn xem video (Next.js) | 3241 |
| invidious | "Người môi giới" thay bạn nói chuyện với YouTube (không quảng cáo/theo dõi) | 7601 |
| invidious-db | Database nhỏ nhớ kênh, playlist, token | nội bộ |
| companion | Trợ giúp mở khóa luồng video thật | nội bộ |
(Vẫn còn backend Go all-in-one cũ cho ai muốn chạy 1 container duy nhất — xem Các cách triển khai khác.)
🔀 Luồng dữ liệu (Data Flow)
Xem sơ đồ chi tiết tại phần tiếng Anh. Tóm tắt đơn giản:
- Thiết bị của bạn gửi yêu cầu tới kv-tube-ui (trang web)
- kv-tube-ui hỏi invidious phía sau
- invidious lấy dữ liệu từ YouTube, giải mã chữ ký stream qua companion
- Video phát trên thiết bị của bạn — quảng cáo và theo dõi không bao giờ xuất hiện
📦 Các cách triển khai khác
All-in-One cổ điển (1 container)
Muốn gói tất cả vào một container duy nhất (backend Go/Gin + Next.js + yt-dlp)? Không cần Invidious:
git clone https://github.com/vndangkhoa/kv-tube.git
cd kv-tube
docker build -t kv-tube:latest .
docker run -d -p 3241:3000 -p 8080:8080 -v ./data:/app/data kv-tube:latest
Image dựng sẵn
| Image | Nội dung | Dùng cho |
|---|---|---|
kv-tube-ui (~485 MB) |
Chỉ frontend Next.js | Stack 4 container được khuyến nghị (docker-compose.yml) |
kv-tube (~1.1 GB) |
Frontend + backend Go + yt-dlp + ffmpeg | Chế độ all-in-one cổ điển |
Có sẵn trên Docker Hub (vndangkhoa/kv-tube[-ui]:latest), GHCR (ghcr.io/vndangkhoa/...) và Forgejo (git.khoavo.myds.me/vndangkhoa/...).
Kho mã nguồn
- GitHub: https://github.com/vndangkhoa/kv-tube
- Forgejo: https://git.khoavo.myds.me/vndangkhoa/kv-tube
⚙️ Cấu hình
Phần lớn người dùng không cần sửa gì. Các chỉnh sửa thường gặp nằm trong docker-compose.yml.
Frontend (service kv-tube / frontend/.env)
| Biến | Mặc định | Ý nghĩa |
|---|---|---|
INVIDIOUS_URL |
http://invidious:3000 |
Địa chỉ nội bộ giữa các container — giữ nguyên |
NEXT_PUBLIC_INVIDIOUS_URL |
http://127.0.0.1:7601 |
Nơi trình duyệt tìm thấy Invidious. Thay 127.0.0.1 bằng IP máy chủ để các thiết bị khác dùng được |
INVIDIOUS_TOKEN / NEXT_PUBLIC_INVIDIOUS_TOKEN |
trống | Token phiên (tùy chọn) cho feed/lịch sử riêng tư |
NEXT_PUBLIC_SITE_URL |
https://youtube.khoavo.myds.me |
URL công khai của site (dùng cho preview chia sẻ) |
NEXT_PUBLIC_SPONSORBLOCK_URL |
https://sponsor.ajay.app |
Endpoint API SponsorBlock |
NEXT_PUBLIC_RYD_URL |
https://returnyoutubedislikeapi.com |
Endpoint API Return YouTube Dislike |
Khu vực thịnh hành mặc định là
VN; mỗi người dùng có thể tự đổi trong ứng dụng (lưu bằng cookie).
Backend Go cũ (backend/.env) — chỉ chế độ all-in-one
| Biến | Mặc định | Ý nghĩa |
|---|---|---|
PORT |
8080 |
Cổng lắng nghe backend |
KVTUBE_DATA_DIR |
./data |
Thư mục SQLite database + cache |
GIN_MODE |
release |
release hoặc debug |
CORS_ALLOWED_ORIGINS |
http://localhost:3000,... |
Origin được phép, cách nhau bởi dấu phẩy, hoặc * |
RATE_LIMIT_RATE / _INTERVAL / _BURST |
300 / 1m / 120 |
Giới hạn tốc độ theo IP |
YTDLP_PROXY |
trống | Proxy HTTP/SOCKS5 tùy chọn cho yt-dlp |
YTDLP_COOKIES |
trống | Đường dẫn cookies.txt (cần cho bình luận, qua màn bot-check) |
FORCE_IPV6 |
bỏ trống | 1 ép IPv6, 0 tắt, bỏ trống = tự dò |
YTDLP_AUTO_UPDATE |
true |
Tự cập nhật yt-dlp hằng ngày |
📱 Ứng dụng Di động & TV
Hai ứng dụng Android gốc đi kèm (Kotlin + Jetpack Compose):
| Ứng dụng | Điểm nổi bật | Tương thích |
|---|---|---|
📲 Điện thoại/Tablet (android-app/) |
Material 3, nghe nền, tải MP4 ngay trên thiết bị (NewPipeExtractor + WorkManager), trình quản lý tải, tự cập nhật | Android 5.0+ |
📺 Android TV (android-tv/) |
Compose for TV, điều khiển D-pad, phát HLS/DASH, kết nối Invidious của bạn | Android 7.0+ |
Tự build:
cd android-app && ./gradlew assembleDebug # APK điện thoại
cd android-tv && ./gradlew :app:assembleDebug # APK TV
adb install -r app/build/outputs/apk/debug/app-debug.apk
💻 Dành cho lập trình viên
./launch.sh dev # frontend + backend có hot reload
./launch.sh prod # chế độ production
./stop.sh # dừng tất cả
Thủ công:
cd frontend && npm install && npm run dev # Next.js ở cổng :3000
cd backend && go run main.go # backend Go ở cổng :8080
💖 Ủng hộ dự án
KV-Tube miễn phí, mã nguồn mở và không quảng cáo. Nếu nó giúp bạn thoát quảng cáo, hãy cân nhắc ủng hộ:
Mỗi đóng góp giúp duy trì máy chủ hoạt động. Cảm ơn bạn! ❤️
🤝 Đóng góp
Mọi đóng góp đều được chào đón!
- Fork repository
- Tạo nhánh mới (
git checkout -b feature/amazing-feature) - Commit (
git commit -m 'feat: add amazing feature') - Push (
git push origin feature/amazing-feature) - Mở Pull Request
🌟 Support & Community
If you find KV-Tube valuable, please consider giving the repository a Star ⭐ to support future development!
📄 Giấy phép
Phân phối theo Giấy phép MIT. Xem LICENSE.
Nếu dự án hữu ích, hãy ⭐ star trên GitHub nhé!
Xây dựng với ❤️ bởi Khoa Vo