Skip to content

Repository files navigation

VibeStream

A self-hosted video streaming server for personal media libraries. Stream your MKV, MP4, and AVI files from anywhere with real-time FFmpeg transcoding, rich metadata from TMDB/iTunes/TVmaze, and simple PIN-based device authentication.

🎬 Your media. Your server. Your rules. A complete, self-hosted streaming stack that runs anywhere Docker does — no accounts, no cloud, no telemetry.

🐳 One-command deploy  •  ⚡ GPU-accelerated  •  📦 Zero build step  •  🏠 100% self-hosted

✨ Features

🎥 Streaming & Playback

  • 🎞️ Real-time transcoding of MKV, MP4, AVI, and MOV with FFmpeg — no pre-conversion, ever
  • GPU acceleration (Intel VA-API / QuickSync, AMD, and NVIDIA NVENC) with automatic software fallback
  • 📺 Adaptive quality on the fly: native → 720p → 480p → 240p → 144p → audio-only
  • 🔊 Smart audio — 5.1 sources downmixed to clear stereo so dialogue never gets lost
  • 💬 On-the-fly subtitles extracted to WebVTT straight from the source file
  • ⏯️ Resume & continue-watching with watch history synced across every device

🗂️ Library & Metadata

  • 🖼️ Gorgeous poster wall with auto-detected Movies, Shows, and Anime libraries
  • 🧠 Triple-source metadata scraping — TMDB → iTunes → TVmaze fallback, posters and all
  • 🔎 Instant search, sort, and season grouping for libraries of any size
  • 🧑‍🤝‍🧑 Actor tagging with one-click "more from this actor" discovery

⬇️ Get More Content

  • 🎬 Trailer & video downloaders built in: TMDB trailers, YouTube channels (via yt-dlp), and Archive.org
  • 🧩 Browser extension to send downloadable videos straight into your library
  • 🤖 Optional AI upscaling through a remote GPU worker (Real-ESRGAN x4)

🔐 Access & Security

  • 📟 PIN-based device pairing with a custom JWT implementation — grant or revoke per device
  • 🔒 HTTPS out of the box with an auto-generated self-signed certificate
  • ⌨️ Fully keyboard-driven — power-user fast, mouse entirely optional

🚀 Built for Self-Hosting

  • 🐳 Deploy in one command with Docker Compose
  • 📦 No build step, no framework — server-rendered HTML and vanilla JS
  • 🏠 Truly yours — no accounts, no cloud dependencies, no phoning home

Quick Start

The fastest way to run VibeStream is Docker — it bundles every dependency:

docker compose up -d --build

Open http://localhost:3000 and enter the device PIN from docker compose logs -f vibestream. See Run with Docker for volumes, ports, and GPU acceleration.

Run without Docker

Requires Node.js 18+, FFmpeg/FFprobe in PATH, and optionally yt-dlp for YouTube downloads.

npm install
node server.js

Open http://localhost:3000. A device PIN will print to the console on first visit.

Environment Variables

Variable Default Description
PORT 3000 HTTP listen port
HTTPS_PORT 443 HTTPS listen port (self-signed cert auto-generated)
VIDEO_DIR ./videos Media library root
DATA_DIR ./.appdata Settings, device tokens, JWT secret
HWACCEL (unset) GPU encoder: vaapi, qsv, or nvenc. Unset = software. See GPU Acceleration

Configuration

All runtime configuration is done through the web UI at /settings:

  • TMDB API Key — Get a free key at themoviedb.org
  • Storage paths — Visible on the settings page to confirm mount points
  • Device management — Grant/revoke device access

Run with Docker (recommended)

The included docker-compose.yml builds the image from source and runs it — no registry or external image needed. From the project root:

docker compose up -d --build

Then open http://localhost:3000. On first visit a device PIN prints to the container log — grab it with docker compose logs -f vibestream and enter it to register your browser.

The compose file ships with sensible defaults:

Setting Default Notes
Media library ./videos/data/videos Change the left side to point at your media folder
App data ./appdata/data/appdata Settings, device tokens, metadata cache, TLS certs
HTTP host 3000 Plain HTTP
HTTPS host 8443 Self-signed cert auto-generated on first run

The image bundles FFmpeg, yt-dlp, and the Intel VA-API drivers, so transcoding and downloads work out of the box. By default it uses software encoding, which runs anywhere. To use a GPU, see below.

Common commands:

docker compose logs -f vibestream   # view logs (and the first-run PIN)
docker compose restart vibestream   # restart
docker compose down                 # stop and remove the container
docker compose up -d --build        # rebuild after pulling new code

GPU Acceleration

Hardware transcoding is optional. Leave it off and VibeStream encodes in software — correct everywhere, just heavier on CPU. To offload encoding to a GPU, you set the HWACCEL environment variable and pass the GPU into the container. Both steps are pre-wired (commented out) in docker-compose.yml.

Supported HWACCEL values:

Value Hardware FFmpeg encoder
(unset) none — software libx264
vaapi Intel iGPU / AMD GPU (VA-API) h264_vaapi
qsv Intel QuickSync h264_qsv
nvenc NVIDIA GPU h264_nvenc

If a GPU is requested but the encode test fails at startup, VibeStream logs a warning and automatically falls back to software — it will not crash.

Intel / AMD (VA-API or QuickSync)

In docker-compose.yml, uncomment the HWACCEL line and the /dev/dri passthrough block:

environment:
  - HWACCEL=vaapi          # or: qsv
# ...
devices:
  - /dev/dri:/dev/dri
group_add:
  - "44"    # 'video'  group GID — run on host: getent group video
  - "104"   # 'render' group GID — run on host: getent group render

The group_add GIDs must match your host. Run getent group video and getent group render and substitute the numbers you get back.

NVIDIA

Install the NVIDIA Container Toolkit on the host, then uncomment the HWACCEL=nvenc line and the deploy.resources block:

environment:
  - HWACCEL=nvenc
# ...
deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          count: 1
          capabilities: [gpu]

Apply any of these with docker compose up -d. Confirm the GPU is active in the logs:

docker compose logs vibestream | grep hwaccel

You should see your accelerator verified (e.g. [hwaccel] VAAPI h264 encoding verified) rather than not set (software encoding).

Running on bare metal

The Run without Docker steps cover a plain Node.js install. GPU acceleration works there too — export HWACCEL before starting (e.g. HWACCEL=vaapi node server.js), provided the matching FFmpeg drivers are installed on the host.


Developer Reference

Architecture

Single-process Node.js/Express server with server-rendered HTML pages. No frontend build step, no framework. The entire backend is organized as:

server.js               Entry point — Express setup, middleware, route registration
lib/
  config.js             Paths, env vars, path resolution
  theme.js              CSS theme variables and SVG assets
  settings.js           JSON file persistence for settings and device access
  auth.js               JWT implementation (no library), auth middleware
  utils.js              Filename parser, formatters, directory type detection
  ffmpeg.js             FFprobe metadata extraction
  scrapers.js           TMDB, iTunes, TVmaze metadata scrapers
  downloads.js          Download source definitions (TMDB trailers, YouTube, Archive.org)
routes/
  auth-routes.js        Login page, PIN registration, device management API
  settings-routes.js    Settings page and API
  api-routes.js         Library scan, metadata CRUD, file management
  download-routes.js    Download search/start/cancel, YouTube channels
  native-api-routes.js  JSON API (/api/library, /api/file, /api/recent)
  stream-routes.js      FFmpeg piped streaming, HLS, subtitle extraction
  player-page.js        Video player page with Video.js
  library-page.js       Library browser with grid layout, sorting, search, download modal

Data Storage

$VIDEO_DIR/
  Movies/               Library directories (type set via UI dropdown or .library marker)
  Shows/
  .metadata/            Cached .meta (JSON) and .png (poster) files, keyed by base64url path

$DATA_DIR/
  settings.json         TMDB key, JWT secret, YouTube channels
  access.json           Registered devices

Streaming

  • Web browsers receive a piped fragmented MP4 stream from FFmpeg (/stream/:id)
  • HLS is also available (/hls/:id/stream.m3u8) for clients that can't handle piped HTTP streams
  • Audio is downmixed to stereo (-ac 2) for proper center channel (dialogue) from 5.1 sources
  • HLS sessions are cached and restarted when stream parameters change

Keyboard Shortcuts

Library: S (search), arrows (navigate), Enter (open), Esc (back/home), I (info), E (edit title), D (download), U (upload), C (new folder), L (scan), R (refresh), O (cycle sort), Shift+O (toggle sort direction), Del (delete)

Download Modal: arrows (navigate results), Enter (download selected / search from input), Space (preview thumbnail), O (cycle sort), Shift+O (toggle sort direction), Esc (close)

Player: Space (play/pause), Left/Right (seek), Up/Down (volume), F (fullscreen), M (mute), T (theater), A (aspect ratio), C (crop), I (info), B (stats), Esc (back)

License

ISC

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages