cinebox is a Python TUI for browsing IMDb, resolving playable streams through
a provider chain, and opening them in mpv or VLC. It supports TV episode
browsing, batch downloads, subtitles, history, favorites, and a configurable
terminal interface.
Inspired by ani-cli. cinebox indexes
publicly accessible sources and hosts no media.
Features
- Terminal-first interface — arrow-key navigation, themed panels, ANSI poster art, and a numbered fallback for SSH or non-interactive sessions.
- Movies and TV — search IMDb, pick a season and episode, or jump directly to an IMDb ID.
- Provider fallback chain — if one source fails, the next provider is tried automatically.
- Stream or download — open a stream in mpv/VLC or save it locally with yt-dlp. TV episodes can be marked and downloaded in batches.
- Subtitles — keyless YIFY and SubSource sources, plus optional OpenSubtitles support for movies and per-episode TV subtitles.
- History and favorites — resume a recent title or keep a personal watch list.
- Configurable — player, download paths, quality, 17 color themes, poster scale, subtitle languages, and Discord Rich Presence.
- Extensible — drop a new provider into
src/cinebox/providers/and it is discovered automatically.
Requirements
- Python 3.11+
- mpv (default) or VLC
- yt-dlp and ffmpeg on your
PATHfor downloads - Linux is the primary target; macOS should work when the media tools are installed
Optional: pypresence for Discord Rich Presence.
Installation
Package manager
uv tool install cinebox
# or
pipx install cinebox
Run without installing:
uvx cinebox
From source
git clone https://github.com/hosam00/cinebox
cd cinebox
uv sync --group dev
uv run cinebox
Usage
# Interactive home screen
cinebox
# Search IMDb
cinebox search "the matrix" -t movie
cinebox search "breaking bad" -t tv
# Stream by IMDb ID
cinebox play tt0133093
cinebox play tt0944947 -t tv -s 1 -e 1
# Download
cinebox download "the matrix" -q 720p
cinebox download "breaking bad" -t tv
| Command | Description |
|---|---|
cinebox |
Open the interactive home screen |
cinebox search <query> |
Search IMDb and browse results |
cinebox play <imdb-id> |
Stream a movie or TV episode directly |
cinebox download <query> |
Search and download a title |
For scripted or headless use:
printf '1\n' | cinebox search "inception" -t movie
Use cinebox -v for debug logging.
Key bindings
| Key | Context | Action |
|---|---|---|
Up / Down |
All menus | Navigate |
Enter |
Results | Play selected |
Enter |
Quality menu | Watch |
d |
Quality menu | Download at highlighted quality |
d |
Episode picker | Download marked or highlighted episodes |
Space |
Episode picker | Toggle episode mark |
f |
Search results | Toggle favorite |
b |
Any menu | Back |
q |
Any menu | Quit |
Configuration
The first run creates ~/.config/cinebox/config.toml. Settings can also be
edited from the TUI with S.
[player]
default = "mpv" # mpv | vlc
fullscreen = true
extra_args = []
[download]
movies_dir = "~/Movies"
tv_dir = "~/Movies/TV"
quality = "1080p"
[ui]
theme = "blue" # one of 17 themes
poster_scale = 1.0
[subtitle]
enabled = true
source = "auto" # auto | provider | yifysubtitles | subsource | opensubtitles
default_lang = "en"
auto_download = false
[opensubtitles]
enabled = true
api_key = "" # app key from opensubtitles.com
username = ""
password = ""
[cache]
enabled = true
ttl_hours = 24
Unset keys fall back to their defaults. See
src/cinebox/config.py for the full configuration
surface, including history, Discord, download concurrency, and subtitle
languages.
Security
If OpenSubtitles is configured, config.toml contains an API key and account
password in plaintext. The file is created with 0600 permissions and lives
outside the repository, but it should still be treated as a secret. Never
commit or share it. Rotate any credential that may have been exposed.
How it works
IMDb suggestions
│
▼
┌─────────┐ resolve ┌─────────────────────────┐
│ cinebox │ ─────────────▶ │ provider chain │
└─────────┘ │ imdb_su → vidsrc → ... │
│ └────────────┬────────────┘
│ download │ play
▼ ▼
yt-dlp mpv / VLC
- Search — queries IMDb's public suggestion endpoint and merges results from keyword-based providers when available.
- Resolve — providers turn an IMDb ID into an HLS or MP4 stream URL and return the headers required by the CDN.
- Play — mpv receives the stream URL and the required
Referer,Origin, andUser-Agentheaders. VLC receivesRefererandUser-Agent; VLC 3 cannot set a customOrigin. - Download — the resolved URL is passed to yt-dlp. Subtitles are supplied to the player during playback and are not muxed into downloads.
| Provider | Role | Notes |
|---|---|---|
imdb_su |
Primary | Follows the embed chain to the vaplayer stream API |
vidsrc |
Fallback | Best-effort; browser-gated results are skipped |
multiembed |
Fallback | Best-effort; currently Turnstile-gated |
Providers are tried in priority order and may change or disappear over time. Resolution is best-effort by design.
Project structure
src/cinebox/
├── __init__.py CLI and TUI orchestration
├── config.py configuration, paths, defaults
├── models.py typed search and stream models
├── search.py IMDb search and result merging
├── metadata.py cached IMDb metadata enrichment
├── player.py mpv and VLC command construction
├── downloader.py yt-dlp wrapper and quality mapping
├── subtitles.py keyless subtitle sources and OpenSubtitles
├── settings.py TUI settings catalog and editor
├── history.py watch history
├── favorites.py saved titles
├── discord_rpc.py optional Rich Presence
├── providers/ streaming provider chain and discovery
└── ui/ terminal UI, themes, posters, components
Development
uv sync --group dev
uv run pytest --cov=src/cinebox
uv run ruff check src tests
uv run ruff format --check src tests
uv build
The test suite is hermetic and does not require network access. CI runs lint, format, tests, and builds on Python 3.11 through 3.14.
Adding a provider
Create a module under src/cinebox/providers/:
from cinebox.models import MediaType, StreamInfo
from cinebox.providers.base import BaseProvider
class ExampleProvider(BaseProvider):
name = "example"
priority = 40 # lower runs first; imdb_su is 10, vidsrc is 20
def resolve(
self,
imdb_id: str,
media_type: MediaType,
season: int | None = None,
episode: int | None = None,
) -> StreamInfo:
...
No registry edits are required. Concrete BaseProvider subclasses are
discovered automatically. For sources that resolve by keyword instead of IMDb
ID, subclass KeywordProvider in
src/cinebox/providers/keyword.py.
Troubleshooting
- No stream found — providers can be temporarily unavailable. Retry, try
another title, and run
cinebox -vfor debug logs. - VLC does not open the stream — verify
vlc --version. VLC 3 cannot send a customOriginheader; use mpv if a source requires it. - Downloads fail — confirm
yt-dlpandffmpegare installed and on yourPATH. - Subtitles are missing — keyless sources do not cover every title. For
OpenSubtitles, set the API key, username, and password under
[opensubtitles]. - Terminal rendering is broken — use a terminal at least 80 columns wide. Piped or non-interactive sessions fall back to a numbered menu.
Contributing
Contributions are welcome. See CONTRIBUTING.md for setup and
pull request expectations. For bug reports, include your OS, player version,
cinebox --version, and relevant -v logs with credentials removed.
Roadmap
- PyPI release via Trusted Publishing
- Keyword-search provider interface
- Automatic provider discovery
- fzf integration and fuzzy search over history/favorites
- More subtitle sources, including forced subtitles
- Per-provider enable/disable and health checks
- A full Stardima keyword provider
Disclaimer
For content you have the right to consume. cinebox indexes publicly
accessible streams and hosts no media. Providers and their CDNs may change or
break at any time. Use at your own risk and respect copyright.
License
Metadata
Release files for cinebox 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| cinebox-0.2.0.tar.gz | 55.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cinebox-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.7 kB
Release files / cinebox-0.2.0.tar.gz
| Download URL | cinebox-0.2.0.tar.gz |
|---|---|
| Size | 55.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ec0e4ffa6918e8b9e2c629ff51df86db5cf833d153a8394b89da5b8ca39038ae
|
|
BLAKE2b-256 checksum How to use checksums |
fe60119420e35b094d2b7abcfff6bce0cbdb6816e57189e81f4c11f2d4c43d8d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / cinebox-0.2.0-py3-none-any.whl
| Download URL | cinebox-0.2.0-py3-none-any.whl |
|---|---|
| Size | 65.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c4b3cab2f169963d5a75e82697ab7412fe2f49a9a3f62dc8010eac0d9e50a454
|
|
BLAKE2b-256 checksum How to use checksums |
00143b50dacfcdb33eced6edb5e8d35ce9ae75b8c6a1458450a340cbbbd3b274
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for cinebox 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for cinebox-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.