LoganBarnett/loku

★ 1Forks 0RustGitHub ↗Compare

README

Loku — Local Roku

Introduction

Loku is a local video browser and player. Point it at one or more media directories and get a browseable, searchable interface in your web browser.

It pairs well with yt-dlp (download a channel’s videos alongside their metadata and thumbnails) and with MakeMKV disc rips, which it turns into first-class library items: friendly titles from Kodi .nfo sidecars or cleaned-up rip filenames, extracted thumbnails, and a guaranteed browser-playable copy produced by a built-in ffmpeg worker.

Key characteristics:

  • Multiple named libraries, each typed as yt-dlp downloads or MakeMKV discs.
  • Full-text search across every library at once, over yt-dlp info.json and Kodi .nfo metadata plus filenames.
  • Multi-title disc rips grouped into one item with a pick-the-main-title flow.
  • In-browser playback with codec-aware source selection; masters that browsers cannot play get an automatically derived H.264/AAC compat copy (the original file is never modified).
  • A rebuildable SQLite index kept current by filesystem watching; sidecar files remain the source of truth.

Installation

From source

Requires Rust (stable) and cargo.

git clone https://github.com/LoganBarnett/loku
cd loku
cargo build --release

The binary is at target/release/loku-server.

With Nix

nix run github:LoganBarnett/loku

Usage

Start the server, pointing it at a video library:

loku-server --library /path/to/videos

Then open http://localhost:3000 in a browser.

--library is single-root convenience; multi-library setups define [[library]] entries in a config file instead (see config.example.toml) and pass --config:

[[library]]
name = "downloads"
path = "/media/videos"
kind = "downloads"

[[library]]
name = "discs"
path = "/media/rips"
kind = "discs"
FlagDefaultDescription
--configdiscoveredPath to the TOML config file
--library(none)Single downloads-kind root shortcut
--listen127.0.0.1:3000host:port, socket path, or
sd-listen
--state-dirSTATE_DIRECTORY /Where the media index database lives
XDG state home
--log-levelinfoLogging verbosity

ffmpeg and ffprobe on PATH enable codec probing and compat derivation; without them Loku still browses and serves, with those features disabled and /healthz reporting a degraded media-tools component.

Gotchas and Tradeoffs

  • The index is derived, the filesystem is truth: metadata comes from sidecars (info.json, Kodi .nfo, thumbnails, .compat.mp4) indexed into SQLite in the state directory. Deleting the state directory only costs a rescan (plus any manual main-title picks).
  • Derived files live beside masters: the worker writes foo.compat.mp4 and foo.jpg next to foo.mkv, so library paths must be writable by the server and other consumers of the same trees (e.g. Kodi) should exclude *.compat.mp4 from their scans.
  • Local only by default: the default bind is 127.0.0.1. Use --listen 0.0.0.0:3000 to expose on the LAN; for real deployments use the NixOS module’s socket activation behind a TLS proxy with OIDC.

Upgrading

Elm compiler or Elm packages

The Elm frontend is compiled hermetically in Nix. Two files in frontend/ describe the dependency set and must be kept in sync with elm.json:

  • elm-srcs.nix — one sha256 + version entry per package, generated by elm2nix convert.
  • registry.dat — a snapshot of the Elm package registry, generated by elm2nix snapshot.

After adding, removing, or bumping any package in elm.json:

cd frontend
elm2nix convert 2>/dev/null > elm-srcs.nix
elm2nix snapshot
git add elm-srcs.nix registry.dat
git commit -m "Update elm-srcs.nix and registry.dat for new dependencies"

Both elm2nix and elm are available in the Nix dev shell (nix develop).

The Nix build uses pkgs.elmPackages.fetchElmDeps to assemble an offline ELM_HOME from the packages listed in elm-srcs.nix, then compiles with elm make --optimize. No generated JavaScript lives in the repository.

Rust dependencies

cargo update
cargo test --workspace
git add Cargo.lock && git commit -m "Update Cargo.lock"

Contributing

nix develop --command cargo test --workspace
nix develop --command cargo fmt --check

Contributors

LoganBarnettgithub-actions[bot]dependabot[bot]

Issues