A minimalist self-hosted Media Server built with Laravel.
Core Features β’ Demo β’ Getting Started β’ Similar Projects
MediaServer is a lightweight, self-hosted media player for your home server (or NAS). It scans your folders, indexes your video and audio files, and serves them through a fast, minimalist web interface.
It was built for people who prefer a YouTube-like browsing experience for their collection of media files with metadata customisation.
Jellyfin is designed primarily for commercial media, is metadata-first and works great for large automatically downloaded libraries. MediaServer is naturally folder-oriented and great for mixed, personal, or highly customised libraries.
Both can serve shows, movies, and music but with different approaches.
| Feature | Jellyfin | MediaServer |
|---|---|---|
| Content Focus | Official metadata-first; built for movies/TV/Music | Folder-first; great for mixed/personal content and TV shows / music |
| Watch History | Only resume + watched flag | Full watch history with timestamps, re-watch counts, total view counts, per-user history, and playback heatmaps |
| Player Experience | Fullscreen; no browsing while playing | YouTube-style; browse folders while watching |
| Libraries | Unified global search | Library-scoped and account based access control |
| Sharing | No shareable URLs for videos/folders/shows | Direct and readable folder/video links with rich open graph previews |
- π₯ Fully custom-built media player (no native browser controls)
- π Folder-based browsing & sharing
- π§ Watch history, view counts and playback analytics
- π¬ Subtitle support (VTT) with auto-extraction from embedded and external SRT / ASS
- π§ Music support with embedded cover art detection
- π΅ Music player with lyrics viewer/editor based on LrcLib
- π Editable metadata for videos, folders, and albums
- π Docker-based deployment with automatic releases
- π Server dashboard for library management and background task queue
- πΌοΈ Open Graph preview generator (Anilist-style)
- π Fully responsive UI with Dark/Light mode
Extended Features
- Custom UI with Keyboard Shortcuts:
k: Play/Pausej/β: Rewind 10sl/β: Fast Forward 10sSHIFT+N: Play NextSHIFT+P: Play Previousm: Mutef: Toggle Fullscreenc: Toggle Lyrics / Captionsp: Toggle playlist (autoplay)
- Playback Features:
- Speed Controls
- Player Statistics
- Ambient Background (toggleable)
- Heatmap Visualisation (after 5+ seeks)
- Watch Party UI Demo (coming soon)
- Auto-Scrolling Lyrics Viewer
- Media Session API Integration
- Share individual videos or folders via URL (
/library/folder?video={id}or/library/{folder-name})
- Video Metadata:
- Thumbnail
- Description
- Tags
- Season/Episode
- Release Dates
- Captions
- Music Metadata:
- Cover
- Description
- Tags
- Disk/Track
- Release Dates
- Lyrics
- Artist
- Album
- Folder Metadata:
- Thumbnail
- Description
- Studio
- Release Dates
- Persistent Metadata Mapping:
- Retains info even if file is moved or renamed when metadata tagging is enabled
- Track view counts (per user and total)
- Filterable watch history
- Future: playback frequency analytics
- Automatic extraction of embedded subtitles (SRT / ASS β VTT)
- Manual extraction of external subtitles next to media (in format
/media/library/folder/{filename}.{lang}.{extension}) - Subtitle size controls in player
- Scanning Job Manager
- Library / Folder Manager
- User Manager
- Server Performance Metrics
MediaServer automatically generates Open Graph images for media and folders, styled similarly to platforms like AniList.
These previews are embedded when sharing links on platforms like:
- Discord
- Twitter / X
- Telegram
Each image includes:
- πΈ Thumbnail from the media or folder
- ποΈ Title, studio, description and metadata (e.g. season, tags, release date)
- π¨ Custom layout designed to look clean and modern
The preview is rendered server-side using Browsershot and cached for performance.
Example:
Sharinghttps://yourserver.com/library/showwill show a rich preview card with folder art and metadata.
β Works even on private, self-hosted domains as long as your Open Graph routes are accessible.
- π Advanced Playback Stats
- Activity
- Most Played (daily, weekly, monthly)
- Personal Favorites
- Average watch time over time
- π Captions/Subtitles Support
- Auto embedded subtitle extraction
- Two-way audio metadata editing (apply deep metadata edits to file)
- Ex/ Artist, Album, Cover-Art, Disk, Track, Year, Composer, Genre
- Real World Ex/ Musicolet Editor
- πΌοΈ Image Extraction / Generation / Upload System
- Implement a better system for image metadata
- Have 3 different levels
- embedded (cover art or auto thumbnails)
- auto (from 3rd party metadata sources)
- user (uploaded / provided via url by the user)
- Download Links
- Must be optional and per library or folder
- Indexing Overhaul
- Media Tagging Cache
- Put tagged media in cache, ideally on a different disk to reduce thrashing and increase speed
- Server Configuration Interface (Tentative Placement)
- Configure Concurrent Process Limits
- Manage global settings
- Scan Frequency
- Cache Location
- Supported File Types
- FFmpeg / ExifTool Settings
- Audio Spectograph Visuals (Low Priority)
- Just for fun
- π¬ Timed Comments (like SoundCloud)
- π User Roles (Admin / Contributor / Viewer)
- π€ User Profiles & Friends System
- Activity Tracker
- Logins / Logouts
- Edits
- Playback Start / Stop / Finish
- Shares
- Deletes
- π Live Sync Playback (Parties)
- In Browser Lyrics Editor/Generator with Playback (currently can only paste in timed lyrics but not generate them)
- Playlists
- Library Manager
- Add libraries in browser via path
- Mount path in docker and then point to it
- Similar to Immich
- Track symbolic links
- Add libraries in browser via path
- π οΈ Refactor Index and Verify Metadata Jobs (MAJOR) (Oldest code in the project)
- Break into service structure with concurrent index jobs
- Simplify metadata extraction and stop storing folder structure in JSON files
- Implement cache disk feature to reduce time taken to tag media
- Make feature domains consistent
libraryinstead ofcategorymediainstead ofvideo(maybe a better name exists)
- Fix date inconsistencies and store everything in the same format / time-zone
Note
The demo is running the latest beta image with static media. User accounts and edits are reset automatically every 15 minutes.
- π Live Demo
- π¦ Docker Image
Below are screenshots of the current webpage on Desktop and Android.
Other Pages
MediaServer can be run via Docker (recommended) or a standard manual installation.
Warning
Use the beta image to get the latest features. The main image is a couple of months behind.
-
Download the latest or beta Docker release ZIP for your platform.
- It includes a
docker-compose.yamlfile that automatically sets up the (latest by default) required images.
- It includes a
-
Unzip it to a folder with generous read/write/execute permissions.
- The server will perform the following in this directory:
- Rewrite your media with embedded UUID's for tracking (ffmpeg copy codec).
- Read and write extracted album art and thumbnails from music and videos.
- Read and write generated preview images.
- Read and write Laravel + NGINX logs.
- Permissions must stay consistent in this folder to prevent server errors.
- The container uses the UID and GID 9999 under www-data.
- The server will perform the following in this directory:
-
Run the startup script (with Docker running) and let it create/copy the required files:
- Windows:
startDocker.bat - Linux/macOS:
sudo bash startDocker.sh
- Windows:
-
Visit
https://app.testin your browser and follow the setup wizard.- You will need to add app.test to your hosts file if you don't have a real url or set your APP_HOST to localhost manually.
- There is a powershell script included to do this automatically.
- On Linux, you are given the command.
- You will need to add app.test to your hosts file if you don't have a real url or set your APP_HOST to localhost manually.
-
Add your media to
./data/media/LIBRARY/FOLDER/VIDEO.MP4- Media must be grouped by a folder (library) and subfolder (folder) in order to show up on the website
- There are certain names that you cannot use for folders or videos such as
- profile
- settings
- history
- dashboard
- log-viewer
- pulse
- horizon
- __debug
- api
- ...
More to come...
Warning
This setup is probably outdated and may need some tinkering to get right. I have since moved to docker for production installations but still use this method on my main instance (Linux).
To set up MediaServer without Docker, youβll need:
- π₯οΈ A web server: Caddy or NGINX
- π§ Backend: PHP 8.3+, PostgreSQL
- π¨ Frontend (for compiling only): Node.js with Vue 3 + Tailwind CSS
- πΌ Media tools: FFmpeg (required), ExifTool (optional)
- π HTTPS: A valid SSL certificate is required to enable certain metadata features
Tip
You can use Laragon to simplify local setup. This will only be available on the host machine.
# 1. Clone the repository
git clone https://github.com/aminnausin/mediaServer.git
cd mediaServer
# 2. Install backend dependencies
composer install
# 3. Install frontend dependencies
npm install
# 4. Set up your database and .env
cp .env.example .env
# Edit the .env file with your PostgreSQL DB info
# Example:
# DB_CONNECTION=pgsql
# DB_HOST=127.0.0.1
# DB_PORT=5432
# DB_DATABASE=mediaServer
# DB_USERNAME=postgres
# DB_PASSWORD=
# 5. Generate Laravel app and reverb keys
php artisan key:generate
php artisan reverb:generate
# 6. Run database migrations
php artisan migrate
# 7. Link storage (for thumbnails, posters, etc.)
php artisan storage:link
# 9. Build frontend assets
npm run build
# 9. Set app domain in .env (required for Sanctum & WebSockets) (6001 for reverb)
# Example:
# APP_URL=https://app.test:8080
# SANCTUM_STATEFUL_DOMAINS=app.test:8080,0.0.0.0:6001,app.test:6001
# SESSION_DOMAIN=app.test
# REVERB_HOST=app.test
# 10. Run the app in development mode
npm run vite:php- π οΈ Operations Guide β Symbolic linking, scanning, metadata jobs, supported formats
Some similar projects that serve the same purpose but were not direct sources of inspiration include:
MediaServer is intended for personal use only. It is designed to help users organise and access their own legally obtained media on a self-hosted server.
This project does not condone or support piracy, and I do not encourage the use of MediaServer for unauthorised distribution or consumption of copyrighted material.
Please respect local laws and content ownership rights when using this software.
















