Introduction
A fast, lightweight terminal client for streaming and downloading movies, TV shows, anime, and live TV — powered by your local media player.
MovieBox-TUI replaces ad-heavy streaming websites and clunky browser players with a clean, keyboard-driven terminal interface. It scrapes stream links directly from multiple sources and launches playback in your native media player with hardware acceleration, audio track switching, and automatic subtitle synchronization.
Features
- Multi-Source Streaming: Search and stream titles across MovieBox, 4KHDHub, BDIX mirrors, custom IPTV playlists, and community Stremio HTTP addons. Press
Ctrl+Pon the Details screen to switch providers in-place. - Hardware-Accelerated Playback: Direct playback in
mpv,IINA(macOS), orVLCwith stream authentication headers forwarded automatically. - Automatic Subtitles: Automatically searches, downloads, and syncs subtitles in your preferred language directly into your player.
- Season Batch Downloads: Download individual episodes or entire seasons with one keypress (
d), with HTTP range resume support and clean folder structure (Movies/andSeries/). - Interactive Settings Hub: Configure your default media player, download folder, content modes, and themes inside an in-app visual modal via
/settings(Ctrl+S). - Modes: Switch instantly between standard Streaming, Live TV (
Ctrl+T), and Addon Mode (Ctrl+A). - Ergonomics & Themes: Full keyboard navigation (vim-style
j/k,/,Tab) and mouse support (click, scroll, drag) with 6 built-in themes (Catppuccin, TokyoNight, Nord, Dracula, Gruvbox, Rosé Pine) and terminal theme autodetection.
Prerequisites
MovieBox-TUI delegates video decoding to an external media player. Install at least one of the following:
| Player | Platform | Quick Install |
|---|---|---|
| mpv (Recommended) | Linux, macOS, Windows | brew install mpv / sudo apt install mpv / winget install mpv |
| IINA | macOS (Native GUI) | brew install --cask iina |
| VLC | Cross-platform | brew install --cask vlc / sudo apt install vlc / winget install VideoLAN.VLC |
| Android Player | Android (Termux) | pkg install -y termux-tools termux-am (launches external player) |
Documentation Directory Map
Getting Started
| Guide | Description |
|---|---|
| Installation | Platform installation instructions, package managers, and binary verification |
| Keyboard & Controls | Complete keybindings, vim navigation, text editing, and slash commands |
| Configuration Guide | config.json schema, settings hub options, and environment variables |
Features & Modes
| Guide | Description |
|---|---|
| Content Providers | Built-in providers, scrapers, stream extractors, and authentication headers |
| Hardware Players | Media player detection, launch flags, stream headers, and watch tracking |
| Batch Downloads | Multi-segment download engine, range resume, and folder layout |
| Stremio Addons | Addon manifest installation, catalog browsing, and stream resolution |
| Live TV & IPTV | M3U playlist manager, channel parsing, and live stream playback |
Architecture & Internals
| Guide | Description |
|---|---|
| System Architecture | Subsystem diagrams, async event loop, and task cancellation |
| Module Breakdown | Crate structure, module responsibilities, and call boundaries |
| Caching Strategy | Binary disk caching, TTL policies, and LRU memory management |
| Logging System | File logging, log rotation, and tracing diagnostics |
| Cross-Platform Operations | Platform compatibility matrix across macOS, Linux, Windows, and Termux |
Reference & Maintenance
| Guide | Description |
|---|---|
| Testing Suite | Unit tests, integration tests, and verification gates |
| Debugging Guide | Troubleshooting common issues, terminal rendering, and player errors |
| Release Checklist | Pre-release validation, binary packaging, and deployment workflow |
| Known Issues | Tracked limitations, terminal quirks, and workarounds |
| Contributing Guide | Contribution guidelines, code standards, and PR process |
| Changelog | Complete release history and unreleased changes |
Installation
MovieBox-TUI is available across macOS, Linux, Windows, and Android (Termux).
macOS & Linux
Install via the automated script:
curl -fsSL https://raw.githubusercontent.com/mesamirh/MovieBox-Tui/main/install.sh | bash
macOS via Homebrew
brew tap mesamirh/moviebox-tui https://github.com/mesamirh/MovieBox-Tui
brew trust mesamirh/moviebox-tui
brew install moviebox-tui
Windows
Install via PowerShell (run in Windows Terminal or PowerShell 5.1+):
irm https://raw.githubusercontent.com/mesamirh/MovieBox-Tui/main/install.ps1 | iex
Android (Termux)
Install Termux tools and the intent bridge, run the installer script to fetch the precompiled native Android ARM64 binary, and grant storage permissions:
pkg update && pkg install -y curl tar termux-tools termux-am
curl -fsSL https://raw.githubusercontent.com/mesamirh/MovieBox-Tui/main/install.sh -o install.sh && bash install.sh
termux-setup-storage
The installer automatically downloads the native Android ARM64 release package (MovieBox_Android_arm64.tar.gz) built against the Android NDK and Bionic libc, requiring zero on-device compilation.
Media Player Requirements: Android streams are rendered through external Android video players (such as VLC for Android, MX Player, Just Player, or MPV Android APK) triggered via
termux-openortermux-am. Command-linempvinstalled directly in Termux (pkg install mpv) runs without a video output surface unless an X11 desktop environment (like Termux:X11) is configured.
To compile from source on Termux:
pkg install -y rust clang
cargo install moviebox-tui --locked
Cargo (Crates.io)
Install directly using Cargo:
cargo install moviebox-tui --locked
Compile from Source
Clone the repository and build the release binary:
git clone https://github.com/mesamirh/MovieBox-Tui.git
cd MovieBox-Tui
cargo build --release --locked
The compiled binary will be located at target/release/moviebox-tui.
Verify Release Integrity
All release assets include cryptographically signed SHA-256 checksums and GitHub provenance attestations:
sha256sum -c SHA256SUMS --ignore-missing
gh attestation verify <archive-file> -R mesamirh/MovieBox-Tui
Controls & Shortcuts
MovieBox-TUI is designed for fast keyboard navigation with complete mouse support throughout the interface. You can press ? anywhere inside the application to open the mode-aware interactive help dialog.
Global Shortcuts
| Key | Action |
|---|---|
↑ / ↓ / k / j | Navigate lists, search results, or move cursor up/down |
← / → / h / l | Move text input cursor, step wide grid columns, or switch Details panes (Audio/Seasons/Episodes/Streams) |
Home / End / g / G | Jump to start / end of list or search results (auto-fetches next page), or move cursor to beginning / end of input line |
PageUp / PageDown | Scroll search results, lists, and modal pickers by visible page height (or scroll help overlay) |
Enter | Open, play, or confirm the selected item |
Space / P | Direct resume playback for recorded season/episode on /history or Home Continue Watching items |
Esc | Focus search input (when results present), dismiss popup dialog, or return to landing |
Tab / Shift+Tab | Auto-complete suggestion / command; cycle landing deck tabs (Continue Watching / Favorites); switch details panes; toggle dialog buttons |
Backspace | Delete character before cursor, or return focus to search bar from results |
Delete | Delete character at cursor in text inputs, or remove entry in TV/Addon managers |
Ctrl+U | Clear entire input line (Search, TV URL, Addon URL) |
Ctrl+W | Delete backward word in text inputs |
c | Clear active search query and return to landing screen (Normal mode) |
x / X | Cancel active download and preserve partial .part data |
Ctrl+S | Switch to standard Streaming Mode |
Ctrl+T | Toggle / switch to TV Mode |
Ctrl+A | Toggle / switch to Addon Mode |
? | Open interactive in-app help menu |
Ctrl+C / q | Quit application and restore terminal |
Text Input & Cursor Editing
Text editing across Search, TV Playlist Manager, and Addon Manager uses a unified grapheme-safe input engine:
| Key | Action |
|---|---|
Left / Right | Move text cursor one grapheme cluster left or right |
Home / End | Jump cursor directly to the beginning or end of the input line |
Backspace | Delete the grapheme cluster immediately before the cursor |
Delete | Delete the grapheme cluster at the cursor position |
Ctrl+W | Delete the preceding word (up to space or punctuation delimiter) |
Ctrl+U | Clear the entire input buffer |
Tab | Auto-complete active search suggestion or slash command |
Enter | Submit search query, save TV playlist URL/path, or verify and install Addon manifest |
Esc | Cancel input, dismiss input prompt, or clear search buffer |
Modal Dialogs & Pickers
All popup dialogs (Theme picker, Browse categories, Provider menu, Settings Media Player picker, TV Manager, Addon Manager, Download Confirmation) support standard keyboard controls:
↑/↓/k/j: Move selection up / down by one item (vim keysk/jsupported in pickers such as theme selector in Settings).Home/End: Jump immediately to the first or last item in the list.PageUp/PageDown: Step up or down by 5 items.Enter: Confirm selection, activate entry, or submit dialog.Esc: Dismiss popup dialog without applying changes.- Download Confirmation Dialog:
Tab/Shift+Tab/BackTab: Toggle active selection between[ Download ]and[ Cancel ].Left/Right: Switch between[ Download ]and[ Cancel ].Enter: Confirm the currently focused action.Esc: Cancel and close the confirmation dialog.
Mode-Specific Controls
Streaming Mode
Ctrl+P: Cycle content providers (MovieBox→4KHDHub→BDIX). On the Details screen, re-searches and fetches alternate streams for the current movie in-place.←/→/h/l/Tab/Shift+Tab: Switch Details screen selector panes (Audio Languages, Seasons, Episodes, Streams).Enter: Play selected stream or open selected title.d: Download current episode or full season batch.r: Refresh search results / stream list.f: Favorite / unfavorite the selected title (Home & Details screens)./settings: Open interactive Settings & Preferences Hub./browse: Open curated browse categories (Trending, Popular, Top Rated, etc.)./history: Open watch history (SpaceorPto instantly resume recorded episode/movie)./favorites: Open your starred titles./clear: Clear active search query and return to landing.
Live TV Mode
Enter: Play selected TV channel immediately with default player.r: Reload all active M3U playlist sources./list: Show all loaded channels.
Addon Mode (HTTP Addons)
/settings: Open Settings Hub to manage addons and configuration.Enter: Select title or play resolved stream.d: Download HTTP stream release.r: Refresh addon catalog search results.f: Favorite / unfavorite the selected title (Home & Details screens)./history: Open watch history (SpaceorPto instantly resume recorded episode/movie)./favorites: Open your starred titles./clear: Clear active search query and return to landing.
Mouse Controls
| Action | Result |
|---|---|
| Click provider badge | Open anchored provider selection menu; click provider to switch directly |
| Click search bar | Enter search input mode |
| Click search result row | Select item and load preview; click again to open full details |
| Click landing deck tab header | Switch between Continue Watching and Favorites tabs |
Click [x] Cancel on download bar | Cancel active download |
| Click Continue Watching row (landing) | Select an in-progress title; click again to resume playback with auto-play |
| Click Favorites row (landing) | Select a starred title; click again to open details |
| Click “+N more • /history” or “+N more • /favorites” | Open the full watch history or favorites list |
| Click audio / season / episode / stream | Switch audio language, change season, or select episode; click a specific stream row to play; click empty stream pane space to focus without playing |
| Click footer buttons | Switch provider / mode, open help ([?]), or quit ([q]) |
| Click modal buttons | Choose a theme, subtitles, player, or confirm actions |
| Click outside a modal | Dismiss popup dialog |
Slash Commands
Type these commands directly into the search bar:
| Command | Applicable Mode | Action |
|---|---|---|
/settings | All | Open interactive Settings & Preferences Hub (aliases /config, /pref, /preferences, /options) |
/browse | Streaming / Addon | Browse curated views (Trending, Popular) or Addon catalogs (Top Movies, Top Series) |
/history | Streaming / Addon | View watch history with latest progress |
/favorites | Streaming / Addon | View all starred titles |
/clear | All | Clear search results and return to landing |
/help | All | Open interactive keybinding help menu (alias /?) |
/list | TV | View live TV channels |
/exit | All | Exit application and return to shell (aliases /quit, /q) |
Help Menu Overlay
- Open with
?; close with?,Esc, orq. ↑/↓,PageUp/PageDown, and the mouse wheel scroll long content.- Other keys are ignored while help is open.
Update Notification & Self-Update Modals
When a new release is detected, a centered modal card displays the version comparison, environment instructions, release highlights, and quick actions:
u/U: Download and install update immediately (direct binary replacement platforms).b/B: Copy Homebrew upgrade command (brew upgrade moviebox-tui) to clipboard with status toast on Homebrew-managed installations.o/O: Open GitHub release notes in the system browser.Esc: Dismiss modal and return to previous screen.- The notification modal formats release notes into clean, indented category sections (
[Added],[Fixed]) with bold feature titles and bullet items, stripping decorative prefixes and duplicate paragraph text. - During self-update (
u), a focused progress modal displays an active spinner with a unified action status (⠋ Downloading MovieBox-Tui v.../⠋ Installing MovieBox-Tui v...) and a cross-platform warning notice (⚠ Please wait • do not close terminalon modern terminals,[!] Please wait - do not close terminalon basic terminals) with generous border clearances. - Modal presentation is deferred while actively typing in the search bar (
InputMode::Editing) to prevent input hijacking. During update installation, keyboard and mouse inputs are locked while the progress modal is displayed.
Wide-Terminal Grid
On terminals at least 110 columns wide, search results render in two
columns (three at 160+). ↑/↓ move one visual row, ←/→ move one
item, and clicks map through column bounds. Narrower terminals keep the
classic single-column list where ←/→ jump a full page.
Configuration
config.json
Written atomically under the config directory (dirs::config_dir()/moviebox-tui/;
macOS ~/Library/Application Support/moviebox-tui, Linux ~/.config/moviebox-tui).
| Field | Type | Meaning |
|---|---|---|
auto_update | bool | Check for updates on startup (max once/hour). |
last_update_check | u64 | Epoch seconds of the last update check. |
active_mode | string | Last active mode (streaming, tv, addon) restored on startup. |
active_provider | string | Last provider (moviebox, fourkhdhub, …). |
active_theme | string | Theme name. |
bdix_enabled | bool | Show BDIX providers (Bangladesh-only). |
streaming_enabled | bool | Enable Streaming Mode navigation in bottom dock (/settings → Content Modes). |
tv_enabled | bool | Enable TV Mode navigation in bottom dock (/settings → Content Modes). |
addons_enabled | bool | Enable Addon Mode navigation in bottom dock (/settings → Content Modes). |
default_player | string or null | Preferred player: mpv, iina, vlc, android; absent/null until you choose one from the in-app picker. |
download_dir | string or null | Custom directory for video and subtitle downloads (null uses OS default). |
Interactive Settings Hub (/settings)
All settings in config.json can be configured interactively inside the application by typing /settings into the search bar.
- General: Toggle automatic update checks, choose default media player (
mpv,VLC,IINA,Android), and edit download folder path. - Content Modes: Enable or disable Streaming Mode, BDIX FTP sources, Live TV (IPTV), and HTTP Addons with safety guards (preventing 0 active modes).
- Appearance: Cycle color themes live with real-time palette swatches and launch the visual theme swatch picker.
- Maintenance: Purge disk cache, query GitHub for release updates, and view repository information.
Other persisted files
addons_config.json— list of installed HTTP addons in the config directory (see addons-mode.md).tv_config.json— list of M3U playlist sources in the config directory (see tv-mode.md).history.json— watch history in the system data directory (dirs::data_dir()/moviebox-tui/).favorites.json: starred titles in the system data directory. Independent ofhistory.json; clearing watch history or cache never touches it.playback/— temporary playback states in the system data directory for resilient progress tracking.scripts/— bundled player scripts (moviebox_tracker.lua) in the system data directory.iptv_cache/— legacy TV image cache directory thatClearCachestill removes.
Environment variables
| Variable | Purpose |
|---|---|
MOVIEBOX_LOG | Log level: off, error, warn, info, debug, trace. See logging.md. |
MOVIEBOX_PLAYER | Preferred player (overrides default_player). |
MOVIEBOX_MPV_PATH | Custom mpv executable. |
MOVIEBOX_VLC_PATH | Custom VLC executable. |
MOVIEBOX_IINA_PATH | Custom IINA/iina-cli executable. |
MOVIEBOX_FOURKHDHUB_URL | Override the 4KHDHub base URL. |
MOVIEBOX_THEME | Force a theme (e.g. Mocha, Latte, Macchiato, Frappe, Nord, TokyoNight, Dracula, Gruvbox, RosePine). When unset and no saved theme exists, the app auto-detects: NO_COLOR wins, truecolor terminals get full palettes, 256-color terminals get quantized palettes, and the OSC 11 background query picks light/dark variants with WCAG AA contrast. |
MOVIEBOX_NO_IMAGE | Disable poster image queries (set to 1 or true). |
MOVIEBOX_IMAGE_PROTOCOL | Override image protocol (kitty, sixel, iterm2, or none/off). |
MOVIEBOX_CELL_SIZE | Override terminal cell size as WxH (e.g. 10x20) for poster scaling. |
CLI
moviebox-tui --helpandmoviebox-tui -hprint the help manual and exit.moviebox-tui --version,moviebox-tui -v, andmoviebox-tui -Vprint the version and exit.
Providers
MovieBox-Tui aggregates several movie/stream providers plus user M3U playlists. Each
provider is an independent async client exposing a similar shape, normalized into the
shared typed models in providers/models.rs and the moviebox JSON schema used by the UI.
Provider kinds
| Provider | Module | Description |
|---|---|---|
| MovieBox | providers/moviebox | Primary provider. Requires request signing (crypto). |
| FourKHdHub | providers/fourkhdhub | 4K releases; hubcloud mirror resolver. |
| BdixCircleFtp | providers/bdix/circleftp | BDIX FTP directory scrapes. |
| BdixDhakaFlix | providers/bdix/dhakaflix | BDIX indexer. |
| Addons | providers/addons | Community HTTP addons (Cinemeta, streams). |
BDIX sources are only reachable from supported Bangladeshi ISPs and are hidden by
default (bdix_enabled in config; /settings → Content Modes → BDIX Sources).
Active streaming providers can be cycled via Ctrl+P or visually selected by clicking the provider badge ([MovieBox · ^P]) on the landing search bar to open the anchored provider popup menu.
Shared Provider Contract
Search, details, and episode-streams are dispatched per provider. Pluggable provider seams
in providers/mod.rs give every client a shared, strictly-typed async trait shape:
Provider::id(&self) -> ProviderKind: Returns the provider’s unique identifier.Provider::capabilities(&self) -> ProviderCapabilities: Reports supported capabilities (supports_search,supports_pagination,supports_series,supports_subtitles,supports_homepage).Provider::search(&self, query: &str, page: usize) -> Result<Vec<CatalogItem>, ProviderError>: Dispatches search queries, returning strongly-typedCatalogItems.Provider::details(&self, id: &str) -> Result<MediaDetails, ProviderError>: Dispatches metadata queries, returning strongly-typedMediaDetails.ReleaseProvider::episode_streams(&self, id: &str, season: usize, episode: usize) -> Result<Vec<Release>, ProviderError>: Returns the typedReleaselist for release-based providers.ProviderError: Standardized error boundary (Network,RateLimited,NotFound,Parsing,Unavailable) with.user_message(provider)generating clean UI toast notifications.
Strongly Typed Architecture & Binary Disk Caching
All internal state (AppState), UI screens (details.rs, home.rs), and the action event bus transport native Rust structs directly:
CatalogItem/SearchResultfor search results and discover catalogs.MediaDetails(withVec<Season>andVec<AudioTrackOption>) for media metadata.Release(withVec<SourceMirror>and optionalresource_id) for streams.SubtitleOptionfor external subtitles.
Disk caching in src/cache.rs uses high-performance portable binary serialization via rmp-serde (MessagePack) with a 4-byte magic signature (MBC1) and versioned TTL envelope (CacheEnvelope<T>), eliminating all runtime JSON parsing and string allocation bottlenecks.
Playback resolves to a PlaybackSource { provider, url, headers, subtitle, source_label },
which app/playback.rs::launch_player feeds to the external player.
Adding a New Provider
Adding a new streaming or BDIX provider to MovieBox TUI takes 3 simple steps:
-
Define the Provider Variant (
src/providers/models.rs): Add the new variant toProviderKindwith its label, cache key, and serialization aliases. -
Implement the
ProviderTrait (src/providers/<new_provider>/): ImplementProvider::id,Provider::capabilities,Provider::search, andProvider::detailsfor your client struct, returning typed domain models (CatalogItem,MediaDetails). If your provider resolves release streams, also implementReleaseProvider. -
Register the Client in
MovieBoxService(src/service.rs): Add your client struct toMovieBoxService, instantiate it inMovieBoxService::new(), and map it incapabilities,search_typed, anddetails_typed. All search, details, and stream dispatches operate natively with zero JSON shims.
MovieBox
- Base host pool + per-request HMAC-MD5 signature, client token, and a spoofed Android
device identity (
crypto.rs) spoofing APKv4.0.01.0813.03(version_codes: 50020117..50020121) to satisfy the backend gateway and prevent notice video substitution. - Hosts are retried; a shared runtime token is re-initialized when all hosts fail.
- Mobile
User-Agentgenerated by the crypto module is forwarded through playback and download pipelines to satisfy CDN anti-bot checks. - Multi-resolution discovery (
fetch_collection_resolutions) dynamically discovers available stream resolutions with descending quality sorting. - Multi-resolution DASH manifests (
index.mpd) and adaptive streams are labeled with a distinct[Multi]badge, stripping confusing raw CDN resolution tags from release titles. - Title normalization lives in
moviebox/title.rs(clean_moviebox_title). - DASH Manifest Playback & Downloads: Media streams are hosted on CloudFront as segmented MPEG-DASH manifests (
index.mpd) protected by signed policy cookies. Stream playback forwardsCookie,Referer, andUser-Agentheaders to external players (mpv,IINA). Local downloads utilizeyt-dlpwith forwarded authentication headers to demux and assemble audio/video streams into.mp4.
4KHDHub
client.rs::resolve_releaseresolves release mirrors concurrently using bounded-concurrency probing (select_okin batches of 3) with a 3.5s per-probe timeout.- Direct links undergo automatic path percent-encoding normalization (
validate_playback_url) to handle filenames containing unencoded spaces, brackets, and special characters. - Preflight probes issue a bounded range probe (
Range: bytes=0-8191) and inspect response bodies for expired mirror errors ("Failed to extract link","Token Expired","404") to fail fast on expired torrents. hubcloud.rsscores and prioritizes candidate streams (Cloudflare R2 / S3 / Seekable Streams → Storage → PixelDrain API → Google UserContent / Direct Attachments), automatically decoding base64Watch Onlinemirrors (vdplay.pages.dev/?u=...).- Multilingual audio detection:
parser.rs::detect_languageparses release titles and metadata for 30+ regional and international languages (Hindi, Tamil, Telugu, Kannada, Malayalam, Bengali, Marathi, Punjabi, Gujarati, Urdu, Japanese, Korean, Chinese, Spanish, French, German, Italian, etc.) and formats all available audio tracks for stream display. - Errors are mapped into
ProviderError::Unavailablewith user-actionable instructions guiding selection of alternate releases.
BDIX
circleftpanddhakaflixscrape FTP-style indexes; both are used behind the Bangladesh-only gate.
Community HTTP Addons
providers/addonscommunicates with HTTP addon manifests (/manifest.json).- Cinemeta provides catalog searches and metadata details (
/catalog,/meta). - Stream addons (e.g. HdHub, direct CDN manifests) resolve playable HTTP/HTTPS streams concurrently. See addons-mode.md.
M3U playlists (TV mode)
providers/tv parses an M3U playlist from an https:// URL or a local file path.
Each channel yields { id, name, logo, group, stream_url }; TV mode groups channels by
group-title and dedupes by stream_url. See tv-mode.md.
Error handling
Each provider defines its own thiserror enum (ScraperError, FourKHdHubError,
CircleFtpError, DhakaFlixError). Errors bubble to app/requests.rs handlers, which
surface them in the UI status bar and log the full detail (see logging.md).
Players
Playback is handed to an external player. player.rs detects available players and
builds the exact command; tui/app/playback.rs spawns it.
Detection
player::detect() (powered by a centralized probe_player_executable engine) returns players in priority order, resolving paths dynamically with non-negative caching:
- macOS: IINA (if present), then mpv, then VLC (probing
/Applications,~/Applications, Homebrew/opt/homebrew/bin, MacPorts/opt/local/bin, Nix profiles~/.nix-profile/binand/run/current-system/sw/bin, and standard/bin). - Linux: mpv, then VLC (probing native
$PATH, user.local/bin, Flathub/Flatpak user & system exportsorg.videolan.VLC/io.mpv.Mpv, Snap/snap/bin/*, Nix profiles, standard/bin, andflatpak run). - Windows: mpv, then VLC (probing executable-adjacent binaries, WinGet Links & Packages directory
%LOCALAPPDATA%\Microsoft\WinGet\Packages,%USERPROFILE%\Downloadsand%USERPROFILE%\Desktopextractions,Program Filesincludingmpv,mpv-player,mpv.net, andVideoLAN\VLC,LOCALAPPDATA\Programs, portable drive rootsC:\mpv,C:\vlc,C:\tools, Scoop shims & apps, Chocolatey, and Windows RegistryApp PathsandEnvironment\Path). - Android/Termux: Android intent chooser (
termux-open,termux-open-url, ortermux-am). Streams play via external Android video players (VLC for Android, Just Player, MX Player, MPV Android APK).
Resolution caches detected paths across runs while allowing newly installed players to be discovered dynamically when opening or navigating the Settings Hub (/settings), without requiring an application restart. A preferred player can be forced via MOVIEBOX_PLAYER env or default_player in config (e.g. mpv, iina, vlc, android), which reorders the list. The media player picker in the Settings Hub lists every detected player on your system and saves your selection to config.json. Playback launches directly using the preferred compatible player without intermediate modal dialogs.
Command construction
| Player | Invocation | Notes |
|---|---|---|
| mpv | mpv --autofit=WxH --geometry=50%:50% --idle=no --keep-open=no [--start=..] [--script=..] [--script-opts=..] [--http-header-fields=..] [--sub-file=..] <url> | Window sized to the terminal. Injects moviebox_tracker.lua for position tracking and resume. Flatpak mpv is launched via flatpak run. |
| VLC | vlc --width=W --height=H --play-and-exit [--start-time=..] [--http-referrer=..] [--http-user-agent=..] [--sub-file=..] <url> | Supports start time resume via --start-time. |
| IINA | iina-cli --keep-running --no-stdin --mpv-autofit=.. [--mpv-start=..] --mpv-http-header-fields=.. --mpv-sub-files=.. <url> | Uses the installed IINA iina-cli; falls back to open -a IINA <url> only if the CLI is absent. |
| Android / Termux | termux-open --chooser --content-type video/* <url> (or termux-open-url / termux-am) | Opens an app chooser on the device, delegating playback to external apps (VLC, MX Player, Just Player, MPV Android). Requires pkg install -y termux-tools termux-am. Forwards User-Agent, Referer, and subtitles when using termux-am. |
Window size is derived from the live terminal size times the font cell size reported by the image picker, then clamped to a fixed range.
Headers
Playback sources (for example 4KHD and MovieBox) may carry Referer/User-Agent headers.
MovieBox DASH streams additionally carry signed Cookie headers for CloudFront authentication.
mpv/IINA send them via http-header-fields (--http-header-fields=... or --mpv-http-header-fields=...),
while VLC maps them to --http-referrer / --http-user-agent. Android intent playback forwards Referer/User-Agent extras when using am/termux-am, and supports unauthenticated streams (CircleFTP, DhakaFlix, IPTV) and CDN streams natively.
The supports_headers gate in app/playback.rs validates whether a player can satisfy required stream headers. MovieBox-TUI strictly respects the user’s configured default player: if the chosen player cannot satisfy a stream’s headers (such as VLC or Android Player attempting to play signed MovieBox DASH manifests with CloudFront cookie requirements), playback will not silently fall back to an alternative player. Instead, an explicit warning notification informs the user of the exact incompatibility and lists available compatible alternatives (e.g. mpv) or the option to switch providers with Ctrl+P.
Subtitles
- mpv receives the remote subtitle URL directly (
--sub-file=<url>); mpv fetches it with the stream headers applied. - VLC and IINA download the subtitle to a temp file first, preserving the URL’s extension (srt/vtt/ass/…), and pass the local path. The download applies the source headers. On failure a status is shown and playback continues without subtitles.
- Android intent playback passes subtitle paths to
am/termux-amviasubtitles_locationandsubsintent extras. - Temp files are cleaned up after the player exits and purged at startup if stale.
Playback Tracking & Resume
When launching media with in-progress watch history, the player command automatically includes the starting position (--start / --mpv-start / --start-time).
- Immediate Start Registration: Media sessions are pre-registered into watch history (
record_start) upon launch, ensuring that fast-exiting intent dispatchers (Androidtermux-open/am start, macOSopen -a IINA) and unexpected terminal terminations retain history immediately. - Pre-Seeded State Files: Before launching mpv or IINA, MovieBox-TUI creates a pending state file populated with metadata (
title,cover_url,stype,release_year). If the application exits abruptly during playback,reconcile_from_dirself-heals and inserts new items into watch history without data loss. - Latched Lua Tracker (
moviebox_tracker.lua): Observestime-posanddurationevery 5 seconds. State file writes are atomic (.tmpfile flushed and renamed with destination removal for Windows compatibility). Video completion at ≥ 90% or EOF is permanently latched, preventing player shutdown events from resetting completion status. Missing or live stream durations write JSONnullto prevent invalid duration calculations. - Isolated Tracker vs Fallback Reconciliation: Players with active Lua trackers (
mpv,iina-cli) rely strictly on state file reconciliation, eliminating wall-clock progress overwrite races during pauses or seeks. Process elapsed time is used strictly as a guarded fallback for players without tracker scripts (e.g. VLC).
Spawning
launch_player spawns the player with null stdin/stdout, piped stderr, and its own
process group (Unix) or no-console flag (Windows). A blocking task reads stderr and
reports every non-zero process exit as a player error, including failures with no
diagnostic output. Watch progress is reconciled only after a successful exit.
Android / Termux Playback Architecture
On Android (Termux), terminal sessions do not have access to an X11 or Wayland display server by default:
- Command-Line
mpv(pkg install mpv): Operates in headless/audio-only mode. Video output cannot be rendered to the terminal screen and will fail or produce audio without video. - External Player Intent Dispatch: Video playback is designed to open in dedicated Android video player applications (VLC for Android, Just Player, MX Player, or MPV Android APK).
- Prerequisites: Termux requires
pkg install -y termux-tools termux-am.termux-open(fromtermux-tools) broadcasts anandroid.intent.action.VIEWintent toTermuxOpenReceiver, presenting Android’s native app chooser.termux-am(fromtermux-am) connects directly totermux-app’s local Unix domain socket (am.sock), allowing intent parameter passing (includingUser-Agent,Referer, and subtitles).- SELinux & Exit Code 126 Protection: On Android 10+, executing
/system/bin/amdirectly from an unrooted Termux environment causes Android’s system shell to callcmd activity, which is blocked by SELinux when executing Termux app data binaries (Permission denied, exit code 126). MovieBox-TUI detects Termux environments, prevents illegal systemaminvocations, preservesLD_PRELOADfor Termux applet compatibility, and surfaces actionable remediation notifications.
Downloads
The download engine in download.rs streams a video URL to disk with resume, ranges,
and optional segmentation. Orchestration lives in app/download.rs.
How it works
- Single-episode downloads write to
<dest>.partplus a<dest>.part.jsonmetadata sidecar (etag, last-modified, total size, segment count). - Resume: on a retry, the engine checks what is already in the
.partfile and continues from there usingRangerequests. - Segmentation: files above a size threshold can be downloaded in parallel segments (up to a capped count), then stitched.
- I/O Aggregation: Download segment writers are buffered with a 256KB
tokio::io::BufWriter, aggregating incoming 8KB–16KB HTTP response chunks into sequential disk writes and reducing filesystem syscalls by up to 96.8%. - Retries: a failed attempt is retried a limited number of times; 30s idle
- Cancel: an
AtomicBoolcancel flag pauses/resumes cleanly, preserving the partial file for a later resume. - User-Agent: the download HTTP client inherits the active provider’s mobile
User-Agentto prevent CDN stream rejections when downloading media segments. - Stream Engines:
- Progressive Streams (CircleFTP, DhakaFlix, 4KHDHub, Addons): Handled directly by the native Rust multi-segment range downloader, splitting files into parallel chunks with
.partstate tracking. - MPEG-DASH Streams (MovieBox): Multi-track segmented audio/video streams (
index.mpd) requiring CloudFront cookie authentication. Downloaded viayt-dlpwith automatic authentication header forwarding (Cookie,Referer,User-Agent), real-time progress parsing, and track multiplexing into.mp4.
- Progressive Streams (CircleFTP, DhakaFlix, 4KHDHub, Addons): Handled directly by the native Rust multi-segment range downloader, splitting files into parallel chunks with
External Tool Prerequisites
Downloading from MovieBox requires yt-dlp and ffmpeg on the host system to demux and merge MPEG-DASH audio and video streams:
- macOS: Install via Homebrew:
brew install yt-dlp ffmpeg - Linux: Install via your system package manager (e.g.
sudo apt install yt-dlp ffmpeg,sudo pacman -S yt-dlp ffmpeg) - Windows: Install via WinGet or Scoop:
winget install yt-dlp.yt-dlp Gyan.FFmpeg - Android / Termux: Install via Termux package manager:
pkg install yt-dlp ffmpeg
If a MovieBox download is initiated without yt-dlp installed, MovieBox-TUI prevents execution and displays an OS-tailored notification with installation guidance. Progressive streams from other providers (CircleFTP, DhakaFlix, 4KHDHub, Addons) do not require yt-dlp or ffmpeg.
File names and directories
safe_file_stem sanitizes titles for all platforms: control/whitespace/illegal
characters are replaced, Windows reserved names (CON, COM1-COM9, …) are avoided,
and length is capped.
- Series downloads: Saved under
<base_dir>/Series/<Title>/Season <N>/<Title> - S<N:02>E<E:02>.<ext>(and subtitle<Title> - S<N:02>E<E:02>.<lang>.<sub_ext>). - Movie downloads: Saved under
<base_dir>/Movies/<Title>/<Title>.<ext>(and subtitle<Title>.<lang>.<sub_ext>). - Default path: Files go to the user’s OS download directory (
~/Downloads/MovieBox-TUI). On Android-family environments the code prefers sharedstorage/downloadswhen present. - Custom path: Users can set a custom download directory in
/settings→ General → Download Folder or reset to default. Target directories are validated with a write probe before saving, and the code creates theMovieBox-TUIsubfolder hierarchy (Movies/andSeries/). If custom storage becomes unavailable at runtime, the engine falls back to the default download location.
Contextual triggers & Seasons
- Contextual trigger: Pressing
d(or clicking[Download]) while focused on the Seasons pane prompts to download all episodes of the selected season. Triggering download while on the Episodes or Streams pane prompts to download only that single episode. - Duplication prevention: When starting a download or processing a season batch queue, the engine checks if the target media file is already completed on disk. Existing completed episodes are skipped.
- A season download enqueues every episode (
download_queue) and processes them one at a time, each resolving its stream and subtitle. Progress is reported throughAction::UpdateDownloadand the status bar; failures pause and preserve partial data. - Season downloads ask for the subtitle policy once per batch. The selected language, including an explicit
Nonechoice, is reused for every queued episode.
Selected subtitle sidecars are saved next to the video using ISO 639-1 language codes (e.g. .en.srt, .hi.srt) and supported subtitle extensions (.srt, .vtt, .ass, .ssa, .sub).
Download Bar & Progress Architecture
- High-Contrast Responsive Bar: Renders a proportional progress track (
[━━━━━────]on modern terminals and[=====>----]on basic terminals) with prominent media title display (⬇ Downloading: <Title>), percentage badge, and separated transfer metrics (<Size> | <Speed> | ETA <Time>). - Monotonic DASH Normalization: Multi-stream MPEG-DASH downloads via
yt-dlpautomatically normalize segmented tracks (video 0–90%, audio 90–98%, and track merger 99–100%) so that progress strictly increases and never resets backwards to 0% mid-download. - Throttled Updates: Progress events are throttled to 250ms intervals, eliminating terminal flicker and event-channel flooding from high-frequency chunk streams.
- Background Download Continuity: Downloads continue running uninterrupted in the background when switching content providers (
Ctrl+P) or toggling modes (Ctrl+T,Ctrl+A), keeping all active transfer workers and queues alive. - Isolated Cancellation Hitbox: Cancellation is bound strictly to the
x/Xkeyboard shortcut and the[x] Cancelbutton in the top-right corner of the download bar. Clicking anywhere else on the bar safely consumes the mouse event without interrupting active downloads.
Outcomes
DownloadCompleted / DownloadPaused / DownloadFailed drive the UI status and
notifications. ClearCache and stale-file cleanup do not touch in-progress downloads.
Addon Mode (HTTP Addons)
Addon Mode enables support for community HTTP addon manifests. You can install any standard addon manifest URL to fetch metadata catalogs and aggregate direct HTTP/HTTPS media streams.
Features
- Standard Protocol Support: Compatibility with standard addon manifests (
/manifest.json,/catalog,/meta,/stream). - Core Metadata Protection & Fast Resolution: Cinemeta is pre-installed out-of-the-box as the core metadata provider (
[Core]) and locked to prevent accidental removal. Metadata requests prioritize media type resolution with full support for alternate crew fields (directors,writers,stars). - Direct HTTP Stream Engine: Automatically extracts and filters direct Cloudflare R2, PixelDrain, direct video CDN, and HubCloud/HubDrive HTTP streams.
- Multi-Addon Concurrency: Simultaneously queries all enabled stream addons and aggregates releases.
- Quality, Resolution & Codec Parsing: Ranks streams with high-contrast color-coded resolution badges (
4K UHD,1080p FHD,720p HD,SD) and granular audio/video codec tags (HDR,DV,ATMOS,5.1,HEVC,AV1,BluRay,WEB-DL,REMUX), file size in GB/MB, and audio language tracks (e.g.[Dual],[Multi],Hindi + English). - Series & Episode Hierarchy: Series are automatically organized into explicit
SeasonsandEpisodesselector panes with smooth horizontal navigation (←/→/h/l/Tab). Selecting any episode drives episode-specific stream requests (/stream/series/:id:season:episode.json). - Episode Stream Isolation: Built-in token parsing (
parse_season_episode) guarantees that only streams matching the selected season and episode are displayed, eliminating cross-episode stream mixing. - Direct Playback & Custom Headers: Video stream headers (
behaviorHints.headers) such asRefererandUser-Agentare preserved and forwarded directly to external media players (mpv,IINA,VLC) and the multi-segment downloader. - Watch History & Progress Parity: Full
/historysupport in Addon Mode with real-timempvposition tracking, scrub lines, and auto-resume. - High-Performance Caching: Curated
/browsecatalogs are cached for1 hour, manifests for24 hours, and stream aggregations for2 hours.
Entering Addon Mode
Ctrl+A: Toggle / Enter Addon Mode.Ctrl+S: Return to standard Streaming Mode.Ctrl+T: Toggle TV Mode./browse: Browse curated addon catalogs (Top Movies,Top Series,Top Rated Movies,Top Rated Series)./settings→ Content Modes: Enable or disable Addon Mode navigation.
Addon Manager
- Interactive modal listing installed addons with capability badges (
[Core],[Meta],[Streams],[Catalog]). [x] / [ ]: Toggle addon enabled/disabled state (EnterorSpace). Core provider remains locked.[ Add Manifest URL ]: Install any public HTTP addon manifest by URL.[d]or[Delete]: Remove the selected addon (protected for core addons).
Persistence
Installed addons are atomically saved to addons_config.json inside the application config directory (~/Library/Application Support/moviebox-tui/ on macOS, ~/.config/moviebox-tui/ on Linux, %APPDATA%\moviebox-tui\ on Windows). If addons_config.json encounters corrupt data on disk, it is preserved and rotated to addons_config.json.corrupt.{timestamp} before initializing fallback defaults, preventing silent data loss.
TV Mode
TV mode streams live channels from M3U playlists. You add playlists by URL or local file path, and the app parses, groups, dedupes, and lets you search and play them.
Entering TV mode
Ctrl+Ttoggles Streaming / TV mode.- On first entry with no playlists, the playlist manager opens.
- While in TV mode, type to filter channels by name or group,
Enterto play,/listfor all channels,/configto manage playlists,[r]to reload.
Adding playlists
/configopens the playlist manager, split into URL playlists and File playlists.- Select
[ Add URL ]or[ Add file ], type the source,Enterto add.- URL example:
https://example.com/playlist.m3u - File example:
~/playlists/mine.m3u
- URL example:
- Sources persist in
tv_config.json(under the config dir). Local file playlists are reread directly on every TV-mode entry; remote URL playlists may reuse a recent cached snapshot for up to 24 hours. Iftv_config.jsonencounters corrupt data on disk, it is safely rotated totv_config.json.corrupt.{timestamp}rather than deleted. - Highlight a source and press
d(orEnter) to remove it; the list reloads.
Parsing and search
src/providers/tv/ parses each source (http(s) or local file), extracting channel id,
name, logo, group-title, and stream URL. Playlist lines are pre-counted to preallocate vector capacity, eliminating dynamic heap reallocations during large 50,000+ channel imports. Channels are deduped by stream URL
across all playlists. The search box filters by name or group; the status bar reports
how many channels were imported and which playlists failed.
Playback
Enter on a channel launches the default player with the channel URL (via the same
launch_player path as movies). Channel logos are cached under the iptv image
namespace.
Commands in TV mode
/list— display all loaded TV channels.[r]key — reload all active M3U playlist sources.- Global commands (
/settings,/clear,/help,/exit) are active across all modes. - Streaming/Addon-only commands (e.g.
/browse,/history,/favorites) display friendly guidance notifications prompting you to switch modes (Ctrl+SorCtrl+A).
Architecture
MovieBox-Tui is a terminal client (ratatui + crossterm + tokio) for streaming movies, series and TV channels from multiple providers. This document describes the shape of the code and how data flows through it.
Module map
src/
main.rs entry point: logging init, panic hook, raw mode,
alternate screen, App::new + App::run
lib.rs crate root, module declarations
cache.rs disk cache: provider-namespaced, TTL'd, atomic writes
config.rs Config load/save (config.json)
download.rs download engine (resume, ranges, segments, retry)
favorites.rs starred-titles persistence (favorites.json)
history.rs watch history persistence
logging.rs file logging (rotation, sanitization)
models.rs shared domain models (SearchResult, BrowseMetrics, StreamPool,
Notification, SubjectIdentity)
net.rs fallback DNS resolution, HTTP client builder, URL validation
player.rs player detection (OnceLock) and command construction (mpv/VLC/IINA/Android)
providers/
mod.rs provider module tree
models.rs shared typed models (ProviderKind, CatalogItem,
MediaDetails, Release, PlaybackSource, …)
moviebox/ primary provider (client + request signing)
fourkhdhub/ 4KHDHub provider (client, hubcloud resolver, parser)
bdix/circleftp/ BDIX CircleFTP provider
bdix/dhakaflix/ BDIX DhakaFlix provider
addons/ Community HTTP addons provider
tv/ Live TV / IPTV provider (M3U parser and models)
service.rs MovieBoxService headless engine (search, details, streams, captions)
updater/ GitHub release update check (mod, check, download, verify,
extract, apply, artifact)
tui/
app/ the application object and all behavior
mod.rs App struct, App::new, helpers
run.rs terminal event loop (run), rendering (draw),
and handle_action dispatcher (thin routing table)
network.rs poster fetch + provider dispatch helpers
search.rs search command routing, search request setup,
provider search dispatch, poster prefetch
playback.rs player launching + playback actions
download.rs download orchestration actions
favorites.rs favorite toggle/open actions, /favorites virtual list
requests.rs suggest/history/homepage/details/preview/
episode-stream actions
navigation.rs list navigation, submit actions, provider helpers
tv.rs TV mode: playlist manager + playback
addons.rs Addon mode: addon manager + HTTP addon actions
keyboard.rs raw key-event handling
mouse.rs mouse click handling and hitbox routing
system.rs help, refresh, cache, theme, updates, focus, resize
state.rs AppState: all UI state + in-memory LRU caches
action.rs the Action enum (event/message model)
commands.rs Slash command registry, parsing, and suggestions
event.rs EventHandler: input events + tick → Action channel
overlay.rs popups, pickers, notifications
screens/ render-only modules (home, details, help)
terminal.rs terminal capability probes
theme.rs color themes
widgets/ reusable widgets (badge, input, modal, poster, scrollbar, settings)
text.rs grapheme-safe text helpers and zero-allocation cursor slicing
The event loop
App::run (in app/run.rs) owns the only loop:
- If
clear_terminal_before_drawis set, the terminal buffer is cleared. - If
state.dirty, the screen is drawn (App::draw). tokio::select!waits for either:- an
Actionfrom theEventHandler(keyboard/mouse/focus/resize/tick), or - an
Actionpushed by a background task (network results, downloads, posters).
- an
EventHandler (event.rs) spawns one task that reads crossterm events and a Tick
interval, forwarding them into the action channel (capacity 128).
Async model
- The tokio runtime is multi-threaded (
rt-multi-thread). - State is single-threaded: all mutations to
AppStatehappen insidehandle_action, which is driven by the single event-loop task. Actions are serialized through the channel, so there are no data races on UI state. - Network uses async
reqwestclients (one per provider) plus per-provider signing. - Blocking work (disk cache reads/writes, image decoding, M3U parsing, watch-history
save, log cleanup) runs on
tokio::task::spawn_blockingso the event loop is never blocked. - Background tasks send
Actionmessages back (e.g.SearchSuccess,EpisodeStreamsReady,DownloadCompleted), whichhandle_actionconsumes.
Data flow — a typical search
- User types a query; the
Keyhandler updatessearch_queryand sendsAction::Search. handle_actionresolves the active provider, dispatches to the provider client (async), and spawns the request in a background task.- On success the task sends
Action::SearchSuccess;handle_actionstoressearch_results, marksdirty, and writes the provider search cache. - Posters for result rows are fetched by background tasks and delivered via
SearchPosterLoaded/PosterSuccess; image protocols are cached per terminal. App::drawrenders the results;dirtyis cleared.
Playback flow
- User selects a result →
Action::PlayStream(moviebox) or 4KHDHub/BDIX resolve. - The provider resolves a
PlaybackSource(url + optional headers/subtitle). launch_playerbuilds the player command (player.rs), optionally downloads the subtitle to a temp file, and spawns the player with null stdin/stdout and piped stderr; a blocking task waits and reports crashes.- Playback is handed to mpv / VLC / IINA / Android intent per the active player.
Configuration and persistence
config.json— settings (mode persistence, mode toggles, theme, provider, auto-update,default_player, download directory, BDIX) in the config dir.addons_config.json— installed HTTP community addons in the config dir.tv_config.json— user M3U playlist sources (URLs or file paths) in the config dir.history.json— watch history in the system data dir.favorites.json: starred titles in the system data dir, independent ofhistory.json.playback/— temporary playback states for session crash/kill reconciliation in the system data dir.scripts/— bundled player scripts (moviebox_tracker.lua) in the system data dir.- Cache lives under the system cache dir, keyed per provider.
- Logs live under the system data dir with rotation.
See config.md and logging.md for exact locations and formats.
Modules
The crate (moviebox_tui) is split into top-level modules and, inside tui, an app
directory that holds the application object. Below is the full tree with each module’s
responsibility.
src/
main.rs Entry point. Logging init, panic hook, raw mode, alternate
screen, TerminalGuard, App::new + App::run.
lib.rs Crate root: declares pub mod cache/config/download/favorites/
history/logging/models/net/player/providers/service/tui/updater.
cache.rs Disk cache: provider-namespaced directories, TTL expiry,
atomic temp-file writes, payload validation, background purge.
config.rs Config struct: load/save config.json (mode persistence,
mode toggles, provider, theme, auto-update, default player,
download directory, bdix flag).
download.rs Download engine (pure, async): resume via .part files,
HTTP ranges, optional multi-segment download, retries, cancel
via an AtomicBool, Windows-safe file stems.
favorites.rs Starred titles: read/write favorites.json, whole-title identity
dedupe via SubjectIdentity, no cap.
history.rs Watch history: read/write history.json, dedupe exact
provider/subject/episode entries, cap 100.
logging.rs File logging: flexi_logger, rotation (5MB, keep 3),
MOVIEBOX_LOG level, URL/path sanitization for sharing.
models.rs Pure domain data models: SearchResult, BrowseMetric,
BrowsePreset, BrowseMetrics, SubjectStreamPool, Notification,
SubjectIdentity (cross-provider identity rules shared by
history and favorites).
net.rs Shared HTTP plumbing: FallbackResolver (hickory DNS reading the
OS configuration, falling back to Cloudflare/Google/Quad9 when
absent) wired into every reqwest client via
net::http_client_builder().
player.rs Player detection (OnceLock) and command construction for
mpv / VLC / IINA / Android intent, subtitle args, headers,
terminal-sized window.
player/
tracker.rs Injected Lua tracker script (`moviebox_tracker.lua`) and
periodic 5-second playback state auto-saving.
providers/
mod.rs Module declarations.
models.rs Shared typed models (ProviderKind, CatalogItem, MediaDetails,
Release, PlaybackSource, RequestContext, SourceMirror) and
canonical JSON domain adapters.
moviebox/ Primary provider.
client.rs Async reqwest client with signed requests (anti-bot).
crypto.rs Request signing: HMAC-MD5 signature, client token,
spoofed device identity (by design of the scraper).
title.rs clean_moviebox_title: strip quality/site suffix noise.
fourkhdhub/ Secondary provider.
client.rs Search/details/stream resolution + preflight validation.
hubcloud.rs Mirror resolver: fetch drive pages, extract playable links.
parser.rs HTML parsing into typed CatalogItem/MediaDetails/Release.
bdix/
circleftp/ BDIX CircleFTP provider (client + parser).
dhakaflix/ BDIX DhakaFlix provider (client + parser).
addons/ Community HTTP addons provider (client, aggregator, adapter, models).
tv/ Live TV / IPTV provider (models + M3U parser).
service.rs MovieBoxService: unified multi-provider headless client &
engine (suggest, search, details, homepage, resolutions,
captions, subtitle download, path resolution).
updater/ GitHub release update check.
mod.rs Module declarations, re-exports, perform_self_update orchestration.
check.rs GitHub release API query (with redirect fallback) and version compare.
download.rs Release asset download (https-only) with retry.
verify.rs SHA-256 hashing and sha256sums parsing for artifact verification.
extract.rs tar.gz / archive extraction for the staged binary.
apply.rs Swap in the new binary, install-environment detection, restart.
artifact.rs Release/ReleaseAsset types, target-platform matching.
tui/
action.rs The Action enum: every UI event/message (input, network
results, downloads, playback, tv, system).
commands.rs Slash command registry (SlashCommand enum, argument parsing,
availability filters, dynamic suggestions, descriptions).
state.rs AppState: all UI state, LRU image/preview caches, and the
PlayerKind enum + label()/parse(), tv manager row model.
event.rs EventHandler: crossterm event stream + tick interval,
forwards to the action channel.
overlay.rs Popups: notifications, pickers, confirmation, modal centering.
screens/
home.rs Home/startup + search list rendering (streaming and TV).
details.rs Details screen rendering.
help.rs Keybinding help (mode-aware).
terminal.rs Terminal capability probes (basic UI, image querying).
theme.rs Color themes + terminal color detection.
text.rs Grapheme-safe text input buffer (TextInputBuffer) and width/truncation helpers.
widgets/ Centralized UI widgets subsystem.
badge.rs Resolution pill badges and audio/video media tag extraction.
input.rs Single-line text input field rendering with grapheme cursor and truncation.
modal.rs Modal dialog frame builder (ModalFrame) and centered footer key action bars.
scrollbar.rs Viewport-accurate vertical scrollbars.
poster.rs Standardized poster placeholder container with in-flight loading animation.
settings.rs Interactive 4-tab Settings Hub modal widget.
tui/app/ The application object (App) and all behavior.
mod.rs App struct, App::new, and small helpers.
run.rs App::run (event loop), App::draw (rendering), and
handle_action dispatcher (thin routing table over action groups).
network.rs fetch_poster_bytes, decode_poster, provider_search,
provider_details.
search.rs Search-mode command routing, search state setup, provider
search dispatch, poster prefetch helpers.
requests.rs handle_requests: suggest/history/homepage/details/preview/
episode-streams/poster actions.
playback.rs handle_playback: play/subtitle/picker/launch/crash actions
+ launch_player.
download.rs handle_download: download orchestration + start_resilient_download.
favorites.rs handle_favorites: toggle/open favorite actions, /favorites virtual
list builder.
navigation.rs handle_navigation + provider/nav helpers.
keyboard.rs handle_key: raw key-event handling.
mouse.rs handle_mouse: mouse click routing and hitboxes across screens,
popups, tabs, buttons, and dialogs.
system.rs handle_system: tick/quit/focus/resize/help/refresh/cache/
theme/status/updates.
tv.rs handle_tv: playlist manager + TV actions.
addons.rs handle_addons: addon manager + HTTP addon actions.
See architecture.md for the event loop, async model and data flow, and the per-topic docs for details.
Cache
Disk caching lives in cache.rs; in-memory caches live in AppState.
Disk layout
<cache dir>/moviebox-tui/
<provider>/ moviebox, fourkhdhub, bdix_circleftp, bdix_dhakaflix, addons
search/<hash>_<page>.cache
details/details_<schema><hash>.cache
streams/<schema><hash>_<season>_<episode>.cache
images/<hash>.img
moviebox/
homepage/home_<tab>_<page>.cache
captions/captions_<hash>.cache
addons/
catalogs/catalog_<hash>.cache
manifests/manifest_<hash>.cache
streams/<hash>_<season>_<episode>.cache
tv_playlists/<md5>.m3u cached remote playlist snapshots
The cache directory is dirs::cache_dir()/moviebox-tui (macOS
~/Library/Caches, Windows %LOCALAPPDATA%, Linux $XDG_CACHE_HOME).
Properties
- Binary MessagePack Envelopes: Cache entries are serialized with
rmp-serdewrapped in a binary envelope starting with the 4-byte magic signatureMBC1and an 8-byte TTL timestamp (CacheEnvelope<T>). Legacy JSON files are read and migrated on the fly. - Fast Table-Lookup Hex Hashing: Cache file naming and key hashing in
md5_hexuses static 16-byte lookup table encoding, eliminating dynamiccore::fmt::writeformatting allocations and speeding up digest encoding by 2.51x. - Provider namespacing: Keys include
provider.cache_key(), preventing collisions across sources. - Atomic writes: Entries are written to a unique temp file (
path.with_extension("tmp-PID-STAMP")) and atomically replaced (durable_replace), preventing truncated or corrupt files on unexpected exits. - Validation: Empty search or stream results are never written or served from cache.
- Purge: Background cleanup runs at startup to delete entries older than 7 days.
/settings→ Maintenance → Clear Disk Cache recursively empties all cached provider responses, images, TV playlists, temporary subtitles across Android/Windows/Unix, resets in-memory LRU caches, and cancels in-flight background request tasks.
In-memory caches (AppState)
image_cache(30),search_posters(300),failed_posters(300),search_poster_protocols(300),preview_cache(30):lru::LruCachefor poster images, negative lookup cache, and terminal image protocols;stream_pool: resolved streams per subject.
All disk access in async code is wrapped in tokio::task::spawn_blocking so the event
loop never blocks. Failures are logged (see logging.md) and treated as
cache misses.
Logging
The app writes a file log so issues invisible in the TUI (full error text, URLs, statuses, content-types) are recorded and can be shared.
Location
- macOS:
~/Library/Application Support/moviebox-tui/logs/ - Windows:
%LOCALAPPDATA%\moviebox-tui\logs\ - Linux:
$XDG_DATA_HOME/moviebox-tui/logs/(else~/.local/share/moviebox-tui/logs/)
The active file is moviebox-tui_rCURRENT.log; rotated files are
moviebox-tui_r00000.log, ….
Behavior
- Level is controlled by
MOVIEBOX_LOG(off|error|warn|info|debug|trace). Default iswarnin release builds,infoin debug builds. - Rotation: rotates at 5MB and keeps 3 files.
- Terminal output: normal log lines go only to the file without writing to stdout or stderr, preventing screen bleed before entering alternate screen mode. Setup errors (if any) are reported on
stderr. - Session header: version, OS, and the log path are written on startup.
- Panics: the panic hook logs the payload to the file, then restores the terminal.
--versionand--helpnever create a log file.
What is logged
error: hard failures (all-hosts exhausted, resolve failures, player spawn/crash, download failures, panics) and everyError:status the UI shows.warn: recoverable issues (mirror rejected, subtitle unavailable, cache write failed, GitHub rate limit).info: session start, playable mirror found, playback launch.debug: full request context (enable withMOVIEBOX_LOG=debug).
Privacy / sharing
Logs are sanitized so they can be pasted into a GitHub issue:
- URLs are reduced to
scheme://host— file tokens, filenames, and query params are removed. - Absolute paths are rewritten to
~so your username does not appear. - Headers,
Authorization, search queries, and watch history are never logged.
Reproduce the problem, then attach the current log file. See debugging.md.
Cross-platform
Build targets: macOS, Linux, Windows, and Android (Termux via the Linux ARM64
binary). The codebase uses
crossterm (all platforms), ratatui, and a couple of small per-OS branches.
“Build target” does not mean every runtime integration is verified on every
device. Desktop builds are covered by CI; external players and Termux require
the release checks in release-checklist.md.
OS notes
| Platform | Notes |
|---|---|
| macOS | IINA preferred player (via the installed IINA iina-cli); VLC/mpv .app paths detected. process_group(0) on spawn. |
| Windows | mpv/VLC detected via Program Files + %LOCALAPPDATA%; path-safe file stems; static MSVC CRT linking (+crt-static) for zero-dependency standalone binaries; handle-safe atomic download replacement (dropping file handles before renames); background process spawning (registry queries, yt-dlp downloader, and update helper) hardened with canonical CREATE_NO_WINDOW (0x08000000). |
| Linux | Flatpak mpv/VLC supported (flatpak run …); xdg data/cache dirs. |
| Android (Termux) | Targets aarch64-linux-android linked against the Android NDK (Clang API 24+) and system Bionic libc.so, producing a native ELF executable with a valid PT_PHDR program header table and /system/bin/linker64 dynamic loader. This eliminates Could not find a PHDR: broken executable? crashes and executes natively without on-device compilation. Includes a pure-Rust DNS resolver that reads system configuration and falls back to public resolvers (Cloudflare, Google, Quad9) for zero-config name resolution. Android playback delegates to external video players (VLC for Android, Just Player, MX Player, MPV Android) via Termux intent dispatchers (termux-open, termux-open-url, termux-am), requiring pkg install -y termux-tools termux-am. To protect against Android 10+ SELinux execute restrictions (exit code 126), system /system/bin/am fallbacks are strictly avoided in Termux; LD_PRELOAD is preserved for Termux applets while PATH is sanitized for system calls. Android intent playback supports unauthenticated streams (CircleFTP, DhakaFlix, IPTV) and standard CDN streams (4KHDHub). Real-device chooser behavior is a release prerequisite. |
Terminal capabilities
The app probes the terminal at startup via ratatui_image (400ms cap,
off the UI thread). Non-graphics terminals (e.g. macOS Apple_Terminal,
legacy Windows conhost, and TERM=dumb/linux/cygwin) are skipped to
prevent escape sequence probe leakage (Gi=31...):
- Poster rendering: Sixel, Kitty, and iTerm2 protocols where the probe
detects them. Terminals that report kitty/sixel capability but no cell
size (Windows Terminal sixel, iTerm2 over SSH) are salvaged with default
cell metrics. On terminals lacking graphics support (e.g. standard Windows
PowerShell, legacy console host, macOS Terminal.app), search result cards
and details screens display standardized bordered containers with centered
No Artindicators, ensuring consistent layout geometry without confusing broken blocks. automatically gated behindhas_active_modal()to prevent graphic bleed through modal popups and overlays.MOVIEBOX_NO_IMAGE=1disables queries;MOVIEBOX_IMAGE_PROTOCOLforces a protocol (kitty,sixel,iterm2);MOVIEBOX_CELL_SIZE=WxHoverrides metrics. - Colors & Themes: With no explicit theme,
NO_COLORwins, then truecolor RGB (auto-detected across Ghostty, Kitty, WezTerm, iTerm2, Alacritty, Foot, Windows Terminal, Hyper, Tabby, Warp, and VSCode; enabled by default on Windows 10/11 console host and Windows Terminal), quantized 256-color palettes for strict terminals, and a tuned high-contrast 16-color ANSI fallback palette (Theme::fallback) using crisp cyan accents; an OSC 11 background query picks light/dark variants. Light mode themes (including Catppuccin Latte) are tuned for WCAG AA compliance, ensuring high-contrast readability across light terminal backgrounds. Modal pickers feature clean transparent border backdrops, minimum 7-row breathing room, and background selection suppression to isolate dialog focus. An explicitMOVIEBOX_THEMEor saved theme always wins over autodetection. - Keyboard & Cursor: The kitty keyboard protocol (disambiguated escapes, event
types) is requested at start and popped on exit; unsupported terminals
ignore it. Real input cursor styling (
SetCursorStyle::SteadyBar) activates during text editing modes on supported terminals. - Loading & Progress Indicators: Unicode Braille loading spinners (
⠋ ⠙ ⠹ ...) render during search, metadata discovery, and stream fetching, falling back to clean text indicators (..) on basic/dumb terminals. - Window Titles: Contextual terminal emulator window titles are emitted dynamically
reflecting active navigation mode and title (
MovieBox-Tui — Streaming,MovieBox-Tui — Live TV,MovieBox-Tui — Addons,MovieBox-Tui — {Title}). - Terminal classification:
TERM=dumb/linuxfall back to a basic UI. - Focus events re-render in place without clearing; results render in two columns from 110 columns wide (three from 160).
- Responsive Installers: Both Unix (
install.sh) and Windows (install.ps1) installation scripts query terminal width dynamically (tput cols/stty size/$Host.UI.RawUI.WindowSize.Width), adapting the header across wide (72-column block art), compact (31-column 2-line half-block art for mobile/Termux portrait mode), and minimal (text-only) tiers with dynamic horizontal centering to prevent line wrapping.
Network & TLS portability
- TLS Engine: Uses
rustlswith embedded Mozilla roots (webpki-roots) across all targets (macOS, Linux, Windows, Android/Termux). The release binary has no OpenSSL runtime dependency; theringcryptography backend is compiled into the binary by the platform build toolchain. - DNS Resolution: Pure-Rust resolver (hickory) on all platforms: it reads the OS
configuration first (
/etc/resolv.conf, registry on Windows) and falls back to embedded public resolvers (Cloudflare1.1.1.1, Google8.8.8.8, Quad99.9.9.9) when no system configuration exists — as on Android/Termux or minimal containers. No JNI orndk-contextrequired.
In-App Self-Update Engine
MovieBox-TUI embeds an in-app binary upgrade engine (src/updater/) with cross-platform environment detection and deterministic fallback:
- Direct Replacement: Supported on Linux (
x86_64,aarch64), macOS (Universal binary), and Windows (x64,arm64). Downloaded release archives are validated against SHA-256 checksums, unpacked to temporary staging files, and swapped atomically with rollback on failure. - Windows Helper Script: On Windows, because running executables are locked by the OS, an external transient batch helper (
moviebox_update_helper.bat) waits for the parent process PID to terminate, attempts atomic binary replacement with a 5-iteration retry loop (to tolerate antivirus/SmartScreen file locks), restarts the application, and self-deletes. - Homebrew Managed Environments: Automatically detected via path markers (
/Cellar/,/opt/homebrew/,/usr/local/Cellar/,/home/linuxbrew/). In-app binary overwrites are disabled to protect package manager integrity; the update modal displays Homebrew instructions (brew upgrade moviebox-tui) with a dedicated[b]shortcut. - Android / Termux: Protects Termux environments from overwriting bionic libc binaries with incompatible Linux glibc binaries. Instructs users to re-run the universal installer script (
curl -fsSL ... | bash). - Deterministic GitHub Asset Fallback: When GitHub API requests are unauthenticated or rate-limited (status 403), tag resolution falls back to HTTP redirects, and asset download URLs are computed deterministically from release tags rather than failing update operations.
- Input Isolation & Event Locking: Update notifications defer blocking modal presentation while typing in search mode (
InputMode::Editing) to prevent keystroke hijacking. During in-flight update execution (is_updating), all keyboard and mouse events are locked while displaying an active Braille progress spinner.
Things to verify per release
- Player launch on each OS (mpv/VLC/IINA/Android intent) — window sizing, subtitles, headers.
- Poster rendering across Sixel (Windows Terminal, foot), Kitty, iTerm2, and basic non-graphics terminals.
- TV mode with a sample M3U playlist (URL and local file).
- Addon Mode with sample HTTP addon manifests (Cinemeta, torrent/stream addons).
- Termux: on-device check that Play opens the Android chooser and the stream plays.
Testing & QA Architecture
This document describes the testing architecture, quality assurance procedures, and validation guidelines for MovieBox-TUI.
1. Test Architecture
The test suite comprises 320+ automated tests across 10 test suites (213 unit tests in src/lib.rs and 110 integration tests across 9 focused suites in tests/), running fully offline by default without mocking or live network dependencies.
The MovieBox-TUI test architecture follows a strict separation of concerns:
MovieBox-TUI/
├── src/
│ └── **/*.rs # Pure algorithms & inline unit tests (#[cfg(test)])
└── tests/
├── common/
│ └── mod.rs # Shared test utilities & temporary directory helpers
├── fixtures/
│ └── addons/
│ └── manifest.json
├── settings_hub.rs # Interactive Settings Hub modal tab navigation, choices, & option rows
├── tui_acceptance.rs # Headless TUI rendering, theme rendering, and resize matrix
├── update_lifecycle.rs # Update single-flight checks, modal hitboxes, & platform assets
├── content_pipeline.rs # Content/metadata pipeline, stale request isolation, & cache keys
├── addons_manifest.rs # Addon manifest deserialization & catalog checks
├── error_handling.rs # Failure state cleanup, error toasts, and recovery
├── history_audit.rs # Cross-mode watch progress, series advancement, & boundary audit
├── favorites_lifecycle.rs # Favorites persistence, identity, and navigation lifecycle
├── performance_audit.rs # Empirical benchmark measurements (truncation, hashing, M3U, draw latency)
└── live_stream_verification.rs # Live MovieBox CDN signed stream & resolution verification (opt-in)
A. Inline Unit Tests (src/**/*.rs)
Inline unit tests live inside #[cfg(test)] mod tests blocks within their respective modules. They verify:
- Title normalization (
clean_moviebox_title) - HMAC-MD5 cryptographic signing and token generation (
generate_x_client_token,generate_x_tr_signature) - Segment partitioning math and byte range calculations
- Internal helper logic, parsing functions, and release asset matching
- Update modal layout geometry calculations and semver comparisons
B. Subsystem Integration Tests (tests/*.rs)
Integration tests live in the tests/ directory and test externally observable behaviors without mocking internal types:
settings_hub.rs: Validates the interactive Settings Hub modal tabs, choices, dynamic player detection refresh, mode toggles, and appearance settings.tui_acceptance.rs: Validates headless TUI rendering, all theme palettes, end-to-end user journeys (search, details, navigation, mode switching), mouse click and scroll interactions, modal dismissals, and terminal resize matrices across 8 standard and boundary dimensions without panics.update_lifecycle.rs: Validates update single-flight concurrency barriers, error recovery on network failure, modal actions, checksum integrity verification (valid, mismatch, missing, multi-format), archive extraction with strict path traversal rejection (..), active work protection (playback and download guards), environment detection (Homebrew, ReadOnly, DirectReplace), and safe atomic binary replacement/rollback.content_pipeline.rs: Validates stale metadata response protection (request_idvalidation), cache key dimensional isolation, search failure vs empty result status distinction, mode-switch stale response isolation, poster image identity mapping, and search preview fallback metadata isolation.addons_manifest.rs: Validates deserialization of Cinemeta/Stremio addon manifests, multi-season episode decomposition, episode stream isolation (parse_season_episode), token and codec parsing, core Cinemeta protection, and addon enabling/disabling lifecycle.error_handling.rs: Validates active player session lifecycle, playback debounce guards, search failure cleanup, stream and download resolution failure notifications, URL scheme rejection, and authoritative player bypass protections.history_audit.rs: Validates cross-mode watch progress, series advancement and completion tracking, threshold boundaries for in-progress states, history disk persistence roundtrips, Lua tracker reconciliation, update precision preservation, repeated play deduplication, and/historysearch list integration.favorites_lifecycle.rs: Validates Favorites persistence boundaries, identity deduplication,/favoritesloading, landing-row navigation, and independence from watch-history clearing.performance_audit.rs: Validates empirical performance benchmarks and regression thresholds across algorithmic hot paths (SIMD text truncation, MD5 hex table lookup, M3U capacity preallocation, and headless frame draw latencies).live_stream_verification.rs: Validates real-world stream link resolution across MovieBox signed CDN endpoints and 4KHDHub multi-mirror releases. The tests are#[ignore]-gated for offline execution; opt in withcargo test --test live_stream_verification -- --ignored.
2. Running Automated Tests
Run the full test suite (all unit and integration tests):
cargo test --all-features --locked
Run only unit tests:
cargo test --lib --all-features --locked
Run a specific integration test:
cargo test --test settings_hub --all-features --locked
cargo test --test tui_acceptance --all-features --locked
cargo test --test history_audit --all-features --locked
Run the opt-in live-network acceptance test:
MOVIEBOX_LIVE_TESTS=1 cargo test --test real_acceptance --all-features --locked -- --ignored
3. Code Hygiene and Static Analysis
Every commit and pull request must pass all hygiene checks:
# Check formatting
cargo fmt -- --check
# Compiler check
cargo check --all-targets --all-features --locked
# Clippy linter with warnings treated as errors
cargo clippy --all-targets --all-features --locked -- -D warnings
# Security vulnerability scan
cargo audit
4. Manual QA Matrix
Because TUI and media player interactions depend on terminal capabilities and external processes, manual QA testing covers:
Terminal Emulators
- Ghostty (Primary testing terminal)
- macOS Terminal.app
- iTerm2
- Windows Terminal
- Linux VTE / Alacritty / Kitty
- tmux session & pane switching
Supported Media Players
- mpv (Full IPC tracking, script options, state reconciliation)
- VLC (Local playback and stream forwarding)
- IINA (macOS native player integration)
- termux-open / Android Intents (Android Termux)
Key Flows to Verify
- Search & Browse: Type queries, switch between MovieBox, 4KHDHub, BDIX, Addons, and Live TV.
- Playback Launch & Return: Launch stream in player, exit player, verify terminal state is cleanly restored without residual escape sequences.
- History & State: Verify playback progress and watched checkmarks update accurately.
- Downloads: Test single episode and batch season download queuing.
5. Performance Verification & Benchmarking Guidelines
All performance optimizations in MovieBox-TUI must be backed by empirical before-and-after measurements. Changes without quantitative verification must be classified as refactors or code cleanups, not performance improvements.
A. Required Benchmark Measurements
When submitting or claiming a performance improvement, measure and report exact deltas:
-
CPU & Algorithmic Hot Paths:
- Measure wall-clock duration using
std::time::Instantacross ≥ 1,000 iterations. - Run benchmarks on release builds (
cargo test --releaseor isolated binary harness) to reflect production compiler optimizations. - Report: Baseline vs. Optimized duration in microseconds (µs) or milliseconds (ms), plus relative speedup (N×).
- Measure wall-clock duration using
-
Memory & Allocations:
- Count heap allocations and memory footprint deltas on hot paths (e.g., zero-copy slices vs. cloned
StringorVec). - Report: Total allocations eliminated or reduction percentage.
- Count heap allocations and memory footprint deltas on hot paths (e.g., zero-copy slices vs. cloned
-
TUI Render Latency:
- Measure full frame draw cycles using headless
TestBackend:#![allow(unused)] fn main() { let backend = TestBackend::new(120, 30); let mut terminal = Terminal::new(backend).unwrap(); let start = std::time::Instant::now(); for _ in 0..1_000 { terminal.draw(|f| app.draw(f)).unwrap(); } let avg_us = start.elapsed().as_micros() as f64 / 1_000.0; } - Report: Average draw duration per frame across standard terminal dimensions (80x24, 120x30).
- Measure full frame draw cycles using headless
-
I/O & Syscalls:
- Quantify eliminated filesystem operations (e.g. cache lookups, redundant directory reads) or network roundtrips.
- Report: Number of disk reads/writes or HTTP requests saved per action.
-
Release Binary Footprint:
- Measure stripped release binary size (
target/release/moviebox-tui). - Report: Baseline size, optimized size, and exact byte/kilobyte delta.
- Measure stripped release binary size (
B. Standard Performance Reporting Format
Document benchmark results in PR descriptions, commit messages, or changelog entries using this structured format:
Benchmark: [Subsystem / Hot Path Name]
- Baseline: [value] [unit] (e.g. 142.3 µs / op, 84 allocs)
- Optimized: [value] [unit] (e.g. 12.1 µs / op, 2 allocs)
- Delta: [multiplier]x faster (-[percentage]% allocations)
- Target: [Architecture / OS, e.g. Apple M3 / arm64-darwin, release profile]
Debugging
The app writes a sanitized file log so full errors are available even though the TUI only shows a short status line. See logging.md for location and settings.
Reproducing an issue
- Run with debug logging:
MOVIEBOX_LOG=debug moviebox-tui - Reproduce the problem (search, open details, play, download, TV).
- Grab the current log file (path printed at startup, and in the log’s session header):
- macOS:
~/Library/Application Support/moviebox-tui/logs/moviebox-tui_rCURRENT.log - Windows:
%LOCALAPPDATA%\moviebox-tui\logs\moviebox-tui_rCURRENT.log - Linux:
$XDG_DATA_HOME/moviebox-tui/logs/moviebox-tui_rCURRENT.log(else~/.local/share/moviebox-tui/logs/moviebox-tui_rCURRENT.log)
- macOS:
- Include it when opening an issue.
What to include in a GitHub issue
- The version (
moviebox-tui --version). - Operating system and terminal (e.g. macOS + iTerm2, Windows + Windows Terminal, Termux).
- The player used, if the issue is playback.
- The log file (sanitized — safe to share; URLs and paths are redacted).
Reading the log
Each line is [timestamp] LEVEL [module:line] message. Focus on ERROR lines first;
WARN lines explain recoverable fallbacks (e.g. a 4KHD mirror rejected, subtitles
unavailable). With MOVIEBOX_LOG=debug you also get request context.
Known quick checks
- “Player unavailable” → no mpv/VLC/IINA detected; set
MOVIEBOX_PLAYERor install one. - “no playable mirrors” on 4KHD → all mirrors were rejected by the preflight; the log lists each mirror and the reason.
- TV mode “no channels” → playlists failed to load; the log names the failing source.
Release Checklist
Use this before calling a new build production-ready. Static gates are necessary but not sufficient for this project because player launch, terminal rendering, and Termux chooser behavior depend on the real runtime environment.
1. Static gates
Run the repository checks first:
cargo fmt --check
cargo clippy --all-targets --all-features --locked -- -D warnings
cargo check --all-targets --all-features --locked
cargo test --all-features --locked
cargo audit
cargo package --locked
Confirm the entire unit and integration test suite passes on the CI host matrix
(docs/testing.md). Release targets that are cross-compiled must at least build
cleanly and pass the release workflow’s target-binary --version smoke test; they
still require native player/runtime checks before release certification. A local
host without the target C/linker toolchain cannot substitute for that runner result.
Known gap: the Windows ARM64 binary is built and published but never executed by the
release workflow (x64 runners cannot run it); smoke-test it manually, e.g. under
Windows on ARM emulation or a native ARM64 device, before certifying a release.
Confirm the main GitHub Actions workflows are green:
CIReleasePublish to Crates.iowhen applicableUpdate Homebrew Formulawhen applicable
If you manually dispatch Publish to Crates.io or Update Homebrew Formula,
run them against the explicit release tag, not a branch head.
2. Desktop playback checks
Verify at least one real playback launch on each supported desktop OS:
- macOS: IINA and/or mpv/VLC
- Linux: mpv and/or VLC
- Windows: mpv and/or VLC
For each checked platform, confirm:
- the player launches from MovieBox-Tui
- the window size is reasonable
- playback works for a source with no extra headers
- playback works for a source carrying
Referer/User-Agent - subtitles still attach for mpv / VLC / IINA
3. Terminal rendering checks
Verify poster rendering on the terminal families the docs claim to support:
- Kitty protocol terminal
- Sixel-capable terminal
- iTerm2 protocol terminal
- Non-graphics basic terminal (clean text placeholder)
Confirm:
- posters appear on search/details screens
- resize redraw still works
- focus loss/gain redraw does not corrupt the screen after returning from playback
4. TV mode checks
Verify TV mode with both supported playlist source types:
- remote
http(s)M3U - local file M3U
Confirm:
- playlist import succeeds
- broken playlists report an error without breaking the app
- dedupe by stream URL still behaves correctly
/configand/listwork in TV mode- channel playback launches the player
5. Termux / Android checks
Verify on a real Termux device before calling the desktop release production-ready:
- app starts normally
- app does not reproduce the historical
rustls-platform-verifierinitialization panic Playopens the Android chooser throughtermux-openor/system/bin/am- chosen player starts playback
- downloads still go where the docs describe
This remains mandatory because chooser behavior is device/environment dependent.
6. Release artifact checks
Verify the published release contains:
- expected archives for macOS, Linux x64, Linux arm64, Windows x64, and Windows arm64
SHA256SUMS- working install scripts / formula references
Spot-check:
install.shinstall.ps1- Homebrew formula install path
Exit criteria
Only call the release production-ready when:
- all static gates pass
- the relevant GitHub Actions workflows pass
- the runtime checks above were performed on real target environments
- no open blocker remains in
docs/known-issues.mdfor the release target
Known issues and limitations
Tracked here so future work and issue reports reference the same facts.
Latent / by-design
supports_headersis compatibility policy, not just a parser guard. Sources that carry authentication headers (e.g. MovieBox CloudFront signed cookies) exercise it for Android intent and VLC playback. Android intent and VLC players support unauthenticated streams (CircleFTP, DhakaFlix, IPTV, direct streams) as well as streams with standardreferer/user-agentheaders (4KHDHub). Streams requiring custom cookies or auth tokens trip the compatibility gate and guide the user to mpv. Keepplayer.rs::supports_headersin sync with VLC and Android opener capabilities.- BDIX clients use nested
if let Okpyramids in search handling; they work and are logged, but are harder to read. Flattening is deferred (behavior-neutral refactor with moderate churn). - MovieBox request signing hardcodes an API secret and spoofs a device identity in
crypto.rs. This is inherent to the scraper; treat the module as one unit. - Android intent playback forwards
User-Agent,Referer, and subtitles (subtitles_location/subs) when usingamortermux-am. Chooser-based launches viatermux-openopen the raw video URL directly.
Environment-dependent
- 4KHDHub mirrors rotate and can be expired on upstream hosts. Direct streams are resolved concurrently across all available release mirrors using prioritized scoring (Cloudflare R2 / S3 / Seekable Streams → Storage → PixelDrain API → Google UserContent / Direct Attachments) and bounded concurrency (
select_okin chunks of 3). When all upstream mirrors for an older release are dead/expired (e.g. 404 or expired tokens), the resolver fails fast (<4.5s) and guides the user to select another release. - Termux playback needs the device confirmed on each release:
termux-open/amavailability and the Android chooser behavior. The historicalrustls-platform-verifierinitialization panic reported for v0.1.12 is not in the v0.1.13 dependency graph, but the upstream report remains open until a real Termux launch is observed.
Verification
- Automated testing is enforced via
cargo test --all-features --lockedcovering 346+ unit and integration tests across 21 test suites (seedocs/testing.md). The count is updated when tests change; it does not replace real-player and real-device verification. - Static correctness is enforced by strict compiler type checking, the lint gate (
cargo clippy --all-targets --all-features --locked -- -D warnings), formatting (cargo fmt --check), dependency vulnerability scanning (cargo audit), and packaging verification (cargo package --locked). - Runtime and platform-specific behavior (terminal resize, focus handling, external player launch, and Termux chooser) are verified through the release checklist in
release-checklist.md.
Contributing to MovieBox-Tui
Thanks for taking the time to contribute. Bug reports, ideas, docs improvements, and pull requests are all welcome.
If you’re planning a large or breaking change, please open an issue first so we can talk it through before you invest significant time.
Getting set up
You’ll need Rust 1.90 or newer (edition 2024). Install it via rustup.rs.
# Fork on GitHub, then clone your fork
git clone https://github.com/<your-username>/MovieBox-Tui.git
cd MovieBox-Tui
# Add the upstream remote to keep in sync
git remote add upstream https://github.com/mesamirh/MovieBox-Tui.git
# IMPORTANT: Enable our pre-commit hooks to ensure your code formatting and lints pass
git config core.hooksPath .githooks
# Build and run
cargo run --release
To test playback and download features locally, install mpv (see Media Players).
Project layout
The app is message-driven and organized into focused modules. Full maps live in
docs/architecture.md and docs/modules.md.
Short version:
src/tui/app/: The application object (App).run.rsholds the thinhandle_actiondispatcher that routes everyActionto ahandle_*method in its module (run.rs,requests.rs,search.rs,playback.rs,download.rs,navigation.rs,tv.rs,addons.rs,keyboard.rs,mouse.rs,system.rs,network.rs).src/tui/: UI state, event loop plumbing, slash commands (commands.rs), screens, themes.src/providers/: HTTP clients for streaming sources (moviebox,fourkhdhub,bdix), community HTTP addons (addons/), and Live TV playlists (tv/).src/service.rs: Unified headless multi-provider client & engine.src/download.rs: Background media downloading.src/cache.rs: Local disk caching to minimize API calls.
The app is message-driven. User input and background tasks produce Action values,
handled by the dispatcher in src/tui/app/run.rs. When adding behavior, prefer adding a
new Action variant over blocking the UI thread.
Workflow
- Create a branch off
main:git checkout main git pull upstream main git checkout -b feat/short-description - Make your change in small, logical commits.
- Push and open a pull request against
main.
Local Checks & Pre-Commit Hook
Formatting and linting are enforced automatically: the pre-commit hook (enabled during
setup with git config core.hooksPath .githooks) runs cargo fmt --check and
cargo clippy --all-targets --locked -- -D warnings on every commit, and the
commit is rejected if either fails. You do not need to run them manually before every
commit, but you should still run the full local/CI parity checks before opening a PR or
cutting a release.
If the hook rejects a commit, run cargo fmt to auto-fix the formatting, then stage and
commit again.
For release readiness, static checks are not enough on their own. Before declaring a
release production-ready, work through docs/release-checklist.md.
Guidelines:
- Follow idiomatic Rust and standard
rustfmtdefaults. Don’t hand-format. - Keep the async, message-passing architecture intact.
- Avoid panics on paths that handle network or user input.
- Don’t add new dependencies without a good reason. Mention it in the PR if you do.
Commit messages
Follow Conventional Commits. Keep the subject concise and in the imperative mood.
Examples:
feat: add support for custom mpv argumentsfix: prevent panic when clipboard is unavailabledocs: document /browse categoriesrefactor: extract stream resolution into helper
Common types: feat, fix, refactor, docs, style, perf, chore.
Pull requests
- Keep PRs focused on a single concern. Large PRs mixing unrelated changes may be asked to be split.
- In your PR description, explain what changed and why. Link related issues (
Closes #12) and include screenshots or recordings for anything visible in the UI. - Never commit
target/, editor settings, or debug dump files.
License
By contributing, you agree that your contributions will be dual-licensed under the MIT and Apache-2.0 licenses, consistent with the rest of the project.
Changelog
[0.1.18] - 2026-09-06
Added
- Minimal Update Available Modal & Indented Release Notes:
- Formatted release notes into a clean, scannable indented hierarchy under
Release Notes:with category badges ([Added],[Fixed]) and bullet points, displaying concise feature titles without decorative tree glyphs, block prefixes (▌), or multi-line duplicate text walls. - Stripped decorative star icons and redundant prompt sentences, keeping the header focused on a clean, high-contrast version diff (
Installed: vX.Y.Z → Latest: vX.Y.Z). - Separated dialog sections with subtle horizontal card divider lines (
─) and dedicated action button pills ([u] Update Now,[o] Open Release Page,[Esc] Dismiss).
- Formatted release notes into a clean, scannable indented hierarchy under
- Calm, Minimal Self-Updating Progress Dialog:
- Redesigned
draw_updating_modalinto a calm, focused card with top and bottom border clearances, eliminating visual crowding against the title and frame. - Streamlined the in-flight display into a unified active status line with spinner (
⠋ Downloading MovieBox-Tui v.../⠋ Installing MovieBox-Tui v...) and a cross-platform safety warning (⚠ Please wait • do not close terminal/[!] Please wait - do not close terminal).
- Redesigned
Fixed
- Landing Screen ASCII Banner Bleed-Through:
- Modal Frame Corner Backdrops & Transparent Halos:
- Removed block-level background color overrides from
ModalFrame, eliminating dark rectangular halos and square pixel spillage around rounded corner glyphs (╭,╮,╰,╯) across transparent and custom terminal themes.
- Removed block-level background color overrides from
- Update Modal Geometry & Border Clearances:
- Widened the modal from 72 to 76 columns to align with standard dialog geometry and provide a generous 3-column safety margin, preventing text lines and bullet points from crowding the outer borders.
- Search Bar Synthetic Cursor Artifacts:
- Removed artificial block glyphs (
▎/█) drawn directly into search input paragraphs, relying on native terminal cursor positioning without visual cursor duplication or blinking redraw churn.
- Removed artificial block glyphs (
- README Walkthrough Media Attachment:
- Formatted the WebM walkthrough attachment link in
README.mdanddocs/README.mdfor native inline playback.
- Formatted the WebM walkthrough attachment link in
- CI Performance Benchmark Runner Tolerance:
- Bound wall-clock timing assertion tolerances during unoptimized debug test execution in
tests/performance_audit.rs, eliminating flaky runner noise failures across virtualized CI runners while maintaining release regression bounds.
- Bound wall-clock timing assertion tolerances during unoptimized debug test execution in
Performance
- Zero-Allocation Text Truncation Pipeline (
src/tui/text.rs):- Implemented SIMD
is_ascii()fast path inwidthand migratedtruncate_widthtoCow<'a, str>, eliminating 100% of heap allocations on fitting titles and text spans. - Reduced 10,000-operation truncation latency from
5,243.5µsto246.2µs(21.3x faster,524.3ns -> 24.6ns/op) under release compiler profile on Apple Silicon. - Streamlined
truncate_middle_widthto construct output into a single preallocated buffer, eliminating intermediateVec<&str>, reversal, and concatenation allocations.
- Implemented SIMD
- Table-Lookup Hex Encoding (
src/cache.rs):- Replaced 16 dynamic
core::fmt::writedispatches per MD5 digest with direct 16-byte static lookup table indexing inmd5_hex. - Reduced 10,000-digest hashing latency from
4,597.9µsto1,829.8µs(2.51x faster,459.8ns -> 183.0ns/op).
- Replaced 16 dynamic
- Preallocated IPTV M3U Playlist Parser (
src/providers/tv/parser.rs):- Added newline-count capacity preallocation to
M3UParser::parse_m3u, eliminating repeated dynamic vector reallocations during large playlist loads and achieving352.0µsparse duration for 500-channel playlists.
- Added newline-count capacity preallocation to
- Buffered Downloader Chunk Write Aggregation (
src/download.rs):- Wrapped segment file descriptors in
tokio::io::BufWriter::with_capacity(256 * 1024), aggregating incoming 8KB–16KB HTTP response chunks into sequential 256KB disk blocks and eliminating up to 96.8% of unbuffered filesystem write syscalls.
- Wrapped segment file descriptors in
- TUI Draw Loop Allocation Pruning (
src/tui/screens/home.rs,src/tui/screens/details.rs):- Eliminated redundant
display_title.clone()and duplicate Unicode width calculations in search result and landing deck render loops, delivering headless draw latencies of32.3µs/frame(80×24),43.4µs/frame(120×30), and67.3µs/frame(160×40).
- Eliminated redundant
[0.1.17] - 2026-09-06
Added
- Anchored Provider Selection Menu:
- Replaced immediate mouse cycling on the landing search bar provider badge (
[MovieBox · ^P]) with a styled popup menu anchored directly beneath the provider badge. - Added dedicated keyboard navigation (
↑/↓/k/j,Home/End,Enter/Space,Esc) for the provider menu while preserving directCtrl+Psequential provider cycling across all screens. - Implemented shared geometry (
search_bar_provider_pill_rectandprovider_popup_bounds) between renderers and mouse hitboxes, ensuring exact alignment and zero geometry divergence.
- Replaced immediate mouse cycling on the landing search bar provider badge (
- Redesigned High-Contrast Download Bar & Responsive Layout:
- Replaced the solid rectangular download gauge with a sleek proportional track (
[━━━━━────]on modern terminals and[=====>----]on basic terminals) with filled accent contrast and dimmed surface rail. - Added prominent media title indicators on the top border (
⬇ Downloading: <Title>or⬇ S<N>E<N> (<current>/<total>): <Title>) with bold styling and automatic terminal width truncation. - Replaced ambiguous whole-area click cancellation with an isolated
[x] Cancelbutton hitbox on the top-right border, preventing accidental download interruptions while keeping the bar mouse-safe. - Formatted transfer statistics into clean badges (
<Size> | <Speed> | ETA <Time>) with zero unclosed parenthesis artifacts and zero floating dots.
- Replaced the solid rectangular download gauge with a sleek proportional track (
- Details Screen UX & UI Deduplication:
- Replaced repetitive audio language strings in the metadata header with a concise summary badge (
N Audio Tracks), reserving line space for genre tags and IMDb ratings. - Eliminated the redundant workflow breadcrumb bar on wide/desktop layouts where selector columns are already visible side-by-side, reclaiming a vertical display row to show more episodes without scrolling.
- Standardized selector list typography and cursor alignment, eliminating irregular bullet padding and double-space indentation across Audio, Season, and Episode items.
- Deduplicated stream table columns by showing clean CDN/provider origins under
SOURCEand stripping redundant resolution/codec suffixes from theRELEASEcolumn. - Added count context to pane titles (
Audio (N),Seasons (N),Episodes (N)), providing immediate visibility into available content quantities.
- Replaced repetitive audio language strings in the metadata header with a concise summary badge (
- Native Android ARM64 Release Target & Pipeline:
- Added native
aarch64-linux-androidbuild target to the release workflow (.github/workflows/release.yml) using Android NDK r26d and Clang (API 24+). - Configured automated packaging of
MovieBox_Android_arm64.tar.gzwith native Bionic dynamic linking (libc.so), valid ELFPT_PHDRprogram header table, and/system/bin/linker64dynamic loader. - Added Android ELF header validation in CI to verify
PT_PHDRand/system/bin/linker64presence, preventingCould not find a PHDR: broken executable?aborts on Android devices. - Updated universal installer script (
install.sh) to detect Android Termux on 64-bit ARM and automatically fetchMovieBox_Android_arm64.tar.gzwith verified SHA256 checksums, enabling 1-second native installation without on-device compilation.
- Added native
- Native mdBook & GitHub Pages Documentation Architecture:
- Integrated
mdBookdocumentation engine reading directly from canonicaldocs/*.mdguides with zero duplicated markdown files and zero third-party web frameworks. - Added
docs/SUMMARY.mddefining table-of-contents chapter navigation across all guides, architecture diagrams, and operational workflows. - Added
docs/installation.mddetailing complete installation instructions for macOS (curl script and Homebrew tap), Linux, Windows (PowerShell), Android (Termux), Cargo, and source builds. - Formatted
docs/README.mdas the book’s introductory landing page featuring core capabilities, prerequisites player matrix, and the live terminal demonstration video streamed from the GitHub CDN. - Added minimal root
book.tomlwithnavydark theme, collapsible sidebar navigation, and client-side full-text search. - Added automated GitHub Actions deployment workflow (
.github/workflows/pages.yml) publishing the documentation site to GitHub Pages on every push tomain. - Added documentation build integrity validation step in CI hygiene pipeline (
.github/workflows/ci.yml).
- Integrated
Changed
- Codebase Cleanups, Dead Code Removal & Shared Logic Centralization:
- Removed obsolete compatibility forwarders and dead code (
render_favorites_landing,remove_last_grapheme,pad_to_width,ctrl_key, and unused shortcut constants). - Centralized
theme_colorinsrc/tui/theme.rs, eliminating duplicate definitions across widgets and screens. - Centralized favorite status lookups for active details into
AppState::is_selected_details_favorited, unifying 30-line duplicate calculations in details screen rendering and mouse hitbox detection. - Unified subtitle picker label formatting (
"None"->"No subtitles", language sanitization) intoformat_subtitle_label. - Consolidated details pane border, title, and selection styling through
pane_styles, eliminating over 50 lines of duplicate style branching. - Streamlined details footer action definitions into declarative primary/secondary group builders, cutting redundant code blocks while preserving exact keybindings and layout.
- Hardened cross-platform process spawning by unifying the Windows
CREATE_NO_WINDOW(0x08000000) flag into a canonical constant inplayer.rs. - Decoupled network URL validation by moving
is_http_urltocrate::net, eliminating backend network provider dependencies on the TUI text formatting module.
- Removed obsolete compatibility forwarders and dead code (
Fixed
- Global Modal Background Unfocus & Dimming:
- Automatically unfocused and dimmed all background components across Details, Home, and Runner views whenever any modal or popup dialog is active, replacing bright active borders, focus bullets, and selection highlight rectangles with dimmed styling (
theme.muted). - Dimmed background resolution badges (
Multi,4K,1080p, etc.) and provider origin tags to muted styling (theme.mutedon surface backgrounds) during active modal popups, preventing neon badge colors from competing with foreground dialogs. - Dimmed unselected list items across Audio dubs, Seasons, Episodes, and Search Results to
theme.muted, eliminating bright white text bleeds in the background. - Dimmed background footer shortcuts and download bar elements during open dialogs, ensuring visual focus remains strictly on the active foreground popup.
- Suppressed terminal graphics protocol rendering for background posters when a modal dialog is open, preventing image pixels from bleeding over foreground confirmation dialogs.
- Automatically unfocused and dimmed all background components across Details, Home, and Runner views whenever any modal or popup dialog is active, replacing bright active borders, focus bullets, and selection highlight rectangles with dimmed styling (
- Stream Table Source Column Resolution:
- Prioritized specific mirror and uploader labels (
file.source_label()) in the stream tableSOURCEcolumn before falling back to generic provider names, displaying actual source tags (Pahe.in,PSA,NF,GalaxyRG, etc.) when present while retaining provider fallbacks for direct CDN streams.
- Prioritized specific mirror and uploader labels (
- MovieBox DASH Progress Normalization, Throttling & Background Continuity:
- Normalized multi-stream MPEG-DASH download percentages across video (0–90%), audio (90–98%), and merger (99–100%) stages, eliminating progress resets back to 0% when the video stream finishes and the audio stream begins.
- Enforced monotonic progress tracking and throttled progress event emissions to 250ms intervals, eliminating terminal text jitter and channel saturation.
- Preserved active downloads and queue processing across content provider switching (
Ctrl+P) and mode toggling (Ctrl+T,Ctrl+A), eliminating premature download pauses and false cancellation warnings when navigating the TUI. - Added explicit cancellation feedback notifications when dismissing the subtitle selection popup via
Escor outside mouse click, preventing silent stream launch cancellations.
- Empty Search Clear Guarding on Landing Screen:
- Guarded search-cleared status notifications in
Action::GoBack,c/C, andCtrl+Uto only fire when an active search query or loaded results actually existed, eliminating spurious “Search cleared.” status messages when navigating on an already-empty landing page. - Allowed pressing Enter on an empty search input in editing mode to cleanly switch back to normal mode without triggering unneeded state resets.
- Guarded search-cleared status notifications in
- MovieBox DASH Stream Download Engine & Header Authentication:
- Forwarded mirror authentication headers (
Cookiecontaining CloudFront signed policy andReferer) throughAction::StartDownloadandstart_resilient_download, eliminatingHTTP 403 Forbiddenerrors on MovieBox CDN downloads. - Added dedicated MPEG-DASH stream engine utilizing
yt-dlpto assemble multi-track audio/video manifests (index.mpd) into.mp4, maintaining full feature parity with progressive single-file downloads. - Integrated real-time child process progress parsing (
parse_ytdlp_progress), reporting live percentage, speed, and ETA metrics to the TUI status bar. - Implemented dynamic, OS-tailored installation guidance for
yt-dlpandffmpegwhen missing from the host system (Homebrew on macOS, package managers on Linux, WinGet on Windows, and Termuxpkg install yt-dlp ffmpegon Android). - Hardened Windows background process spawning with
CREATE_NO_WINDOWand added cross-platform path resolution fallbacks for macOS Homebrew, Nix, and Termux environments. - Preserved external subtitle sidecar retrieval alongside DASH video downloads, maintaining clean
<base_dir>/Movies/<Title>/and<base_dir>/Series/<Title>/Season <N>/directory hierarchy.
- Forwarded mirror authentication headers (
- Series Season Default & Episode List Rendering Normalization:
- Initialized unselected series search results with
season: 0, preventing catalog season counts from masquerading as watch history progress and erroneously defaulting multi-season shows (e.g. Breaking Bad) to their final season on initial selection. - Guarded history pre-seeding in search submission strictly to
/historyqueries and active continue-watching items, ensuring search results always open at Season 1 Episode 1 for new series while resuming at the user’s progress for previously watched shows. - Authoritatively resolved target season and episode in
DetailsSuccess, preserving in-view season and episode positions across audio dub switches while defaulting fresh series navigation to Season 1 Episode 1. - Replaced
"· "unwatched episode status prefix with clean whitespace padding, eliminating double middots (· · EP 01) and stray dots before unselected episodes in the details pane. - Guarded duration formatting against empty strings in
MediaDetails, eliminating duplicate bullet dividers (· ·) in the metadata header for series without runtime durations.
- Initialized unselected series search results with
- Accurate Playback & Download Preparation Notifications:
- Replaced misleading “Fetching subtitles” toast notifications during stream and episode download preparation with accurate stream preparation notices (
Preparing <filename>...andResolving episode stream...), eliminating false subtitle retrieval messages when streams rely on embedded subtitles or contain no external captions. - Clarified external subtitle download failure status to
External subtitle unavailable; playing stream directly.to prevent ambiguity when video containers carry built-in subtitles. - Standardized download mirror error notice to
No downloadable mirrors were found for this release.and normalized notification title casing.
- Replaced misleading “Fetching subtitles” toast notifications during stream and episode download preparation with accurate stream preparation notices (
- MovieBox Subtitle Resolution & High-Speed Multi-Tier Aggregation:
- Implemented multi-tier subtitle resolution in
MovieBoxService::get_ext_captionswith immediate early-exit (< 250ms) when the active stream provides rich subtitles (≥ 5 tracks), eliminating 15–20 superfluous sibling network round-trips that previously triggered 15-second playback resolution timeouts. - Replaced sequential nested loops for sibling dub crawls with concurrent parallel dispatch via
futures::future::join_all, bounding multi-dub subtitle aggregation (e.g. Ek Deewane Ki Deewaniyat) to < 1.2s. - Added asynchronous background subtitle cache pre-warming in
Action::EpisodeStreamsReady, fetching and caching subtitle options as soon as streams are received so that pressing Enter on a stream yields an instant < 1ms cache hit. - Resolved full multi-language subtitle availability (English, Bengali, Arabic, Chinese, Filipino, French, Hindi, Indonesian, Malay, Portuguese, Punjabi, Russian, Urdu) on MovieBox by linking genuine upload
resourceIdidentifiers to releases instead of internal CDN transcoding stream IDs. - Filtered out 34-byte dummy placeholder caption files returned by transcoding endpoints and deduplicated subtitle tracks by language and download URL.
- Added automatic fallback to subject resources in
MovieBoxService::get_ext_captionswhen a stream ID does not directly attach captions. - Added
in_idlanguage code mapping tosanitize_language_labelfor localized Indonesian subtitle display. - Registered
draw_subtitle_pickerinApp::draw, restoring the visual “Subtitles” modal picker overlay during stream playback and download preparation when external captions exist. - Tightened modal picker vertical height calculation in
picker_layout, eliminating blank gap lines between the last list item and the bottom divider for short lists. - Hardened
Action::PlayStreamerror handling with structured diagnostic warnings on subtitle timeout or resolution failure before dispatching direct playback.
- Implemented multi-tier subtitle resolution in
- Termux Android Player Exit Code 126 & Intent Bridge Resolution:
- Eliminated
Player Error: Crash code: 126 (/system/bin/am[11]: /data/data/com.termux/files/usr/bin/cmd: Permission denied)crash in Termux on Android 10+ by prioritizing native Termux openers (termux-open,termux-open-url,termux-am) and strictly avoiding unprivileged/system/bin/amshell script calls. - Preserved
LD_PRELOADfor Termux applet compatibility while prepending system paths (/system/bin:/system/xbin) for system command invocations. - Added actionable diagnostic notifications when player execution fails or when no player is detected in Termux, directing users to install
termux-tools termux-amand verify an external Android player (VLC, Just Player, MX Player). - Updated universal installer (
install.sh), README, and documentation guides withtermux-amprerequisites and architecture details explaining external Android video player integration versus headless CLImpv.
- Eliminated
- Android Intent Player Stream Compatibility:
- Eliminated blanket player incompatibility errors on Android: unauthenticated streams (CircleFTP, DhakaFlix, IPTV, direct streams) and streams carrying standard
Referer/User-Agentheaders (4KHDHub) now dispatch directly to Android video players viatermux-openoram start. - Added empty-header guard to
supports_headers, ensuring streams without authentication requirements are never falsely rejected as incompatible. - Forwarded
User-Agent,Referer, and subtitles (subtitles_locationandsubs) as intent extras when dispatching playback viaamortermux-am. - Prevented circular provider switch prompts when playing 4KHDHub streams by tailoring notification hints based on the active provider.
- Eliminated blanket player incompatibility errors on Android: unauthenticated streams (CircleFTP, DhakaFlix, IPTV, direct streams) and streams carrying standard
- Documentation Mobile Layout & Typesetting Normalization:
- Replaced unparsed LaTeX syntax (
$\to$,$\ge$,$\mu\text{s}$,$N\times$) across all documentation guides with standard Unicode characters (→,≥,µs,N×), eliminating raw unrendered markup in mdBook output. - Added responsive documentation stylesheet (
docs/custom.css) integrated viabook.toml, enabling smooth touch horizontal scrolling, compact cell padding, visible scrollbars, and dynamic code text wrapping across mobile and small screen viewports. - Formatted provider matrix table in
docs/providers.mdwith explicit column alignments and bold provider labels to optimize scannability on narrow screens.
- Replaced unparsed LaTeX syntax (
Changed
- Documentation Readability & Typography Polish:
- Expanded reading container width (
--content-max-width: 860px) and relaxed line-height (1.62em) with vertical list spacing (0.45em) indocs/custom.css. - Added theme-adaptive inline code badge containers (
:not(pre) > code) with bordered backgrounds, and framed<pre>code blocks with rounded corners and drop shadows. - Added table row hover transitions and container borders across configuration, platform, and player documentation tables.
- Implemented responsive mobile header title scaling (
.menu-title) and smooth anchor navigation scrolling (scroll-behavior: smooth).
- Expanded reading container width (
[0.1.16] - 2026-09-05
Added
- Home Landing Deck Continue Watching & Multi-Tab Navigation:
- Implemented interactive multi-tab landing deck on the Home screen supporting both
Continue WatchingandFavorites. - Added seamless
TabandShift+Tabkeyboard cycling between Continue Watching and Favorites tabs with instant row focus retention. - Added one-click/key direct resume (
Enter,Space, orP) on Continue Watching items, automatically configuring episode advancement, season positioning, and auto-play in Details view. - Formatted Continue Watching rows with title truncation, series episode badge (
S01E03), progress percentage, and remaining duration (45% · 24m left). - Added mouse support for clicking the landing deck header bar to switch tabs, and double-clicking items to play/open.
- Implemented interactive multi-tab landing deck on the Home screen supporting both
- Windows TrueColor & High-Contrast Terminal Theming:
- Enabled 24-bit TrueColor auto-detection by default on Windows 10/11 (
conhost.exe, Windows Terminal, PowerShell, CMD), ensuring Windows users receive rich Catppuccin themes out of the box. - Overhauled 16-color ANSI dark fallback palette (
Theme::fallback), replacing low-contrast dark blue and magenta with high-contrast cyan accents for borders, titles, headers, and highlights. - Added background row selection suppression in Settings Hub when modal popups (media player picker, theme picker, download directory input) are active, directing 100% of user focus to floating dialogs.
- Clamped popup picker minimum height to 7 rows, eliminating visual crowding on single-item selections.
- Elevated active selection surface styling to
theme.surface1with accent-highlighted cursor indicators (▌/▸) across lists and settings rows.
- Enabled 24-bit TrueColor auto-detection by default on Windows 10/11 (
- In-App Self-Update Engine Hardening:
- Added deterministic fallback download URL generation for GitHub release assets and
SHA256SUMSwhen unauthenticated API requests encounter HTTP 403 rate limits. - Added active in-flight self-update progress modal (
draw_updating_modal) featuring animated Braille spinners, version upgrade indicators (v{old} → v{new}), and real-time status steps. - Added environment-aware update modal actions: displays Homebrew upgrade instructions (
brew upgrade moviebox-tui) with[b]shortcut on Homebrew installations, Termux installer guidance on Android, and package manager notifications on read-only installations. - Added 5-iteration retry loop with bounded 1-second backoff in the Windows update helper script (
moviebox_update_helper.bat) to tolerate transient file locks from antivirus or Windows search indexers during binary replacement. - Cached full
Releasemetadata inAppStateand action pipeline, eliminating duplicate network queries between release checking and self-update invocation.
- Added deterministic fallback download URL generation for GitHub release assets and
- Empirical Performance Standards & Benchmark Testing Guidelines:
- Added strict performance verification standards requiring empirical before-and-after measurements (runtime latency, allocations, frame render latency, I/O syscalls, binary footprint) across hot paths.
- Documented standardized performance benchmark reporting format in
docs/testing.mdfor reproducible optimization audits.
- Centralized Poster Placeholder & UI Animation Widgets:
- Extracted reusable
render_poster_placeholderwidget tosrc/tui/widgets/poster.rs, standardizing placeholder containers, loading dots, and geometry clamping across Home and Details screens. - Centralized
loading_spinnerinsrc/tui/widgets, providing uniform ASCII fallback (..,...) on basic terminals and animated Braille frames on modern terminals. - Added zero-allocation cursor helpers (
cursor_prefix_str,cursor_column_offset,cursor_split_parts) toTextInputBuffer, replacing dynamic vector and string allocations with zero-copy slices during typing and cursor blinking. - Added
step_list_selectiontosrc/tui/state.rs, centralizing bounds-safe list stepping for PageUp and PageDown navigation across browse, theme, and favorites lists. - Added
clear_poster_cacheandclear_poster_protocolstoAppState, guaranteeing consistent flushing of in-flight requests, LRU image handles, and terminal protocols across provider switches and search resets.
- Extracted reusable
Removed
- Poster Graphics Configuration & Halfblocks Engine:
- Removed Unicode Halfblocks poster engine (
▀/▄), eliminating low-resolution cell distortion, font scanlines, and terminal redraw lag during list scrolling. - Removed redundant
Poster Graphicstoggle from Settings Hub (/settings$\to$ Appearance) andconfig.json, delegating terminal graphics strictly to automatic native GPU protocol detection (Kitty, Sixel, iTerm2).
- Removed Unicode Halfblocks poster engine (
Fixed
- Cross-Platform Handle Safety & Silent Failure Elimination:
- Fixed Windows file sharing violation (
ERROR_SHARING_VIOLATION) in multi-segment download assembly by explicitly flushing, syncing, and dropping the file write handle before executing destination renames. - Added overwrite handling on destination collisions during download finalization on Windows, preventing failed renames on re-downloaded media.
- Guarded
FavoritesManager::load_from_pathagainst premature corrupt file rotation on transient read errors, matching history and configuration persistence invariants. - Hardened Lua tracker script and state file directory initialization to return
Noneon directory creation or write failures rather than passing non-existent paths to media players. - Handled web browser launch failures in Settings Hub (
open::that), logging warnings and displaying the repository URL on headless or restricted environments. - Added
CREATE_NO_WINDOWflag (0x08000000) to the Windows update helper process spawn to eliminate console window flashes during in-app updates.
- Fixed Windows file sharing violation (
- Resilient Cross-Platform Cache Clearing & In-Flight Task Isolation:
- Hardened
clear_all_cachewith recursive directory contents deletion, leaving the root directory node intact to preventERROR_ACCESS_DENIEDandERROR_SHARING_VIOLATIONfailures when Windows processes or shells hold folder handles. - Added Windows read-only attribute clearing before unlinking locked files.
- Included external Android subtitle cache directory (
~/storage/downloads/moviebox_subs) and temporary system subtitle caches in the cache purge sequence. - Connected
Action::ClearCachedirectly toself.request_tasks.cancel_all()and added cancellation guards inspawn_search_posters, preventing in-flight background requests from writing stale responses or posters immediately after cache clearance. - Propagated concrete filesystem
Result<(), String>toAction::CacheCleared, replacing hardcoded success notifications with real error reporting.
- Hardened
- Unified Search Result Selection Background:
- Unified search result card selection highlight across the entire item slot (
item_area), eliminating fragmented background rendering between cursor indicators, posters, and text columns. - Removed redundant poster sub-area buffer clearing before image rendering, preventing selection background clipping and black gutter artifacts on the right edge of posters.
- Unified search result card selection highlight across the entire item slot (
- High-Precision Playback Tracking & Race Elimination:
- Eliminated wall-clock race condition where process elapsed time overwrote exact seek/pause positions from
mpvandiina-cliLua trackers. - Hardened
moviebox_tracker.luawith latched completion: reaching $\ge 90%$ playback or EOF permanently latches completion, preventing shutdown events from reverting completed status. - Implemented atomic state file persistence in Lua using temporary files (
.tmp) and clean destination replacement for Windows and Unix platforms. - Handled unknown stream durations by writing JSON
null, preventing zero-duration calculations. - Pre-registered media playback on launch (
record_start), ensuring immediate watch history persistence for Android intent dispatchers (termux-open,am start) and app fallbacks. - Added self-healing recovery in
reconcile_from_dir: pre-seeded pending state files carry metadata (title,cover_url,stype,release_year), restoring new items into watch history even after sudden terminal exits or reboots. - Implemented smart series episode advancement: completing an episode automatically cues the next episode (
episode + 1or next season) on resume (Space/P) and in the Details view.
- Eliminated wall-clock race condition where process elapsed time overwrote exact seek/pause positions from
- Details View Empty Stream Source Label Geometry:
- Replaced verbose empty stream message with a compact string (
No stream sources found on {provider} (Ctrl+P to switch provider, r to retry)), preventing awkward multi-line text wrapping on standard 80-column terminals.
- Replaced verbose empty stream message with a compact string (
- Standardized ‘No Art’ Poster Containers Across Terminals:
- Replaced robot eyes and broken infinite loading spinners with clean, static, centered
No Artbordered blocks across search results and details screens on terminals without graphics support. - Preserved full-fidelity native GPU graphics rendering on supported terminals while standardizing card geometry and poster container boundaries across all platforms.
- Gated background poster network requests and CPU image decoding strictly behind
image_supported, eliminating redundant network bandwidth and CPU cycles on standard terminals.
- Replaced robot eyes and broken infinite loading spinners with clean, static, centered
Changed
-
Provider Switching Shortcut:
- Scoped
Ctrl+Pstrictly to Streaming Mode for provider cycling, eliminating redundantCtrl+Phandling in TV and Addon modes. - Streamlined
/configas a direct alias for/settings.
- Scoped
-
Pruned Redundant Theme Slash Command:
- Removed standalone
/themeslash command, parser routing, and auto-suggestions; theme selection and visual palette swatches are managed directly within the interactive Settings Hub (/settings$\to$ Appearance $\to$ Theme).
- Removed standalone
-
Discover Categories Landing Card UX:
-
Clean Segmented Landing Deck Header Styling:
- Replaced crowded decorative star (
★) and bracket ([ ]) glyphs with a clean, segmented tab bar header (Continue Watching │ Favorites (Tab)). - Streamlined overflow row formatting to centered minimalist pill indicators (
+N more · /historyand+N more · /favorites). - Streamlined
Discover & Quick Categoriescard: elevated/browsecommand to a right-aligned header badge ([ /browse ]), eliminated redundant/browse ·row prefixes, and adapted category rows dynamically between Streaming and Addon modes. - Added direct mouse click navigation to discover categories, routing clicks to preset browse queries or the addon catalog menu.
- Replaced crowded decorative star (
-
Command Dispatch & Cache Lookup Optimization:
- Unified
ParsedCommandandSlashCommandinto a single canonical enum, eliminating duplicate type definitions across command dispatch and testing. - Streamlined image disk cache lookups (
get_namespaced_image_cache), eliminating 6-iteration fallback namespace scans across unrelated provider directories on cache misses. - Replaced duplicate
is_termux_envin player module withcrate::updater::artifact::is_termux_environment.
- Unified
-
Automation Workflows & Installer Hardening:
- Added bounded execution timeouts (
timeout-minutes) across all CI and release pipeline jobs to prevent runner hangs. - Accelerated release preflight by eliminating redundant cross-compilation target toolchain downloads during source packaging.
- Streamlined Homebrew formula updater (
homebrew.yml) by parsing the release’s attestedSHA256SUMSmanifest directly with strict 64-char hex validation, eliminating redundant ~50MB archive downloads. - Added on-device binary execution smoke tests to
install.ps1and enhancedinstall.sherror diagnostics with API version resolution fallbacks.
- Added bounded execution timeouts (
-
Documentation & User Guide Streamlining:
- Overhauled root
README.mdinto a developer-focused technical guide, pruning marketing copy, redundant comparison tables, and promotional buzzwords. - Added structured media player setup guide with package manager commands (
brew,apt,winget). - Updated macOS Homebrew installation with explicit
brew truststep required by Homebrew 6.0+ for third-party taps. - Streamlined quickstart section to reference in-app interactive help (
?) anddocs/controls.md, preventing documentation drift.
- Overhauled root
-
Streamlined Test Architecture & High-Signal Test Suite:
- Consolidated unit assertions for file stem sanitization, MD5 hashing, atomic writing, and badge rendering directly into their respective modules (
src/download.rs,src/cache.rs,src/tui/widgets/badge.rs). - Pruned 10 redundant, weightless, and duplicate test suites (
player_integration.rs,url_security.rs,download_integration.rs,m3u_integration.rs,cache_lifecycle.rs,real_acceptance.rs,grand_user_journey.rs,history_reconciliation.rs,version_upgrade_e2e.rs), reducing integration test files from 20 to 9 focused suites while preserving complete regression coverage. - Hardened
.omp/AGENTS.mdanddocs/testing.mdwith strict engineering rules rejecting weightless tests, duplicate test layers, and monolithic multi-phase journey tests. - Aligned update modal keyboard tests with modal input isolation, verifying keystrokes do not fall through to background search results while the dialog is active.
- Consolidated unit assertions for file stem sanitization, MD5 hashing, atomic writing, and badge rendering directly into their respective modules (
Fixed
-
Responsive Text Sizing & Layout Truncation:
- Raised Details footer split threshold (
DETAILS_FOOTER_SPLIT_THRESHOLD) to 106 columns, ensuring shortcuts use a clean 2-row layout on terminals between 80 and 105 columns without clipping. - Omitted
[Ctrl+P] Providerhint from the Details footer when in Addon mode or viewing addon streams, recovering 18 columns of footer space. - Added line-width budgeting to Details metadata: audios and extra metadata (Genre, Director, Cast) now dynamically truncate to available row width without wrapping beyond their allocated lines.
- Synchronized Settings tab hit-testing (
category_tab_rects) with compact rendering (popup_area.width < 58), resolving mouse click target divergence on compact terminals. - Added dynamic subtext and label truncation in Settings rows, preventing 2-row Paragraph wrapping and off-screen line displacement.
- Replaced hardcoded path truncation in Settings download directory with dynamic middle truncation (
truncate_middle_width), maximizing displayed path length while fitting compact rows. - Added dynamic description truncation to Home discover categories card, preventing overflow on narrow (50–54 col) screens.
- Added responsive compact labels (
[Try Provider (P)]and[Clear (c)]) and narrowed separation to No-Results buttons when terminal width is under 56 columns. - Removed obsolete
Ctrl+Phint from search bar mode pill in Addon mode, replacing it with[Addon Mode]. - Added available width clamping to non-landing search bar placeholders and status messages to prevent 1-row Paragraph wrapping.
- Omitted redundant media type separator in search results metadata when terminal width is under 36 columns and release year is present, keeping provider badges intact.
- Budgeted list entry lengths in TV Playlists and Addon Manager popups to fit within inner popup bounds regardless of installed badge counts.
- Raised Help menu two-column threshold to 102 columns to prevent keybinding description truncation.
- Added compact title formatting to download gauge when width is under 60 columns.
- Added compact button formatting (
[u] Update [o] Web [Esc] Back) to Update Modal on terminals under 60 columns. - Added compact header formatting to Updating progress modal when inner width is under 42 columns.
- Added title boundary protection to
ModalFrame, truncating overly long titles to preserve border integrity. - Eliminated dark rectangular halo artifact around modal popups by removing block-level background color overrides from
ModalFrame, allowing rounded borders to cleanly render against transparent and custom terminal backgrounds without pixel spillage.
- Raised Details footer split threshold (
-
Resilient Configuration & Accurate Metadata:
- Safeguarded user TV playlists (
tv_config.json) and HTTP addons (addons_config.json): replaced destructive error-swallowing deletion with timestamped.corrupt.{timestamp}file rotation and sanitized logging on JSON parse failures. - Eliminated fabricated S01E01 fallback in addon metadata adapter, accurately reporting empty series episodes when an upstream catalog entry lacks episode records instead of injecting unplayable dummy data.
- Safeguarded user TV playlists (
-
Discover Card Layout & Truncation:
- Fixed horizontal text clipping on discover card category descriptions by adjusting
margins_lento account for visual pointer and margin cell budgets. - Suppressed discover card rendering while search suggestions dropdown is open, preventing visual overlap.
- Fixed horizontal text clipping on discover card category descriptions by adjusting
-
Update Modal Input Isolation & Event Guards:
- Prevented keystroke hijacking: deferred blocking update modal presentation while the user is actively typing in the search bar (
InputMode::Editing), ensuring keys (u,o,Esc) never trigger unintended update actions. - Added input lock during in-flight updates (
is_updating), consuming all keyboard and mouse events to prevent mid-upgrade process termination or disk corruption.
- Prevented keystroke hijacking: deferred blocking update modal presentation while the user is actively typing in the search bar (
-
Comprehensive Multi-Platform Player Detection & Dynamic Settings Refresh:
- Expanded Windows MPV and VLC candidate discovery across executable-adjacent directories (
.\mpv.exe,.\vlc.exe), WinGet Packages (%LOCALAPPDATA%\Microsoft\WinGet\Packages), userDownloadsandDesktopextractions,mpv.net(mpvnet.exe,mpv.net),mpv.com, Scoop apps and shims, Chocolatey, portable drive roots (C:\mpv,C:\vlc,C:\tools), and Windows RegistryApp PathsandEnvironment\Path. - Expanded macOS and Linux discovery across Nix profiles (
~/.nix-profile/bin,/run/current-system/sw/bin), Homebrew, MacPorts, user.local/bin, and user/system Flatpak exports. - Replaced permanent negative caching (
OnceLock<Option<String>>) with non-negative path caching across MPV, VLC, IINA, and Android Intent openers, ensuring players installed after cold start are discovered immediately. - Added non-destructive dynamic player detection merging to Settings Hub (
ToggleSettingsPopup,ShowSettingsPopup), player selection activation, and value cycling, refreshingavailable_playersin real time without requiring an app restart.
- Expanded Windows MPV and VLC candidate discovery across executable-adjacent directories (
-
Direct Playback & Header Compatibility:
- Eliminated vestigial in-stream “Open with” popup that blocked playback when only VLC was installed, routing playback directly to the preferred compatible player.
- Prevented silent player overrides: when a user explicitly selects a default player (e.g. VLC) that cannot satisfy stream authentication headers (e.g. MovieBox signed DASH manifests), the app now halts playback and warns the user with actionable detected alternatives instead of silently launching an unselected player.
- Added structured
PlaybackResolutionengine with dynamic context-aware notifications across playback resolution and download operations.
-
Terminal Graphics Probe Leak:
- Prevented raw Kitty APC escape sequence leak (
Gi=31...) on macOSTerminal.appand legacy non-graphics consoles by skipping graphics stdio probes. - Removed unsafe mid-session stdio graphics re-probing on
FocusChangeevents.
- Prevented raw Kitty APC escape sequence leak (
-
High-Performance Player Detection Engine (
src/player.rs):- Centralized OS executable probing (
mpv,vlc,IINA) into a singleprobe_player_executableengine, stripping ~150 lines of duplicate path traversal. - Added static caching (
OnceLock) toIINAresolution and Android Termux Intent detection, eliminating repeated expensive filesystem IO and PATH lookups during playback launches. - Expanded candidate resolution: added macOS MacPorts (
/opt/local/bin/*) and standard/bin/*locations. - Aligned installer (
install.sh,install.ps1) player detection with the app engine, explicitly probing standard/Applications/*.appandC:\Program Filesdeployments so GUI installations are correctly discovered immediately post-install.
- Centralized OS executable probing (
-
Responsive Mobile Installer Headers (
install.sh&install.ps1):- Implemented dynamic terminal column detection (
tput cols,stty size, and$COLUMNSininstall.sh;$Host.UI.RawUI.WindowSize.Widthininstall.ps1) with automatic multi-tier banner sizing. - Eliminated ASCII art banner wrapping and visual corruption on narrow mobile viewports (e.g. Android Termux portrait mode at 40–55 columns) by rendering an adaptive 31-column compact half-block banner (
█▀▄▀█...) and dynamic horizontal centering.
- Implemented dynamic terminal column detection (
-
Android Termux Static-PIE & TLS Alignment:
- Linked
aarch64-unknown-linux-musltarget as static-PIE (-C relocation-model=pic -C link-arg=-pie) to produceET_DYN(ELFe_type: 0x0003) binaries accepted by Android Bionic’s/system/bin/linker64, resolving runtime failure (unexpected e_type: 2). - Added 64-byte
PT_TLSalignment anchor insrc/main.rsand post-build ELF program header alignment in.github/workflows/release.ymlto satisfy Android Bionic’s ARM64 TLS segment minimum alignment validation. - Added automated ELF
e_typeandPT_TLSvalidation checks to.github/workflows/release.ymland a post-installation execution smoke test toinstall.sh.
- Linked
Removed
- Pruned unused legacy type aliases (
SeasonInfo,EpisodeInfo,StreamResource,StreamMirror) insrc/models.rs. - Removed dead
util_rowstruct field fromLandingRowsinsrc/tui/screens/home.rs. - Removed vestigial
ShowPlaybackPickerandShowPlayerPickeraction variants and playback picker state fields in favor of direct compatible player dispatch. - Removed unreferenced static screenshot assets (
assets/), reducing repository clone size by ~1.3MB. - Redundant Slash Commands:
- Pruned 10+ legacy slash commands (
/download-dir,/clear-cache,/update,/github,/probe,/toggle-update,/toggle-bdix,/toggle-streaming,/toggle-tv,/toggle-addons,/enable-*,/disable-*) superseded by the interactive Settings Hub. - Removed 300+ lines of redundant command execution and file write probing in
src/tui/app/search.rs. - Removed duplicate unreachable
Ctrl+Ukey handling insrc/tui/app/keyboard.rs.
- Pruned 10+ legacy slash commands (
[0.1.15] - 2026-09-03
Added
- MovieBox MPEG-DASH Stream Playback:
- Implemented visitor login authentication with JWT session tracking and atomic disk persistence (
~/.cache/moviebox-tui/moviebox_session.bin). - Added CloudFront DASH manifest resolution (
index.mpd) labeled with[Multi]badge in stream listings for multi-resolution playback (1080p,720p,480p). - Forwarded authentication headers and mobile
User-Agenttompv,IINA, andVLCfor authenticated CloudFront DASH demuxing.
- Implemented visitor login authentication with JWT session tracking and atomic disk persistence (
- Seekable 4KHDHub Stream Resolution:
- Prioritized seekable Cloudflare R2, S3, and FSL stream mirrors (
HTTP 206 Partial Content) over attachment downloads. - Added automatic unwrapping of base64
watch-onlineredirect URLs and expanded HubCloud button selectors. - Concurrently probe resolver mirror candidates in chunks of 3 with a 4-second timeout, filtering expired or broken links.
- Prioritized seekable Cloudflare R2, S3, and FSL stream mirrors (
- Interactive Settings Hub (
/settings):- Added a unified 4-tab modal (
General,Content Modes,Appearance,Maintenance) for media player selection, download directory configuration, live theme palette preview, and provider toggles.
- Added a unified 4-tab modal (
- TUI Layout & Ergonomics:
- Added
/exitslash command (with/quitand/qaliases) to exit and restore the terminal directly from the search prompt. - Added direct watch history resume on
Space/Pfor the recorded season and episode. - In-place provider switching (
Ctrl+P) on the Details screen to re-query titles without returning to the landing screen. - Multi-
Escnavigation: firstEscreturns focus to the search bar; secondEscclears the query and returns to the home landing. - Added fluid 10-frame Unicode Braille loading spinners (
⠋⠙⠹...) with ASCII fallbacks. - Grapheme-cluster-safe text input (
TextInputBuffer) across search, TV playlist, and addon inputs withCtrl+W,Ctrl+U,Delete, andHome/Endsupport. - Added 4-tier responsive stream table layout and dynamic single-column fallback for narrow terminals (<85 cols).
- Added Kitty keyboard protocol support (
DISAMBIGUATE_ESCAPE_CODES,REPORT_EVENT_TYPES) for lower latency input on supported terminals. - Added terminal theme autodetection using OSC 11 background luminance queries, with
NO_COLORoverride support.
- Added
Changed
- Unified Favorite Keybinding: Standardized favorite toggling across all screens exclusively on
f/F. - Search & Landing UX:
- Anchored search bar at row 0 across empty, loading, and zero-results states to eliminate layout shifting.
- Structured zero-results and query error screens with actionable guidance shortcuts (
[Ctrl+P] Switch Provider,[r] Retry,[Esc] Back). - Enclosed landing favorites list in an aligned bordered card.
- Streams Table Display:
- Replaced non-existent stream duration column with source and uploader columns, expanding room for codec and media tags.
- Grouped secondary stream audio/video codec tags (
DV,ATMOS,HEVC) with subtle separator points. - Isolated stream row selection highlight so background styling applies exclusively to the active stream row rather than table headers.
- MovieBox Client Spoofing: Updated client identity headers to APK
v4.0.01to ensure backend compatibility and avoid upgrade notice videos. - Search Prefetching: Bounded initial search prefetching to visible viewport bounds to reduce initial network requests.
Fixed
- Stream Playback & Resolver State:
- Fixed an issue where timed-out or failed stream resolutions left the playback state locked, preventing subsequent playback attempts.
- Fixed empty stream panel click focusing the pane without inadvertently triggering playback of index 0.
- Prevented transient “No stream sources found” flash while metadata or streams are loading.
- Metadata & UI Isolation:
- Guarded search preview metadata and details merging with strict provider and item ID checks, preventing stale metadata leakage when navigating quickly.
- Suppressed Sixel, Kitty, and iTerm2 poster graphics while modal dialogs or search dropdowns are open to prevent graphic bleed-through.
- Fixed poster placeholder widget incorrectly drawing over loaded images on the results screen.
- Fixed text wrapping panic on multibyte / CJK characters during title year extraction.
- Cross-Platform & Installation:
- Windows: Fixed self-update batch script losing staged binary on process exit, preserved leading backslashes on UNC paths, and sanitized NTFS forbidden characters in tracker state filenames.
- Android (Termux): Added fallback directory resolution for config, cache, and data paths, and added architecture guard preventing incompatible glibc Linux ARM64 binaries from overwriting Termux installations.
- DNS: Replaced hardcoded
/etc/resolv.confrequirement with custom resolver querying OS DNS first and falling back to public DNS (Cloudflare, Google, Quad9) on zero-config platforms. - Installers: Hardened path quoting, signal handling, and TLS 1.2 negotiation in
install.shandinstall.ps1.
Performance
- MessagePack Binary Disk Cache (
src/cache.rs): Replaced raw JSON disk caching with binary MessagePack serialization (rmp-serde) with magic signatureMBC1, versioned envelopes, and automatic migration from legacy JSON caches. - Zero-Copy IPTV M3U Parser (
src/providers/tv/parser.rs): Converted playlist attribute parsing to single-pass slice scanning, eliminating bulk heap allocations on large playlists. - Scraper Efficiency (
src/providers/fourkhdhub/): Precompiled static CSS selectors usingLazyLock<Selector>across scraping paths. - Connection Pooling & DNS (
src/net.rs): Shared static DNS resolver cache and tuned HTTP connection pool settings (tcp_nodelay, keepalive, idle timeouts).
Removed
- Removed deprecated JSON conversion adapters and untyped
serde_json::Valueservice endpoints in favor of strongly typed domain structs. - Removed redundant
[o] Open Withand[s] SubtitlesDetails shortcuts in favor of/settingsmedia player selection and automatic subtitle loading. - Removed obsolete
*favorite shortcut in favor off/F.
[0.1.14] - 2026-08-26
Added
- Favorites:
- Added a Favorites feature for starring whole movies and series (
src/favorites.rs,favorites.json), independent of watch history and unaffected by/clear-cache. - Added
*on the Home screen andf/Fon the Details screen to toggle a title’s favorite status, with a★indicator on favorited rows and a[f] Favorite/[f] Unfavoritehint on the Details screen. - Added an arrow-navigable Favorites row on the landing screen (Streaming and Addon modes) showing up to 5 recently-starred titles, with a
+N more • /favoritesoverflow link;Downfrom the search bar focuses the row,Enteropens the selected title,Escreleases focus. - Added the
/favoritesslash command, mirroring/history, to load the full starred list into the results view;*unstars the selected row there. - Added mouse support for the landing Favorites row (select/open rows, open the full list via the overflow line).
- Extracted cross-provider title-identity matching into
SubjectIdentity(src/models.rs), now shared by watch history and Favorites so remakes, cross-provider duplicates, and movie/series title collisions are deduplicated identically.
- Added a Favorites feature for starring whole movies and series (
Fixed
- External player failure reporting: Treat every non-zero player exit, including exits after several seconds or without stderr output, as a playback error instead of reconciling false watch progress.
- Search focus: Restore Backspace on the Home screen as a reliable way to focus the search input from results or Favorites.
- Season subtitles: Remember an explicit subtitle or no-subtitle choice for every episode in a season download.
- Playback state safety: Sanitize provider and subject identifiers before using them in tracker state filenames.
- Cross-platform release validation: Run all-feature locked builds/tests, binary startup smoke tests, Unix and Windows installer syntax checks, and release-target builds in CI.
- Release artifact smoke tests: Execute each native release target’s produced binary on its CI runner before archiving.
- Documentation accuracy: Document Android intent limitations, the actual Termux binary model, macOS-only IINA support, native runtime verification requirements, and the current automated test count.
- Windows VLC & player spawn fix: Removed erroneous
CREATE_NO_WINDOWflag that suppressed GUI window creation and caused VLC to crash on Windows; normalized Windows backslash subtitle paths in--sub-fileand gracefully handle subtitle download failures without breaking stream playback. - Termux player opener resolution: Resolve
termux-open,termux-open-url, andtermux-amdirectly in$PREFIX/binand static Termux paths; remove broken/system/bin/amfallback in unrooted Termux that crashed with Permission Denied (exit code 126). - Termux dependency path: Remove the Android platform-verifier dependency path that caused the v0.1.12 startup panic; real-device confirmation remains required.
[0.1.13] - 2026-08-21
Added
- Production-Grade In-App Self-Update Engine:
- Implemented modular self-update architecture (
src/updater/withcheck.rs,artifact.rs,download.rs,verify.rs,extract.rs, andapply.rs). - Added streaming SHA-256 integrity verification validating exact hash matching against release
SHA256SUMS. - Added hardened archive extraction for
.tar.gzand.zipwith strict path traversal protection against..components and absolute root paths. - Added multi-platform installation strategies: atomic binary replacement with
.oldbackup and automatic rollback on Unix/Linux/macOS/Termux, detached helper process on Windows, and Homebrew prefix detection guiding users tobrew upgrade moviebox-tui. - Added active work protection deferring self-update when active video playback or background downloads are running.
- Connected
[u]shortcut and[u] Update Nowbutton in the existing Update Available modal, preserving visual styling, animations, and dismissal model. - Added safe terminal state restoration (
disable_raw_mode,LeaveAlternateScreen,DisableMouseCapture,ShowCursor) before process exec/restart.
- Implemented modular self-update architecture (
- Update System Concurrency & Platform Compatibility Architecture:
- Added single-flight guard (
is_checking_updates) ensuring manual (/update) and automatic startup checks never spawn duplicate concurrent network requests. - Added shared geometry calculation (
UpdateModalLayout,update_modal_layout) guaranteeing 1:1 synchronization between popup rendering and mouse hit testing. - Added release asset data modeling (
Release,ReleaseAsset,TargetPlatform) with deterministic platform compatibility detection across macOS Universal, Linux x64/arm64, Windows x64/arm64, and Android Termux ARM64. - Added dedicated integration test suite
tests/update_lifecycle.rstesting update single-flighting, error recovery, mouse hit testing, and asset filtering.
- Added single-flight guard (
- Comprehensive QA & Regression Test Architecture:
- Introduced the initial 132-test automated suite covering critical algorithmic boundaries, end-to-end user journeys, watch history reconciliation & precision progress tracking, cross-mode history audit, in-app self-update lifecycle, real-world release artifact downloads, live SHA-256 verification, genuine version upgrade execution, content & metadata loading pipelines, stale request isolation, active player session lifecycle & duplicate launch protection, dynamic slash command autocomplete (
/download-dir reset), search/command draft cancellation viaEsc, error handling, addon manifest validation, mouse interactions, modal dismissals, TUI rendering across terminal size matrices, state reconciliation, crypto HMAC signing, download chunk arithmetic, and URL/stem security. - Added structured integration tests in
tests/(including content, error, TUI, history, Favorites, update, release, cache, player, TV playlist, addon, download, and URL-security suites) and test fixtures (tests/fixtures/). - Added
docs/testing.mddetailing test architecture, command references, and manual QA procedures.
- Introduced the initial 132-test automated suite covering critical algorithmic boundaries, end-to-end user journeys, watch history reconciliation & precision progress tracking, cross-mode history audit, in-app self-update lifecycle, real-world release artifact downloads, live SHA-256 verification, genuine version upgrade execution, content & metadata loading pipelines, stale request isolation, active player session lifecycle & duplicate launch protection, dynamic slash command autocomplete (
- Playback Tracking & Watch History Progress:
- Added real-time playback position tracking for
mpvwith injected tracker script (moviebox_tracker.lua) and 5-second periodic state auto-save to disk. - Added automatic startup state reconciliation (
reconcile_pending_playback_states) ensuring watched progress is preserved even when closing the terminal or killing tmux mid-playback. - Added two-tone smooth scrub line progress bars (
━─────── 1% (2h 18m left) • Watched 11h ago) and completion status badges ([✓ Completed],[✓ Watched]) in/historyand Details screens. - Added cross-provider title-based history deduplication and auto-resume from the last watched position.
- Added real-time playback position tracking for
- Addon Mode Watch History Parity:
- Added full watch history support (
/history) in Addon Mode matching Streaming Mode, enabling seamless watch progress tracking, scrub bars, and completion badges for community HTTP addon content.
- Added full watch history support (
- Pluggable Provider Trait & Capability Architecture:
- Formalized the public
ProviderandReleaseProvidertraits across all built-in scrapers (MovieBox,4KHDHub,CircleFTP,DhakaFlix, andAddons). - Added
ProviderCapabilities(supports_search,supports_pagination,supports_series,supports_subtitles,supports_homepage) andMovieBoxService::capabilities()for dynamic capability reporting. - Added structured
ProviderErrorboundaries (Network,RateLimited,NotFound,Parsing,Unavailable) with.user_message()for consistent error notifications.
- Formalized the public
- Theme System Expansion & Official Color Calibration:
- Added official Dracula, Gruvbox, and Rosé Pine themes to the
/themepicker alongside Catppuccin and Nord. - Added alias parsing support for
"dracula","gruvbox","rose-pine", and"catppuccin". - Guaranteed 100% transparent terminal compatibility across all themes with zero background opacity overrides.
- Fixed modal backdrop rendering by removing fullscreen screen clearing when opening
/theme. - Optimized live preview navigation to eliminate unnecessary disk I/O on arrow key navigation.
- Added official Dracula, Gruvbox, and Rosé Pine themes to the
- Universal Multi-OS Player Detection & Flathub/Snap Compatibility:
- Added sub-millisecond, filesystem-backed player probing across Linux (Flathub, Flatpak exports, Snap, and Native), macOS (Homebrew, MacPorts, App Bundles), Windows (Program Files, WinApps, Scoop, Chocolatey, WinGet), and Android (Termux).
- Fixed Flathub/Flatpak VLC detection failure by adding direct probes for
~/.local/share/flatpak/exports/bin/org.videolan.VLCand/var/lib/flatpak/exports/bin/org.videolan.VLC. - Added full Flathub/Flatpak and Snap compatibility for MPV (
io.mpv.Mpv,/snap/bin/mpv). - Centralized player process construction (
build_player_process_command) and standardized subtitle flag arguments (--sub-file=<path>) across all platforms.
- Codebase Optimization & Comprehensive Caching Architecture:
- Centralized application paths (
config_dir,data_dir,cache_dir,logs_dir,scripts_dir,playback_state_dir) insrc/config.rs. - Added dedicated disk caching for Addon Mode stream aggregation (
2hTTL), catalog/browsepresets (1hTTL), and verified manifests (24hTTL). - Added search pagination caching (
search_{hash}_{page}.json) preventing redundant API calls when navigating multi-page search results. - Eliminated redundant
reqwest::Clientallocations in background poster pipelines in favor of the sharedservice.http_client(). - Streamlined
MovieBoxServiceusage across background tasks and removed redundantaddon_clientfield fromAppState. - Centralized formatting utilities (
format_file_size,format_duration) insrc/tui/text.rs. - Modernized
Configloading and persistence with safe, standard Serde derives.
- Centralized application paths (
- Addon Mode (Community HTTP Addons):
- Added full support for community HTTP addon manifests (
/manifest.json,/catalog,/meta,/stream) with dedicatedCtrl+Amode switching. - Pre-installed and locked Cinemeta out-of-the-box as the default core metadata provider with zero API keys required.
- Added interactive Addon Manager dialog (
/addons,Ctrl+Pin Addon Mode) with one-click enabling, removal, and manifest URL adding. - Added concurrent multi-addon stream resolution aggregating playable releases from all enabled stream addons.
- Added a smart runtime torrent detector that automatically detects if an addon’s streams are 100% blocked raw torrents (e.g., Torrentio without Debrid) and flashes a UI warning toast that only HTTP streams are supported.
- Added full support for community HTTP addon manifests (
- Addon Mode
/browse& Curated Catalog Exploration:- Added
/browsesupport in Addon Mode with a minimal, organized 4-preset catalog picker (Top Movies,Top Series,Top Rated Movies,Top Rated Series). - Added direct catalog fetching (
/catalog/{type}/{id}.json) with poster hydration, details navigation, stream resolution, and/reloadsupport.
- Added
- Strict Slash Command Guarding & Guidance:
- Intercepted all
/slash commands to guarantee zero remote catalog network requests. - Added warning toast notifications for unrecognized slash commands (
"Command '/xyz' is not recognized. Type '/' to view available commands."). - Added platform-aware mode-guidance toasts (
^T/^S/^Aon macOS,Ctrl+T/Ctrl+S/Ctrl+Aon Linux/Windows) for mode-restricted commands.
- Intercepted all
- Active Mode & Provider State Persistence:
- Added
active_modeconfiguration field inconfig.jsonautomatically persisting and restoring the last active mode (streaming,tv,addon) and active provider across app restarts.
- Added
- Configurable Mode Navigation:
- Added
/enable-streaming,/disable-streaming,/enable-tv, and/disable-tvslash commands alongside/enable-addonsand/disable-addons. - Enforced safety validation ensuring at least one mode remains active and gracefully migrating focus when disabling the current mode.
- Added
- Dynamic Multi-Source Host & Resolver Resolution:
- Added 100% dynamic domain-based host extractor (
extract_domain_label) and stream tag parser (detect_stream_host) identifying and formatting direct hosts (Pixeldrain, Hubcloud, Fast Download, Google Drive, Mega, etc.) and debrid resolvers without hardcoded tables.
- Added 100% dynamic domain-based host extractor (
- Full Emoji & Symbol Sanitization:
- Added
strip_emojisandclean_stream_textsanitizing all raw stream titles, release names, source labels, and languages from community addons for clean terminal alignment without broken characters. - Standardized checkbox representations to clean ASCII
[x] / [ ].
- Added
- Complete Mouse Navigation:
- Added dynamic footer hitboxes for
[Ctrl+S] Streaming,[Ctrl+T] TV,[Ctrl+A] Addons,[Ctrl+P] {Provider},[?] Help,[q] Quit. - Added complete mouse click support for Addon Manager modal and browse popups.
- Added dynamic footer hitboxes for
Fixed
- Windows MSVC Static CRT Linking (
+crt-static):- Configured
target-feature=+crt-staticin.cargo/config.tomlforx86_64-pc-windows-msvcandaarch64-pc-windows-msvc, statically embedding the C runtime to eliminate externalVCRUNTIME140.dlldependency and resolve0xC0000135(STATUS_DLL_NOT_FOUND) on clean Windows installations.
- Configured
- Cross-Platform Installer Polish & Windows In-Memory Execution:
- Replaced file-based execution commands in Windows documentation with the in-memory stream pipeline (
irm ... | iex) to eliminatePSSecurityExceptionexecution policy blocks. - Added immediate active process
$env:PATHupdate ininstall.ps1so the command is recognized in the current shell session without terminal restart. - Replaced rigid fixed-width boxed summary tables with responsive, borderless hero layouts across both
install.ps1andinstall.sh, preventing broken box-drawing characters and layout overflow on narrow screens.
- Replaced file-based execution commands in Windows documentation with the in-memory stream pipeline (
- Pending History Reconciliation Order:
- Sorted pending Lua tracker state files chronologically during startup reconciliation to guarantee correct playback state replay order.
- MovieBox Title Sanitization (DEF-02):
- Fixed destructive title truncation where leading bracket tags (
[Dub],[1080p],[RAW]) and titles starting with parentheses (e.g.(500) Days of Summer) were stripped down to empty strings. - Preserved release years in parentheses (
Inception (2010)) and added a fallback safeguard returning the trimmed original title if sanitization ever results in an empty string.
- Fixed destructive title truncation where leading bracket tags (
- Watch History Identity & Deduplication Collisions (DEF-03):
- Enforced
stypeseparation inHistoryManager::is_same_showso Movies and TV Series sharing identical titles (e.g.Home) never overwrite one another. - Enforced strict canonical identity (
provider + subject_id), preventing cross-provider conflicts and ensuring remakes with differing release years remain distinct entries.
- Enforced
- Background Episode Playback State Reconciliation (MISS-01):
- Fixed a state loss bug in
reconcile_pending_playback_stateswhere a completed episode’s watched status was discarded if the user had already advanced to a subsequent episode before the state file was processed.
- Fixed a state loss bug in
- Windows MPV Script Options Path Escaping (DEF-04):
- Fixed path corruption in MPV’s
--script-optson Windows by normalizing backslashes (\) to forward slashes (/), preventing MPV escape sequence parsing from corruptingstate_filepaths inmoviebox_tracker.lua.
- Fixed path corruption in MPV’s
- M3U Single-Quoted Attribute Support (DEF-07):
- Extended
M3UParserattribute extraction to support both single-quoted (tvg-id='...') and double-quoted attributes, preserving channel IDs, logos, and groups across varied IPTV playlists.
- Extended
- Continuous OS-Level SIGINT Handling (DEF-05):
- Wrapped
tokio::signal::ctrl_c()in a continuous background loop to ensure repeated non-interactive OS signals are reliably handled.
- Wrapped
- Subtitle Prefetch Fallback (DEF-08):
- Reduced subtitle download timeout from 30s to 8s to prevent unnecessary startup delays when launching external players if a subtitle mirror hangs.
- Addon Stream Sorting & Rendering:
- Fixed addon streams randomly scrambling on UI hover when sizes are tied by adding a secondary stable sort based on the mirror label.
- Fixed misleading
0MBstream sizes for community addons that omit video sizes by cleanly rendering--instead.
- Terminal Race Condition & Blank Screen on
/clear-cache:- Replaced physical terminal clear with a soft image refresh when executing
/clear-cache, resolving a race condition with terminal emulators that swallowed the full Home screen render and caused the screen to go completely blank after a few seconds. - Added comprehensive state isolation preventing search queries, results, and details states from lingering after cache clears.
- Sanitized slash command input handling to prevent visual query glitches.
- Replaced standard status messages with elevated toast notifications for cache actions.
- Replaced physical terminal clear with a soft image refresh when executing
- Atomic Mode Highlight & Single Active Selection:
- Added canonical
AppModeenum (Streaming,Tv,Addon) and atomic state transitions guaranteeing that only one active mode is highlighted in the bottom dock at any time. - Hardened state isolation with automatic cleanup across mode switches.
- Added canonical
- Notification Readability & Word-Boundary Wrapping:
- Replaced horizontal middle-truncation with unicode display-width aware word wrapping (
wrap_text). - Added adaptive width (up to 72 chars) and dynamic height scaling with guaranteed unbroken rounded borders.
- Replaced horizontal middle-truncation with unicode display-width aware word wrapping (
- Resilient Addon Metadata & Fallbacks:
- Added flexible visitors and serde aliases for
genres,cast,director,imdbRating,releaseInfo, andruntimepreventing deserialization failures across varied community addon JSON schemas. - Added multi-tier fallback resolution in the Details screen to guarantee titles, release years, synopsis, and posters are always preserved from search results and previews.
- Added flexible visitors and serde aliases for
- Android / Termux TLS Certificate Compatibility:
- Switched
reqwestto use pure-Rust embeddedwebpki-rootscertificate verification, resolvingrustls-platform-verifiercrashes and panics in non-JVM Android CLI environments like Termux.
- Switched
- Transparent Stream & Search Diagnostics:
- Replaced misleading generic
"No matches"and"Rate Limit"errors with truthful, contextual diagnostics:"No stream sources available on {provider}","Network connection failed to {provider}","Rate limited by {provider}", and"Episode S{season}E{episode} is not listed on {provider}". - Added helpful actionable hints (
Press Ctrl+P to try another provider, or r to refresh).
- Replaced misleading generic
- Rate-Limiting & Concurrency Hardening:
- Added HTTP 429
Retry-Afterheader parsing with bounded exponential backoff inMovieBoxClient. - Added semaphore concurrency limiting (
Semaphore::new(2)) during parallel episode page resolution to prevent burst requests from tripping provider rate limiters.
- Added HTTP 429
- Addon Mode Series Hierarchy & Episode Stream Isolation:
- Fixed series misclassification as movies in Addon Mode when metadata omitted the
videosarray by ensuring canonical season structures and series-first metadata endpoint prioritization. - Added regex and token-based episode stream isolation (
parse_season_episode) instream_item_to_release, preventing cross-episode stream pollution (e.g. S01E06 streams appearing when viewing S01E08). - Added preservation of
episodeNumbersarrays from addon metadata in the season list state.
- Fixed series misclassification as movies in Addon Mode when metadata omitted the
- Direct Addon & BDIX Playback & Download Dispatch:
- Fixed Addon and BDIX playback and download routing in
handle_playbackandhandle_downloadto dispatch directly to external media players and the chunk downloader, preserving custom HTTP headers (behaviorHints.headers) and source labels without unnecessary Moviebox API subtitle timeouts.
- Fixed Addon and BDIX playback and download routing in
- Selector Tab Preservation in Standard Displays:
- Maintained visibility of Audio Languages, Seasons, and Episodes selector tabs side-by-side in standard ~80-column terminals when focusing Streams, preventing tabs from disappearing when 0 streams are available.
Changed
- Modular TV Provider Architecture:
- Reorganized Live TV / IPTV provider into a dedicated module directory (
src/providers/tv/) with separatedmodels.rsandparser.rs.
- Reorganized Live TV / IPTV provider into a dedicated module directory (
- Core Infrastructure Consolidation:
- Centralized atomic file operations (
atomic_write_file,atomic_write_file_async), MD5 digest formatting (md5_hex), and text extraction helpers incache.rsandservice.rs. - Centralized application paths, border type resolution, and mode status announcements across TUI modules.
- Centralized atomic file operations (
- Addon Manager UI Optimization:
- Implemented full cursor navigation (
Left/Rightkeys) and inline editing (Backspace/Delete) for the Addon Manager input field. - Implemented a scrolling viewport renderer for the Addon Manager input, allowing editing of very long manifest URLs without wrapping or truncation.
- Compacted the Addon Manager dialog with an aligned two-tier layout placing
[ Add Manifest URL ]and[ Done ]action buttons side-by-side.
- Implemented full cursor navigation (
- Multi-System Core Module Decoupling:
- Promoted
player.rs(process management & detection),config.rs(shared configuration), andupdater.rs(release checks) to core modules insrc/, preparing the architecture for upcoming CLI and GUI frontends with full backward compatibility.
- Promoted
Documentation
- Streamlined README & Controls Guide:
- Transformed
README.mdinto a focused landing page with measured~5 MB RAMbenchmark data, defensible value propositions, and direct links to deep guides indocs/. - Created standalone
docs/controls.mdcovering all keyboard shortcuts, mouse controls, and slash commands. - Added a 3-phase project roadmap: Terminal UI (TUI) -> Command-Line Interface (CLI) -> Desktop GUI Client.
- Added a community-first feedback and support section with optional crypto donation options.
- Transformed
[0.1.12] - 2026-08-15
Added
- CLI Help Flag: Added
-h/--helpCLI flags printing formatted usage, available options, and environment variables. - Full Mouse Support: Complete mouse navigation throughout the application:
- Click search bar to edit; click suggestion items to search immediately.
- Click search results to select/preview; click again or double click to enter Details.
- Click Details panes (Audio Languages, Seasons, Episodes, and Streams) to select and launch playback.
- Click centered footer toolbar buttons (
[Ctrl+P] Provider,[Ctrl+T] TV,[?] Help,[q] Quit). - Full click support across all modal popups (Theme, Browse, Subtitles, Players, TV playlists & actions, and Download confirmation).
- Contextual Downloads:
- Pressing
dor clicking[Download]while on the Seasons pane prompts to download the whole season (all episodes). - Triggering download while on Episodes or Streams downloads that single episode.
- Pressing
- Organized Downloads & Custom Directory:
- Structured Series downloads under
<base_dir>/Series/<Title>/Season <N>/<Title> - S<N:02>E<E:02>.<ext>and Movies under<base_dir>/Movies/<Title>/<Title>.<ext>. - Added ISO 639-1 language code tagging to subtitle sidecars (e.g.
<BaseName>.en.srt) for automatic track identification in media players and servers. - Added smart duplication prevention: completed episodes on disk are automatically skipped during season batch downloads.
- Added
/download-dir <path>slash command with directory creation and active write-probe validation. - Added
/download-dir reset(contextually suggested only when custom path is configured) to revert to OS default. - Safe automatic fallback to default OS Downloads folder if custom path becomes inaccessible.
- Configuration persistence across sessions in
config.json.
- Structured Series downloads under
- Tree Branch Suggestions:
- Redesigned search and slash command autocomplete into a minimal, transparent tree-branch layout (
├─/└─) anchored directly under the search prompt. - Added aligned slash command descriptions (
browse,history,theme,config,update, etc.) without duplicate leading slashes. - Clean typography-driven active selection with bold vibrant accent styling.
- Redesigned search and slash command autocomplete into a minimal, transparent tree-branch layout (
- Multilingual Audio Track Detection:
- Expanded 4kHDHub release parser to detect 30+ regional and international languages (Hindi, Tamil, Telugu, Kannada, Malayalam, Bengali, Marathi, Punjabi, Gujarati, Urdu, Japanese, Korean, Chinese, Spanish, French, German, Italian, etc.) and abbreviations (
Tam,Tel,Kan, etc.). - Responsive stream list formatting showing all available languages without crowding mirror counts.
- Expanded 4kHDHub release parser to detect 30+ regional and international languages (Hindi, Tamil, Telugu, Kannada, Malayalam, Bengali, Marathi, Punjabi, Gujarati, Urdu, Japanese, Korean, Chinese, Spanish, French, German, Italian, etc.) and abbreviations (
- Floating Pill HUD & Smooth Resize:
- Added floating terminal dimension HUD and event coalescing for smooth window resizing without blank screens.
- Elevated Notification Badges:
- Redesigned notification popups into elevated, rounded bottom-right badge cards with clean typography.
- Persistent Long-Term Poster Caching:
- Increased image cache retention to 30 days (
IMAGE_CACHE_EXPIRY_SECS), serving previously fetched posters instantly from disk across sessions with zero redundant network requests. - Unified image caching under a shared namespace with automatic cross-namespace lookup across MovieBox, 4KHDHub, IPTV, CircleFTP, and DhakaFlix.
- Increased image cache retention to 30 days (
- Streamlined Browse Views:
- Curated
/browseviews into 4 categorized shelves (Popular, Top Rated, Trending, Most Watched) with proper filtering.
- Curated
- Native Graphics & Single Standardized ‘No Poster’ Placeholder:
- Replaced redundant dual labels (
Poster unavailable/No Art) and noisy halfblock mosaic fallback with a single clean, centeredNo Posterlabel across search results, details, and history on non-graphics terminals. - Eliminated ANSI block characters, yellow/white selection redraw bars, and unnecessary background image downloads on basic terminals.
- Preserved full native high-resolution graphical rendering on Sixel, Kitty, and iTerm2 supported terminals.
- Added
MOVIEBOX_NO_IMAGE=1environment override to disable image probing on slow or headless sessions.
- Replaced redundant dual labels (
- Next-Gen Multi-Tiered Animated Installers (
install.sh&install.ps1):- Multi-tier progressive rendering with official MovieBox branding and Catppuccin Mocha aesthetic.
- Live smooth Braille spinners (
⠋ ⠙ ⠹ ...), SHA256 cryptographic verification againstSHA256SUMS, and media player ecosystem detection. - 100% sudo-less user-level installation into
~/.local/bin(or%LOCALAPPDATA%\Programs\MovieBox-Tui\binon Windows) with automatic non-destructive shell PATH integration and zero password prompts. - Added full CLI flags:
--version <tag>,--dir <path>,--force,--dry-run, and--uninstall.
- Explicit Download Directory Autocomplete Hints:
- Added
/download-dir <path>slash command suggestion with clear action descriptions (Set custom folder (e.g. ~/Movies)vs.View current download folder). - Added friendly guidance notification if a user inputs literal
<path>placeholders.
- Added
Fixed
- Custom Download Directory Container Hierarchy:
- Ensured custom download directories always maintain the standardized
MovieBox-TUIroot container (MovieBox-TUI/Movies/...andMovieBox-TUI/Series/...) without duplicating if already namedMovieBox-TUI.
- Ensured custom download directories always maintain the standardized
- Multiline Notification Toast Rendering:
- Upgraded notification toast layout to compute dynamic height and wrap multiline messages per line cleanly without horizontal middle-truncation across newlines.
- Sanitized notification folder paths by substituting home directory with
~.
- Default Audio Track Prioritization (Original / English):
- Fixed movie and series details defaulting to regional Hindi dubs on MovieBox by prioritizing
OriginalandEnglishaudio tracks over localized search result subject IDs. - Preserved explicit user language selections when intentionally switching between dubs.
- Fixed movie and series details defaulting to regional Hindi dubs on MovieBox by prioritizing
- Home Landing Header & Footer Persistence:
- Fixed ASCII logo header and shortcut footer disappearing into a blank screen when clearing history or viewing empty search states by removing fragile tick-based animation gates.
- Ensured the landing screen renders the logo, version, centered search bar, and footer shortcuts immediately on every frame.
- Watch History Consolidation & Latest Progress Representation:
- Consolidated watched episodes of the same series into a single entry per show in
/historydisplaying the latest watched season and episode. - Automatically deduplicated and migrated legacy history rows on startup while maintaining complete per-episode checkmark indexes in
self.watched.
- Consolidated watched episodes of the same series into a single entry per show in
- History Poster Auto-Hydration & In-Memory Cache Retention:
- Fixed “No Poster” placeholders in
/historyby automatically resolving missing cover URLs and decoding posters in the background. - Preserved in-memory decoded image caches when opening
/historyto eliminate unnecessary UI redraw latency. - Added multi-source fallback extraction for cover URLs across playback, preview, and search results.
- Fixed “No Poster” placeholders in
- Stream Pool Initialization on Audio Selection: Fixed stream fetching hanging on “Loading streams…” when selecting non-default audio dubs by ensuring stream pool entries are initialized before episode fetch.
- Title Sanitization & Preservation: Enhanced
clean_moviebox_titleto sanitize international audio dubs, video quality tags, and format markers across downloads, folder organization, and watch history while preserving 4-digit release years. - Terminal Restoration & Signal Handling: Added
Ctrl+Ckeyboard handling and asynchronousSIGINTsignal listener to guarantee raw mode and alternate screen are always cleanly restored. - Download Hierarchy & Numbering: Fixed series media type detection and removed season/episode off-by-one addition.
- Parser UTF-8 Safety: Hardened language detection boundary checks for multibyte titles against panics.
- Startup Screen Artifacts: Removed early startup
eprintln!to eliminate terminal screen artifacts before entering alternate screen mode. - Android / Termux Stability: Removed
hickory-dnsfrom network dependencies to resolve NDK context panics and crashes on Android. - Screen Flickering & Blanking:
- Eliminated full terminal clear on list navigation and infinite scroll pagination.
- Fixed screen blanking when pressing
Escor resizing windows. - Replaced terminal clear with direct backend clear to eliminate cursor read timeouts.
- Search & Navigation:
- Fixed search bar auto-closing when switching providers.
- Fixed provider switching delays and event stream drops.
- Kept chosen audio dub selected and prevented unwanted pane jumping on details refresh.
- Handled empty query loading states and preset failures gracefully.
- Downloads & Playback:
- Resolved MovieBox movie stream key mismatches and hardened resilient download flows.
- Protected active downloads from accidental cancellation when typing
xin the search bar. - Fixed playback lock edge cases and subtitle picker clipping.
- Theme & Configuration:
- Fixed theme cancellation reverting correctly without persisting unapplied themes.
- Unified
/themecommand and removed obsolete/discover,/tab, and/themesaliases.
Changed
- Removed startup screen delay for instant app launch.
- Modernized in-place update notifications and dialogs.
- Rendered details footer on a single clean line to balance bottom margins.
- Removed search bar underline clutter in favor of clean header spacing.
[0.1.11] - 2026-08-11
Added
- User-Owned M3U Playlists: Full custom playlist management in TV mode with remote URL and local file support.
- Android Runtime Support: Termux playback and shared-storage handling continue to be exercised on real devices, but release artifacts remain desktop-focused.
Refactored
- Domain Modularization: Split the application monolith into cohesive domain modules (
network,playback,download,requests,navigation,tv,system,keyboard). - State Decomposition: Split the monolithic application state into specialized domain state structs.
- Strict Verification Gates: Enforced workspace lint checks, static analysis, and testing.