Skip to content

debpalash/Opal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

281 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Opal logo

Opal

Play everything.

The evolved media player for the next decades of entertainment.

CI Release License: GPL-3.0 Zig 0.16 Platforms: macOS, Linux, and Windows

Get it Β· See it Β· The AI Β· Under the hood Β· Support Development (Ko-fi, PayPal)

Opal home β€” time-aware greeting, an ask-anything box, and tonight's trending row It's late. Opal knows it's late.

It's 11 PM and you just want to watch something. So why are there nine tabs open? A player for the files. A site for the show. An app for the server. A wiki for "what episode was that." A feed deciding what you see next. Opal's whole thesis is that this is one job: you say what you're in the mood for β€” a title, a file, a magnet, a vibe β€” and a moment later you're watching it. That's it. That's the app.

For decades the "media player" has been the dumb end of the pipeline β€” the thing other apps hand a file to. Opal is what comes after: the place where watching starts. It searches everywhere at once, curates to your taste, remembers where you left off, and plays anything β€” a local-first media app written in Zig, with an immediate-mode dvui interface and an mpv heart. It opens in a blink, idles in silence, and quits with a receipt: Clean shutdown: 0 memory leaks.

πŸ™… No accounts πŸ“‘ No telemetry ☁️ No cloud πŸ’³ No subscription
nothing to sign up for nothing phones home your history is a SQLite file you own it's your computer

πŸš€ Get it

One command. It figures out your platform, verifies checksums, and it's also the updater (… -s -- update) and version manager (OPAL_VERSION=v0.1.0 …):

curl -fsSL https://raw.githubusercontent.com/debpalash/Opal/main/scripts/install.sh | sh

Prefer to do it yourself? Find your row β€” every file is on the Releases page:

Platform The move
🍎 macOS (Apple silicon) open the .dmg, drag, done
🍺 Homebrew brew install debpalash/tap/opal
πŸ“¦ Debian / Ubuntu sudo apt install ./opal_*_amd64.deb
🎩 Fedora / openSUSE sudo dnf install ./opal-*.x86_64.rpm
🏹 Arch yay -S opal-bin (or opal to build)
🐧 Any Linux chmod +x Opal-*.AppImage and run it
πŸͺŸ Windows (x64) run the .msi β€” or unzip the portable .zip anywhere
πŸ›  From source git clone β†’ zig build run (deps below)

🍎 macOS calls the downloaded .dmg "damaged" β€” it isn't; that's Gatekeeper's way of saying we haven't paid Apple $99/yr for notarization yet. Either use the one-command installer above (no quarantine, no dialog), or run sudo xattr -cr /Applications/Opal.app once after dragging. πŸͺŸ Windows builds are the newest of the family β€” treat the first releases as adventurous (SmartScreen will also want a word). 🍎 Intel Macs: source build works (HOMEBREW_PREFIX=/usr/local).

First launch: open Settings (⌘,) and paste a free TMDB v4 token to light up movie/TV browsing. Voice and AI models are opt-in downloads β€” one button each, nothing installs itself.

🧱 Building from source

Zig 0.16.x plus a handful of native friends:

brew install zig mpv sqlite onnxruntime sdl2
# plus: libtorrent-rasterbar, g++ (torrent wrapper), ffmpeg/whisper-cpp for voice

git clone https://github.com/debpalash/Opal.git
cd Opal
zig build run        # first build is slow; incrementals are fast

Linux/Wayland: use make run (forces system SDL2 β€” the bundled one is X11-only). macOS builds read HOMEBREW_PREFIX (default /opt/homebrew).

πŸ”§ For hackers: dev loops, tests, and the contract
  • ./dev.sh β€” hot-reload loop that survives C changes; -r for ReleaseFast.
  • just hot β€” native --watch -fincremental, millisecond rebuilds.
  • just release / just app β€” ReleaseFast / macOS Opal.app bundle.
just test-all       # the comprehensive gate β€” must stay 0 fail
zig build test      # pure-Zig unit tests only (fast)

fail = real regression. skip = optional component not installed. That's the contract β€” and every PR reports its tally (see CONTRIBUTING.md).

πŸ“ Where your stuff lives

