Oblecto is a self-hosted media server for the movies and TV shows you already own. It indexes your folders, fetches metadata and artwork, and streams to its own web app and to Jellyfin apps.
- Movie and TV libraries, identified and kept up to date in the background.
- Metadata and artwork from TMDb, TVDB and fanart.tv, with cast and crew, person pages and related titles. Oblecto ships with the project's API keys; you can use your own.
- A web app with browsing, search, continue watching, a full player and remote control of other devices. Progress and library changes show up as they happen.
- Direct play, and on-the-fly conversion to HLS with FFmpeg when a device needs it.
- A Jellyfin-compatible API on port 8096, so Jellyfin apps on phones, TVs and desktops can sign in, browse, keep favourites and play.
- Accounts with groups and permissions, per-user preferences and avatars, and an optional profile picker on the local network.
- A problem files page for anything that could not be identified or read, with retry.
- Optional federation between Oblecto servers, with mutual pairing, library synchronization and remote playback, plus seedbox import.
Planned for later releases: favourites, a watchlist and ratings in the web app, editing metadata by hand, subtitle files beside the video, automatic library scans, and music. See PLAN.md.
Oblecto needs Node.js 24 or newer, FFmpeg, and guessit (python3-guessit on Debian and Ubuntu, or pip install guessit).
npm install -g oblecto
oblecto init # writes /etc/oblecto/config.json with a random secret
oblecto adduser USERNAME - "Your Name" you@example.com Administrators
oblecto startoblecto adduser asks for the password when you pass -. Then open http://localhost:8080 and sign in. Add your library folders under Settings.
With SQLite, Oblecto uses the native sqlite3 module when its binary is installed, and Node's built-in node:sqlite otherwise. The native module keeps the server responsive during long queries, which matters for large libraries. npm 12 skips the step that installs its binary, so to get it, allow that step:
npm install -g --allow-scripts=sqlite3 oblectoThe startup log says which one is in use. Installs from a checkout and the Docker image get the native module on their own.
To keep your data somewhere else, run oblecto init --config-dir DIR and set OBLECTO_CONFIG_PATH=DIR/config.json for every later command.
contrib/oblecto.service runs Oblecto as its own user under systemd. The install steps are at the top of that file.
docker run -d --name oblecto \
-p 8080:8080 -p 8096:8096 \
-v oblecto-data:/etc/oblecto \
-v /path/to/movies:/movies:ro \
-v /path/to/shows:/shows:ro \
ghcr.io/robinp7720/oblecto
docker exec -it oblecto oblecto adduser USERNAME - "Your Name" you@example.com AdministratorsThe first start writes a config into the /etc/oblecto volume. Everything Oblecto keeps lives there: config, SQLite database, artwork and logs.
Oblecto reads OBLECTO_CONFIG_PATH, or /etc/oblecto/config.json. Anything the file leaves out takes its default from res/config.json. Most settings can be changed in the web app under Settings.
| Setting | What it does |
|---|---|
server.port |
Web app and API port (8080) |
jellyfin.enabled, jellyfin.port, jellyfin.host |
The Jellyfin-compatible API (on, 8096, all interfaces) |
jellyfin.serverName, jellyfin.loginDisclaimer, jellyfin.customCss |
What Jellyfin apps call the server (Oblecto), text under their sign-in form, and extra CSS for the Jellyfin web client. Settings → Jellyfin apps in the web app edits these and the three above; administrators can also change the first three from a Jellyfin app's dashboard |
database |
sqlite with storage for the file, or mariadb/mysql with host, username, password and database |
database.migrateOnStart |
Update the database schema when Oblecto starts (on) |
movies.directories, tvshows.directories |
Library folders |
themoviedb.key, tvdb.key, fanart.tv.key |
Metadata and artwork API keys (the project's, unless you set your own) |
authentication.secret |
Signs sign-ins; oblecto init generates it |
authentication.tokenLifetimeDays |
How long a web sign-in lasts (30) |
authentication.profilePicker, localPasswordlessLogin, allowPasswordlessLogin |
Sign-in without typing a username or password on the local network (all off) |
authentication.localSubnets, trustProxy |
What counts as the local network, and whether to trust X-Forwarded-For |
server.corsOrigins |
Other web origins allowed to call the APIs from a browser (none) |
logging |
Log directory (beside the config file), level, maxSizeMB, maxFiles |
indexer.runAtBoot, cleaner.runAtBoot |
Scan the libraries, or clean up missing files, at every start (off) |
queue.concurrency |
How many background jobs (identifying, metadata, artwork) run at once (1) |
files.doHash, fileExtensions.video |
Hash files to find duplicates (on), and which extensions count as video |
ffmpeg.pathFFmpeg, ffmpeg.pathFFprobe |
FFmpeg and ffprobe to use, if not the ones on PATH |
streaming.trickplay, streaming.trickplayInterval, streaming.detectSegments |
Generate seek thumbnails (on), every 10 seconds (1–60); detect intro/credit segments (on). Existing libraries: Settings → Maintenance → Analyse playback |
streaming, transcoding |
Playback cache, encoder limits and hardware encoding; see docs/STREAMING.md |
assets, artwork |
Where artwork, avatars and seek thumbnails (assets.trickplayLocation) are stored, and the sizes artwork is scaled to |
federation, seedboxes |
Federation with other Oblecto servers (docs/FEDERATION.md) and seedbox imports |
web.enabled |
Serve the web app (on) |
Oblecto refuses to start without a config file or a signing secret, and says why.
The first start creates two groups. Administrators may change settings, manage users and libraries, and run maintenance. Users may watch. Put people in groups on the Users settings page, or from the command line:
oblecto usergroup USERNAME AdministratorsOblecto will not delete or demote the last administrator.
oblecto start | start-tui Run the server, or with a terminal dashboard
oblecto init [--config-dir DIR] Write a config, artwork folders and federation keys
oblecto init database | assets Create just the database, or just the artwork folders
oblecto migrate [--status] Update the database (also runs at start)
oblecto adduser USERNAME - NAME EMAIL [GROUP]
oblecto changepassword USERNAME
oblecto removepassword USERNAME
oblecto usergroup USERNAME GROUP
oblecto deluser USERNAME
Back up your database, install the new version and start it. See docs/UPGRADING.md for what changes and what to check.
git clone --recurse-submodules https://github.com/robinp7720/Oblecto.git
cd Oblecto
npm ci
npm run build:web
OBLECTO_CONFIG_PATH=/path/to/dev-config.json npm run dev
npm run verify # lint, typecheck and tests, as CI runs themnpm run build builds both web apps and the server into dist/. npm run test:network runs the tests that call the real metadata services. The Playwright suites run with npm run test:player:ui and npm run test:playback:browser.
To run the web app from Vite's dev server against a local Oblecto, add its origin to server.corsOrigins.
API references: REST, realtime, streaming, and Jellyfin compatibility.
See SECURITY.md for what Oblecto protects, what it leaves public on purpose, and how to report a problem.
AGPL-3.0-or-later. The bundled Jellyfin web client is GPL-2.0, from jellyfin-web.