feat(cast): self-contained casting package skeleton - #73
Open
susamn wants to merge 1 commit into
Open
Conversation
Introduces internal/cast, which will send MPD's audio to external players (Chromecast, Home Assistant media_player, DLNA/UPnP). Model is "sender only": mpdtui enables MPD's httpd output, points the device at that stream URL, then steps back -- MPD stays the source of truth and the device keeps playing after mpdtui exits. This commit is the interface + lifecycle core, with provider stubs: - CastProvider interface; Target/Session/MediaMeta/NowCasting types - Manager: concurrent discovery (fan-out, dedupe by (Kind,ID), one dead or slow provider can't block others), single-session lifecycle - StartCast: snapshot outputs -> enable httpd (+ disable others when cast_exclusive) -> persist session -> device Play, with rollback on any failure - StopCast: works from in-memory session, the on-disk state file, or a discovery fallback (device found playing our stream) -- so -cast-stop works with no TUI running - Reattach: adopt a persisted session iff the device is still playing our stream URL; discard stale (>24h) / mismatched / gone - state.go: atomic JSON session file under $XDG_CACHE_HOME/mpdtui - stream.go: stream-URL derivation (override -> httpd port -> config -> 8000; reject loopback host with a LAN-IP fallback) - config.go: reads ~/.config/mpdtui/config directly (own keys, no internal/config change) - cli.go: List / Start / Stop headless entrypoints + name/ID matching - chromecast/homeassistant/dlna providers: interface-conformant stubs (errNotImplemented); real protocols land in follow-up commits 12 internal tests cover discovery, the full lifecycle, rollback, re-attach match/mismatch/staleness, URL derivation and target matching. Nothing imports internal/cast yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JBJdG8Qenand5i16WT6BHG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #72. Second slice of the casting feature.
What
Introduces
internal/cast— the interface + lifecycle core, with provider stubs. Nothing imports it yet.CastProviderinterface;Target/Session/MediaMeta/NowCastingtypes; narrowMPDinterfaceManager: concurrent discovery (fan-out, dedupe by(Kind,ID), one dead/slow provider can't block the rest), single-session lifecycleStartCast: snapshot outputs → enable httpd (+ disable others whencast_exclusive) → persist session → devicePlay, with rollback on any failureStopCast: from in-memory session, on-disk state file, or a discovery fallback (device found playing our stream) — so-cast-stopworks with no TUI runningReattach: adopt a persisted session iff the device is still playing our stream URL; discard stale (>24h) / mismatched / gonestate.goatomic JSON session file under$XDG_CACHE_HOME/mpdtuistream.gostream-URL derivation (override → httpd port → config → 8000; reject loopback host with LAN-IP fallback)config.goreads~/.config/mpdtui/configdirectly (own keys, nointernal/configchange)cli.goList/Start/Stopheadless entrypointsTests
12 internal tests: discovery, full lifecycle, rollback, re-attach match/mismatch/staleness, URL derivation, target matching.
Design constraint
All casting logic stays in this one package; existing files get only tiny hooks later.
🤖 Generated with Claude Code