Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

4K Video Gallery

A self-hosted video streaming server with a gallery landing page, HTML5 player, YouTube-style Stats for Nerds, and a built-in network speed test.

Features

  • Gallery — responsive dark-themed grid of video cards with real thumbnails extracted from each video
  • Streaming player — HTTP range-request streaming so seek/scrub works at any point without buffering the whole file
  • Stats for Nerds — YouTube-style overlay showing live resolution, buffer health, dropped frames, network throughput chart, file size, host, and playback rate. Toggle with the S key or the Stats button.
  • Speed Test — measures latency (ping/jitter), download speed, and upload speed between the browser and the server, with live sparkline charts and a video quality rating
  • True 4K content — Big Buck Bunny 4K (3840×2160) plus 1080p open-source Blender films

Tech Stack

Layer Choice
Backend Node.js + Express
Frontend Vanilla HTML / CSS / JS (no build step)
Streaming HTTP range requests (206 Partial Content)
Thumbnails ffmpeg frame extraction

Project Structure

video-server/
├── server.js           # Express server — streaming, API, speed test endpoints
├── package.json
├── public/
│   ├── index.html      # Gallery landing page
│   ├── player.html     # Video player + Stats for Nerds overlay
│   ├── speedtest.html  # Network diagnostics page
│   ├── app.js          # Gallery logic
│   ├── player.js       # Player + stats collection
│   ├── speedtest.js    # Ping / download / upload test logic
│   └── styles.css      # All styles (gallery, player, stats panel, speed test)
├── thumbnails/         # JPEG thumbnails (one per video, extracted by ffmpeg)
└── videos/             # MP4 video files (not committed — download separately)

Setup

Prerequisites

  • Node.js 18+
  • ffmpeg (for thumbnail extraction)
  • curl or wget (for downloading videos)

Install

git clone https://github.com/YOUR_USERNAME/video-server.git
cd video-server
npm install

Download Videos

The video files are not committed to the repo (too large). Download the open-source Blender films:

# Big Buck Bunny (720p, ~59 MB)
curl -L -o videos/big-buck-bunny.mp4 \
  "https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4"

# Elephants Dream (720p, ~45 MB)
curl -L -o videos/elephants-dream.mp4 \
  "https://archive.org/download/ElephantsDream/ed_1024_512kb.mp4"

# Tears of Steel (720p, ~73 MB)
curl -L -o videos/tears-of-steel.mp4 \
  "https://archive.org/download/Tears-of-Steel/tears_of_steel_720p.mp4"

# Cosmos Laundromat (1080p, ~146 MB)
curl -L -o videos/cosmos-laundromat.mp4 \
  "https://archive.org/download/cosmos-laundromat-first-cycle/Cosmos%20Laundromat%20-%20First%20Cycle.mp4"

# Big Buck Bunny 4K UHD (3840×2160, ~615 MB)
curl -L -o videos/big-buck-bunny-4k.mp4 \
  "https://archive.org/download/big-buck-bunny-4k-60fps/BigBuckBunny4k60fps.ia.mp4"

Generate Thumbnails

ffmpeg -i videos/big-buck-bunny.mp4     -ss 00:01:30 -vframes 1 -vf scale=640:360 -update 1 thumbnails/big-buck-bunny.jpg     -y
ffmpeg -i videos/elephants-dream.mp4    -ss 00:01:00 -vframes 1 -vf scale=640:360 -update 1 thumbnails/elephants-dream.jpg    -y
ffmpeg -i videos/tears-of-steel.mp4     -ss 00:01:30 -vframes 1 -vf scale=640:360 -update 1 thumbnails/tears-of-steel.jpg     -y
ffmpeg -i videos/cosmos-laundromat.mp4  -ss 00:01:00 -vframes 1 -vf scale=640:360 -update 1 thumbnails/cosmos-laundromat.jpg  -y
ffmpeg -i videos/big-buck-bunny-4k.mp4  -ss 00:01:30 -vframes 1 -vf scale=640:360 -update 1 thumbnails/big-buck-bunny-4k.jpg  -y

Run

npm start
# Server starts at http://localhost:3000

API Reference

Endpoint Description
GET /api/videos JSON list of all video metadata (title, file, thumbnail, resolution, fileSize, available)
GET /videos/:file Streams a video file with range-request support
GET /thumbnails/:file Serves a thumbnail image
GET /api/speedtest/ping Returns {ts, server} for latency measurement
GET /api/speedtest/download?mb=N Streams N MB of test data (max 100 MB)
POST /api/speedtest/upload Accepts a body and returns {bytes, duration}

Stats for Nerds

Open any video and press S (or click the Stats button in the top bar) to toggle the overlay. It updates every second and shows:

Stat Source
Resolution video.videoWidth × videoHeight
Viewport window.innerWidth × innerHeight
Playback Rate video.playbackRate
Buffer Health Seconds of video buffered ahead of current position
Throughput Bytes received via PerformanceObserver → Mbps, color-coded green/yellow/red
Frames video.getVideoPlaybackQuality().totalVideoFrames
Dropped droppedVideoFrames (red if > 0)
File Size From /api/videos metadata
Host window.location.host

A live sparkline chart shows throughput history over the last 60 seconds.

Adding More Videos

  1. Drop an .mp4 file into videos/
  2. Extract a thumbnail with ffmpeg
  3. Add an entry to the VIDEO_METADATA array in server.js
  4. Restart the server

License

Videos are open-source works by the Blender Foundation, licensed under Creative Commons. Server code is MIT.

About

Self-hosted 4K video gallery with streaming, Stats for Nerds, and speed test

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages