Back to blog

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

javaspring-bootreactnextjsvideo-streaming
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:

LayerTechnologyTại sao
BackendSpring 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
FrontendNext.js 15 (React 19)SSR cho SEO trên trang public, CSR cho trang app/admin, App Router cho pattern hiện đại
DatabasePostgreSQL 17ACID transaction, relational model hoàn hảo cho course/user/subscription, powerful indexing
CacheRedis 7Lưu JWT refresh token, tracking transcoding progress, cache course catalog
VideoFFmpeg 6Transcoder tiêu chuẩn ngành, HLS output với adaptive bitrate, tạo thumbnail
StreamingNginx + HLSNginx serve video segment trực tiếp từ disk — nhanh, không tốn JVM overhead
PaymentStripeHosted Checkout (PCI-compliant), Customer Portal, webhook-driven subscription lifecycle
AuthSpring Security + JWTAccess/refresh token pattern, OAuth2 client cho Google/GitHub
UI Componentshadcn/ui + Tailwind CSSComponent đẹp, accessible, build trên Radix UI, utility-first styling
DeploymentDocker ComposeDeploy 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_path thay 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_preview trê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_progress và 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_id trê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_link module 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 — @Async vớ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 .ts segment 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ạnhTodo AppE-CommerceVideo Platform
File handlingKhông cóImage uploadUpload video multi-GB + transcoding
StreamingKhông cóKhông cóHLS adaptive bitrate streaming
Async processingKhông cóOrder emailVideo transcoding pipeline
PaymentKhông cóOne-time checkoutRecurring subscription + webhook
Content securityKhông cóKhông cóSigned URL + token validation
Auth complexityCơ bảnTrung bìnhJWT + OAuth2 + subscription gating
InfrastructureSingle serverApp + DBApp + DB + Redis + Nginx + FFmpeg
System designĐơn giảnTrung bìnhProduction-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.