Documentation
¶
Overview ¶
Package device discovers media renderers on the local network and speaks their control protocols (DLNA/UPnP AVTransport, Chromecast). The Device interface is deliberately small: the cast pipeline decides what to send (subtitles are burned in upstream), a Device only needs to fetch and play.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SelfFetches ¶ added in v1.8.0
SelfFetches reports whether a renderer of this type fetches media URLs itself (a smart client such as Chromecast, or Roku's channel Video node) versus only playing bytes castor serves to it (DLNA). It is a static property of the protocol, known before the network round-trip of discovery and connect, so the cast pipeline can decide up front that a non-self-fetching renderer will always serve a local spool and begin buffering the single-use source while connect runs concurrently. It MUST agree with the connected renderer's Capabilities().SelfFetch, which the copy-vs-encode stage reads once the device is in hand: each family's media.Renderer literal sets SelfFetch by calling its own selfFetches() rather than re-stating the bool, so the two can't drift independently.
Types ¶
type Config ¶ added in v1.8.0
type Config struct {
Name string
Type Type
// Address, when set, pins where the renderer is so a cast connects to it
// directly and skips discovery. It is what the user configured: a bare host or
// host:port for any family, or a DLNA device description URL. Locate turns it
// into the concrete Info each family's connect needs. Empty means "find me by
// Name over discovery".
Address string
Family any
}
Config is the resolved device target the agnostic layers carry and forward: which renderer to reach (Name, Type) plus an opaque Family payload. It names no device family, so core/cast and every other device carry it without knowing any one family exists. The composition root (internal/config) fills Family with the selected family's typed connect settings; only that family's strategy reads it, via a type assertion in its own connect. Family is nil for a family that needs none.
type Device ¶
type Device interface {
// Play points the renderer at streamURL, advertised as contentType.
Play(ctx context.Context, streamURL *url.URL, contentType string) error
// Capabilities reports what this renderer can play: the containers it
// accepts as-is and the video envelopes it decodes natively. Each device
// resolves this from itself at connect time (DLNA negotiates it over
// GetProtocolInfo; Chromecast reports its known receiver profile), so the
// copy-vs-encode decision follows what the renderer advertises rather than
// an assumption baked in per device type.
Capabilities() media.Renderer
// StreamHeaders returns protocol-specific HTTP headers the local stream
// server must send when this renderer fetches contentType. Nil when the
// protocol needs none.
StreamHeaders(contentType string) map[string]string
Close() error
}
Device is a connected renderer, ready to play. Obtain one via Connect.
type Info ¶
func Discover ¶
Discover scans the local network for renderers of every registered family in parallel (DLNA via SSDP MediaRenderer, Chromecast via mDNS _googlecast._tcp, Roku via SSDP roku:ecp), sharing one timeout window; a family that fails contributes no devices rather than failing the whole scan. Results follow the registry order.
func Locate ¶ added in v1.8.0
Locate builds a connectable Info for a renderer whose address is known ahead of time, dispatching to its family strategy so the cast skips discovery entirely. This is the direct-connect path: it serves renderers reachable by unicast but not by discovery, whose SSDP/mDNS is multicast and so crosses no VLAN and is refused where interface enumeration is denied (Android/Termux, where discovery fails with "route ip+net: netlinkrib: permission denied"); it also shortcuts the discovery window for a device at a stable address.
address is what the user pinned: a bare host or host:port for any family, or, for DLNA, its device description URL. Each family turns that into the concrete Info its connect needs; DLNA additionally resolves a bare host to a description URL over a unicast SSDP request. name is carried through as the label and defaults to the host, since a pinned device is not found by name.
type RokuConfig ¶ added in v1.8.0
RokuConfig carries what discovery can't: which channel to launch (AppID, the sideloaded "dev" channel by default) and the developer-web-server Password used to sideload Castor's channel the first time. The dev web server's user is always "rokudev", so it is not configurable.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package rokuchannel builds Castor's Roku channel: a SceneGraph app whose only job is to play a stream URL passed over ECP.
|
Package rokuchannel builds Castor's Roku channel: a SceneGraph app whose only job is to play a stream URL passed over ECP. |