fix: resolve queued stream metadata in the background

Queue labels were only enriched through selected-entry playback. Resolve unplayed titles serially at utility priority, preempt enrichment for playback, and bind updates to queue item IDs.

Verified: make check-resolved check-queue check-youtube all.
This commit is contained in:
2026-10-22 18:01:07 +02:00
parent f1339050d9
commit 6ed7db8167
7 changed files with 207 additions and 18 deletions
+3 -1
View File
@@ -47,7 +47,7 @@ The manifest is bounded to 8 MiB, version 1, and 1–4096 entries in playback or
Use canonical YouTube video pages or supported Miruro episode pages, never expiring source addresses. Stable identities must be unique even across alternate YouTube forms or different Miruro slugs. Reports must have distinct absolute nonexistent destinations, each under a canonical, nonsymlink, user-owned `0700` directory. Tubular retains each item's existing identity registration/session and stores the manifest in the first session. The CLI validates the complete document before launching; the GUI validates it again before opening any media. Invalid queues fail rather than falling back to a single stream. Queue launch requires either `--new-instance` (replace in a separate player) or `--enqueue` (append to the running player), accepts `--no-config`, and cannot combine with `--url`, `--source-file` or `--progress-file`. `--enqueue` and `--new-instance` are mutually exclusive.
The supplied order is preserved (local-file batches still use natural filename order). Existing sidebar reorder/remove/play and previous/next navigation apply. Natural end advances without clearing the queue. Sources resolve only when selected, resolve afresh on revisits, and canceled/stale results cannot replace a newer selection. Labels start with descriptive page information and update from resolved titles/optional metadata.
The supplied order is preserved (local-file batches still use natural filename order). Existing sidebar reorder/remove/play and previous/next navigation apply. Natural end advances without clearing the queue. Unselected labels are enriched serially at utility priority after playback loading settles; buffering, selection and quality changes cancel background work. yt-dlp extraction supplies page titles; Miruro uses optional watch-route metadata without fetching playback sources. Failures keep the supplied label and do not block later entries or surface playback errors. Results follow item IDs across reordering and cannot rename removed/replaced rows. Only titles are retained: playback resolves fresh on selection/revisits, and canceled/stale results cannot replace a newer selection.
Enqueue uses native macOS URL-open delivery to the explicit application, not launch arguments: repeated requests reach the existing process. Both one-item and multi-item requests use the same manifest. The current selection, playback/pause state, timeline, pending resolution and metadata stay intact; an empty player selects and starts the first entry. Original single-file, single-stream and resolved-source playback remain navigable when items are appended. Enqueue never silently deduplicates: any identity still in the queue, or any report-path collision, rejects the complete batch with an error in the player. Removed videos can be re-added with fresh report destinations, including the original standalone video. Old report paths remain reserved for the process lifetime; at most 4096 queue-report destinations may be registered, counting retired sessions. Existing files are never adopted as reporting sessions. Keep manifests and private sessions available until delivery; CLI success acknowledges macOS delivery, not GUI acceptance or playback.
@@ -55,6 +55,8 @@ Each report is immutably bound to its stable identity in the native decoder. Reg
Runnable headless queue checks: `make check-cli check-queue check-reporting check-resolved`. The existing `check-resolved` local HTTP/HLS/VTT harness drives a real native `PlayerModel` through mixed YouTube/Miruro queues with injected fixture resolution, stale-result cancellation, manual navigation, natural-end advancement, fresh revisits/resume and isolated v1/v2 reports. It also delivers repeated enqueue URLs while paused and playing, checks original standalone selection/timeline preservation, lazy append ordering, atomic invalid/conflicting requests, independent single/queue report revisits, removal/re-addition with fresh reports and unchanged retired files, and empty-player startup. These checks require no browser or live streaming service. Actual LaunchServices/UI delivery remains a separate user-owned verification step; no GUI smoke result is claimed for enqueue.
Background-title verification: `make check-resolved check-queue check-youtube all` passed. The native local-HLS smoke exercises unplayed YouTube/Miruro titles, serial utility-priority enrichment, unchanged paused selection/position/title, reordering during lookup, failure fallbacks, fresh playback preemption, and stale removal/replacement results. No browser or live service was used; sidebar appearance remains a user-owned visual check.
Removal/re-addition verification: the new native registration regression failed before the fix and passed afterward. `make check-reporting check-queue .build/resolved-playback-check all` passed. A focused `.build/resolved-playback-check /absolute/source.json --enqueue-only` smoke using local video-only H.264 HLS passed paused/playing append, natural-end advancement, atomic conflicts/rollback, removal and re-addition of the current standalone video and an inactive queued video, fresh-session playback, byte-for-byte retired-report preservation, and empty-player startup. The source document requires `headers` and `subtitles` (empty values are valid). No full A/V-suite or packaged-GUI/LaunchServices pass is claimed; the app was built, not installed. Actual UI confirmation remains user-owned; temporary fixture/server files were removed.
### Optional native metadata