Xây Dựng Nền Tảng Video Streaming: Tổng Quan Series

Ai cũng từng xem course trên Udemy, Coursera hay Pluralsight. Click play, video chạy mượt mà, quay lại đúng chỗ dang dở, subscription tự gia hạn hàng tháng. Trải nghiệm đơn giản, đúng không?
Đằng sau sự đơn giản đó là cả một challenge kỹ thuật sâu sắc. Video transcoding, adaptive bitrate streaming, secure content delivery, subscription billing, progress tracking, admin dashboard — một video platform chạm đến backend, frontend, DevOps và payment infrastructure cùng một lúc.
Đó là lý do tại sao nó là project hoàn hảo để build từ đầu. Trong series 15 bài viết này, chúng ta sẽ đi từ một directory trống đến một nền tảng video course tự host, có subscription, deploy lên production, sử dụng Spring Boot, Next.js, FFmpeg, PostgreSQL, Redis và Stripe.
Tại Sao Build Một Video Streaming Platform?
Một video platform là một trong những full-stack project hoàn chỉnh nhất bạn có thể build. Nó cover rất nhiều real-world challenge:
✅ Video processing — transcoding với FFmpeg, HLS adaptive bitrate streaming
✅ Secure content delivery — signed URL, Nginx token validation, chống download
✅ Subscription billing — Stripe Checkout, webhook, subscription lifecycle management
✅ Authentication — JWT token, OAuth2 social login (Google, GitHub)
✅ Database design — course, section, lesson, subscription, progress tracking
✅ Admin dashboard — content management, analytics, user management
✅ Frontend development — custom video player, course catalog, responsive UI
✅ DevOps — Docker Compose, Nginx reverse proxy, VPS deployment
✅ Performance — Redis caching, async processing, CDN-ready architecture
Không giống những toy project, một video platform có những production concern thực sự: Làm sao stream video không bị buffer? Làm sao ngăn truy cập trái phép vào paid content? Xử lý ra sao khi payment fail giữa chừng subscription? Làm sao transcode file upload 2GB mà không block server?
Chúng Ta Sẽ Build Gì?
Kết thúc series này, bạn sẽ có một video course platform hoàn chỉnh với những feature sau:
Core Feature
- Video upload & transcoding — upload file MP4, tự động transcode sang HLS với nhiều quality level (360p, 720p)
- Adaptive streaming — video player tự động chuyển quality dựa trên tốc độ mạng
- Course management — tổ chức nội dung theo course → section → lesson
- Subscription billing — monthly/yearly plan với Stripe, tự động gia hạn
- Progress tracking — xem tiếp video từ chỗ dang dở, theo dõi tiến độ course
User Feature
- Email + social login — đăng ký bằng email/password hoặc đăng nhập qua Google/GitHub
- Course catalog — duyệt, lọc và xem preview course trước khi subscribe
- Free preview — một số lesson có thể xem miễn phí không cần subscription
- Video player — quality selector, playback speed (0.5x–2x), fullscreen, keyboard shortcut
- Account management — xem subscription status, quản lý billing qua Stripe Portal
Admin Feature
- Content dashboard — tạo/sửa/publish course với drag-and-drop sắp xếp lesson
- Video management — upload video, theo dõi transcoding progress, re-upload file lỗi
- User management — xem subscriber, cấp quyền truy cập thủ công, tìm kiếm user
- Analytics — biểu đồ revenue, popular lesson, completion rate, subscriber growth
Tech Stack
Đây là mọi công nghệ chúng ta sẽ dùng và lý do tại sao:
| Layer | Technology | Tại sao |
|---|---|---|
| Backend | Spring Boot 3 (Java 17+) | Framework production-grade với built-in security, async processing, và tích hợp Stripe/OAuth2 tuyệt vời |
| Frontend | Next.js 15 (React 19) | SSR cho SEO trên trang public, CSR cho trang app/admin, App Router cho pattern hiện đại |
| Database | PostgreSQL 17 | ACID transaction, relational model hoàn hảo cho course/user/subscription, powerful indexing |
| Cache | Redis 7 | Lưu JWT refresh token, tracking transcoding progress, cache course catalog |
| Video | FFmpeg 6 | Transcoder tiêu chuẩn ngành, HLS output với adaptive bitrate, tạo thumbnail |
| Streaming | Nginx + HLS | Nginx serve video segment trực tiếp từ disk — nhanh, không tốn JVM overhead |
| Payment | Stripe | Hosted Checkout (PCI-compliant), Customer Portal, webhook-driven subscription lifecycle |
| Auth | Spring Security + JWT | Access/refresh token pattern, OAuth2 client cho Google/GitHub |
| UI Component | shadcn/ui + Tailwind CSS | Component đẹp, accessible, build trên Radix UI, utility-first styling |
| Deployment | Docker Compose | Deploy tất cả 5 service bằng một lệnh (API, web, Postgres, Redis, Nginx) |
System Architecture
Đây là cái nhìn tổng quan về hệ thống chúng ta sẽ build:
Quyết định kiến trúc quan trọng: Nginx serve HLS video segment trực tiếp từ disk. Spring Boot API chỉ tạo signed URL và validate subscription — nó không bao giờ chạm vào video byte thực sự. Điều này giữ cho JVM rảnh tay xử lý API request trong khi Nginx lo phần file serving throughput cao.
Request Flow: Xem Video
Request Flow: Upload & Transcode Video
Database Schema Preview
Đây là schema chúng ta sẽ thiết kế và phát triển dần trong suốt series:
Những design decision quan trọng chúng ta sẽ khám phá:
- Tại sao
video_paththay vì lưu video byte? — video nằm trên disk dưới dạng HLS segment, database chỉ lưu path - Tại sao
is_free_previewtrên lesson? — cho phép một số lesson xem miễn phí không cần subscription, tăng conversion - Tại sao tách
lesson_progressvàcourse_enrollments? — tracking chi tiết từng lesson vs. phần trăm hoàn thành course tổng quan - Tại sao
stripe_subscription_idtrên subscription? — Stripe là source of truth; chúng ta mirror state về local qua webhook
Roadmap Toàn Bộ Series
Bài #1: Tổng Quan Series & Architecture — Bạn đang ở đây
- Tại sao build một video platform
- Quyết định tech stack và trade-off
- System architecture và data flow
- Database schema preview
Phase 1: Project Setup
Bài #2: Project Setup (Spring Boot + Next.js + Docker Compose)
Chủ đề:
- Khởi tạo Spring Boot project với Spring Initializr
- Next.js project với App Router, TypeScript, Tailwind CSS
- Docker Compose cho development (API, web, PostgreSQL, Redis)
- Cấu trúc project và tổ chức module
- Development workflow với hot reload
- Cấu hình environment và profile
Kết Quả Học Tập:
✅ Setup monorepo Spring Boot + Next.js từ đầu
✅ Cấu hình Docker Compose cho multi-service development
✅ Thiết lập cấu trúc project cho ứng dụng full-stack có thể scale
✅ Chạy toàn bộ development stack bằng một lệnh
Phase 2: Authentication
Bài #3: Authentication (JWT + OAuth2 Social Login)
Chủ đề:
- Cấu hình Spring Security cho JWT
- Pattern access token (15 phút) + refresh token (7 ngày)
- Đăng ký và đăng nhập bằng email/password
- Google và GitHub OAuth2 social login
- BCrypt password hashing
- Next.js auth context và protected route
- Token refresh interceptor với Axios
Kết Quả Học Tập:
✅ Implement JWT authentication với Spring Security
✅ Thêm Google và GitHub OAuth2 social login
✅ Build secure token refresh flow
✅ Bảo vệ frontend route dựa trên auth state
Phase 3: Course Data Model
Bài #4: Course & Lesson Data Model (JPA + Flyway Migration)
Chủ đề:
- Thiết kế JPA entity (Course, Section, Lesson relationship)
- Flyway migration script cho schema versioning
- Admin CRUD API cho course, section và lesson
- Slug generation và đảm bảo uniqueness
- Quản lý sort order cho drag-and-drop reordering
- DTO mapping với MapStruct
Kết Quả Học Tập:
✅ Thiết kế JPA entity với relationship đúng chuẩn
✅ Quản lý database schema change với Flyway
✅ Build admin CRUD endpoint với validation
✅ Xử lý sort ordering cho nested content
Phase 4: Admin Dashboard
Bài #5: Admin Dashboard (React + shadcn/ui + Drag-and-Drop)
Chủ đề:
- Next.js admin layout với sidebar navigation
- Course editor form với react-hook-form và Zod validation
- UI quản lý section và lesson
- Drag-and-drop reordering với @dnd-kit
- Course publishing workflow (DRAFT → PUBLISHED → ARCHIVED)
- Bảo vệ admin route với role checking
Kết Quả Học Tập:
✅ Build admin dashboard hoàn chỉnh với shadcn/ui
✅ Tạo form với client-side validation
✅ Implement drag-and-drop content reordering
✅ Xử lý publishing workflow với status transition
Phase 5: Video Upload
Bài #6: Video Upload & Storage
Chủ đề:
- Multipart file upload với Spring Boot (tối đa 2GB)
- File validation (format, size, MIME type)
- Thiết kế storage layout trên VPS disk
- Upload progress tracking
- Admin UI cho video upload với progress bar
- Xử lý upload fail và retry
Kết Quả Học Tập:
✅ Xử lý large file upload với Spring Boot
✅ Validate và lưu trữ video file an toàn
✅ Thiết kế disk storage layout cho video content
✅ Build upload UI với real-time progress
Phase 6: Video Transcoding
Bài #7: Video Transcoding Pipeline (FFmpeg + HLS)
Chủ đề:
- FFmpeg cơ bản: codec, container, bitrate
- HLS (HTTP Live Streaming) format giải thích chi tiết
- Transcoding sang nhiều quality level (360p + 720p)
- Async processing với Spring @Async và ThreadPoolTaskExecutor
- Progress tracking qua Redis (parse FFmpeg stderr)
- Tạo thumbnail với ffprobe
- Error handling và retry cho transcode fail
Kết Quả Học Tập:
✅ Hiểu HLS streaming và adaptive bitrate
✅ Build FFmpeg transcoding pipeline trong Java
✅ Process video async mà không block API
✅ Track transcoding progress real-time
Phase 7: Secure Streaming
Bài #8: Secure Video Streaming (Nginx + Signed URL)
Chủ đề:
- Cấu hình Nginx cho HLS file serving
- Nginx
secure_linkmodule cho token validation - Tạo signed URL trong Spring Boot (MD5 + expiry)
- Cấu hình CORS cho video request
- Cache header cho video segment
- Chống download video trực tiếp
Kết Quả Học Tập:
✅ Cấu hình Nginx serve HLS video segment
✅ Bảo vệ video content bằng signed URL
✅ Validate streaming token tại Nginx layer
✅ Ngăn truy cập trái phép vào paid content
Phase 8: Video Player
Bài #9: Video Player & Progress Tracking (hls.js + React)
Chủ đề:
- HLS playback với hls.js trong browser
- Custom React video player component
- Quality selector, playback speed, fullscreen control
- Resume từ vị trí cuối cùng khi load trang
- Debounced progress saving (mỗi 30 giây)
- navigator.sendBeacon cho progress khi rời trang
- Tự động đánh dấu lesson hoàn thành khi xem >90%
- Course enrollment và progress percentage
Kết Quả Học Tập:
✅ Build custom video player với hls.js
✅ Track và persist watch progress cho từng lesson
✅ Resume playback từ vị trí đã xem
✅ Tính toán course completion percentage
Phase 9: Stripe Integration
Bài #10: Stripe Subscription Integration
Chủ đề:
- Stripe Checkout Session để thu thanh toán
- Webhook handler cho subscription event
- Subscription lifecycle (active → past_due → canceled → expired)
- Stripe Customer Portal cho self-service management
- Access gating middleware (kiểm tra subscription)
- Xử lý grace period cho payment fail
- Testing với Stripe CLI và test mode
Kết Quả Học Tập:
✅ Tích hợp Stripe Checkout cho subscription payment
✅ Xử lý Stripe webhook cho subscription lifecycle
✅ Gate content access dựa trên subscription status
✅ Cho phép user tự quản lý subscription
Phase 10: Course Catalog
Bài #11: Public Course Catalog & SEO
Chủ đề:
- Server-rendered course catalog với Next.js SSR
- Trang chi tiết course với curriculum outline
- Free preview lesson playback cho người chưa subscribe
- generateMetadata() cho Open Graph tag
- JSON-LD structured data (Course schema)
- Sitemap và robots.txt generation
- Responsive catalog grid với filtering
Kết Quả Học Tập:
✅ Build trang public tối ưu SEO với Next.js SSR
✅ Implement free preview lesson để tăng conversion
✅ Thêm structured data cho search engine visibility
✅ Tạo responsive course catalog với filtering
Phase 11: Analytics
Bài #12: Admin Analytics & User Management
Chủ đề:
- Dashboard metric (subscriber, revenue, content stat)
- Biểu đồ revenue với Recharts
- Popular lesson và completion rate analytics
- User management (liệt kê, tìm kiếm, lọc theo subscription)
- Cấp quyền truy cập thủ công cho testing và promotion
- Data table với @tanstack/react-table
Kết Quả Học Tập:
✅ Build admin analytics với aggregation query
✅ Trực quan hóa data với Recharts chart
✅ Tạo user management với search và action
✅ Xử lý manual subscription override
Phase 12: Security
Bài #13: Security & Performance Hardening
Chủ đề:
- Rate limiting trên auth và API endpoint
- HLS AES-128 encryption với FFmpeg
- CORS, CSP và security header
- Redis caching cho course listing (5-min TTL)
- Next.js ISR cho course page
- Email notification (welcome, subscription, expiry reminder)
- Spring Boot Actuator health check
Kết Quả Học Tập:
✅ Tăng cường bảo mật platform chống lại attack phổ biến
✅ Mã hóa video segment bằng AES-128
✅ Cải thiện performance với caching và ISR
✅ Thêm email notification cho event quan trọng
Phase 13: Testing
Bài #14: Testing Strategy (Unit, Integration, E2E)
Chủ đề:
- Unit testing với JUnit 5 + Mockito (service, utility)
- Spring Boot test slice (@WebMvcTest, @DataJpaTest)
- Integration testing với Testcontainers (PostgreSQL, Redis)
- Testing Stripe webhook với mock event
- Frontend testing với Playwright
- Test coverage và CI integration
Kết Quả Học Tập:
✅ Viết unit test cho Spring Boot service
✅ Build integration test với Testcontainers
✅ Test payment webhook mà không tốn tiền thật
✅ Setup end-to-end test với Playwright
Phase 14: Deployment
Bài #15: Deployment & Production (Docker + VPS)
Chủ đề:
- Multi-stage Docker build cho Spring Boot và Next.js
- Production Docker Compose (5 service: API, web, Postgres, Redis, Nginx)
- Nginx SSL với Let's Encrypt và certbot
- Flyway migration trong production
- Deployment script (rsync-based)
- Database backup strategy (pg_dump + off-site storage)
- Monitoring với Spring Boot Actuator
- VPS sizing và ước tính chi phí
Kết Quả Học Tập:
✅ Containerize toàn bộ ứng dụng cho production
✅ Cấu hình Nginx với SSL termination
✅ Deploy lên VPS bằng một script duy nhất
✅ Setup backup và monitoring cho production
Giải Thích Các Quyết Định Architecture
Trước khi bắt đầu code, hãy hiểu một vài quyết định quan trọng:
Tại Sao Spring Boot Thay Vì Express Hay FastAPI?
Spring Boot là Java framework phổ biến nhất trong enterprise. Với một video platform cần xử lý file upload, async transcoding và payment webhook, Spring Boot cho chúng ta:
- Built-in async processing —
@Asyncvới thread pool executor, hoàn hảo cho video transcoding - Spring Security — OAuth2 client, JWT validation, role-based access control có sẵn
- Robust file handling — multipart upload tới 2GB với streaming support
- Stripe SDK — Java SDK chính thức với type-safe webhook handling
- Production-proven — đã được thực chiến cho đúng loại backend workload này
Tại Sao Self-Hosted Video Thay Vì YouTube/Vimeo/Bunny.net?
Third-party video host dễ setup hơn nhưng có trade-off:
- Cost at scale — Bunny.net tính phí theo GB bandwidth; self-hosted có chi phí VPS cố định
- Control — bạn sở hữu content, player và user experience
- Learning — mục đích chính là học cách video streaming hoạt động end-to-end
- Không vendor lock-in — migrate sang bất kỳ infrastructure nào mà không cần re-upload
Với business thực tế, bạn có thể sẽ bắt đầu với third-party host rồi chuyển sang self-hosted khi scale. Chúng ta chọn self-hosted vì đây là learning project.
Tại Sao HLS Thay Vì DASH Hay Progressive Download?
HLS (HTTP Live Streaming) là streaming protocol thống trị:
- Adaptive bitrate — player tự chuyển quality dựa trên tốc độ mạng
- Nginx-native — HLS chỉ là HTTP file serving, không cần media server đặc biệt
- Universal support — chạy trên mọi browser qua hls.js, native trên Safari/iOS
- CDN-friendly — file
.tssegment tĩnh cache hoàn hảo trên bất kỳ CDN nào
DASH (Dynamic Adaptive Streaming over HTTP) về mặt kỹ thuật tương tự nhưng browser support kém hơn. Progressive download (single MP4 file) không thể adapt theo network condition và lãng phí bandwidth.
Tại Sao Stripe Checkout Thay Vì Custom Payment Form?
Stripe Checkout là hosted payment page xử lý:
- PCI compliance — số thẻ không bao giờ chạm server của bạn
- 3D Secure / SCA — strong customer authentication built-in
- Tax calculation — tự động tính thuế ở các region được hỗ trợ
- Mobile-optimized — form thanh toán responsive với Apple Pay / Google Pay
- Subscription management — Customer Portal cho plan change và cancellation
Build custom payment form nghĩa là bạn phải tự xử lý PCI compliance. Với platform nhỏ, Stripe Checkout loại bỏ hoàn toàn một mảng security concern.
Learning Path
Chọn lộ trình phù hợp với mục tiêu của bạn:
Path 1: Backend Developer (Bài 1–10)
Thời gian: 5–6 tuần, 1–2 giờ mỗi ngày
Focus: API design, video pipeline, payment, auth
Bỏ qua các bài frontend nặng (5, 9, 11) và dùng curl hoặc Postman để test API. Path này cover core backend engineering — video transcoding, secure streaming và Stripe integration.
Path 2: Full-Stack Developer (Tất cả 15 bài)
Thời gian: 8–9 tuần, 1–2 giờ mỗi ngày
Focus: Phát triển platform end-to-end
Theo dõi mọi bài theo thứ tự. Bạn sẽ build toàn bộ platform từ Spring Boot API đến Next.js frontend đến VPS deployment.
Path 3: DevOps Focus (Bài 2, 7–8, 14–15)
Thời gian: 2–3 tuần, 1–2 giờ mỗi ngày
Focus: Docker, Nginx, video infrastructure, deployment
Tập trung vào infrastructure — Docker Compose setup, FFmpeg pipeline, Nginx streaming config, testing và production deployment.
Path 4: Payment & SaaS Focus (Bài 1–3, 10–12)
Thời gian: 3–4 tuần, 1–2 giờ mỗi ngày
Focus: Auth, Stripe subscription, analytics
Build auth system, tích hợp Stripe và thêm analytics. Path này cover business logic của SaaS platform — hoàn hảo nếu bạn đang lên kế hoạch build subscription product.
Điều Kiện Tiên Quyết
Trước khi bắt đầu series này, bạn nên thành thạo:
- Java 17+ — class, interface, annotation, lambda, stream
- Spring Boot cơ bản — controller, service, dependency injection, application properties
- React fundamentals — component, hook, state management, API call
- SQL cơ bản — SELECT, INSERT, JOIN, index
- Docker cơ bản — chạy container, Dockerfile (chúng ta sẽ cover Docker Compose chi tiết)
- Git — commit, branch, workflow cơ bản
Mới với Spring Boot? Xem Spring Boot Learning Roadmap và Getting Started with Spring Boot trước.
Mới với React/Next.js? Xem bài React Fundamentals.
Video Platform vs Các Project Khác
Tại sao video platform tốt hơn todo app hay e-commerce site để học?
| Khía cạnh | Todo App | E-Commerce | Video Platform |
|---|---|---|---|
| File handling | Không có | Image upload | Upload video multi-GB + transcoding |
| Streaming | Không có | Không có | HLS adaptive bitrate streaming |
| Async processing | Không có | Order email | Video transcoding pipeline |
| Payment | Không có | One-time checkout | Recurring subscription + webhook |
| Content security | Không có | Không có | Signed URL + token validation |
| Auth complexity | Cơ bản | Trung bình | JWT + OAuth2 + subscription gating |
| Infrastructure | Single server | App + DB | App + DB + Redis + Nginx + FFmpeg |
| System design | Đơn giản | Trung bình | Production-grade architecture thực sự |
Một video platform đủ phức tạp để dạy enterprise engineering skill nhưng đủ tập trung để build trong vài tháng. Nó cũng áp dụng trực tiếp được — nếu bạn muốn launch course platform riêng, bạn đã có sẵn nền tảng.
Tiếp Theo Là Gì?
Trong Bài #2, chúng ta sẽ scaffold Spring Boot API và Next.js frontend từ đầu, kết nối chúng bằng Docker Compose (PostgreSQL, Redis, và tất cả), đồng thời thiết lập cấu trúc project sẽ đồng hành cùng chúng ta xuyên suốt series. Kết thúc Bài #2, bạn sẽ có một development stack chạy được với hot reload trên cả backend và frontend.
Cùng build thứ gì đó thực sự nào.
Series: Xây Dựng Video Streaming Platform
Tiếp theo: Phase 1: Project Setup
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.