refactor: delegate Miruro playback resolution to Terebi
This commit is contained in:
@@ -7,7 +7,7 @@ A modal terminal YouTube and Miruro browser built with Rust and [Ratatui](https:
|
||||
- A recent stable Rust toolchain, including Cargo, to build and install.
|
||||
- [`yt-dlp`](https://github.com/yt-dlp/yt-dlp) on `PATH` for YouTube searches, feeds, and full descriptions; Miruro uses the native API client.
|
||||
- `curl` on `PATH` for YouTube thumbnails and Miruro cover art.
|
||||
- The **Terebi CLI** installed on `PATH`, together with its app bundle and streaming dependencies, for playback. YouTube requires `--new-instance --url … --progress-file PATH`; Miruro additionally requires `--source-file PATH` and version-2 episode progress support.
|
||||
- The **Terebi CLI** installed on `PATH`, together with its app bundle and streaming dependencies, for playback. Both providers use `--new-instance --url … --progress-file PATH`; Miruro requires native Miruro episode-URL resolution and version-2 episode progress support.
|
||||
|
||||
The default playback setup requires **macOS 15+**, since Terebi is a native macOS player. Install Terebi separately and follow its dependency/setup instructions; installing Tubular does not install the player.
|
||||
|
||||
@@ -61,13 +61,13 @@ Each selection opens an independent player instance without replacing existing p
|
||||
|
||||
Choose **Miruro** at startup or use `--miruro` to start directly. Its interface is **catalog → series → episodes**, with a separate saved-show library organized by overlapping category tags, without YouTube's Search/Feed tabs or channel controls.
|
||||
|
||||
Catalog autocomplete returns at most eight anime titles, without pagination. Titles show the available format, status, season/year and planned/listed episode counts; press `d` for cover art, a bold title, dimmed metadata and a synopsis excerpt, using the same info layout as YouTube. Press `d` again for the full scrollable synopsis and returned facts; another `d` returns to info, and Esc closes either mode. The series screen lists only actual returned episodes—not planned or absolute episode numbers—with titles, dates and durations when supplied. Selected episode details appear first, above the series synopsis and beside the series cover art in info mode. Listed counts do not guarantee that a supported Sun source is available.
|
||||
Catalog autocomplete returns at most eight anime titles, without pagination. Titles show the available format, status, season/year and planned/listed episode counts; press `d` for cover art, a bold title, dimmed metadata and a synopsis excerpt, using the same info layout as YouTube. Press `d` again for the full scrollable synopsis and returned facts; another `d` returns to info, and Esc closes either mode. The series screen lists only actual returned episodes—not planned or absolute episode numbers—with titles, dates and durations when supplied. Selected episode details appear first, above the series synopsis and beside the series cover art in info mode. Listed counts do not guarantee a playable source; Terebi resolves playback.
|
||||
|
||||
| Key | Miruro action |
|
||||
| --- | --- |
|
||||
| `i` / `/` | Edit the catalog query; Enter searches, Esc cancels |
|
||||
| `j` / `k`, ↓ / ↑; `g` / `G`, Home / End | Select a title or episode |
|
||||
| Enter | Open a series, or resolve a fresh direct **ssub / sun** source and play the episode |
|
||||
| Enter | Open a series, or pass the selected episode URL to Terebi for resolution and playback |
|
||||
| `-` / `+` | Back / forward through cached screens, preserving query and selection |
|
||||
| `w` / `v` | Save the selected episode to watch later / saved episodes |
|
||||
| `s` | Edit the selected show's category tags; Enter saves the show, including with no tags |
|
||||
@@ -85,11 +85,11 @@ These actions reuse the existing `[keys]` configuration; live hints and help omi
|
||||
|
||||
Space checks categories for combined browsing; Enter opens their deduplicated union even when the filter hides them. With no checks, Enter opens the hovered category or All saved shows.
|
||||
|
||||
Only episodes can have their watch status edited. Reopening a saved episode resolves new URLs; identity is the opaque Miruro catalog ID plus its returned episode number. Each interface shows only its provider's collections, while playback, watched state and storage remain shared. Episode markers show saved/watch-later/currently-watching membership and watched status; Terebi owns resume positions.
|
||||
Only episodes can have their watch status edited. Reopening a saved episode passes its stable identity to Terebi for fresh resolution; identity is the opaque Miruro catalog ID plus its returned episode number. Each interface shows only its provider's collections, while playback, watched state and storage remain shared. Episode markers show saved/watch-later/currently-watching membership and watched status; Terebi owns resume positions.
|
||||
|
||||
Catalog results, series screens and saved-show lists use the returned `cover_url`; missing artwork leaves a text-only preview, and image failures do not hide metadata. Offline episode collections retain their stored text-only details. JPEG, PNG and WebP covers load, decode and resize off-thread, with native terminal graphics or proportional half-block rendering. The session image cache retains eight inactive images plus the current selection; a successful `r` refresh clears it.
|
||||
|
||||
Stream and external VTT subtitle headers are supplied explicitly; Terebi selects the source's declared default subtitle. Sources requiring media redirects, cross-origin HLS, proxies, iframe playback, or provider-specific playlist rewriting fail explicitly. No provider/language fallback or automatic expired-source refresh is performed.
|
||||
Tubular owns catalog browsing, selection, collections and watched decisions. Terebi owns source resolution, stream/subtitle headers, subtitles, playback titles and optional timeline metadata. Miruro launches use `https://barelystarted.miruro.tv/watch/OPAQUE_ID/episode?ep=RETURNED_EPISODE`; `episode` is a non-identifying placeholder slug, not a title. No source file or collection migration is required. Current Terebi displays the generic title `Miruro episode N`; title enrichment and intro/outro bands in the controls progress bar remain Terebi work. No automatic skipping or skip buttons are requested. See the [Terebi URL-playback handoff](docs/terebi-url-playback-handoff.md) for canonical-route handling and acceptance scenarios; this is not a claim of implemented timeline UI.
|
||||
|
||||
|
||||
## YouTube controls
|
||||
@@ -284,11 +284,11 @@ Files are siblings of `config.toml`:
|
||||
- `currently-watching.toml`: versioned metadata for unfinished videos, added by playback or marked manually.
|
||||
- `watch-state.toml`: versioned global watched video IDs.
|
||||
- `miruro-library.toml`: versioned saved-show catalog metadata and overlapping category tags, independent of episode collections.
|
||||
- `playback-sessions/`: private per-launch progress streams, expected identities, metadata snapshots, durable admission/manual-edit markers, and Miruro source documents.
|
||||
- `playback-sessions/`: private per-launch progress streams, expected identities, metadata snapshots, and durable admission/manual-edit markers.
|
||||
|
||||
State writes are atomic and owner-only. Invalid state files or detected external edits are reported rather than overwritten; repair the file or restart before retrying. Each state file is limited to 8 MiB.
|
||||
|
||||
Progress sessions survive Tubular exit so later player reports can be recovered on the next launch. Miruro source documents are `0600` files in `0700` session directories and remain unchanged, even after launcher exit or reported end/close; they contain private, expiring resource URLs and headers. Sessions are retained because CLI exit does not prove the independent GUI has finished; up to 4,096 are monitored. Close the corresponding players before removing their inactive session directories, then restart Tubular. Never remove an active player's directory.
|
||||
Progress sessions survive Tubular exit so later player reports can be recovered on the next launch. Session directories are `0700`; snapshots, identity markers and Terebi-created reports are owner-only. New Miruro launches contain no resolved-source documents or CDN credentials. Existing sessions from earlier versions remain readable and are not automatically removed. Sessions are retained because CLI exit does not prove the independent GUI has finished; up to 4,096 are monitored. Close the corresponding players before removing their inactive session directories, then restart Tubular. Never remove an active player's directory.
|
||||
|
||||
## Saved videos
|
||||
|
||||
@@ -376,7 +376,7 @@ Video info shows a thumbnail, title, author/publication details, and a clipped d
|
||||
|
||||
## Development
|
||||
|
||||
[Miruro API notes](docs/miruro-api.md) document the native `tubular::miruro` wrapper, source-document projection, stable episode/progress contracts, and verification limits.
|
||||
[Miruro API notes](docs/miruro-api.md) document the native catalog-only `tubular::miruro` wrapper, stable episode/progress contracts and historical source/CDN research. The [Terebi URL-playback handoff](docs/terebi-url-playback-handoff.md) defines the playback interface and remaining title/timeline work.
|
||||
|
||||
Unit tests live in `tests/unit/`, grouped by source module and loaded with `#[cfg(test)]` and `#[path]` so they retain access to private implementation details. Cargo runs them with the commands below; they are not separate integration-test crates.
|
||||
|
||||
@@ -386,10 +386,10 @@ cargo test --locked
|
||||
cargo clippy --locked --all-targets -- -D warnings
|
||||
```
|
||||
|
||||
Read-only native Miruro smoke (search → detail/episodes → fresh sources → HLS master/subtitle):
|
||||
Read-only native Miruro smoke (search → detail/episodes):
|
||||
|
||||
```sh
|
||||
cargo run --locked --example miruro_probe
|
||||
```
|
||||
|
||||
This uses the documented research title and direct Sun provider, stops on errors/protection pages, and does not download media segments or save tokenized URLs. The sample can become unavailable; passing it proves resource retrieval, not full player playback.
|
||||
This uses the documented research title and stops on errors/protection pages. The sample can become unavailable; passing it proves catalog retrieval, not Terebi playback. Earlier source/HLS/subtitle probe results remain historical evidence in the API notes.
|
||||
|
||||
Reference in New Issue
Block a user