Personal video hosting and streaming platform with a YouTube-style channel experience.
I wanted a place to host and share my own videos without relying entirely on another platform's interface.
Shernan.TV is a personal video platform with channel pages, watch pages, vertical scrolling, comments, likes, embeds, and an admin dashboard for managing uploads.
- Hosts and streams uploaded videos
- Supports adaptive-bitrate HLS playback through Mux
- Includes a YouTube-style channel homepage and watch experience
- Supports a TikTok-style fullscreen vertical video feed
- Lets users like and comment on videos
- Provides embeddable video players for external sites
- Includes an admin dashboard for uploading, editing, deleting, and ordering videos
- Supports Google, LinkedIn, and GitHub authentication
Admin uploads video
↓
Mux direct upload
↓
Video processing
↓
HLS playback asset
↓
Supabase metadata
↓
Shernan.TV
↙ ↓ ↘
Channel Watch Scroll
↓
Embed API
- Built direct video uploads using Mux and
@mux/upchunk - Streamed videos using HLS adaptive-bitrate playback
- Built a custom video player with playback controls, quality selection, fullscreen, and theatre mode
- Added browser-side compression with FFmpeg.wasm for larger uploads
- Built a vertical fullscreen video feed with looping navigation
- Added realtime like and comment counts through Supabase
- Created embeddable video players for use across other websites
- Exposed a public CORS-enabled video API for external surfaces
- Built admin workflows for upload, editing, deletion, ordering, and comment management
Next.js 16 · React · TypeScript · Supabase · PostgreSQL · Mux · HLS · hls.js · FFmpeg.wasm · Vercel
Shernan.TV uses Mux for video upload, transcoding, and HLS delivery.
Video file
↓
Mux upload
↓
Transcoding
↓
Playback ID
↓
HLS stream
↓
AdaptiveVideo
↓
VideoPlayer
The player supports:
- play / pause
- seeking
- volume control
- adaptive quality
- manual quality selection
- fullscreen
- theatre mode
Videos can also be served through a minimal embed route without the surrounding Shernan.TV interface.
Browser
↓
Next.js application
├── Channel
├── Watch
├── Scroll
├── Embed
└── Admin
↓
API routes
├── Videos
└── Mux uploads
↓
Supabase
├── PostgreSQL
├── Authentication
├── Storage
└── Realtime
↓
Mux
├── Upload
├── Transcoding
├── HLS playback
└── Thumbnails
The application stores video metadata and engagement state in Supabase while Mux handles the video processing and playback pipeline.
Repo structure
The main product surfaces are:
app/
├── page.tsx
├── watch/
│ └── [id]/
├── scroll/
│ └── [[...id]]/
├── embed/
│ └── [id]/
├── admin/
│ └── dashboard/
└── api/
├── videos/
└── mux/
├── uploads/
└── assets/
components/
├── AdaptiveVideo.tsx
├── VideoPlayer.tsx
├── EmbedPlayer.tsx
├── WatchContent.tsx
└── VideoCard.tsx
| Route | Purpose |
|---|---|
/ |
Channel homepage with search, filters, and video grid |
/watch/[id] |
Video player, metadata, engagement, comments, and up-next |
/scroll/[[...id]] |
Fullscreen vertical video feed |
/embed/[id] |
Minimal embeddable video player |
/admin/dashboard |
Video and comment management |
Run locally
Install dependencies:
pnpm installStart the development server:
pnpm devOpen:
http://localhost:3000
Environment variables:
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
MUX_TOKEN_ID
MUX_TOKEN_SECRET
NEXT_PUBLIC_SITE_URL
Useful local routes:
http://localhost:3000/embed/VIDEO_ID
http://localhost:3000/api/videos
Implementation notes
The main video records include:
- title
- description
- video URL
- thumbnail URL
- categories
- view count
- like count
- duration
- Mux playback ID
- Mux processing status
- display order
- publish date
- creation date
The application exposes API routes for:
POST /api/mux/uploads
GET /api/mux/uploads/[id]
DELETE /api/mux/assets/[id]
These handle direct upload creation, processing status, and asset deletion.
Shernan.TV also exposes:
GET /api/videos
The endpoint returns ready videos with metadata such as:
- title
- thumbnail
- views
- likes
- comments
- video URL
It is CORS-enabled so external sites can consume the video listing.
Videos can be embedded using:
<iframe
src="https://tv.shernanjavier.com/embed/VIDEO_ID"
width="640"
height="360"
allow="autoplay; fullscreen"
frameborder="0"
></iframe>Supabase
- PostgreSQL
- Google / LinkedIn / GitHub authentication
- thumbnail storage
- realtime likes and comments
Mux
- direct uploads
- video transcoding
- adaptive HLS streaming
- CDN playback
- thumbnail generation
hls.js
- client-side HLS playback
- quality selection
FFmpeg.wasm
- browser-side compression for videos over 50MB