Skip to main content

cinebox

Search, stream, and download movies and TV shows from your terminal.

CI PyPI Python License Ruff

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 PATH for 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
  1. Search — queries IMDb's public suggestion endpoint and merges results from keyword-based providers when available.
  2. Resolve — providers turn an IMDb ID into an HLS or MP4 stream URL and return the headers required by the CDN.
  3. Play — mpv receives the stream URL and the required Referer, Origin, and User-Agent headers. VLC receives Referer and User-Agent; VLC 3 cannot set a custom Origin.
  4. 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 -v for debug logs.
  • VLC does not open the stream — verify vlc --version. VLC 3 cannot send a custom Origin header; use mpv if a source requires it.
  • Downloads fail — confirm yt-dlp and ffmpeg are installed and on your PATH.
  • 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

MIT

Built with Python, Rich, httpx, and yt-dlp.

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)

Source distribution for cinebox 0.2.0
File Size Uploaded Provenance
cinebox-0.2.0.tar.gz 55.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for cinebox 0.2.0
File Interpreter ABI Platform
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page