XDG-compliant, no surprises:

  • ~/.config/opal/ β€” config, tokens (0600), and opal.db (history, AI memory)
  • ~/.cache/opal/ β€” caches
  • ~/Downloads/opal β€” default downloads
  • ~/.config/opal/plugins/<name>/ β€” content plugins (manifest.json + a search/resolve executable that prints JSON; Lua runs sandboxed, native binaries don't β€” install only what you trust)

🎯 The goal

Become the true alternative to the whole stack β€” the streaming apps, the server front-ends, the trackers, the recommendation feeds β€” by being self-sufficient: one interface that understands what you need and quietly takes care of it, powered by an AI that runs on your hardware and answers to you.

A media system shouldn't need a corporation attached. Discovery, curation, memory, playback β€” Opal's bet is that all of it can live on your machine, learn your taste without reporting it, and get out of the way. Every release walks further in that direction (ROADMAP.md).


✨ The tour, in motion
Press play on a torrent result; playback starts while it downloads
🧲 Magnets behave like files
Press play on a torrent β€” you're watching while it downloads. (Sintel, Β© Blender Foundation, CC-BY 3.0)
One query fanned out across every source, ranked
πŸ”­ One search, every source
Disk, torrents, Jellyfin, Stremio, anime, YouTube, TMDB, comics β€” one ranked, playable list.
Scrolling the trending wall, then switching to the YouTube tab
πŸ—ΊοΈ Browse like you own the place
Trending walls, genres, episode drill-downs β€” one tab bar, zero franchises acquired.
A suggestion chip answered by the local AI with a poster rail
πŸ€– An AI that lives on your machine
Local LLM with tool use answers with playable picks β€” no API key, no bill, no feed.

Why it sticks

  • 🧲 Magnets behave like files β€” piece-prioritized streaming: press play on a torrent and you're watching while it downloads.
  • πŸ”­ Search once, everything answers β€” disk, torrents, Jellyfin, Stremio, anime, YouTube, TMDB, comics β†’ one ranked list, a play button on every row.
  • πŸ€– A local AI copilot β€” "what should I watch if I loved Interstellar?" answered with playable picks; hands-free voice (Whisper ears, Piper/Kokoro mouth, barge-in); taste memory in on-disk sqlite-vec. No API key, no bill, no "your data helps us improve."
  • ▢️ A player that sweats details β€” subtitles embedded, fetched, or Whisper-generated on the spot Β· SponsorBlock Β· Chromecast Β· LAN watch-party Β· phone web remote (:3000) Β· session restore mid-sentence.
  • πŸ—ΊοΈ Browse like you own the place β€” trending walls, genres, episode drill-downs across every source, including your Jellyfin and Plex.
  • 🧰 …and the drawer β€” comics & manga reader Β· live OCR on video frames Β· language-learning flashcards Β· recommendations Β· history & queue Β· RSS Β· incognito (I) Β· seven themes Β· JSON API (:41595) for your own automations.

⌨️ Keyboard-first, remote-friendly

S search B browser D library H history
F fullscreen P playlist G grid layout Z fit/crop
⌘O open file ⌘, settings Esc backs out of things, politely ⇧I the cheat sheet

βš™οΈ Under the hood

src/
β”œβ”€β”€ main.zig     # appFrame() β€” one function per frame, immediate mode
β”œβ”€β”€ core/        # alloc, state, config, paths, io shim, sqlite (+sqlite-vec)
β”œβ”€β”€ player/      # mpv wrapper, playlists, subtitles, watch history
β”œβ”€β”€ services/    # search, AI, torrents, jellyfin, remote API, ...
└── ui/          # dvui widgets β€” theme tokens, shell, grid, player chrome
web/             # companion web UI (its own Zig project)

The parts we're quietly proud of: the whole system β€” player, search, torrent streamer, AI β€” compiles to one fast native binary; one global allocator with leak detection on every exit; fixed-size buffers instead of heap churn; a single state.app hub with disciplined thread-safety rules; a render loop that repaints only when something changed (your fans will thank us); and a threaded-Io shim for Zig 0.16. House rules in CONTRIBUTING.md; where this is all going in ROADMAP.md.

Content sources ship off: the core has no sources configured and nothing enables itself β€” you explicitly install endpoints from the plugin registry, and you can un-install them just as fast (CONTENT_POLICY.md).

πŸ’œ Support development

Opal has no telemetry to monetize and no account system to upsell β€” it runs on goodwill:

  • β˜• Buy the maintainer a coffee on Ko-fi or πŸ’Έ chip in via PayPal β€” donations keep the release cadence honest and the coffee supply uninterrupted.
  • ⭐ Star the repo β€” it's genuinely how people find it.
  • πŸ› File good bugs (how) Β· πŸ”§ send PRs (how).
  • πŸ“£ Show someone. This pitch lands best as a 30-second demo β€” the GIFs above are yours to share.

🀝 Contributing

Yes please β€” read CONTRIBUTING.md and the CODE_OF_CONDUCT.md, run just test-all, and report the tally in your PR. Questions live in Discussions; the full help map is in SUPPORT.md.

πŸ“œ License

GPL-3.0 (see LICENSE, NOTICE.md) β€” the honest choice for a program linked against libmpv. Bundled dependencies keep their own licenses (libtorrent BSD, dvui/ONNX MIT, SDL2 zlib, SQLite public domain).

The fine print

Opal is a player and an aggregator β€” it hosts, indexes, and distributes nothing. It connects to sources you configure. Only access media you have the legal right to access in your jurisdiction; read CONTENT_POLICY.md before enabling content plugins or torrent features. BitTorrent exposes your IP to the swarm β€” use a VPN if that matters to you. Rights holders: see DMCA.md for the takedown process.

Provided "as is", no warranty. The authors are not responsible for how the software is used or for content reached through third-party sources.



Built with Zig, mpv, and an unreasonable number of late nights.
Now go watch something.