Skip to content

geethakash/srv-stream

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

42 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

srv-stream (Video Manager & Streamer)

A secure personal Media Server, Video Manager, and Streaming application built with a Python (Flask) backend and a React + TypeScript frontend. Styled using Tailwind CSS and powered by the Vidstack Player, it offers native seekable playback, on-the-fly subtitle extraction, and interactive hover seek-previews.

Interface


πŸš€ Introduction

srv-stream is designed to turn any local directory of videos and media files into a self-hosted, streaming platform. Whether running on a home server, NAS, or remote VPS, it indexes your videos, tracks media details dynamically, and serves them with full seekability.

Unlike traditional heavy media servers, srv-stream is highly efficient and lightweight. It relies on standard browser media engine capabilities, utilizing smart server-side helpersβ€”such as FFmpeg for subtitle demuxing, and OpenCV for spatial storyboard generationβ€”to deliver an incredibly premium streaming experience directly in the browser.


✨ Features

🎬 Streaming & Media Experience

  • Native Byte-Range Seeking: Engineered with a custom HTTP byte-range streamer enabling instant seek capabilities in MKV, MP4, and WebM videos without full file buffering.
  • On-the-fly Subtitle Extraction: Dynamically extracts specific internal subtitle tracks (VTT/SRT) from video containers (e.g., MKV) using FFmpeg on demand, serving them instantly to the browser player.
  • Hover-Seek Storyboard Previews: Automatically generates a 10x5 spatial image grid (storyboard.jpg) and a mapping .vtt file (thumbnails.vtt) for hover seek-previews in the video player using OpenCV in a background thread.
  • Premium Vidstack Player: Integrates the state-of-the-art Vidstack Media Player for fluid controls, keyboard shortcuts, quality/track menus, and elegant styling.
  • Track Inspection: Employs ffprobe to scan video containers and index all audio/subtitle streams automatically.

πŸ“‚ File & Directory Management

  • Hierarchical Tree & Browser: Explore files easily using an interactive directory tree sidebar or a visual grid/list content viewer.
  • Full File Operations: Perform full-fledged management tasks directly in the browser: Copy, Move, Rename, and Delete files and directories.
  • Background Thumbnails: Crawls newly added directories in the background, extracting keyframes to generate beautiful video thumbnails without UI blocking.

πŸ“₯ Direct & Remote Upload Engine

  • Local Multi-file Uploader: Drag, drop, and upload multiple video files directly into your active workspace directories.
  • Asynchronous Remote URL Downloader: Pass any direct HTTP download link (along with custom headers, cookies, and SSL bypass toggles) and download media files directly to the server in a background worker thread with real-time status and progress tracking.

πŸ”’ Security & Optimization

  • Token-Based Authentication: All streaming, browsing, file management, and upload endpoints are fully protected using secure token authentication (sent via Cookies, Authorization Header, or query params).
  • Caching Layer: File durations, track layouts, and spatial storyboard images are securely cached in localized .essentials subdirectories, reducing CPU overhead during repeated browsing.

πŸ› οΈ Tech Stack

Backend

  • Python 3.9+ & Flask (Micro-framework)
  • OpenCV (opencv-python) (Frame & storyboard generation)
  • Pillow (PIL) (Image optimization and processing)
  • FFmpeg / FFprobe (Stream inspection and subtitle extracting)
  • Flask-CORS (Secure cross-origin handling)
  • python-dotenv (Environment configuration)
  • Gunicorn (Production WSGI HTTP server)

Frontend

  • React 18 & TypeScript
  • Vite (Next-gen frontend toolchain)
  • Tailwind CSS (Utility-first CSS styling)
  • Vidstack Player (Premium web media player framework)
  • Axios (Promise-based HTTP client)

βš™οΈ Environment Configuration

The application is configured using environment variables. Before running, create a .env file in the root directory:

SECRET_TOKEN=your_secure_random_token_here
ROOT_DIR=/absolute/path/to/your/media/library
PORT=4000

Configuration Details

Variable Description
SECRET_TOKEN Bearer token used to authenticate frontend requests. Keep this strong and private.
ROOT_DIR The base path on the server where all video and audio files are stored. The web app is sandboxed to this folder.
PORT The port the Flask backend will listen on (defaults to 4000 in Docker).

πŸ“¦ Installation & Setup

You can run srv-stream either natively (for local development) or as a containerized stack using Docker.

Method 1: Running Containerized (Docker & Docker Compose) - Recommended

This is the easiest and most robust method because all dependencies (FFmpeg, FFprobe, OpenCV development libraries, Node, and Python) are pre-packaged and configured.

  1. Ensure you have Docker and Docker Compose installed.
  2. Clone the repository and configure your .env file in the project root:
    cp env.exaple .env
    # Edit .env with your desired configuration
  3. Set your /path/outside/rootdir under the volume configuration in docker-compose.yml to match your local media folder.
  4. Run the compose environment:
    docker-compose up -d --build
  5. Open your browser and navigate to http://localhost:4000. Log in using your configured SECRET_TOKEN.

Method 2: Running Locally (Manual Setup)

1. Backend Setup (Python)

  1. Install system dependencies:
    • macOS: brew install ffmpeg
    • Ubuntu/Debian: sudo apt update && sudo apt install -y ffmpeg libgl1-mesa-glx
  2. Create and activate a Python virtual environment:
    python3 -m venv .venv
    source .venv/bin/activate
  3. Install backend dependencies:
    pip install -r requirements.txt
  4. Start the backend:
    python3 server.py

2. Frontend Setup (React & Vite)

  1. Navigate to the frontend folder:
    cd frontend
  2. Install npm packages:
    npm install
  3. For development with Hot Module Replacement (HMR):
    npm run dev
    (Ensure you update the API baseURL or setup a proxy to route /browse, /stream, etc. to the Flask backend running on port 4000)
  4. To build the production frontend bundle served directly by Flask:
    npm run build
    The build files will compile into frontend/dist, which the Flask app is configured to serve automatically at /.

🧬 System Architecture & Under-the-Hood

graph TD
    Client[Browser / Vidstack Player] -->|1. Browse / Tree / Operations| Flask[Flask API Server]
    Client -->|2. Stream Request with Range| Flask
    Client -->|3. Get Subtitle Track index| Flask
    
    Flask -.->|Scan Container| FFprobe[FFprobe Process]
    Flask -.->|Extract Stream on-the-fly| FFmpeg[FFmpeg Process]
    Flask -.->|Async Thumbnailing / Storyboard| OpenCV[OpenCV & Pillow]
    
    FFprobe -->|Metadata JSON| Flask
    FFmpeg -->|WebVTT Stream| Flask
    OpenCV -->|Cached jpg / vtt| Filesystem[(.essentials/ Cache)]
    
    Flask -->|Serve API, Media Chunk, or Subtitles| Client
Loading

1. Byte-Range Seek Streamer

When the browser requests a chunk of video using the Range header (e.g. bytes=1048576-), services/video_services.py intercepts the request. It parses the start and end offsets, dynamically computes content lengths, reads the requested chunk from disk in high-performance blocks (4KB buffers up to a max chunk size of 5MB), and responds with an HTTP 206 Partial Content status. This makes video seeking instantaneous and eliminates buffering lags.

2. Live Subtitle Demultiplexing

Most modern web video engines do not natively parse subtitle formats inside .mkv files. To solve this, srv-stream maps available subtitle track indices via ffprobe. When a subtitle track is activated in the Vidstack UI, the backend runs a subprocess:

ffmpeg -v error -i <video_file> -map 0:<track_index> -f webvtt pipe:1

The output stream is piped dynamically directly into the HTTP response. This extracts subtitles on the fly with zero disk-write footprint.

3. Seek Preview Storyboards

To make seeking interactive, the app implements hover preview sprites:

  1. OpenCV parses the video file and samples 50 frames uniformly distributed throughout the length.
  2. It arranges them in a 10x5 grid and saves a single lightweight image (storyboard.jpg) inside the .essentials cache folder.
  3. It creates a .vtt file (thumbnails.vtt) which maps timeline offsets (e.g. 00:01:20.000 --> 00:01:23.000) to specific spatial coordinates in the image grid (storyboard.jpg#xywh=180,202,180,101).
  4. The Vidstack player reads this VTT file to display accurate, real-time video preview thumbnails on hover.

πŸ“‘ API Endpoints

All endpoints require authentication bearer tokens via:

  • Authorization: Bearer <SECRET_TOKEN> header, OR
  • Auth_token cookie, OR
  • token URL query parameter.
Endpoint Method Description
/browse GET Lists directories and files for a path; triggers async thumbnailing.
/tree GET Generates a full recursive directory tree mapping for the sidebar.
/file/info GET Returns duration, size, metadata, and tracks (audio/subtitles).
/file/delete POST Deletes a list of files or directories.
/file/rename POST Renames a file or folder.
/file/move POST Moves file(s) to a target directory.
/file/copy POST Copies file(s) to a target directory.
/stream GET Streams a video file supporting HTTP Byte-Ranges.
/subtitle GET Dynamically streams a subtitle track extracted as WebVTT.
/storyboard.jpg GET Returns the 10x5 grid storyboard image.
/thumbnails.vtt GET Returns the WebVTT file mapping times to storyboard coordinates.
/thumbnail GET Returns the keyframe preview thumbnail for folder browsing.
/upload POST Uploads local video files to the specified directory.
/upload/remote POST Initiates an async URL download in a background thread.
/upload/remote/status/<id> GET Returns download status, progress, download speed, and size.

πŸ“ License & Notes

  • Make sure ffmpeg and ffprobe are present in your system's PATH.
  • All essential metadata caches (thumbnails, storyboards, track info, durations) are saved as hidden .essentials/ folders inside your media directory. Do not delete them unless you want the server to re-generate the assets.
  • Built with β˜• by geethakash. Feel free to submit pull requests or report issues.

About

a DB-less web based file manager to manage your server multimedia.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors