frontend

package
v0.3.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2026 License: GPL-3.0 Imports: 39 Imported by: 0

Documentation

Overview

Package frontend defines the protocol-facing contracts provided by Ether.

Index

Constants

View Source
const (
	KindMovie      = core.KindMovie
	KindCollection = core.KindCollection
	KindSmart      = core.KindSmart
	KindPlaylist   = core.KindPlaylist
	KindLocal      = core.KindLocal
	TypeMovie      = core.TypeMovie
	TypeShow       = core.TypeShow
	TypeSeason     = core.TypeSeason
	TypeEpisode    = core.TypeEpisode
)
View Source
const (
	ImagePoster   = "poster"
	ImageBackdrop = "backdrop"
	ImageThumb    = "thumb"
	ImageBanner   = "banner"
	ImageStill    = "still"
	ImagePerson   = "person"
	ImageChannel  = "channel"
)
View Source
const (
	PrerollBeforeTrailers = core.PrerollBeforeTrailers
	PrerollAfterTrailers  = core.PrerollAfterTrailers
)

Pre-roll placements relative to Cinema Trailers.

View Source
const (
	DiagnosticKindClientCapabilities = diagnostics.KindClientCapabilities
	DiagnosticKindDevice             = diagnostics.KindDevice
	DiagnosticKindPlaybackDecision   = diagnostics.KindPlaybackDecision
	DiagnosticKindPlaybackReported   = diagnostics.KindPlaybackReported
	DiagnosticKindRequest            = diagnostics.KindRequest
	DiagnosticKindRequestStarted     = diagnostics.KindRequestStarted
)
View Source
const (
	ProtocolDASH    = core.ProtocolDASH
	ProtocolHLS     = core.ProtocolHLS
	ProtocolTorrent = core.ProtocolTorrent
)

Playback protocols and media kinds.

View Source
const (
	MediaAny   = core.MediaAny
	MediaMovie = core.MediaMovie
	MediaTV    = core.MediaTV
)
View Source
const (
	PrewarmBrowse  = core.PrewarmBrowse
	PrewarmTrailer = core.PrewarmTrailer
)

Prewarm reasons.

View Source
const (
	UsenetFailed = core.UsenetFailed
	UsenetNone   = core.UsenetNone
)

Release-source states.

View Source
const (
	VersionRead = iota
	VersionOffer
	VersionFreeze
	VersionEnd
	VersionTouch
)

Version flow modes for VersionFlows.Call.

View Source
const (
	VariantIDBase  = 9_000_000_000_000_000
	VariantIDSpace = 7_199_254_740_990 // ids stay below 2^53
)
View Source
const (
	ClusterTopicResync    = clusterbus.TopicResync
	ClusterMaxPayload     = clusterbus.MaxPayload
	ClusterPublishTimeout = clusterbus.PublishTimeout
)
View Source
const (
	ContainerMPEGTS   = transcode.ContainerMPEGTS
	ContainerFMP4     = transcode.ContainerFMP4
	ContainerMatroska = transcode.ContainerMatroska

	InitSegment        = transcode.InitSegment
	InitSegmentName    = transcode.InitSegmentName
	MatroskaHeaderName = transcode.MatroskaHeaderName
)
View Source
const (
	StatisticsYear   = hoststat.SpanYear
	StatisticsMonth  = hoststat.SpanMonth
	StatisticsWeek   = hoststat.SpanWeek
	StatisticsDay    = hoststat.SpanDay
	StatisticsHour   = hoststat.SpanHour
	StatisticsSecond = hoststat.SpanSec
)
View Source
const (
	DecisionDirectPlay = core.DecisionDirectPlay
	DecisionRemux      = core.DecisionRemux
	DecisionTranscode  = core.DecisionTranscode
)
View Source
const (
	SortAdded      = core.SortAdded
	SortDuration   = core.SortDuration
	SortPopularity = core.SortPopularity
	SortRating     = core.SortRating
	SortReleased   = core.SortReleased
	SortTitle      = core.SortTitle
	SortUpdated    = core.SortUpdated
	SortYear       = core.SortYear
)
View Source
const (
	KindShow    = core.KindShow
	KindSeason  = core.KindSeason
	KindEpisode = core.KindEpisode
	KindExtra   = core.KindExtra
)

Catalogue key kinds and constructors stay owned by core. Adapters compare and rebuild parent keys through these aliases.

View Source
const ExtraSourceCommand = "command"

ExtraSourceCommand marks an ExtraClip whose video is resolved by the owner's command.

View Source
const LibraryCollagePrefix = "library-collage/"

LibraryCollagePrefix marks a generated library-view collage. The remainder is the hex identity of the view and the child posters it was built from.

View Source
const LiveTVProvider = "tv.plex.providers.epg.xmltv:1"

LiveTVProvider is the EPG provider identifier reported on Plex Live TV routes.

View Source
const MaxExtras = 10

MaxExtras caps how many extras one title advertises.

View Source
const MaxPlayQueues = 2000

MaxPlayQueues bounds the play-queue store.

View Source
const MaxSubtitleFontAttachments = 32

MaxSubtitleFontAttachments bounds the number of Matroska font attachments exposed per subtitle stream.

View Source
const MaxVariants = core.MaxVariants
View Source
const PlaylistExpandLimit = 500

PlaylistExpandLimit bounds playlist expansion.

View Source
const PrewarmDetail = core.PrewarmDetail

PrewarmDetail is the warm-up reason for an opened detail page.

View Source
const ProtocolHTTP = core.ProtocolHTTP

ProtocolHTTP is the release protocol for a stream URL read with HTTP range requests. Its value stays owned by core.

View Source
const RemoteMetadataArt = plexmeta.RemoteArt
View Source
const SeriesNextUpLimit = 1000

SeriesNextUpLimit is the indexed window for one series' next-up listing. The lookup is keyed by the series, never the library.

View Source
const StreamGrantParam = streamgrant.StreamGrantParam
View Source
const VersionPreplayTTL = 90 * time.Second

VersionPreplayTTL bounds a version flow's preplay snapshot.

Variables

View Source
var (
	ErrArticleCorrupt    = core.ErrArticleCorrupt
	ErrArticleMissing    = core.ErrArticleMissing
	ErrBudgetExhausted   = core.ErrBudgetExhausted
	ErrDebridAuth        = core.ErrDebridAuth
	ErrDownloadLimit     = core.ErrDownloadLimit
	ErrDownloadPaused    = core.ErrDownloadPaused
	ErrDownloadQueued    = core.ErrDownloadQueued
	ErrDownloadRefused   = core.ErrDownloadRefused
	ErrNoSources         = core.ErrNoSources
	ErrNoTorrentSources  = core.ErrNoTorrentSources
	ErrNotCached         = core.ErrNotCached
	ErrPolicyUnconfirmed = core.ErrPolicyUnconfirmed
	ErrPrepareSlow       = core.ErrPrepareSlow
	ErrReleaseRejected   = core.ErrReleaseRejected
	ErrSourceUnavailable = core.ErrSourceUnavailable
	ErrUnreleased        = core.ErrUnreleased
)

Domain errors, shared by identity for errors.Is checks.

View Source
var (
	// ErrSubtitleFontsUnavailable reports that embedded font attachments exceed
	// the retained limit and could not be narrowed to script-referenced fonts.
	ErrSubtitleFontsUnavailable = errors.New("subtitle font attachments unavailable")

	// ErrSubtitleAuthoringUnavailable reports that complete authored ASS/SSA
	// styling could not be extracted when authored fidelity is required.
	ErrSubtitleAuthoringUnavailable = errors.New("authored subtitle styling unavailable")
)
View Source
var (
	ErrPartyNotFound  = errors.New("watch party not found")
	ErrPartyForbidden = errors.New("watch party forbidden")
	ErrPartyDenied    = errors.New("watch party denied")
	ErrPartyConflict  = errors.New("watch party conflict")
)

Watch-party failures are safe to show a client. They do not include the title a viewer is not allowed to see.

View Source
var ErrAlreadyMounted = errors.New("frontend already mounted")
View Source
var ErrAmbiguousLibraryGUID = plexguid.ErrAmbiguous
View Source
var ErrBadPlaylist = errors.New("invalid playlist request")

ErrBadPlaylist is an invalid playlist name, index, or empty change.

View Source
var ErrDownloadBudget = core.ErrDownloadBudget

ErrDownloadBudget identifies an exceeded temporary download disk budget. It shares identity with the domain error for errors.Is checks.

View Source
var ErrDownloadNeedsTranscode = core.ErrDownloadNeedsTranscode

ErrDownloadNeedsTranscode identifies a download source that cannot be copied to MP4. It shares identity with the domain error for errors.Is.

View Source
var ErrIdentityUnavailable = errors.New("frontend identity operation unavailable")

ErrIdentityUnavailable means this host does not implement credential issuance.

View Source
var ErrImageBatchLimit = errors.New("frontend: invalid artwork batch")
View Source
var ErrInvalidPreferences = errors.New("invalid frontend preferences")
View Source
var ErrNotAvailable = core.ErrNotAvailable

ErrNotAvailable means the host has no service for this browse feature. It shares identity with the domain error for errors.Is checks.

View Source
var ErrNotFound = core.ErrNotFound

ErrNotFound identifies an absent or inaccessible frontend resource. It shares identity with the domain error for errors.Is checks.

View Source
var ErrNotRegistered = errors.New("frontend not registered")
View Source
var ErrPeopleQuery = errors.New("frontend: invalid people query")
View Source
var ErrPreferencesLimit = errors.New("frontend preferences limit exceeded")
View Source
var ErrPreferencesNotFound = core.ErrNotFound

ErrPreferencesNotFound identifies a missing record without exposing storage.

View Source
var ErrQuickConnectPending = errors.New("frontend quick connect pending")

ErrQuickConnectPending means the code has not yet been approved.

View Source
var ErrRateLimited = errors.New("frontend identity rate limited")

ErrRateLimited means the verified network peer has exceeded an identity limit.

View Source
var ErrRowViewStale = errors.New("frontend: row view snapshot expired or changed")

ErrRowViewStale asks the client to refresh its visit-scoped row views.

View Source
var ErrSessionBusy = errors.New("session operation capacity exhausted")

ErrSessionBusy means bounded broker admission is temporarily exhausted.

View Source
var ErrSourceGone = errors.New("frontend: offered playback source is gone")

ErrSourceGone means previously offered source facts no longer match a playable source; the client must request fresh detail.

View Source
var ErrStreamLimit = core.ErrStreamLimit

ErrStreamLimit identifies exhausted playback admission.

View Source
var ErrTooManyTranscodes = transcode.ErrTooManyTranscodes
View Source
var ErrTrackNotFound = errors.New("selected track is not available")

ErrTrackNotFound reports that an explicit selection does not identify one stream in the opened source.

View Source
var ErrTrackSourceUnavailable = errors.New("verified track source unavailable")

ErrTrackSourceUnavailable reports that the broker cannot prove the opened source and its track layout across planning and playback admission.

View Source
var ErrTranscodeCapacity = errors.New("transcode capacity exhausted")

ErrTranscodeCapacity classifies an exhausted shared encoder budget.

View Source
var ErrUnauthorized = core.ErrUnauthorized

ErrUnauthorized identifies a viewer who cannot see or change the resource. It shares identity with the domain error for errors.Is checks.

Functions

func AdvertisedName

func AdvertisedName(settings Settings) string

AdvertisedName is the household name a frontend shows. The app fills serverName from the general server name; a frontend does not keep its own.

func ApplyDetailHeader

func ApplyDetailHeader(tagline, overview, header string) (string, string)

ApplyDetailHeader places a viewer's micro-reason the way Plex detail does. An empty tagline takes the header, which is the line under the title. Otherwise the header prefixes the overview and the catalogue tagline stays. The header is never written into both places. An empty header changes nothing.

func ApplyMetadataDisplay

func ApplyMetadataDisplay(title *core.Title, overlay MetadataOverlay)

ApplyMetadataDisplay applies a cached Plex metadata overlay's display fields to title.

func ArtworkKindWanted

func ArtworkKindWanted(ctx context.Context, kind string) bool

ArtworkKindWanted reports whether kind may be used by this read: always, unless WithArtworkKinds narrowed it.

func ArtworkMetadataWanted

func ArtworkMetadataWanted(ctx context.Context) bool

ArtworkMetadataWanted is false under WithoutArtworkMetadata.

func ArtworkTitle

func ArtworkTitle(ctx context.Context, key core.RatingKey) (*core.Title, bool)

ArtworkTitle returns the title stored by WithArtworkTitle when it is the requested key, else the one this request read as a row (ArtworkRows).

func AssembleHome

func AssembleHome(candidates []HomeCandidate, includeContinue, promotedOnly bool, continueID string, renderContinue func(), render func(HomeCandidate) string, accept func(HomeCandidate))

AssembleHome places the continue row at its ranked position and deduplicates rendered identifiers. The renderer returns the stable identifier it actually used; this can differ from the producer's candidate identifier.

func AssemblePostPlay

func AssemblePostPlay[P any](ctx context.Context, selection PostPlaySelection, viewer *core.User, key core.RatingKey, count int,
	next func() (core.RatingKey, P, bool), picks func(PostPlayRow) (P, bool), render func(core.Hub) P) ([]P, error)

AssemblePostPlay retains next-up, personal picks and related row ordering. Rendering runs at each original boundary, before fetching the next source.

func BurnsSubtitle

func BurnsSubtitle(sub StreamInfo, caps ClientCaps, opts DecideOptions) bool

func ClassifyDevice

func ClassifyDevice(product, platform, device string) string

ClassifyDevice maps a client's product, platform and device strings to a device class. The classification table stays owned by core.

func ClientIP

func ClientIP(ctx context.Context) (netip.Addr, bool)

ClientIP returns the verified peer carried by WithClientIP.

func DefaultPort

func DefaultPort(id Protocol) (int, bool)

DefaultPort returns the listener port for protocols that require one. Silo uses its Compose default; the reference lab's 8098 is an override.

func DetachQueryStats

func DetachQueryStats(ctx context.Context) context.Context

func DiagnosticPlaybackRequestPath

func DiagnosticPlaybackRequestPath(path string) bool

func DownloadsAllowed

func DownloadsAllowed(viewer *core.User, ready, allowFriends bool, policy AccessPolicy) bool

DownloadsAllowed is shared capability admission; handlers still enforce it.

func EncodeQueue

func EncodeQueue(q *PlayQueue) (string, error)

func Estimate

func Estimate(ctx context.Context, playback Estimator, viewer *core.Viewer, clientID string, title *core.Title, caps func() core.ClientCaps) (core.MediaInfo, *core.PlaySession)

Estimate returns an existing source's media information or a virtual estimate. It never prepares or resolves a release.

func FilterOutSurroundAudio

func FilterOutSurroundAudio(codecs []string) []string

FilterOutSurroundAudio returns codecs without surround audio formats.

func HLSContainer

func HLSContainer(caps ClientCaps, videoCodec, audioCodec string) string

func HLSCopyPeakKbps

func HLSCopyPeakKbps(info MediaInfo, segDur time.Duration) int

func HLSDecision

func HLSDecision(dec core.Decision, allowDirect bool, reconsider func() core.Decision, forcedStream func(core.Decision) core.Decision) core.Decision

HLSDecision applies the v39 start-time decision rules. A client may reject direct play after its initial decision; in that case reconsider is called before selecting the segmented output. forcedStream, when supplied, applies adapter output constraints only when a still-direct decision is forced to HLS.

func HLSVariantAttributes

func HLSVariantAttributes(info MediaInfo, d Decision) string

func HasHDR10Base

func HasHDR10Base(v *StreamInfo, caps ClientCaps) bool

func HasQuirk

func HasQuirk(product, platform, device, model, version, name string) bool

func HomePurpose

func HomePurpose(h core.Hub) core.RowPurpose

homePurpose translates producer identifiers at the Plex boundary; no wire context or hub identifier is included in the neutral candidate.

func IsASSSubtitleCodec

func IsASSSubtitleCodec(codec string) bool

IsASSSubtitleCodec reports whether a stream codec identifier names an ASS or SSA text subtitle track.

func IsImageSubtitle

func IsImageSubtitle(codec string) bool

func IsSurroundAudioCodec

func IsSurroundAudioCodec(c string) bool

func IsTextSubtitle

func IsTextSubtitle(codec string) bool

func KnownSDR

func KnownSDR(stream StreamInfo) bool

KnownSDR is Emby's evidence rule for an SDR picture. An explicit SDR transfer curve is enough. With no transfer at all, 8-bit 4:2:0 is SDR once the caller knows Dolby Vision is absent and the transfer is not PQ. Other pixel formats, depths, and unrecognised curves stay unlabelled.

func LanguageMatchTier

func LanguageMatchTier(a, b string) int

LanguageMatchTier compares full and generic tags using the host's matching rules; two different regional variants do not match each other.

func LanguagePrimary

func LanguagePrimary(tag string) (string, bool)

LanguagePrimary returns the canonical primary subtag for protocol labels.

func LatestPlayedFilter

func LatestPlayedFilter(ctx context.Context) (played bool, ok bool)

LatestPlayedFilter reports whether Latest should filter on played state.

func MarshalBIF

func MarshalBIF(frames []BIFFrame) ([]byte, error)

func MaySetViewerRating

func MaySetViewerRating(actor *core.Viewer, active *core.User) bool

MaySetViewerRating is the owner-console rule for changing a household rating cap. Delegated sessions and non-owners cannot write it.

func MetadataImageHost

func MetadataImageHost(host string) bool

func MetadataOverlayRatingAllowed

func MetadataOverlayRatingAllowed(viewer *core.User, catalogue, overlay string) bool

MetadataOverlayRatingAllowed reports whether a cached metadata overlay's rating stays within viewer's content-rating cap when combined with the catalogue rating.

func NeedsGeneratedPoster

func NeedsGeneratedPoster(title *Title) bool

NeedsGeneratedPoster exposes shared title fallback eligibility without I/O.

func NewClusterOrigin

func NewClusterOrigin() string

func NormalizeLanguage

func NormalizeLanguage(tag string) string

NormalizeLanguage folds a client language tag to the form Ether stores.

func NotifyTranscodeActivity

func NotifyTranscodeActivity(transcoder core.Transcoder, id, state string)

NotifyTranscodeActivity forwards timeline state to an active output. It is deliberately a no-op for transcoders and outputs without this capability.

func ParseSegmentName

func ParseSegmentName(name string) (int, bool)

func PickAudio

func PickAudio(info core.MediaInfo, langs []string) int

PickAudio selects an audio stream position, or -1 when none exists.

func PlanAdmissionFrom

func PlanAdmissionFrom(ctx context.Context) (func(context.Context) (PlanAdmission, error), bool)

PlanAdmissionFrom returns the admission callback WithPlanAdmission attached.

func PolicyStamp

func PolicyStamp(product, platform, device, model, version string, overrides []core.ClientCapabilityOverride) (dv []int, subs []string, dvChanged, subsChanged bool)

func QueueItemIndex

func QueueItemIndex(items []QueueItem, id int64) int

func QuietIdentity

func QuietIdentity(ctx context.Context) bool

QuietIdentity reports whether activity writes should be skipped.

func RegisterArtworkStores

func RegisterArtworkStores(
	newRemoteCache func(budget int64, client *http.Client) ArtworkImageCache,
	newPaletteCache func(db *sql.DB, submit func(string, func(context.Context)) bool, now func() time.Time, log *slog.Logger, compute func(context.Context, RatingKey, string) (ArtworkPalette, error)) ArtworkPaletteCache,
	computePalette func(ctx context.Context, cache ArtworkImageCache, imageURL ImageURLFunc, key RatingKey, path string, now time.Time, art ArtworkCollectionArt) (ArtworkPalette, error),
	newSource func(cfg ArtworkSourceConfig) ArtworkSource,
)

RegisterArtworkStores wires host artwork store constructors for frontends.

func RegisterLiveTVHelpers

func RegisterLiveTVHelpers(
	diagnose func(stage string, err error) LiveTVTuneDiagnosis,
	virtualDASH func(err error) (string, error, bool),
	showcaseLogo func(c LiveTVChannel) (string, []byte, bool),
)

RegisterLiveTVHelpers wires host Live TV diagnostic and logo helpers for frontends.

func RegisterMigration

func RegisterMigration(component string, version int, sql string)

Store helpers exposed across the frontend boundary.

func RenderTitlePoster

func RenderTitlePoster(ctx context.Context, generated TitlePosterRenderer, t *Title, width int) ([]byte, string, bool, error)

RenderTitlePoster renders Ether's fallback poster for a title with no artwork.

func ResizePoster

func ResizePoster(data []byte, width int) ([]byte, error)

ResizePoster scales a poster JPEG to width.

func ResolutionTier

func ResolutionTier(w, h int) int

func ResolveAudio

func ResolveAudio(want *core.StreamInfo, pos int, info core.MediaInfo) int

ResolveAudio maps an issued audio identity onto a position in the current MediaInfo.Streams. Callers needing an encoder index must translate that position through the selected StreamInfo.Index. The caller must supply a non-nil issued stream identity.

func ResolveSubtitle

func ResolveSubtitle(want *core.StreamInfo, pos int, info core.MediaInfo) int

ResolveSubtitle maps a stored choice onto a stream position, or -1. The choice is language, codec, and source (sidecar URL, or embedded versus external). A matching track at a new index beats whatever now sits in the old slot: variant lists reorder, and that slot is not the track the viewer picked.

func SQLPlaceholders

func SQLPlaceholders(n int) string

func SafeDiagnosticQuery

func SafeDiagnosticQuery(query url.Values) string

func SaferMetadataRating

func SaferMetadataRating(catalogue, overlay string) string

SaferMetadataRating is the stricter of a catalogue and overlay rating.

func SameImage

func SameImage(a, b Image) bool

SameImage compares stable authorization identity, excluding optional metadata.

func SectionAllowed

func SectionAllowed(viewer *core.User, id int) bool

SectionAllowed applies a viewer's library restrictions to an existing section. An empty restriction list means all sections, as it does for an owner.

func SegmentedAudioCopyOK

func SegmentedAudioCopyOK(caps ClientCaps, codec string) bool

func SegmentedVideoCopyOK

func SegmentedVideoCopyOK(caps ClientCaps, codec string) bool
func ShowcaseLogo(c LiveTVChannel) (repoPath string, png []byte, ok bool)

ShowcaseLogo returns the repository path and PNG bytes for a showcase channel.

func ShuffleQueue

func ShuffleQueue(p *PlayQueue)

func SourceLabel

func SourceLabel(s Source) string

func StreamGrantURL

func StreamGrantURL(raw, token string) string

func StreamServeFrom

func StreamServeFrom(ctx context.Context) (remote bool, format string)

StreamServeFrom returns the remote bit and subtitle format WithStreamServe attached.

func SupportsDVProfile

func SupportsDVProfile(c ClientCaps, profile int) bool

func SynchronousArtworkDeadline

func SynchronousArtworkDeadline(ctx context.Context) (time.Time, bool)

SynchronousArtworkDeadline is the time after which artwork hashing returns to the background worker. The second result is false when no budget was set.

func TagClusterMessage

func TagClusterMessage(origin string, b []byte) []byte

func TimelineStored

func TimelineStored(ctx context.Context) bool

func TitleAllowed

func TitleAllowed(policy AccessPolicy, viewer *core.User, title *core.Title) bool

TitleAllowed applies the mandatory content guards and the owner's policy.

func TitlePosterStamp

func TitlePosterStamp(t *Title) (string, bool)

TitlePosterStamp returns the deterministic stamp for a title's generated poster.

func TrickplayCacheKey

func TrickplayCacheKey(s *PlaySession) string

TrickplayCacheKey binds preview work to the selected item, release and opened source member. The identity stays owned by core.

func UnshuffleQueue

func UnshuffleQueue(p *PlayQueue)

func UntagClusterMessage

func UntagClusterMessage(msg []byte) (string, []byte)

func ValidArtworkPath

func ValidArtworkPath(path string) bool

ValidArtworkPath exposes the shared, pure artwork filename contract.

func VariantHash

func VariantHash(key core.RatingKey, releaseID string) int64

VariantHash is the stable hash slot for a variant id.

func ViewerRestricted

func ViewerRestricted(policy AccessPolicy, u *core.User) bool

ViewerRestricted chooses inherited visibility for limited or unknown policies.

func VirtualDASHError

func VirtualDASHError(err error) (message string, cause error, ok bool)

VirtualDASHError unpacks a virtual channel DASH error.

func WireID

func WireID(key core.RatingKey, slot string) int64

WireID is the positive int32-range id Plex clients already parse. Offer rows use it directly and are not stream bindings.

func WithArtworkKinds

func WithArtworkKinds(ctx context.Context, kinds map[string]bool) context.Context

WithArtworkKinds marks a read that signs only these image kinds (a page signer's Kinds): artwork lists skip work that only another kind uses, such as scheduling a backdrop's UltraBlur colours for a poster-only listing.

func WithArtworkRows

func WithArtworkRows(ctx context.Context) context.Context

WithArtworkRows marks ctx as an artwork request that lists no credited people's portraits (ArtworkRows).

func WithArtworkTitle

func WithArtworkTitle(ctx context.Context, title *core.Title) context.Context

WithArtworkTitle carries a title the caller already loaded and authorized. Artwork listing must not read that title again.

func WithBrowseScope

func WithBrowseScope(ctx context.Context, scope string) context.Context

WithBrowseScope identifies a tokenless client's browse scope.

func WithCatalogViewer

func WithCatalogViewer(ctx context.Context, u *User) context.Context

WithCatalogViewer records the catalogue viewer for this request. The context key stays owned by core.

func WithClientIP

func WithClientIP(ctx context.Context, ip netip.Addr) context.Context

WithClientIP supplies the verified network peer for authentication rate limits. A frontend must derive it from the transport and trusted proxies, never an untrusted forwarding header. Missing or invalid addresses fail closed.

func WithHistoryTitle

func WithHistoryTitle(ctx context.Context, title *Title) context.Context

func WithLatestPlayed

func WithLatestPlayed(ctx context.Context, played bool) context.Context

WithLatestPlayed records the Latest IsPlayed filter. False keeps only unplayed items. Jellyfin and Emby both do that when the query omits IsPlayed and the user still has the default HidePlayedInLatest setting.

func WithLiveApp

func WithLiveApp(ctx context.Context, app string) context.Context

WithLiveApp records the live app name for this request. The context key stays owned by core.

func WithPlanAdmission

func WithPlanAdmission(ctx context.Context, admit func(context.Context) (PlanAdmission, error)) context.Context

WithPlanAdmission attaches the prepared source for one Plex Plan call.

func WithPlexSaferRating

func WithPlexSaferRating(ctx context.Context) context.Context

WithPlexSaferRating marks a request for the safer age-rating mapping.

func WithQuietIdentity

func WithQuietIdentity(ctx context.Context) context.Context

WithQuietIdentity tells credential resolution to skip activity writes. Sign-in uses it so the response is not waiting on viewer-times bookkeeping.

func WithRequestMemo

func WithRequestMemo(ctx context.Context) context.Context

WithRequestMemo installs the per-request viewer and visibility memo.

func WithSearchCandidates

func WithSearchCandidates(ctx context.Context, c *SearchCandidates) context.Context

WithSearchCandidates attaches the request-scoped search candidate set.

func WithSearchListFacts

func WithSearchListFacts(ctx context.Context) context.Context

WithSearchListFacts marks a search rendered as list items.

func WithStreamServe

func WithStreamServe(ctx context.Context, remote bool, format string) context.Context

WithStreamServe carries the request's remote bit and subtitle format into ResolveStream and OpenSidecar without changing their signatures.

func WithSubtitleSource

func WithSubtitleSource(ctx context.Context, source string) context.Context

func WithSynchronousArtworkMetadata

func WithSynchronousArtworkMetadata(ctx context.Context, budget time.Duration) context.Context

WithSynchronousArtworkMetadata lets a caller wait briefly for hashing that is already in flight. Stored rows are joined without this budget. The page cache clears it before filling a page, so a browse never holds the cache open for a hash.

func WithTimelineStored

func WithTimelineStored(ctx context.Context) context.Context

func WithWatchOrigin

func WithWatchOrigin(ctx context.Context, origin WatchOrigin) context.Context

func WithoutArtworkMetadata

func WithoutArtworkMetadata(ctx context.Context) context.Context

WithoutArtworkMetadata marks a read whose responses never carry image dimensions or hashes (an IPTV export): artwork lists skip the per-image metadata lookup and do not queue hashing for the titles they list.

func WithoutSynchronousArtworkMetadata

func WithoutSynchronousArtworkMetadata(ctx context.Context) context.Context

WithoutSynchronousArtworkMetadata drops an in-flight artwork wait so a caller, such as the browse page cache, returns as soon as stored rows are joined.

func XtreamUsername

func XtreamUsername(password string) string

XtreamUsername is a generated login name, independent of household sign-in. Its input is a random app password; neither value reveals a viewer identifier.

Types

type AccessPolicy

type AccessPolicy interface {
	Allowed(*core.User, *core.Title) bool
}

AccessPolicy adds owner-defined restrictions to the mandatory title guard.

type ActiveUserSource

type ActiveUserSource interface {
	ActiveUser(context.Context, int64) (*User, error)
}

ActiveUserSource checks current server membership for delegated stream access.

type ActivityPage

type ActivityPage struct {
	Items      []Title
	Total      int
	TotalExact bool
	More       bool
}

ActivityPage reports an exact total only when TotalExact is true; otherwise Total is a lower bound and More indicates that another page is available.

type AiredMemo

type AiredMemo struct {
	Items []core.Title
	Total int
	Err   error
}

AiredMemo is one show's capped local episode page. Season rows on the same request share it instead of reading the show again for every season.

type Announcer

type Announcer interface {
	Start(context.Context) error
	Close() error
}

type AppConnectionAdmission

type AppConnectionAdmission interface {
	PrepareAppConnection(*http.Request, string, PlanRequest) error
}

AppConnectionAdmission lets an authenticated primary URL switch its one playback slot, while old segment URLs cannot steal it back.

type AppConnectionStatus

type AppConnectionStatus interface {
	AppConnections(context.Context, string) (int, error)
}

AppConnectionStatus reports durable login leases, including other nodes.

type AppPasswordIdentity

type AppPasswordIdentity interface {
	AuthenticateAppPassword(context.Context, string, string) (*Viewer, error)
}

AppPasswordIdentity authenticates only a dedicated, revocable app password. The host applies its shared, verified-peer limiter to failed authentication.

type Artwork

type Artwork interface {
	List(context.Context, ArtworkRequest) (images []Image, complete bool, err error)
	Read(context.Context, ArtworkRequest, Image, ArtworkTransform) (data []byte, contentType string, err error)
	RemoteCache() ArtworkImageCache
	PaletteCache() ArtworkPaletteCache
	PosterRenderer() TitlePosterRenderer
	ImageURLFunc() ImageURLFunc
}

Artwork is the host-side source of authorized descriptors and their bytes. An implementation reports complete when its currently selected artwork is authoritative, including on a cold cache. Alternatives may arrive later. It must recheck visibility and descriptor membership on Read; the descriptor is a reference, not an authorization credential.

type ArtworkAccessPolicy

type ArtworkAccessPolicy interface{ Restricted(*User) bool }

ArtworkAccessPolicy is the optional restricted-viewer check an access policy may expose for artwork decisions.

type ArtworkCollectionArt

type ArtworkCollectionArt interface {
	CollectionArtwork(ctx context.Context, viewer *User, key RatingKey, element string, width int) ([]byte, string, bool, error)
}

ArtworkCollectionArt is generated collection artwork used for smart-collection palettes.

type ArtworkImageCache

type ArtworkImageCache interface {
	Get(ctx context.Context, u string, now time.Time) (*ArtworkRemoteImage, error)
	RasterFormat(ctx context.Context, data []byte, ct, format string, now time.Time) ([]byte, string, error)
	IsNotFound(err error) bool
}

ArtworkImageCache is the remote/transformed image cache used by frontend handlers.

func NewArtworkRemoteCache

func NewArtworkRemoteCache(budget int64, client *http.Client) ArtworkImageCache

NewArtworkRemoteCache constructs an in-memory remote artwork cache.

type ArtworkImageFile

type ArtworkImageFile = core.ArtworkImageFile

ArtworkImageFile describes one candidate remote artwork variant.

type ArtworkImages

type ArtworkImages = core.ArtworkImages

ArtworkImages groups candidate artwork variants for a title by kind.

type ArtworkOwner

type ArtworkOwner struct {
	Item          RatingKey
	Images        []Image
	Authoritative bool
}

ArtworkOwner identifies the independently authorized item whose descriptors must be passed to ImageGrants. Incomplete lists must not be granted.

type ArtworkPalette

type ArtworkPalette struct {
	TopLeft, TopRight, BottomLeft, BottomRight string
}

ArtworkPalette holds four-corner hex colors (without leading '#').

func ComputeArtworkItemPalette

func ComputeArtworkItemPalette(ctx context.Context, cache ArtworkImageCache, imageURL ImageURLFunc, key RatingKey, path string, now time.Time, art ArtworkCollectionArt) (ArtworkPalette, error)

ComputeArtworkItemPalette computes the four-corner palette for an item.

type ArtworkPaletteCache

type ArtworkPaletteCache interface {
	Lookup(key RatingKey, path string) *ArtworkPalette
	Preload(ctx context.Context, wants []ArtworkPaletteWant)
	PersistFor(persist func(context.Context, RatingKey) bool)
}

ArtworkPaletteCache is the persistent title palette store used by UltraBlur.

func NewArtworkPaletteCache

func NewArtworkPaletteCache(db *sql.DB, submit func(string, func(context.Context)) bool, now func() time.Time, log *slog.Logger, compute func(context.Context, RatingKey, string) (ArtworkPalette, error)) ArtworkPaletteCache

NewArtworkPaletteCache constructs a title palette cache.

type ArtworkPaletteWant

type ArtworkPaletteWant struct {
	Key  RatingKey
	Path string
}

ArtworkPaletteWant describes a background palette preload request.

type ArtworkPersistenceCatalog

type ArtworkPersistenceCatalog interface {
	PersistsArtwork(context.Context, RatingKey) bool
}

ArtworkPersistenceCatalog reports whether computed artwork palettes may be persisted for a key.

type ArtworkRemoteImage

type ArtworkRemoteImage struct {
	URL         string
	Data        []byte
	ContentType string
	FetchedAt   time.Time
}

ArtworkRemoteImage is a fetched remote artwork payload.

type ArtworkRequest

type ArtworkRequest struct {
	Viewer *core.Viewer
	Device core.Device
	Item   core.RatingKey
	// Channel is a stable LiveTV channel ID. Exactly one of Item and Channel
	// identifies the subject.
	Channel string
}

ArtworkRequest identifies the viewer and presentation context for artwork. Implementations must apply the same item visibility policy as Experience.

type ArtworkRows

type ArtworkRows struct {
	// contains filtered or unexported fields
}

ArtworkRows holds the titles an artwork request read as visibility rows: the row, with the facts the viewer's policy reads, and no credits. Only a request that never lists credited people's portraits (a grant of a title's own images: poster, art, logo...) reads titles this way; its authorization and its image read then share them (ArtworkTitle).

func ArtworkRowsFrom

func ArtworkRowsFrom(ctx context.Context) *ArtworkRows

ArtworkRowsFrom returns WithArtworkRows' holder, or nil.

func (*ArtworkRows) Get

func (r *ArtworkRows) Get(key core.RatingKey) (core.Title, bool)

Get returns a title the request recorded.

func (*ArtworkRows) Put

func (r *ArtworkRows) Put(t core.Title)

Put records a title the request judged.

type ArtworkSource

type ArtworkSource interface {
	Artwork
	Warm(t Title, d Device)
	ChannelImage(viewer *Viewer, channel LiveTVChannel) Image
	ArtPath(ctx context.Context, req ArtworkRequest, element string) (path string, defWidth int, err error)
}

ArtworkSource serves canonical artwork listings, reads, warming, and selection paths.

func NewArtworkSource

func NewArtworkSource(cfg ArtworkSourceConfig) ArtworkSource

NewArtworkSource constructs an ArtworkSource from cfg.

type ArtworkSourceConfig

type ArtworkSourceConfig struct {
	Catalog          StoredTitleLookup
	CollectionDevice string
	Collections      Collections
	Playlists        Playlists
	Visibility       Visibility
	LiveTV           LiveTV
	Discovery        *DiscoveryFeatures
	Images           ArtworkImageCache
	ImageURL         ImageURLFunc
	Palettes         ArtworkPaletteCache
	Now              func() time.Time
	Variants         func(*Title, string) (*ArtworkImages, bool)
	Metadata         func(context.Context, ArtworkRequest, Image) Image
	VirtualSeason    func(context.Context, *User, RatingKey) (*Title, error)
	URLImages        UntrustedImageFetcher
	Raster           SVGRasterizer
	Generated        TitlePosterRenderer
}

ArtworkSourceConfig configures a host-backed ArtworkSource.

type ArtworkTransform

type ArtworkTransform struct {
	Width, Height int
	Format        string
	Blur          bool
}

ArtworkTransform describes the requested output. Zero dimensions preserve the source's normal dimensions; Format is empty, "jpeg", or "png".

type AudioLimit

type AudioLimit = core.AudioLimit

Playback, session and request values.

type Auth

type Auth = core.Auth

Host service ports.

type AuthenticatedLazyStreams

type AuthenticatedLazyStreams interface {
	ServeAuthenticated(http.ResponseWriter, *http.Request, string, PlanRequest)
}

AuthenticatedLazyStreams is the optional WebDAV-style capability for a surface that authenticates each GET and HEAD instead of issuing a bearer URL.

type AvailabilitySource

type AvailabilitySource interface {
	Available(context.Context, RatingKey) (bool, bool)
}

AvailabilitySource is the optional capability reporting whether a title is currently available, and whether that answer is known.

type BIF

type BIF = transcode.BIF

func ParseBIF

func ParseBIF(data []byte) (*BIF, error)

type BIFFrame

type BIFFrame = transcode.BIFFrame

type BackgroundWorker

type BackgroundWorker interface {
	BackgroundBusy() int
}

BackgroundWorker is optionally implemented by a mounted Instance that runs asynchronous work behind requests.

type Binding

type Binding[R any] struct {
	ID          string // client "session" param
	StreamToken string // independent random capability; never a client-chosen ID
	PlayID      string // core.PlaySession.ID
	PlaybackID  string // explicit X-Plex-Session-IDentifier owning this encoder
	UserID      int64
	ClientID    string
	Key         core.RatingKey
	Requested   R // original Decision/start inputs, before policy refinement
	Decision    core.Decision
	Info        core.MediaInfo
	Subtitle    int // selected Subtitle's position in Info, -1 = none
	Caps        core.ClientCaps
	Opts        core.DecideOptions
	Offset      time.Duration
	Started     bool // StartHLS ran
	UpdatedAt   time.Time
	// A failed Decision for this binding (FailKey, FailErr at FailedAt):
	// the start request that follows it answers with the same error at
	// once instead of resolving again. One-shot and short-lived.
	FailKey  core.RatingKey
	FailErr  error
	FailedAt time.Time
}

type BindingTable

type BindingTable[R any] struct {
	// contains filtered or unexported fields
}

func NewBindingTable

func NewBindingTable[R any]() *BindingTable[R]

func (*BindingTable[R]) ByPlayID

func (t *BindingTable[R]) ByPlayID(PlayID string) []string

ByPlayID returns the transcode session ids fed by a playback session.

func (*BindingTable[R]) Claim

func (t *BindingTable[R]) Claim(ID string, UserID int64, ClientID string, now time.Time) bool

Claim reserves a client-chosen ID before any playback/transcoder work. A different viewer or device cannot replace, reuse, stop, or probe that binding.

func (*BindingTable[R]) Expire

func (t *BindingTable[R]) Expire(now time.Time, ttl time.Duration) []string

func (*BindingTable[R]) Fail

func (t *BindingTable[R]) Fail(ID string, UserID int64, ClientID string, Key core.RatingKey, err error, now time.Time)

Fail records a failed Decision on the binding the Decision claimed. A binding owned by another viewer or device is left alone.

func (*BindingTable[R]) ForClient

func (t *BindingTable[R]) ForClient(UserID int64, ClientID string, Key core.RatingKey) []string

ForClient lists the transcode sessions of a client for a title.

func (*BindingTable[R]) Get

func (t *BindingTable[R]) Get(ID string) (*Binding[R], bool)

func (*BindingTable[R]) IDs

func (t *BindingTable[R]) IDs() []string

IDs lists every binding this table still holds.

func (*BindingTable[R]) Put

func (t *BindingTable[R]) Put(e *Binding[R])

func (*BindingTable[R]) Remove

func (t *BindingTable[R]) Remove(ID string)

func (*BindingTable[R]) TakeFailure

func (t *BindingTable[R]) TakeFailure(ID string, UserID int64, Key core.RatingKey, now time.Time) (error, bool)

TakeFailure returns and clears a recent failed Decision for this viewer's binding and title.

func (*BindingTable[R]) Touch

func (t *BindingTable[R]) Touch(ID string, now time.Time)

type BitrateAccessPolicy

type BitrateAccessPolicy = core.BitrateAccessPolicy

Viewer access policy ports.

type BrowseBlocksPolicy

type BrowseBlocksPolicy interface {
	BrowseBlocks(*User) ([]string, []string)
}

BrowseBlocksPolicy is the optional genre and keyword block list an access policy may expose for browse queries.

type BrowseQuery

type BrowseQuery = core.BrowseQuery

Library browse and history values stay owned by core. Adapters build queries and read results through these aliases.

type BrowseShareFilterPolicy

type BrowseShareFilterPolicy interface {
	BrowseShareFilter(*User, MediaType) Filter
}

BrowseShareFilterPolicy is the optional share filter an access policy may expose for child visibility in browse queries.

type CachedMetadataOverlay

type CachedMetadataOverlay = plexmeta.Cached

type CachedTitleBatchReader

type CachedTitleBatchReader interface {
	CachedGetMany(context.Context, []RatingKey) (map[RatingKey]Title, error)
}

CachedTitleBatchReader reads mirrored titles in bulk without provider refresh.

type CachedTitleReader

type CachedTitleReader interface {
	CachedGet(context.Context, RatingKey) (*Title, error)
}

CachedTitleReader reads one mirrored title without triggering a provider refresh.

type CachedTitleSource

type CachedTitleSource interface {
	CachedTitles(context.Context, []RatingKey) ([]Title, error)
}

CachedTitleSource is the optional capability reading titles already in the local cache, without discovery.

type Capabilities

type Capabilities interface {
	Build(context.Context, CapabilityRequest) (CapabilityResult, error)
	ApplyClientRules(HostQualityConfig, core.ClientCaps, *core.Viewer, string) core.ClientCaps
}

Capabilities applies client declarations, device quirks and owner rules.

func BindClientRules

BindClientRules adapts a client-rule function into a Capabilities service.

type CapabilityRequest

type CapabilityRequest struct {
	Viewer       *core.Viewer
	Device       caps.DeviceInfo
	Profile      caps.DeviceProfile
	ProtocolInfo []string
	UserAgent    string
}

CapabilityRequest describes client declarations, not a claim about playback. Viewer must come from the authenticated session when user rules are desired. Build requires WithClientIP using Host.ClientIP on the current request; the host derives network locality and ignores the caller's Remote claim.

type CapabilityResult

type CapabilityResult struct {
	Client  core.ClientCaps
	Quality core.QualityProfile
}

CapabilityResult pairs client playback capabilities with the selected owner quality profile. The profile does not grant additional hardware capabilities.

type Catalog

type Catalog = core.Catalog

type CatalogSchedule

type CatalogSchedule interface {
	ScheduledEpisodes(context.Context, RatingKey) ([]Title, error)
}

CatalogSchedule is the optional capability listing a show's scheduled episodes. Catalogue methods remain released-only; this interface never authorizes playback.

type CertifiedApp

type CertifiedApp struct {
	Name  string        `json:"name"`
	Steps []ConnectStep `json:"steps"`
}

CertifiedApp contains only verified native clients, with their connection steps.

type CinemaIntros

type CinemaIntros interface {
	Trailers(context.Context, *core.Viewer, core.Device, core.RatingKey, int) ([]Extra, error)
}

CinemaIntros returns playable trailers of other visible, unwatched movies to play before feature. An empty slice means cinema intros are off or none match.

type ClientCapabilityOverride

type ClientCapabilityOverride = core.ClientCapabilityOverride

type ClientCaps

type ClientCaps = core.ClientCaps

type ClientPolicy

type ClientPolicy = transcode.ClientPolicy

func ClientPolicyFor

func ClientPolicyFor(c ClientCaps) ClientPolicy

type ClusterBus

type ClusterBus = clusterbus.Bus

Cluster coordination primitives used by protocol adapters when clustered.

type ClusterNode

type ClusterNode = clusterbus.Node

func StandaloneClusterNode

func StandaloneClusterNode(id string) ClusterNode

type Collection

type Collection = core.Collection

type CollectionPage

type CollectionPage struct {
	Items []core.Collection
	Total int
}

type CollectionQuery

type CollectionQuery struct {
	Types         []core.MediaType
	Offset, Limit int
}

CollectionQuery requests viewer-scoped collection pagination. A nonpositive Limit defaults to 50; larger requests are capped at 500.

type Collections

type Collections = core.Collections

type Command

type Command struct {
	Kind                CommandKind
	Position            time.Duration
	StreamIndex         int
	Message             string
	ControllerSessionID string
}

type CommandKind

type CommandKind string
const (
	CommandStop        CommandKind = "stop"
	CommandPause       CommandKind = "pause"
	CommandUnpause     CommandKind = "unpause"
	CommandSeek        CommandKind = "seek"
	CommandSetAudio    CommandKind = "setAudio"
	CommandSetSubtitle CommandKind = "setSubtitle"
	CommandMessage     CommandKind = "message"
)

type CompletedShowsState

type CompletedShowsState interface {
	PlaybackCompletedShows(context.Context, int64, []RatingKey) (map[RatingKey]bool, error)
}

CompletedShowsState reports which shows have had an episode completed in playback.

type ConnectStep

type ConnectStep string

ConnectStep identifies a translated owner-console connection instruction.

type Continuation

type Continuation string

Continuation distinguishes a known next page from exhaustion and a truncated source that cannot determine whether more matches exist.

const (
	ContinuationMore      Continuation = "more"
	ContinuationExhausted Continuation = "exhausted"
	ContinuationUnknown   Continuation = "unknown"
)

type Continue

type Continue interface {
	WithoutFilter() Continue
	InProgress(ctx context.Context, viewer *core.User, t core.MediaType, limit int) ([]core.Title, map[core.RatingKey]core.WatchStatus)
	Row(ctx context.Context, viewer *core.User, kind core.MediaType, limit int) ([]core.Title, map[core.RatingKey]core.WatchStatus)
	Shelf(ctx context.Context, viewer *core.User, kind core.MediaType, limit int) ([]core.Title, map[core.RatingKey]core.WatchStatus, bool)
}

Continue loads continue-watching and on-deck rows.

type ContinueDeck

type ContinueDeck interface {
	Prepare(ctx context.Context, shows []core.RatingKey)
	Select(ctx context.Context, show core.RatingKey) (*core.Title, map[core.RatingKey]core.WatchStatus)
}

ContinueDeck selects on-deck episodes per show.

type ContinueDeckOptions

type ContinueDeckOptions struct {
	Load        func(context.Context, []core.RatingKey) (map[core.RatingKey][]core.Title, map[core.RatingKey]core.WatchStatus)
	Order       func(context.Context, core.RatingKey, []core.Title) ([]core.Title, error)
	Hydrate     func(context.Context, []core.RatingKey) []core.Title
	Unavailable func(context.Context, *core.Title) bool
	Fallback    func(context.Context, core.RatingKey, []core.Title, bool) (*core.Title, map[core.RatingKey]core.WatchStatus)
}

ContinueDeckOptions configures a ContinueDeck.

type ContinueEpisodesCatalog

type ContinueEpisodesCatalog interface {
	ContinueEpisodes(context.Context, []RatingKey) (map[RatingKey]*Title, error)
}

ContinueEpisodesCatalog resolves the next continue-watching episode per show in batch.

type ContinueHider

type ContinueHider interface {
	HideContinue(context.Context, int64, RatingKey) error
}

ContinueHider dismisses a title or show from continue-watching.

type ContinueOptions

type ContinueOptions struct {
	ShowOnDeck         func(context.Context, core.RatingKey) (*core.Title, map[core.RatingKey]core.WatchStatus)
	PrepareShowOnDeck  func(context.Context, []core.RatingKey)
	PrefetchTitles     func(context.Context, []core.RatingKey)
	Filter             func(context.Context, *core.User, []core.Title) []core.Title
	State              core.State
	EpisodeOrder       EpisodeOrderGrouped
	Now                func() time.Time
	Grandchildren      func(context.Context, core.RatingKey) ([]core.Title, error)
	NextEpisode        func(context.Context, core.RatingKey) (*core.Title, error)
	NextEpisodes       func(context.Context, []core.RatingKey) (map[core.RatingKey]*core.Title, error)
	Visible            func(context.Context, *core.User, *core.Title) bool
	SameDayUnavailable func(context.Context, *core.Title) bool
	GetTitles          func(context.Context, []core.RatingKey) []core.Title
	SectionAllowed     func(*core.User, core.MediaType) bool
	OnError            func(error)
	FavoriteShows      func(context.Context, *core.User) (map[core.RatingKey]bool, error)
	Unrestricted       func(*core.User) bool
}

ContinueOptions configures a Continue selector.

type ContinueRestorer

type ContinueRestorer interface {
	RestoreContinue(context.Context, int64, RatingKey) error
}

ContinueRestorer clears a continue-watching dismissal when playback resumes.

type CredentialAcceptance

type CredentialAcceptance = auth.Acceptance

CredentialAcceptance is an opaque host receipt. Only the authenticator can mint it; formatting remains redacted and current revocation is rechecked.

type CredentialAcceptor

type CredentialAcceptor interface {
	Accept(context.Context, string) (*Viewer, CredentialAcceptance, error)
	ReceiptCurrent(context.Context, CredentialAcceptance) error
}

type CreditFilter

type CreditFilter = core.CreditFilter

type DASHSession

type DASHSession = core.DASHSession

type Dashboard

type Dashboard interface {
	SeeDevice(clientID, name, platform string) StatisticsDevice
	Devices() []StatisticsDevice
	Device(id int64) (StatisticsDevice, bool)
	Bandwidth(StatisticsQuery) StatisticsPage
	Media(StatisticsQuery) StatisticsPage
	RecordBytes(accountID int64, accountName, clientID, deviceName, platform string, lan bool, n int64)
	RecordPlay(accountID int64, accountName, clientID string, metadataType int, durationSec int64)
}

type DateFilter

type DateFilter = core.DateFilter

DateFilter is the date predicate accepted by the shared catalogue boundary.

type DecideOptions

type DecideOptions = core.DecideOptions

type Decision

type Decision = core.Decision

func DecideTranscode

func DecideTranscode(info MediaInfo, caps ClientCaps, opts DecideOptions, pol TranscodePolicy) Decision

type DecisionArms

type DecisionArms interface {
	Expire(now time.Time)
	Arm(pr DecisionOwner, key core.RatingKey)
	Armed(pr DecisionOwner, key core.RatingKey) bool
	Disarm(pr DecisionOwner, key core.RatingKey)
	Refresh(now time.Time)
	ClearOwn()
}

DecisionArms records armed playback decisions per owner and title.

type DecisionCandidate

type DecisionCandidate = core.DecisionCandidate

type DecisionKind

type DecisionKind = core.DecisionKind

type DecisionOwner

type DecisionOwner struct {
	ID                  string
	UserID              int64
	ClientID, SessionID string
}

DecisionOwner identifies the authenticated public player, independently of its encoder delivery handle.

type DecisionTrace

type DecisionTrace = core.DecisionTrace

type DelegationAuth

type DelegationAuth interface {
	IssueDelegation(context.Context, int64) (string, error)
}

DelegationAuth is the optional capability issuing a delegation token for an authenticated account.

type DerivedPruner

type DerivedPruner interface {
	Prune(context.Context) (int64, error)
}

DerivedPruner is optionally implemented by a Frontend or Instance that owns derived rows or caches pruned during background maintenance.

type Descriptor

type Descriptor struct {
	ID             Protocol       `json:"id"`
	Name           string         `json:"name"`
	Version        string         `json:"version,omitempty"`
	DocsURL        string         `json:"docsUrl,omitempty"`
	DefaultPort    int            `json:"defaultPort,omitempty"`
	Clients        []string       `json:"clients,omitempty"`
	CertifiedApps  []CertifiedApp `json:"certifiedApps,omitempty"`
	SettingsSchema any            `json:"settingsSchema,omitempty"`
}

type DetailFacts

type DetailFacts struct {
	Header       string
	RatingsKnown bool
	Community    *float64
	Critic       *float64
	Sources      []ExternalRating
}

DetailFacts is per-viewer detail copy and provider ratings for one title. Header is empty when micro-reasons are off or the taste model is too thin to state a match. RatingsKnown means the ratings provider is on: Community and Critic are nil when that source has no cached value, and callers must not substitute the catalogue score. Community is 0–10. Critic is 0–100.

type DetailFactsSource

type DetailFactsSource interface {
	DetailFacts(context.Context, *core.Viewer, core.Title) DetailFacts
	PageRatings(context.Context, *core.Viewer, []core.Title) map[core.RatingKey]DetailFacts
}

DetailFactsSource is optional. Experience implementations that do not personalize detail copy leave the interface unimplemented.

type DetailPlanner

type DetailPlanner interface {
	DetailPlan(ctx context.Context, request PlanRequest) (PlayPlan, error)
	ResolveDetailSource(ctx context.Context, scope VersionScope, handle string) (DetailSourceTarget, error)
	MatchDetailSession(ctx context.Context, scope VersionScope, handle, sessionID string) error
}

DetailPlanner resolves a playable single item within a bounded admission budget. It returns source facts without creating a frontend session. The caller must separately obtain a scoped lazy stream capability.

type DetailRelated

type DetailRelated interface {
	SourceVisible(ctx context.Context, viewer *core.User, key core.RatingKey) bool
	Rows(ctx context.Context, viewer *core.User, key core.RatingKey, count int) ([]core.Hub, error)
}

DetailRelated loads detail-page related rows.

type DetailRelatedOptions

type DetailRelatedOptions struct {
	Source     core.Recommender
	Visibility Visibility
	Get        func(context.Context, core.RatingKey) (*core.Title, error)
}

DetailRelatedOptions configures a DetailRelated selector.

type DetailSourceTarget

type DetailSourceTarget struct {
	Item RatingKey
	ETag string
}

type DetailWarmer

type DetailWarmer interface {
	WarmDetail(context.Context, PlanRequest) bool
}

DetailWarmer is optionally implemented by Host.Sessions. WarmDetail starts the speculative resolve and probe of req.Item that a detail page implies, using the caps the same viewer's device last declared for real playback (PlayIntent.DeclaredCaps), so the later Play takes the warm result. It never warms with req.Caps' generic declaration: that would let a lower release than the device can play stand in for Play's pick. req.Caps only supplies the request's network locality. It is best effort, never blocks on the resolve, and reports whether a warm-up was scheduled.

type Device

type Device = core.Device

func LANDevice

func LANDevice(peer netip.Addr) Device

LANDevice derives a stable DLNA device identity from the verified network peer, never from a client-supplied forwarding header or device identifier.

type DeviceIdentity

type DeviceIdentity interface {
	ResolveDevice(context.Context, string, Device) (*Viewer, time.Time, error)
}

DeviceIdentity optionally validates a credential against its stored device and returns the grant's current absolute expiry. This read-only operation does not extend the grant or write activity on media segment requests.

type DiagnosticClientFacts

type DiagnosticClientFacts = diagnostics.ClientFacts

type DiagnosticClientInput

type DiagnosticClientInput = diagnostics.ClientInput

type DiagnosticEvent

type DiagnosticEvent = diagnostics.Event

type DiagnosticHubSummary

type DiagnosticHubSummary = diagnostics.HubSummary

type DiagnosticKind

type DiagnosticKind = diagnostics.Kind

func ClassifyDiagnosticRequest

func ClassifyDiagnosticRequest(path string, status int, contentType string, bytesWritten int64) DiagnosticKind

type DiagnosticPlaybackCandidate

type DiagnosticPlaybackCandidate = diagnostics.PlaybackCandidate

type DiagnosticPlaybackDecision

type DiagnosticPlaybackDecision = diagnostics.PlaybackDecision

type DiagnosticPlaybackVariant

type DiagnosticPlaybackVariant = diagnostics.PlaybackVariant

type DiagnosticRecorder

type DiagnosticRecorder interface {
	Recording() bool
	BeginSample(string) bool
	EndSample()
	Observe(DiagnosticEvent)
}

DiagnosticRecorder accepts neutral facts for owner-initiated bounded capture. The host owns recording lifetime, redaction, storage and export.

type DiagnosticResponseSummary

type DiagnosticResponseSummary = diagnostics.ResponseSummary

type DiagnosticViewerCandidate

type DiagnosticViewerCandidate = diagnostics.ViewerCandidate

type DiagnosticViewerFacts

type DiagnosticViewerFacts = diagnostics.ViewerFacts

type DiagnosticViewerSection

type DiagnosticViewerSection = diagnostics.ViewerSection

type DiscoveryArtworkSelection

type DiscoveryArtworkSelection struct {
	Title                                       *core.Title
	Enabled                                     bool
	PosterVersion, BackdropVersion, LogoVersion string
}

DiscoveryArtworkSelection contains shared selection facts; adapters own image URLs.

type DiscoveryCandidate

type DiscoveryCandidate struct {
	Index   int
	Purpose core.RowPurpose
	Items   []core.Title
}

DiscoveryCandidate contains a source row's neutral purpose and item candidates.

type DiscoveryFeatures

type DiscoveryFeatures struct {
	Watchlist DiscoveryWatchlist
	Ratings   DiscoveryRatings
	Overlays  DiscoveryOverlays
	Personal  DiscoveryPersonal
	LLM       DiscoveryLLM
	// OverviewTranslate is optional. detail is true only when a viewer opened
	// the item. A library row passes false and must not call a model.
	OverviewTranslate func(ctx context.Context, t *core.Title, lang string, detail bool) (summary, tagline string, ok bool)
	SelectArtworkFn   func(ctx context.Context, viewer *core.User, t *core.Title, lang string) DiscoveryArtworkSelection
	PrepareArtworkFn  func(ctx context.Context, viewer *core.User, t *core.Title, lang string) (*core.Title, string, error)
	RenderArtworkFn   func(ctx context.Context, viewer *core.User, t *core.Title, kind, lang string) ([]byte, string, error)
	CachedRecapFn     func(viewer *core.User, t *core.Title, state core.State, now time.Time) string
}

DiscoveryFeatures exposes optional discovery capabilities to frontends and shared presentation services without importing domain implementations.

func (*DiscoveryFeatures) CachedRecap

func (d *DiscoveryFeatures) CachedRecap(viewer *core.User, t *core.Title, state core.State, now time.Time) string

func (*DiscoveryFeatures) PrepareArtwork

func (d *DiscoveryFeatures) PrepareArtwork(ctx context.Context, viewer *core.User, t *core.Title, lang string) (*core.Title, string, error)

func (*DiscoveryFeatures) RenderArtwork

func (d *DiscoveryFeatures) RenderArtwork(ctx context.Context, viewer *core.User, t *core.Title, kind, lang string) ([]byte, string, error)

func (*DiscoveryFeatures) SelectArtwork

func (d *DiscoveryFeatures) SelectArtwork(ctx context.Context, viewer *core.User, t *core.Title, lang string) DiscoveryArtworkSelection

type DiscoveryLLM

type DiscoveryLLM interface {
	NaturalSearch(ctx context.Context, viewer *core.User, query string, limit int) ([]core.Title, error)
}

type DiscoveryOverlays

type DiscoveryOverlays interface {
	CustomPostersEnabled() bool
	Paths(ctx context.Context, viewer *core.User, t *core.Title, lang string) (string, string)
	WithSettingsSnapshot(ctx context.Context) context.Context
	WithArtworkPage(ctx context.Context, keys []core.RatingKey) (context.Context, error)
}

type DiscoveryPersonal

type DiscoveryPersonal interface {
	Hubs(ctx context.Context, viewer *core.User, limit int) ([]core.Hub, error)
	RemoveContinue(ctx context.Context, uid int64, key core.RatingKey) error
	RestoreContinue(ctx context.Context, uid int64, key core.RatingKey) error
	ContinueAllowed(ctx context.Context, uid int64, t *core.Title) bool
	FilterContinue(ctx context.Context, viewer *core.User, titles []core.Title) []core.Title
}

type DiscoveryRatingBadge

type DiscoveryRatingBadge struct {
	Source string
	Value  float64
	Image  string
}

DiscoveryRatingBadge is a normalized external rating badge for a title.

type DiscoveryRatings

type DiscoveryRatings interface {
	Cached(ctx context.Context, t *core.Title) ([]DiscoveryRatingBadge, error)
	Settings(ctx context.Context) (DiscoveryRatingsSettings, error)
	Queue(t core.Title)
	WithSettingsSnapshot(ctx context.Context) context.Context
}

type DiscoveryRatingsSettings

type DiscoveryRatingsSettings struct {
	Enabled          bool
	Critic, Audience string
	Missing          string
}

DiscoveryRatingsSettings exposes active rating provider preferences.

type DiscoveryRequest

type DiscoveryRequest struct {
	Data     []byte
	Peer     netip.AddrPort
	Endpoint string
}

DiscoveryRequest describes a LAN datagram and this surface's verified, reachable base address. Data is a private copy and contains no credentials.

type DiscoveryResponder

type DiscoveryResponder interface {
	RespondDiscovery(context.Context, DiscoveryRequest) ([]byte, bool)
}

DiscoveryResponder is optional on an Instance. The host multiplexes its responses through a single UDP listener and unregisters it on unmount. Implementations return false for unmatched probes or disabled discovery.

type DiscoverySelection

type DiscoverySelection interface {
	Load(ctx context.Context, viewer *core.User, limit int, load func(context.Context, int) []DiscoveryCandidate) []DiscoveryCandidate
}

DiscoverySelection loads discovery candidates through visibility.

type DiscoverySelectionOptions

type DiscoverySelectionOptions struct {
	Visibility   Visibility
	Unrestricted func(*core.User) bool
}

DiscoverySelectionOptions configures a DiscoverySelection.

type DiscoveryWatchlist

type DiscoveryWatchlist interface {
	Hubs(ctx context.Context, viewer *core.User, limit int) ([]core.Hub, error)
	RecapsEnabled(ctx context.Context) bool
	NaturalSearchEnabled(ctx context.Context) bool
}

type DownloadAccessPolicy

type DownloadAccessPolicy = core.DownloadAccessPolicy

type DownloadItem

type DownloadItem struct {
	ID      int64
	QueueID int64
	Key     core.RatingKey
	Title   string // display Title, for the served filename

	Caps core.ClientCaps // as requested at add time (Download set at Run)
	User *core.User

	Status   string
	Error    string
	Progress float64 // 0..1
	Started  bool
	Cancel   context.CancelFunc
	// Run numbers each start of the Item, so a restarted job gets its own
	// playback session instead of sharing (and later stopping) the
	// previous Run's.
	Run int64

	Path       string
	Size       int64
	ReadyAt    time.Time
	VideoCodec string
	AudioCodec string
	Duration   time.Duration
	Bandwidth  int // requested maxVideoBitrate, kbps
	Burn       bool
}

type DownloadJob

type DownloadJob interface {
	Run(ctx context.Context, q DownloadRequest) (string, int64, error)
}

DownloadJob runs one download preparation.

type DownloadPreparationError

type DownloadPreparationError struct{ Err error }

func (*DownloadPreparationError) Error

func (e *DownloadPreparationError) Error() string

func (*DownloadPreparationError) Unwrap

func (e *DownloadPreparationError) Unwrap() error

type DownloadQueue

type DownloadQueue struct {
	ID       int64
	UserID   int64
	ClientID string
	Items    []*DownloadItem
}

func (*DownloadQueue) Item

func (q *DownloadQueue) Item(ID int64) *DownloadItem

type DownloadQueuePersistence

type DownloadQueuePersistence interface {
	Retain(path string, ready time.Time)
	Save() error
	Load(ctx context.Context)
	Run(ctx context.Context)
}

DownloadQueuePersistence persists the download queue.

type DownloadQueueStore

type DownloadQueueStore interface {
	QueueFor(UserID int64, ClientID string, create bool) *DownloadQueue
	QueueByID(ID, UserID int64, ClientID string) *DownloadQueue
	Add(q *DownloadQueue, u *core.User, t core.Title, caps core.ClientCaps, burn bool) *DownloadItem
	StartReady(ctx context.Context, perUser int, allowed func(*core.User) bool) []DownloadStart
	Expire(now time.Time, expiry time.Duration) []string
	StopForRestart()
	Remove(q *DownloadQueue, ids []int64) []*DownloadItem
	Restart(q *DownloadQueue, ids []int64, release func(string))
	CancelItem(it *DownloadItem) string
	Fail(ctx context.Context, it *DownloadItem, message string)
	Lock()
	Unlock()
	WakeDownloads()
	AllItems() []*DownloadItem
	Prepared(ctx context.Context, it *DownloadItem, info core.MediaInfo) bool
	Progress(ctx context.Context, it *DownloadItem, fraction float64)
	Complete(ctx context.Context, it *DownloadItem, path string, size int64, now time.Time) bool
}

DownloadQueueStore is the download-queue store.

type DownloadRemuxer

type DownloadRemuxer = core.DownloadRemuxer

type DownloadRequest

type DownloadRequest struct {
	Viewer    *core.User
	Item      core.RatingKey
	Caps      core.ClientCaps
	Run       int64
	NoRelease func(error) bool
	Prepared  func(*core.PlaySession) (core.DecideOptions, error)
	Progress  func(float64)
}

type DownloadStart

type DownloadStart struct {
	Item    *DownloadItem
	Context context.Context
	Run     int64
}

type EditionBatch

type EditionBatch interface {
	EditionsMany(context.Context, *core.Viewer, core.Device, []core.RatingKey) (map[core.RatingKey][]Version, error)
}

EditionBatch resolves local copies for a page in one lookup.

type Editions

type Editions interface {
	Editions(context.Context, *core.Viewer, core.Device, core.RatingKey) ([]Version, error)
	Variants(ctx context.Context, req core.ResolveRequest, max int) ([]core.ReleaseVariant, error)
	RefillSearchCache(t *core.Title) <-chan struct{}
	Available(ctx context.Context, key core.RatingKey) (bool, bool)
}

Editions is an optional local-media catalogue and release variant resolver.

type EncodedMediaForwarder

type EncodedMediaForwarder interface {
	ForwardEncodedMedia(w http.ResponseWriter, r *http.Request, id string) bool
}

EncodedMediaForwarder forwards media requests to a distributed encoder owner.

type EncoderBindingDeleter

type EncoderBindingDeleter interface {
	DeleteBinding(ctx context.Context, id string) error
}

EncoderBindingDeleter removes a distributed encoder binding.

type EncoderBindingStore

type EncoderBindingStore interface {
	PlexHLSDistributed(id string) bool
	SavePlexBinding(ctx context.Context, id string, raw []byte) error
	LoadPlexBinding(ctx context.Context, id string) ([]byte, error)
}

EncoderBindingStore persists distributed encoder bindings across cluster nodes.

type EncoderStatus

type EncoderStatus = core.EncoderStatus

type EncoderStatusSession

type EncoderStatusSession interface {
	EncoderStatus() *core.EncoderStatus
}

EncoderStatusSession reports live encoder status metrics.

type EpisodeBatch

type EpisodeBatch interface {
	Load(ctx context.Context, viewer *core.User, ts []core.Title, selectionOnly bool) (map[core.RatingKey][]core.Title, map[core.RatingKey]core.WatchStatus)
}

EpisodeBatch loads episode batches with watch state.

type EpisodeBatchOptions

type EpisodeBatchOptions struct {
	Catalog      core.Catalog
	State        core.State
	EpisodeOrder EpisodeOrderGrouped
}

EpisodeBatchOptions configures an EpisodeBatch.

type EpisodeOrder

type EpisodeOrder interface {
	Customized(context.Context, *Viewer) (bool, error)
	Grouped(context.Context, *Viewer, []RatingKey) (map[RatingKey]bool, error)
	Get(context.Context, *Viewer, RatingKey) (*Title, error)
	Children(context.Context, *Viewer, RatingKey) ([]Title, error)
	Grandchildren(context.Context, *Viewer, RatingKey) ([]Title, error)
	OrderStoredGrandchildren(context.Context, *Viewer, RatingKey, []Title) ([]Title, error)
	Position(context.Context, *Viewer, RatingKey) (season, episode int, name string, ok bool)
}

EpisodeOrder reads the viewer's presented ordering. The host owns saved groups and applies them to stored catalogue pages before adapters render.

type EpisodeOrderGrouped

type EpisodeOrderGrouped interface {
	Grouped(context.Context, *core.User, []core.RatingKey) (map[core.RatingKey]bool, error)
}

EpisodeOrderGrouped is the grouped-episode-order capability selectors use.

type Estimator

type Estimator interface {
	Estimate(context.Context, *core.Title, core.ClientCaps) core.MediaInfo
	SessionFor(int64, string, core.RatingKey) (*core.PlaySession, bool)
}

Estimator is the non-resolving playback surface for detail pages.

type Event

type Event struct {
	Type     string
	ViewerID int64
	// ActorViewerID is set from the authenticated actor for SessionCommand;
	// zero denotes a system-originated stop without an authenticated actor.
	ActorViewerID int64
	Item          core.RatingKey
	SessionID     string
	// SubjectKind and SubjectID identify non-title user data such as a
	// favorite person, collection or channel. Item remains the title key.
	SubjectKind     string
	SubjectID       string
	OriginProtocol  Protocol
	OriginSessionID string
	OriginClientID  string
	Command         *Command
	TargetProtocol  Protocol
	TargetDeviceID  string
	Session         *Session
	Timeline        *Timeline
}

type EventScope

type EventScope struct {
	Viewer *core.Viewer
	Owner  bool
	// Protocol suppresses this surface's own user-data invalidations.
	Protocol Protocol
	// SessionID selects the authenticated client session for targeted commands.
	SessionID string
	// Device binds a socket before a playback session exists and remains valid
	// when this authenticated device's current session changes.
	Device core.Device
}

Owner requests owner scope; the subscriber must verify active owner status.

type ExactRater

type ExactRater interface {
	RateExact(context.Context, int64, RatingKey, float64) error
}

ExactRater persists a rating while distinguishing clearing (-1) from zero.

type Experience

type Experience interface {
	ExperienceServices
	LibraryGUIDs() LibraryGUIDs
	LibraryMetadata() LibraryMetadata
	MarkerRanges
	Views(context.Context, *core.Viewer) ([]View, error)
	Collections(context.Context, *core.Viewer, core.Device, CollectionQuery) (CollectionPage, error)
	NotInterested(context.Context, *core.Viewer, core.Device, PageQuery) (NotInterestedPage, error)
	NotInterestedItem(context.Context, *core.Viewer, core.Device, core.RatingKey) (NotInterestedEntry, error)
	// ResolveExternal resolves an IMDb ID without opening a release, and returns
	// a key only after enforcing current viewer and inherited-show policy.
	ResolveExternal(context.Context, *core.Viewer, core.Device, ExternalRequest) (core.RatingKey, error)
	Rows(context.Context, RowRequest) ([]Row, error)
	Item(context.Context, ItemRequest) (ItemDetail, error)
	Children(context.Context, *core.Viewer, core.Device, core.RatingKey, ItemQuery) (core.Page, error)
	LibraryItems(context.Context, *core.Viewer, core.Device, string, ItemQuery) (core.Page, error)
	Similar(context.Context, *core.Viewer, core.Device, core.RatingKey, ItemQuery) (SearchPage, error)
	Ancestors(context.Context, *core.Viewer, core.Device, core.RatingKey) ([]core.Title, error)
	Facets(context.Context, *core.Viewer, core.Device, string, string) ([]core.FacetValue, error)
	ResolveFacet(context.Context, *core.Viewer, core.Device, string, string, string) (core.FacetValue, error)
	// PersonFacetIDs returns IDs only for credited people of an authorized title.
	// Episode-only credits may not appear in library-wide Facets or ResolveFacet.
	// Requests are bounded to 256 positive TMDB IDs; missing credits are omitted.
	PersonFacetIDs(context.Context, *core.Viewer, core.Device, core.RatingKey, []int64) (map[int64]string, error)
	// NamedFacetIDs resolves exact genre or studio names on one visible title.
	// A request contains at most 256 nonempty names; missing names are omitted.
	NamedFacetIDs(context.Context, *core.Viewer, core.Device, core.RatingKey, string, []string) (map[string]string, error)
	Search(context.Context, *core.Viewer, core.Device, string, ItemQuery) (SearchPage, error)
	UserData(context.Context, *core.Viewer, []core.RatingKey) (map[core.RatingKey]core.WatchStatus, error)
	SetPlayed(context.Context, *core.Viewer, core.RatingKey) error
	SetUnplayed(context.Context, *core.Viewer, core.RatingKey) error
	SetFavorite(context.Context, *core.Viewer, core.RatingKey, bool) error
	SetNotInterested(context.Context, *core.Viewer, core.RatingKey, bool) error
	SetWatchlist(context.Context, *core.Viewer, core.RatingKey, bool) error
	SetEntityFavorite(context.Context, *core.Viewer, FavoriteRef, bool) error
	EntityFavorites(context.Context, *core.Viewer, []FavoriteRef) (map[FavoriteRef]bool, error)
	ResolveEventSubject(context.Context, *core.Viewer, core.Device, FavoriteRef) (ResolvedEventSubject, error)
	SetRating(context.Context, *core.Viewer, core.RatingKey, float64) error
	SetLikes(context.Context, *core.Viewer, core.RatingKey, *bool) error
	RemoveFromContinue(context.Context, *core.Viewer, core.RatingKey) error
}

Experience applies viewer policy before returning any data. Browse operations must not resolve or open a release. Policy is applied before pagination and limits.

func NoopExperience

func NoopExperience() Experience

NoopExperience returns a zero-value Experience implementation for unmounted or partial test servers.

type ExperienceServices

type ExperienceServices interface {
	NewRecent(RecentOptions) Recent
	NewDetailRelated(DetailRelatedOptions) DetailRelated
	NewEpisodeBatch(EpisodeBatchOptions) EpisodeBatch
	NewContinueDeck(ContinueDeckOptions) ContinueDeck
	NewContinue(ContinueOptions) Continue
	NewRowSelection(RowSelectionOptions) RowSelection
	NewHomeSelection(HomeSelectionOptions) HomeSelection
	NewScopedCollection(ScopedCollectionOptions) ScopedCollection
	NewPlaylistSelection(PlaylistSelectionOptions) PlaylistSelection
	NewPostPlaySelection(PostPlaySelectionOptions) PostPlaySelection
	NewDiscoverySelection(DiscoverySelectionOptions) DiscoverySelection
	NewTrackPreferenceSelector(TrackPreferenceSelectorOptions) TrackPreferenceSelector
	SearchFor(src SearchSources, vis Visibility, unrestricted func(*core.User) bool) Search
	StatisticsDefaults(dashboard Dashboard, resources ResourceStatistics, now func() time.Time) (Dashboard, ResourceStatistics)
	MergeShareFilter(filter, share core.Filter) (core.Filter, bool)
	ArrangeHome(ctx context.Context, source core.Recommender, viewer *core.User, hc core.HubContext, section string, rows []core.Hub, candidates []core.NeutralHomeRow) ([]int, error)
	DetailExtras(ctx context.Context, source ExtrasSource, parent *core.Title, language string, wanted map[int]bool) ([]ExtraClip, error)
	DiscoverySearch(source *DiscoveryFeatures) func(context.Context, *core.User, string, int) ([]core.Title, bool)
	FamiliarFrom(st any) func(context.Context, *core.User, []core.RatingKey) map[core.RatingKey]int
	ContinueFilter(state core.State, personal func(context.Context, *core.User, []core.Title) []core.Title) func(context.Context, *core.User, []core.Title) []core.Title
	SameDayUnavailable(ctx context.Context, title *core.Title, now time.Time, filter func(context.Context, []core.Title) []core.Title, source AvailabilitySource) bool
	SeasonNextEpisode(eps []core.Title, st map[core.RatingKey]core.WatchStatus, now time.Time, unavailable func(*core.Title) bool) *core.Title
	ShowOnDeck(eps []core.Title, st map[core.RatingKey]core.WatchStatus, unavailable func(*core.Title) bool) *core.Title
	RequestDatabaseObservation(ctx context.Context) (int64, time.Duration)
	PlaybackMarkerRanges(ctx context.Context, source MarkerRanges, key core.RatingKey, info core.MediaInfo) ([]MarkerRange, error)

	CatalogSource() core.Catalog
	CollectionsSource() core.Collections
	StateSource() core.State
	PlaylistsSource() core.Playlists
	RecommenderSource() core.Recommender
	VibeSearchSource() VibeSearcher
	SearchSources() SearchSources
	FavoriteShowsFunc() func(context.Context, *core.User) (map[core.RatingKey]bool, error)
	FilterAvailableFunc() func(context.Context, []core.Title) []core.Title
	JudgedOnFactsFunc() func(context.Context) func(core.Title) bool
	PrioritizeAvailableFunc() func(context.Context, []core.Title) []core.Title
	EpisodeOrderSource() EpisodeOrder
	DiscoveryFeatures() *DiscoveryFeatures
	DashboardSource() Dashboard
	ResourcesSource() ResourceStatistics
	LibraryTitles() (movies, shows string)
	HomeRevision(ctx context.Context, viewer *core.User) (HomeRevision, bool, error)
	NoProviderWait(ctx context.Context) context.Context
}

ExperienceServices exposes experience selectors, domain sources, and package-level operations on Host.Experience. Implemented in internal/experience (*Service) and wired on Host.Experience.

type ExportPolicy

type ExportPolicy struct {
	Stamp       string
	TitleJudged bool
}

ExportPolicy is what one viewer's export of one view depends on besides catalogue content. Two exports with the same Stamp are built under the same policy; any change to the viewer's restrictions, hidden titles, catalogue rules or library changes it. TitleJudged reports a policy that narrows the export by title facts (a rating cap, share filter, blocked genres or keywords, section limits or the viewer's own catalogue rules): a catalogue write can then change what the viewer may see.

type ExternalRating

type ExternalRating struct {
	Source, Name, Display string
	Score                 float64
	Votes                 int64
}

ExternalRating is one provider score a client can name. Score is 0–100. Display is the source's own scale ("8.2", "94%"). Votes is zero when the provider did not report a count.

type ExternalRequest

type ExternalRequest struct {
	Source          string
	ID              string
	Type            core.MediaType
	Season, Episode *int
}

ExternalRequest identifies an IMDb title with an optional canonical episode. Season and Episode must either both be set or both omitted.

type Extra

type Extra struct {
	Key, ParentKey                          core.RatingKey
	Title, Kind, Source, SourceID, Language string
	Official                                bool
	PublishedAt                             time.Time
	Duration                                time.Duration
	Height                                  int
}

Extra describes a playable trailer or clip. Key is the broker-facing item identity; Source and SourceID describe the upstream reference, not a resolved URL or credentials. Plex media and part identifiers remain adapter-owned.

type ExtraClip

type ExtraClip struct {
	Key         core.RatingKey
	ParentKey   core.RatingKey
	ParentTitle string
	Title       string
	Subtype     string
	ExtraType   int
	Site        string
	SiteKey     string
	Language    string
	Official    bool
	PublishedAt time.Time
	Size        int
	Duration    time.Duration
	Source      string
}

ExtraClip is one playable clip attached to a catalogue title.

func (ExtraClip) IsTrailer

func (e ExtraClip) IsTrailer() bool

IsTrailer reports whether the extra can serve as a Cinema Trailer.

type ExtraStreams

type ExtraStreams interface {
	Lookup(core.RatingKey) (Extra, bool)
	Open(context.Context, core.RatingKey) (container, rawURL string, headers map[string]string, err error)
	Enabled() bool
	List(ctx context.Context, parent *core.Title, lang string) ([]ExtraClip, error)
	Clip(key core.RatingKey) (ExtraClip, bool)
	Resolve(ctx context.Context, e ExtraClip) (ResolvedExtra, error)
	PrewarmBytes() int64
}

ExtraStreams resolves a playable trailer or clip the extras service registered. Open returns a direct media URL. Callers authorize the parent before Open.

type ExtrasSource

type ExtrasSource interface {
	Enabled() bool
	List(context.Context, *core.Title, string) ([]ExtraClip, error)
}

type FacetFilterCatalog

type FacetFilterCatalog interface {
	FacetFilter(ctx context.Context, f Filter, facet string) ([]FacetValue, error)
}

FacetFilterCatalog filters a facet within a library filter.

type FacetPager

type FacetPager interface {
	FacetPage(ctx context.Context, viewer *Viewer, device Device, viewID, kind string, offset, limit int) ([]FacetValue, int, error)
}

FacetPager pages a facet list (Jellyfin and Emby /Studios, /Genres): Facets' values [offset, offset+limit) in its order, and how many it lists, without listing every value of the library.

type FacetValue

type FacetValue = core.FacetValue

type FailedStartRecorder

type FailedStartRecorder interface {
	NoteFailedStart(sessionID, reason string)
}

FailedStartRecorder records a stalled or failed playback start against a source session.

type FamiliarSource

type FamiliarSource interface {
	Familiar(ctx context.Context, userID int64, keys []core.RatingKey) (map[core.RatingKey]int, error)
}

FamiliarSource is a watch-state store that can report a viewer's history with titles (state.State).

type FavoriteKind

type FavoriteKind string

FavoriteKind namespaces stable, policy-checked entity identifiers.

const (
	FavoriteTitle      FavoriteKind = "title"
	FavoritePerson     FavoriteKind = "person"
	FavoriteCollection FavoriteKind = "collection"
	FavoriteChannel    FavoriteKind = "channel"
)

type FavoriteRef

type FavoriteRef struct {
	Kind FavoriteKind
	ID   string
}

FavoriteRef identifies an entity in its own namespace.

type Filter

type Filter = core.Filter

type FilterGroup

type FilterGroup = core.FilterGroup

type Frontend

type Frontend interface {
	Describe() Descriptor
	Mount(context.Context, Host) (Instance, error)
}

type GrantDeviceIdentity

type GrantDeviceIdentity interface {
	ResolveGrantDevice(context.Context, string, string) (*Viewer, Device, time.Time, error)
}

GrantDeviceIdentity retrieves the stored binding for a surface credential. An empty claim permits token-only requests; a nonempty claim must match the stored device ID. The operation never extends the grant or writes activity.

type GrantMediaForwarder

type GrantMediaForwarder interface {
	ForwardGrantMedia(w http.ResponseWriter, r *http.Request, id string) bool
}

GrantMediaForwarder forwards grant-authorized media requests to a distributed encoder owner.

type GrantedImage

type GrantedImage struct {
	Image  Image
	Secret string
}

type HLSLadderSession

type HLSLadderSession = core.HLSLadderSession

type HLSRequest

type HLSRequest = core.HLSRequest

type HLSSession

type HLSSession = core.HLSSession

type HTTPSession

type HTTPSession = core.HTTPSession

type HistoryCount

type HistoryCount = core.HistoryCount

type HistoryEntry

type HistoryEntry = core.HistoryEntry

type HistoryQuery

type HistoryQuery = core.HistoryQuery

type HistoryStore

type HistoryStore interface {
	QueryHistory(context.Context, HistoryQuery) ([]HistoryEntry, error)
	HistoryByID(context.Context, int64, int64) (HistoryEntry, error)
	DeleteHistory(context.Context, int64, int64) error
}

HistoryStore reads and deletes persisted viewing events.

type HistoryTopStore

type HistoryTopStore interface {
	HistoryTop(context.Context, HistoryQuery, KeyKind) ([]HistoryCount, error)
	LifetimeUsers(context.Context, RatingKey, HistoryQuery) ([]HistoryCount, error)
}

HistoryTopStore aggregates persisted viewing events into per-title counts. Adapters apply their own authorization before exposing them.

type HomeAssembly

type HomeAssembly[P any] struct {
	Render      func(core.Hub) P
	Identity    func(P) string
	Report      func(P) (core.Hub, core.NeutralHomeRow)
	Continue    func() (core.Hub, P)
	Playlists   func() (P, bool)
	Discovery   func() []core.Hub
	Live        func() (P, bool)
	InLibraries func(core.Hub) bool
	Keep        func(P) bool
	Layout      func([]P, []core.Hub, []core.NeutralHomeRow) []P
}

HomeAssembly owns row inclusion, deduplication and ordering while adapters supply rendered projections and preserve their exact producer sidecars. Report records layout facts at paint time. Layout receives those facts and must not read the wire value again.

func (HomeAssembly[P]) Rows

func (a HomeAssembly[P]) Rows(hubs []core.Hub, includeContinue, promotedOnly, includePlaylists bool, purpose func(core.Hub) core.RowPurpose) ([]P, map[string]core.Hub)

type HomeCandidate

type HomeCandidate struct {
	Index       int
	Purpose     core.RowPurpose
	Promoted    bool
	InLibraries bool
}

HomeCandidate carries neutral row placement information. Index identifies the producer's candidate without exposing its wire representation.

type HomeInvalidationSubscriber

type HomeInvalidationSubscriber func(invalidate func(viewerID int64)) (close func())

HomeInvalidationSubscriber subscribes a mounted frontend to committed state changes that invalidate a viewer's home screen. Closing fences in-flight callbacks.

type HomeLayoutSource

type HomeLayoutSource = core.HomeLayoutSource

type HomeRevision

type HomeRevision struct {
	Viewer string
	Policy int64
}

HomeRevision stamps a viewer's cached Home. Viewer changes the Home must show on the very next request: the latest watch-state write (Continue Watching, watched badges, ratings), playlists, watchlist, favorites and "not interested" exclusions. Policy is the shared viewer-policy epoch: it also moves on catalogue and guide changes, so only restricted viewers treat it as a hard input.

type HomeRowLayoutGate

type HomeRowLayoutGate interface {
	HomeRowEnabled(context.Context, *User, HubContext, string) bool
}

HomeRowLayoutGate reports whether a home row is enabled for a viewer's layout.

type HomeSelection

type HomeSelection interface {
	Rows(ctx context.Context, viewer *core.User, hc core.HubContext, typ core.MediaType, count int) ([]core.Hub, error)
	Filter(ctx context.Context, viewer *core.User, hubs []core.Hub) []core.Hub
}

HomeSelection loads home rows from a recommender.

type HomeSelectionOptions

type HomeSelectionOptions struct {
	Source     core.Recommender
	Visibility Visibility
	Restricted bool
}

HomeSelectionOptions configures a HomeSelection.

type Host

type Host struct {
	// Support is an owner-initiated, bounded capture; nil disables recording.
	Support            *diagnostics.Recorder
	Experience         Experience
	ViewerCapabilities ViewerCapabilitiesFunc
	ViewerPolicy       ViewerPolicy
	Capabilities       Capabilities
	Preferences        Preferences
	TrackPreferences   TrackPreferenceService
	LiveTV             LiveTV
	VirtualPaths       VirtualPaths
	Sessions           Sessions
	LastPlayedSource   LastPlayedSourceReader
	SourceOffers       SourceOffers
	VersionHandles     VersionHandles
	// Editions lists locally probed copies of one title. It is empty when the
	// process has no local media manifest, and it must not search the network.
	Editions    Editions
	LazyStreams LazyStreams
	LANStreams  LANLazyStreams
	// KindStreams opens byte-addressable media and lists playable leaves for
	// plugin-provided content kinds. Nil means plugin kind media is unavailable.
	KindStreams KindStreams
	Identity    SurfaceIdentity
	IDs         ids.Codecs
	Events      Subscriber
	// WatchRefresh subscribes a mounted frontend to committed watch-state changes.
	WatchRefresh WatchRefreshSubscriber
	// HomeInvalidation subscribes a mounted frontend to committed state changes
	// that invalidate a viewer's home screen.
	HomeInvalidation HomeInvalidationSubscriber
	Tickets          Tickets
	// WatchParty is the shared Silo and Jellyfin room. Nil leaves both off.
	WatchParty  WatchParty
	Images      Images
	ImageGrants ImageGrants
	// Artwork serves the same composited poster bytes the other frontends
	// grant. DLNA has no credential, so it reads this after LANViewer.
	Artwork Artwork
	// ExtraStreams opens a playable trailer or extra. Nil means extras are not
	// configured; listing routes still authorize the parent and return nothing.
	ExtraStreams ExtraStreams
	// DirectProxy selects the proxy for trailer fetches. Nil follows the
	// process environment. The app wires the direct route so frontends do
	// not import the egress policy.
	DirectProxy func(*http.Request) (*url.URL, error)
	// MetadataHTTP fetches remote artwork when shared Artwork is not mounted.
	// Nil uses a 20 s HTTP client.
	MetadataHTTP *http.Client
	// Cinema lists preroll trailers of other movies. Nil means cinema intros
	// are not wired; the intros route returns an empty page after authorization.
	Cinema CinemaIntros
	// Prerolls lists the owner's pre-roll as an intro. Nil means pre-rolls
	// are off and intros are unchanged.
	Prerolls Prerolls
	// Subtitles searches and downloads a sidecar only after an explicit pick.
	// Nil or Enabled false tells clients the server will not fetch one.
	Subtitles  SubtitleCatalog
	Config     func() Settings
	HostConfig func() HostConfig
	Now        func() time.Time
	// TracePlayback logs HLS/transcode diagnostics when ETHER_TRACE_PLAYBACK=1.
	TracePlayback bool
	// ServerIdentity describes how this server presents its machine and build identity.
	ServerIdentity ServerIdentity
	// OwnerSubscription returns the current owner entitlement snapshot.
	OwnerSubscription func() (active bool, features []string)
	// MetadataLanguage is the catalog language (config catalog.language).
	// Empty skips that step of the no-list audio chain.
	MetadataLanguage func() string
	// AudioOrder is the shared no-choice language chain. Frontends call it
	// instead of importing the track-preference package. Nil keeps the
	// caller's own fallback.
	AudioOrder func(audio []string, server, original string, preferOriginal bool) []string
	// PickAudio returns a stream position in MediaInfo, or -1 when no audio
	// stream exists. Nil keeps the caller's own fallback.
	PickAudio func(MediaInfo, []string) int
	Log       *slog.Logger
	// ViewerPortalURL returns a reachable owner-selected viewer portal URL for this client.
	ViewerPortalURL func(context.Context, *http.Request) (string, error)
	// SecurePortalURL selects a verified reachable HTTPS portal address.
	SecurePortalURL func(context.Context, *http.Request) (string, error)
	// SurfaceURL returns a reachable, verified base for this frontend's routes.
	SurfaceURL func(context.Context, *http.Request) (string, error)
	// PublicOrigin returns this server's published public WAN origin, or "" when unavailable.
	PublicOrigin func() string
	// RepoFileURL returns an immutable public URL for a committed repository file, or "".
	RepoFileURL func(path string) string
	// LANViewer resolves the owner-selected active DLNA viewer only after
	// trusted-proxy-aware network classification; other surfaces receive nil.
	LANViewer func(context.Context, *http.Request) (*Viewer, error)
	// ClientSeen reports an authenticated client's protocol-specific device ID.
	ClientSeen func(deviceID string)
	// RemoteClientSeen records authenticated inbound remote connectivity.
	RemoteClientSeen func(address string)
	// ClientIP resolves the transport peer using the configured trusted proxies.
	ClientIP func(*http.Request) (netip.Addr, bool)
	// PageFreshness invalidates cached browse bodies. Nil disables the cache.
	PageFreshness func() PageFreshness
	// CacheDir is a node-local directory this frontend alone may fill with
	// files it can regenerate. It may be emptied between mounts. Empty
	// disables on-disk caches.
	CacheDir string
	// PersonalHomes keeps the last personalized library list so the first
	// UserViews after a restart can include it. Nil keeps that list in memory.
	PersonalHomes PersonalHomeStore
}

type HostConfig

type HostConfig = config.Config

Host configuration snapshots and quality rules exchanged across the frontend boundary.

type HostQualityConfig

type HostQualityConfig = config.Quality

type Hub

type Hub = core.Hub

Home hub values stay owned by core. Adapters render hubs through these aliases.

func SectionView

func SectionView(h Hub, t MediaType) (Hub, bool)

SectionView restricts a Home hub to one library section's media type.

type HubContext

type HubContext = core.HubContext

func NewHubContext

func NewHubContext(now time.Time, product, platform, device string) HubContext

NewHubContext derives the request context for a hubs call.

type HubItemSource

type HubItemSource = core.HubItemSource

type Image

type Image struct {
	Kind, Path, Tag string
	// Subject identifies an entity within the authorized item, such as the
	// tmdb:<id> person whose credit owns a portrait. It is part of the grant.
	Subject string
	// Width and Height describe the cached source pixels; zero means unknown.
	Width, Height int
	// BlurHash is a cached preview of the source; empty means unavailable.
	BlurHash string
	// ThumbHash is padded base64 of the cached source's standard ThumbHash;
	// empty means the background computation has not completed.
	ThumbHash string
}

Image identifies an image authorized for an item. Path is an opaque, server-owned source reference: callers must neither interpret it as a URL nor construct one themselves. Tag changes when the selected artwork changes. Older adapters may still return a TMDB path while migrating to opaque refs.

type ImageBatchItem

type ImageBatchItem struct {
	Item          core.RatingKey
	Authoritative bool
	Images        []GrantedImage
}

type ImageBatchRequest

type ImageBatchRequest struct {
	Credential string
	Device     core.Device
	Items      []core.RatingKey
	Kinds      []string
}

ImageBatchRequest requests primary artwork for a page of items. At most 50 distinct keys and 256 input keys are accepted; duplicates are removed in first-occurrence order. Empty Kinds selects poster. Person and channel images are deliberately excluded. Portraits use PersonImageGrantBatch or a scoped single grant; channel images use a scoped single grant.

type ImageGrantBatch

type ImageGrantBatch interface {
	IssueBatch(context.Context, ImageBatchRequest) ([]ImageBatchItem, error)
}

ImageGrantBatch is an optional extension for rows and grids. Hidden items are omitted. Results preserve first-occurrence item and descriptor order; each requested kind contributes at most its first descriptor. An authorized item with no images is distinguished from an unavailable artwork list by Authoritative. Every secret is independently revalidated when served.

type ImageGrantRequest

type ImageGrantRequest struct {
	Credential string
	Device     core.Device
	Item       core.RatingKey
	Channel    string
	Image      Image
}

ImageGrantRequest asks for one authorized image on one authenticated session. Credential is supplied in-process and must never be placed in an image URL.

type ImageGrants

type ImageGrants interface {
	Issue(context.Context, ImageGrantRequest) (string, error)
	Revoke(context.Context, string, string) error
	Serve(http.ResponseWriter, *http.Request, string)
}

ImageGrants issues and validates short-lived opaque image capabilities. Serve requires a capability, even when the client cannot send account tokens.

type ImagePageRenewal

type ImagePageRenewal struct {
	Credential string
	Device     core.Device
	Items      []ImageBatchItem
}

ImagePageRenewal re-arms images SignPage sealed earlier, for Credential. Items are SignPage results, unchanged.

type ImagePageRenewer

type ImagePageRenewer interface {
	RenewPage(context.Context, ImagePageRenewal) error
}

ImagePageRenewer keeps a cached listing's image URLs valid past the page grant lifetime: each renewal starts a full lifetime for Credential. It authorizes nothing by itself; Serve still rechecks the credential, expiry, revocation and current artwork policy.

type ImagePageRequest

type ImagePageRequest struct {
	Credential string
	Device     core.Device
	Titles     []core.Title
	Kinds      []string
}

ImagePageRequest signs artwork for titles the caller has already authorized for this page. The signer does not write a grant row.

type ImagePageSigner

type ImagePageSigner interface {
	SignPage(context.Context, ImagePageRequest) ([]ImageBatchItem, error)
}

ImagePageSigner is the list path for image URLs. Serve still rechecks the credential, expiry, revocation and current artwork policy.

type ImageURLFunc

type ImageURLFunc = core.ImageURLFunc

type Images

type Images interface {
	ServeHTTP(http.ResponseWriter, *http.Request)
}

Images serves TMDB artwork via GET or HEAD with query parameters path and w. Frontends must authorize access to the item before calling it.

type ImpressionSink

type ImpressionSink = core.ImpressionSink

type Instance

type Instance interface {
	Handler() http.Handler
	Listeners() []ListenerSpec
	Discovery() []Announcer
	Status(context.Context) Status
	Close(context.Context) error
}

type IntentTracker

type IntentTracker interface {
	RecordDetailOpen(ctx context.Context, user *User, t *Title)
	NotePlayback(user *User, key RatingKey)
}

IntentTracker receives live in-session browsing signals: detail opens that do not turn into playback.

type IssuedTrackIdentity

type IssuedTrackIdentity struct {
	Audio            *core.StreamInfo
	AudioPosition    int
	AudioSet         bool
	Subtitle         *core.StreamInfo
	SubtitlePosition int
	SubtitleSet      bool
}

IssuedTrackIdentity is the selection resolvePlaySelection already holds after the Plex adapter has accepted a stream ID from the item-scoped issued registry. Positions are indexes into the full MediaInfo.Streams slice from that issuance. They are not StreamInfo.Index values and they are not audio-only ordinals.

TranslatePlexTrackIdentity does not look up stream IDs, does not see the item, and does not authorize a caller-built StreamInfo. Copy Audio and Subtitle only from a registry reference whose item is the one being played.

AudioSet must equal AudioPosition >= 0, which is how the play resolver derives audio set-ness. Pass AudioPosition -1 and AudioSet false when the client omitted audio. The zero value is not an omission.

SubtitleSet false is omission. SubtitleSet true with a nil subtitle and position -1 is explicit subtitle-off. A nil subtitle with SubtitleSet true and any other position, including an out-of-range or wrong-type slot, is a legacy position-only choice and is preserved.

The translator does not retain either pointer and does not pin a source.

type ItemArtwork

type ItemArtwork interface {
	ItemArtwork(context.Context, *core.Viewer, core.Device, core.RatingKey) ([]Image, bool, error)
}

ItemArtwork is an optional cache-only authorization path for issuing grid artwork without computing playback versions or tracks.

type ItemArtworkPage

type ItemArtworkPage interface {
	ItemArtworkPage(context.Context, *core.Viewer, core.Device, []core.RatingKey) (map[core.RatingKey][]Image, error)
}

ItemArtworkPage authorizes and lists artwork for one grid in a batch. Present keys have authoritative listings (including empty listings); missing keys must not be granted. SignPage and IssueBatch use it without falling back to scalar authorization for missing keys or errors.

type ItemDetail

type ItemDetail struct {
	Collection *core.Collection
	Playlist   *core.Playlist
	Title      core.Title
	UserData   core.WatchStatus
	// CanPlay reflects current playback authorization when known. Nil means the
	// verified peer or policy result is unavailable. It does not guarantee a
	// source, codec, stream slot or transcode capacity will be available.
	CanPlay *bool
	Tracks  []core.StreamInfo
	// TracksEstimated marks a set containing synthesized playback estimates.
	// These streams must not be presented as facts about a resolved source.
	TracksEstimated bool
	Images          []Image
	// ImagesAuthoritative reports whether Images describes the currently selected
	// authorized artwork. Background discovery may add alternatives later.
	ImagesAuthoritative bool
	Versions            []Version
	Markers             []Marker
	Extras              []Extra
}

type ItemProgress

type ItemProgress interface {
	ReportItemProgress(context.Context, SessionAccess, core.RatingKey, Timeline) error
}

ItemProgress records a Jellyfin or Emby timeline when the client play session is not one the broker opened. Infuse generates PlaySessionId and still reports the item and its file-shaped MediaSourceId.

type ItemQuery

type ItemQuery struct {
	// AdjacentTo selects the anchor and its immediately neighboring visible items.
	AdjacentTo core.RatingKey
	// StartAt selects an inclusive starting item after authorization, filtering
	// and ordering. Offset and Limit apply to the resulting suffix. It cannot
	// be combined with AdjacentTo; an absent or filtered anchor is not found.
	StartAt       core.RatingKey
	Offset, Limit int
	Sort          core.SortOrder
	Desc          bool
	Types         []core.MediaType
	Recursive     bool
	Season        *int // Optional presented season number.
	Filter        core.Filter
	Watched       *bool
	Favorite      *bool
	// NoTotal is for clients that page without a total. A library page
	// answered from the catalogue's indexes then skips counting the matches,
	// which reads every title the filter admits; Page.Total is Offset plus
	// the items returned. Other pages still report their exact total.
	NoTotal bool
}

func SeriesNextUpQuery

func SeriesNextUpQuery() ItemQuery

SeriesNextUpQuery is the bounded children request for one series' episodes.

type ItemRequest

type ItemRequest struct {
	Viewer *core.Viewer
	Device core.Device
	Key    core.RatingKey
}

type KeyKind

type KeyKind = core.KeyKind

Catalogue identities are stable across frontends. Their encoding stays in core; adapters parse and render the same identifiers through this boundary.

type KindLeaf

type KindLeaf struct {
	Index    int
	Title    string
	Key      core.RatingKey
	Duration time.Duration
	Size     int64
	MIME     string
}

KindLeaf is one playable leaf entry within a plugin kind container item.

type KindMedia

type KindMedia struct {
	io.ReaderAt
	io.Closer
	Size     int64
	MIME     string
	Duration time.Duration
	Name     string
}

KindMedia is an opened byte-addressable stream for a plugin kind item.

type KindStreams

type KindStreams interface {
	OpenKind(ctx context.Context, viewer *core.Viewer, key core.RatingKey, accept []string) (*KindMedia, error)
	KindLeaves(ctx context.Context, viewer *core.Viewer, parent core.RatingKey) ([]KindLeaf, error)
}

KindStreams opens byte-addressable media and lists playable leaves for plugin-provided content kinds (spec §6.1). Callers authorize viewer access through viewer policy; nil on Host means plugin kind media is unavailable.

type LANLazyStreams

type LANLazyStreams interface {
	IssueLAN(context.Context, *http.Request, PlanRequest) (string, error)
	ServeHTTP(http.ResponseWriter, *http.Request)
}

LANLazyStreams issues a capability only for the currently selected DLNA viewer and verified network peer. The host derives the viewer and device; callers cannot assert either identity. Every use revalidates both.

type LastPlayedSourceReader

type LastPlayedSourceReader interface {
	LastPlayedSource(context.Context, *Viewer, Device, RatingKey) (*PlaybackSourceHistory, error)
}

LastPlayedSourceReader returns source facts only after current item policy authorization. Nil means no trustworthy source facts are available. Facts describe the last durably recorded accepted sample; they can lag playback when asynchronous persistence fails and do not describe the current source.

type LatestItem

type LatestItem struct {
	Title   Title
	AddedAt *time.Time
}

LatestItem carries date added. For a grouped series that is the latest aired episode. Nil means unknown. It is not a catalogue insertion time.

type LazyHLSStreams

type LazyHLSStreams interface {
	IssueHLS(context.Context, string, PlanRequest, StreamRequest) (string, error)
}

LazyHLSStreams issues an HLS master capability without opening a session. All playlist and segment requests remain under that capability and are reauthorized by the broker. IssueHLS alone is not an eligibility check; advertise it only when a resolved PlayPlan reports HLS. Capacity and the current source and policy are checked again when playback starts.

type LazyStreamWarmer

type LazyStreamWarmer interface {
	Warm(context.Context, string, PlanRequest)
}

LazyStreamWarmer is optionally implemented by LazyStreams. Warm starts the resolve and probe that a later GET of the URL Issue returned for the same request joins, so a client that lists streams before the viewer picks one does not pay for resolution after the pick. It is best effort, never blocks on the resolve, and never opens a session or consumes a stream.

type LazyStreams

type LazyStreams interface {
	Issue(context.Context, string, PlanRequest) (string, error)
	ServeHTTP(http.ResponseWriter, *http.Request)
}

LazyStreams issues reusable, short-lived playback capabilities without opening a playback session. The issuing credential never appears in the returned URL.

type LegacyProgressWriter

type LegacyProgressWriter interface {
	LegacyProgress(context.Context, int64, RatingKey, time.Duration) error
}

LegacyProgressWriter persists a standalone playhead progress write without full timeline session semantics.

type LibraryActivity

type LibraryActivity interface {
	LatestAdded(context.Context, *Viewer, Device, string, int) ([]LatestItem, error)
	// requireExact requests a complete filtered count; an implementation must
	// return an error if it cannot determine one within its resource bounds.
	Resume(context.Context, *Viewer, Device, string, []MediaType, int, int, bool) (ActivityPage, error)
}

LibraryActivity provides home-independent library and watch-state queries. LatestAdded returns movie/show library roots; TV defaults to grouped series.

type LibraryActivityGrouping

type LibraryActivityGrouping interface {
	LatestAddedGrouped(context.Context, *Viewer, Device, string, int, bool) ([]LatestItem, error)
}

LibraryActivityGrouping selects grouped series or individual aired episodes.

type LibraryCollageSource

type LibraryCollageSource interface {
	LibraryCollage(context.Context, *Viewer, Device, string) (Image, error)
}

LibraryCollageSource builds that collage for one library view. viewID is the view GUID. A change in the child posters produces a different image.

type LibraryExportPage

type LibraryExportPage struct {
	Items []Title
	Next  RatingKey
	Done  bool
}

LibraryExportPage is a bounded, policy-filtered export batch. Next advances over raw candidates, including those hidden by policy, so no prefix is rescanned.

type LibraryExportPolicy

type LibraryExportPolicy interface {
	ExportPolicy(context.Context, *Viewer, Device, string) (ExportPolicy, error)
}

LibraryExportPolicy reports ExportPolicy without reading the library.

type LibraryExporter

type LibraryExporter interface {
	ExportLibraryPage(context.Context, *Viewer, Device, string, RatingKey, int) (LibraryExportPage, error)
}

type LibraryGUIDs

type LibraryGUIDs interface {
	Cached(context.Context, RatingKey) string
	CachedMany(context.Context, []RatingKey) map[RatingKey]string
	Schedule(...RatingKey)
	ExactKey(context.Context, string) (RatingKey, error)
	Lookup(context.Context, string) (RatingKey, error)
}

LibraryGUIDs reads cached library identities and schedules host refreshes. ExactKey distinguishes ambiguous hierarchy identities from missing entries.

type LibraryID

type LibraryID = core.LibraryID

LibraryID names one library (built-ins 1 = Movies, 2 = TV Shows).

type LibraryMetadata

type LibraryMetadata interface {
	Cached(context.Context, RatingKey) (CachedMetadataOverlay, bool)
	CachedMany(context.Context, []RatingKey) map[RatingKey]CachedMetadataOverlay
	Schedule(...RatingKey)
}

type Lifecycle

type Lifecycle interface {
	Acquire(ctx context.Context, key string) (func(), error)
	References(key string) int
}

Lifecycle serializes playback lifecycle operations per key.

type LineupStreams

type LineupStreams interface {
	IssueLineup(context.Context, string, PlanRequest) (string, error)
}

LineupStreams issues a reusable, media-only lineup capability. The issuer revalidates the source grant and channel policy on every media request. The returned /sessions/lineup/<token>/ prefix is followed by a canonical base64url channel ID and /live/index.m3u8.

type ListenerSpec

type ListenerSpec struct {
	Address    string `json:"address"`
	PathPrefix string `json:"pathPrefix,omitempty"`
	TLS        bool   `json:"tls"`
	// Shared means the app supplies this listener; the manager must not bind it.
	Shared bool `json:"shared,omitempty"`
}

type LiveChannel

type LiveChannel struct {

LiveChannel contains public metadata and a neutral channel identifier. It never contains IPTV source URLs or credentials.

type LiveGuideQuery

type LiveGuideQuery struct {
	Channels    []string
	From, Until time.Time
	Limit       int
	Device      core.Device
}

type LiveLineupObserver

type LiveLineupObserver interface {
	NotifyLiveLineupChanged(viewerID int64)
}

LiveLineupObserver is optionally implemented by a mounted Instance that notifies connected clients when the Live TV lineup changes. A non-positive viewerID broadcasts to all viewers.

type LiveProgramme

type LiveProgramme struct {
	ID, ChannelID                   string
	Start, End                      time.Time
	Item                            core.RatingKey
	Title, Summary, Rating, Artwork string
	ShowTitle, EpisodeTitle         string
	Season, Episode                 int
	Images                          []Image
}

type LiveTV

type LiveTV interface {
	Channels(context.Context, *core.Viewer) ([]LiveChannel, error)
	Guide(context.Context, *core.Viewer, LiveGuideQuery) ([]LiveProgramme, error)
	ResolveChannelGUID(context.Context, *core.Viewer, string) (LiveChannel, error)
	ResolveProgrammeGUID(context.Context, *core.Viewer, string, LiveGuideQuery) (LiveProgramme, error)

	VisibleTo(ctx context.Context, u *User) bool
	ServeXMLTV(w http.ResponseWriter, r *http.Request, u *User)
	Stop(ctx context.Context, id string, u *User) error
	ServeDASHPart(w http.ResponseWriter, r *http.Request, id string, u *User, rep, n int, init bool)
	ServePlaylist(w http.ResponseWriter, r *http.Request, id string, u *User)
	ServeRelaySegment(w http.ResponseWriter, r *http.Request, id string, n int, u *User)
	ServeResource(w http.ResponseWriter, r *http.Request, id, resource string, u *User)
	AllowedChannels(ctx context.Context, u *User) ([]LiveTVChannel, error)
	AllowedChannel(ctx context.Context, u *User, id string) (LiveTVChannel, error)
	Channel(ctx context.Context, id string) (LiveTVChannel, error)
	ChannelForViewer(ctx context.Context, u *User, id string) (LiveTVChannel, error)
	AllChannels(ctx context.Context) ([]LiveTVChannel, error)
	ChannelPermitted(ctx context.Context, u *User, id string) (bool, error)
	LineupChangedFor(u *User) time.Time
	GuideForChannels(ctx context.Context, u *User, from, until time.Time, channelIDs []string) ([]LiveTVProgramme, error)
	GuideWindow(ctx context.Context, u *User, from, until time.Time) ([]LiveTVProgramme, error)
	TuneWithSession(ctx context.Context, u *User, id string, caps ClientCaps, sessionID string) (LiveTVSessionInfo, error)
	Sessions(ctx context.Context, u *User) []LiveTVSessionInfo
	Session(ctx context.Context, id string, u *User) (LiveTVSessionInfo, error)
	ServeDASH(w http.ResponseWriter, r *http.Request, id string, u *User) error
	ServeHTTP(w http.ResponseWriter, r *http.Request, id string, u *User) error
	ViewingSessions() []*PlaySession
	NoteClientActivity()
	AuthenticateMediaGrant(r *http.Request, active func(context.Context, int64) *User) (*User, bool)
	LogoKey() []byte
}

LiveTV applies the same per-viewer access and safety policy across all frontends. Viewer must be from the authenticated session. GUID resolution never returns channels or programmes that the viewer is not permitted to see.

type LiveTVChannel

type LiveTVChannel struct {
	ID            string
	Number        string
	Name          string
	Kind          string
	Enabled       bool
	LogoMatched   bool
	Rating        string
	SourceID      string
	GuideID       string
	GuideSourceID string
	Group         string
	Personal      bool
}

LiveTVChannel is the frontend boundary representation of a Live TV channel.

type LiveTVItem

type LiveTVItem struct {
	Key          RatingKey
	Title        string
	EpisodeTitle string
	ShowTitle    string
	Summary      string
	Rating       string
	Thumb        string
	Art          string
	Genres       []string
	GUID         string
	ShowGUID     string
	MediaType    string
	Premiere     bool
	Live         bool
	Season       int
	Episode      int
	ReleasedMS   int64
}

LiveTVItem is the frontend boundary representation of a scheduled programme's item metadata.

type LiveTVProgramme

type LiveTVProgramme struct {
	ID        string
	ChannelID string
	Start     time.Time
	End       time.Time
	Lens      string
	Item      LiveTVItem
}

LiveTVProgramme is the frontend boundary representation of a guide airing.

type LiveTVSessionInfo

type LiveTVSessionInfo struct {
	ID             string
	SubscriptionID int64
	ActivityID     string
	MediaInfo      *MediaInfo
	Channel        LiveTVChannel
	Programme      *LiveTVProgramme
	StartedAt      time.Time
}

LiveTVSessionInfo is the frontend boundary representation of an active Live TV tune session.

type LiveTVTuneDiagnosis

type LiveTVTuneDiagnosis struct {
	Code           string
	Stage          string
	UpstreamStatus int
	RetryAfter     time.Duration
	Message        string
	LogAttrs       []any
}

LiveTVTuneDiagnosis is a structured classification of a Live TV tune or playback error.

func DiagnoseLiveTV

func DiagnoseLiveTV(stage string, err error) LiveTVTuneDiagnosis

DiagnoseLiveTV classifies a Live TV tune or guide error.

type Marker

type Marker struct {
	Type       string
	Start, End time.Duration
}

type MarkerRange

type MarkerRange struct {
	Type    string `json:"type"`
	StartMS int64  `json:"startTimeOffset"`
	EndMS   int64  `json:"endTimeOffset"`
	Final   bool   `json:"final"`
	Source  string `json:"source"`
}

MarkerRange is a source-specific skip range. Final identifies a terminal credits range; adapters decide how to encode that hint on their wire.

type MarkerRanges

type MarkerRanges interface {
	Markers(context.Context, RatingKey, MediaInfo) ([]MarkerRange, error)
}

type MediaInfo

type MediaInfo = core.MediaInfo

type MediaType

type MediaType = core.MediaType

type Membership

type Membership struct {
	Present bool
	AddedAt *time.Time
}

Membership reports an authorized title's presence and recorded addition time. AddedAt is when this viewer stored the membership. It is not the title's date added, and it is nil when no genuine stored time is known.

type MembershipReader

type MembershipReader interface {
	FavoriteItem(context.Context, *Viewer, Device, RatingKey) (Membership, error)
	WatchlistItem(context.Context, *Viewer, Device, RatingKey) (Membership, error)
}

MembershipReader reads one policy-authorized title at a time. An absent membership is distinct from an inaccessible title or inactive viewer.

type MetadataOverlay

type MetadataOverlay = plexmeta.Overlay

Metadata overlay values retain catalogue identity while enriching display.

type MetadataPerson

type MetadataPerson = plexmeta.Person

type MetadataProber

type MetadataProber interface {
	ProbeMetadata(context.Context, *User, RatingKey, ClientCaps) error
}

MetadataProber obtains exact pre-play source facts without admitting a live session. An error means facts are not ready.

type MicroReason

type MicroReason = core.MicroReason

MicroReason is the per-viewer decision header for a detail page. Its construction stays owned by core.

type MicroReasoner

type MicroReasoner interface {
	MicroReason(ctx context.Context, user *User, t *Title, now time.Time) MicroReason
}

MicroReasoner builds a MicroReason for one viewer and title. The title is only read, never mutated.

type NeutralHomeLayoutSource

type NeutralHomeLayoutSource = core.NeutralHomeLayoutSource

type NeutralHomeRow

type NeutralHomeRow = core.NeutralHomeRow

type NotInterestedEntry

type NotInterestedEntry struct {
	Key     core.RatingKey
	AddedAt time.Time
}

type NotInterestedPage

type NotInterestedPage struct {
	Items []NotInterestedEntry
	Total int
}

type OnDeckPageCatalog

type OnDeckPageCatalog interface {
	OnDeckPageSince(context.Context, int64, int, int, Filter, bool, time.Time) (WatchPage, error)
}

OnDeckPageCatalog pages on-deck items directly from the catalogue store.

type OpenRequest

type OpenRequest struct {
	Protocol Protocol
	PlanID   string
	Viewer   *core.Viewer
	Device   core.Device
}

type OwnerSessionStopper

type OwnerSessionStopper interface {
	NoteOwnerStop(sessionID, reason string)
}

OwnerSessionStopper is optionally implemented by a mounted Instance that delivers an owner stream-termination message to the client's timeline.

type Page

type Page = core.Page

type PageArtwork

type PageArtwork interface {
	ListPage(context.Context, *core.Viewer, core.Device, []core.Title) (map[core.RatingKey][]Image, error)
}

PageArtwork lists artwork for titles the caller already loaded.

type PageFreshness

type PageFreshness struct {
	Catalog, Config, Layout, Watch, Favorite, Hidden, Listed, Images, Grants, Accounts, Safety, Libraries, KindSync uint64
	ArtBucket                                                                                                       int64
}

PageFreshness is every input of a cached browse response. A change drops the cached body. ArtBucket rotates image grants before they expire.

type PageQuery

type PageQuery struct{ Offset, Limit int }

PageQuery defaults nonpositive Limit to 50 and caps it at 500.

type ParentToucher

type ParentToucher interface {
	TouchParents(context.Context, int64, RatingKey, time.Time, bool) error
}

ParentToucher updates parent season/show timestamps and completion counters when an episode timeline commit changes state.

type PartSource

type PartSource struct {
	Session               *core.PlaySession
	Matches               bool
	PreviousID            string
	AnonymousContinuation bool
}

type PartyActor

type PartyActor struct {
	Viewer   *core.Viewer
	Device   core.Device
	Protocol Protocol
}

PartyActor is one device of one viewer on one protocol. The same viewer on Silo and Jellyfin is two actors, so both can sit in one party.

type PartyCommand

type PartyCommand struct {
	ID, Action, Jellyfin, PlaylistItemID, SessionID string
	Position                                        time.Duration
	ExecuteAt, IssuedAt                             time.Time
	Playback                                        string
	SelectionRevision                               int64
	Rate                                            float64
}

PartyCommand is a scheduled transport change. Position is the playhead at ExecuteAt. Clients wait until that server time, which absorbs their latency.

type PartyCreate

type PartyCreate struct {
	RoomID, Mode, Name string
}

PartyCreate opens a room. RoomID may be empty; the engine mints a UUID. Mode is host_pick. Vote is refused until suggestion voting exists.

type PartyEvent

type PartyEvent struct {
	Type                 string
	View                 PartyView
	Command              PartyCommand
	GroupKind            string
	GroupData            any
	Reason               string
	ClientSent, Received time.Time
	Sent                 time.Time
	ErrorCode            string
	ErrorMessage         string
}

PartyEvent is one message for one member's socket.

type PartyInput

type PartyInput struct {
	Action   string
	Position time.Duration
	Rate     float64
}

PartyInput is a play, pause, or seek. Rate 0 leaves the room rate unchanged.

type PartyJoin

type PartyJoin struct {
	Code, Token, GroupID string
}

PartyJoin accepts a Silo code, a Silo invite token, or a Jellyfin group id.

type PartyMember

type PartyMember struct {
	ViewerID                                       int64
	Name                                           string
	Protocol                                       Protocol
	DeviceID                                       string
	Host, Self, Connected, Ready, Buffering, Lobby bool
	IgnoreWait, Blocked                            bool
}

PartyMember is one couch in the room, as seen by a particular actor.

type PartyPick

type PartyPick struct {
	Item              core.RatingKey
	FileID, LibraryID string
}

PartyPick is the title the room will play. File and library are Silo hints. Each member still opens their own broker session for that title.

type PartyQueue

type PartyQueue struct {
	Kind            string
	Items           []core.RatingKey
	Index           int
	PlaylistItemID  string
	Position        time.Duration
	Repeat, Shuffle string
}

PartyQueue is a Jellyfin playlist edit. Replace also arms playback.

type PartyQueueItem

type PartyQueueItem struct {
	Item           core.RatingKey
	ContentID      string
	PlaylistItemID string
}

PartyQueueItem is one title in the shared queue.

type PartyReport

type PartyReport struct {
	Kind                           string
	SessionID, CommandID, Playlist string
	Position                       time.Duration
	Rate                           float64
	Paused, Ready, Lobby, Ignore   *bool
	ClientSent, When               time.Time
	Playing                        bool
}

PartyReport is a realtime membership update from either dialect.

type PartySocket

type PartySocket struct {
	Actor  PartyActor
	Events <-chan PartyEvent
	Close  func()
}

PartySocket is the live Silo room connection.

type PartyTicket

type PartyTicket struct {
	Ticket                string
	ExpiresIn, MaxSeconds int
	Protocol              string
}

PartyTicket is a single-use Silo socket credential.

type PartyView

type PartyView struct {
	RoomID, Code, JoinToken, RoomToken, InvitePath, Name string
	Phase, Playback, SelectionMode, GuestPolicy, Role    string
	SelectionRevision, Generation                        int64
	Item                                                 core.RatingKey
	ContentID, FileID, LibraryID                         string
	Paused                                               bool
	Position                                             time.Duration
	AnchorAt                                             time.Time
	Rate                                                 float64
	HostConnected                                        bool
	CanTransport, CanManage, IgnoreWait                  bool
	AttachedSessionID                                    string
	Members                                              []PartyMember
	Repeat, Shuffle                                      string
	Queue                                                []PartyQueueItem
	QueueIndex                                           int
	UpdatedAt                                            time.Time
}

PartyView is the room as one member is allowed to see it.

type PendingWatchState

type PendingWatchState interface {
	HasPendingWatch(int64) bool
}

PendingWatchState reports whether a viewer has uncommitted watch updates in flight.

type PeopleImageBatchReader

type PeopleImageBatchReader interface {
	AuthorizePersonImages(context.Context, *Viewer, Device, []PersonImageTarget) ([]bool, error)
}

PeopleImageBatchReader validates exact descriptors and current credits in one host policy proof. Output is usable only on success; false entries deny.

type PeopleImageReader

type PeopleImageReader interface {
	AuthorizePersonImage(context.Context, *Viewer, Device, RatingKey, Image, func(context.Context) error) error
}

PeopleImageReader checks exact portrait ownership and current credit policy in one host-owned snapshot. Generic ItemArtwork is not a substitute. The optional trusted admission callback must not publish; it runs after the exact descriptor match, before final policy validation and lease release.

type PeopleQuery

type PeopleQuery struct {
	Query string
	Limit int
	Scope PeopleScope
}

type PeopleReader

type PeopleReader interface {
	People(context.Context, *Viewer, Device, PeopleQuery) ([]PersonDetail, error)
	Person(context.Context, *Viewer, Device, string, PersonReadOptions) (PersonDetail, error)
	// PersonCredit checks one current cached title-credit membership.
	PersonCredit(context.Context, *Viewer, Device, RatingKey, int64) (PersonDetail, error)
}

PeopleReader resolves existing person facet IDs through current visible credit membership, including episode-only credits. Reads never resolve media sources. Prefetch must not schedule a provider refresh.

type PeopleScope

type PeopleScope string
const (
	PeopleAll               PeopleScope = ""
	PeopleVideo             PeopleScope = "video"
	PeopleVideoWithEpisodes PeopleScope = "video_with_episodes"
	PeopleMovies            PeopleScope = "movie"
	PeopleSeries            PeopleScope = "series"
	PeopleEpisodes          PeopleScope = "episode"
)

type Person

type Person = core.Person

type PersonArtwork

type PersonArtwork interface {
	PersonImages(context.Context, ArtworkRequest, Title) ([]Image, error)
}

PersonArtwork constructs known portrait descriptors only from the detached current title supplied by a host's authorized credit snapshot. It performs no metadata lookup, refresh, scheduling, or independent title-cache read.

type PersonCredit

type PersonCredit = core.PersonCredit

type PersonDetail

type PersonDetail struct {
	ID, Name, IMDB string
	TMDB           int64
	ArtworkItem    RatingKey
	Images         []Image
}

PersonDetail contains only facts from currently visible credits. Artwork is optional and remains bound to the authorized title that owns the image.

type PersonImageGrantBatch

type PersonImageGrantBatch interface {
	IssuePersonImages(context.Context, string, Device, []PersonImageTarget) ([]string, error)
}

PersonImageGrantBatch issues independently revocable portrait capabilities. Results align with input, with empty secrets for denied portraits.

type PersonImageTarget

type PersonImageTarget struct {
	Item  RatingKey
	Image Image
}

PersonImageTarget binds a portrait to its current credited title.

type PersonReadOptions

type PersonReadOptions struct{ Prefetch bool }

type PersonalHomeStore

type PersonalHomeStore interface {
	LoadPersonalHome(ctx context.Context, protocol string, viewerID int64, config string) ([]byte, error)
	SavePersonalHome(ctx context.Context, protocol string, viewerID int64, config string, body []byte) error
	PersonalHomeViewers(ctx context.Context) ([]core.User, error)
}

PersonalHomeStore persists one viewer's personalized library list. The body is an opaque JSON document owned by the Media Browser frontend.

type Placement

type Placement string

Placement identifies where rows are rendered.

const (
	PlacementHome    Placement = "home"
	PlacementLibrary Placement = "library"
	PlacementDetail  Placement = "detail"
)

type PlanAdmission

type PlanAdmission struct {
	Source               *core.PlaySession
	Media                core.MediaInfo
	Caps                 core.ClientCaps
	Options              core.DecideOptions
	PreferRemux          bool
	Protocol             string
	RemoteMaxBitrateKbps int
}

PlanAdmission is the source and the version and track selections for one Plex plan. Plan makes the direct, remux, or transcode decision from them. Open publishes that decision. The adapter renders it and does not decide again.

type PlanRequest

type PlanRequest struct {
	// Version is a resolver-issued variant ID in legacy mode, or a scoped
	// VersionHandles handle when ExactVersion is set. Empty selects automatically.
	Version string
	// ResolvedRelease is the release id just returned by VersionHandles.Resolve
	// for Version, in this process. Plan checks that the handle row still names
	// that release and does not list offers again. Callers that did not resolve
	// leave it empty, and Plan validates the offer itself.
	ResolvedRelease string
	// ExpectedSourceETag binds playback to a previously offered resolved source.
	// It is not an authorization credential. A missing or changed source fails
	// closed instead of resolving a different release.
	ExpectedSourceETag string
	// DetailSource is an opaque, scoped handle returned by DetailPlan.
	DetailSource string
	Viewer       *core.Viewer
	Device       core.Device
	Protocol     Protocol
	Item         core.RatingKey
	// Channel is the stable Host.LiveTV channel ID. Exactly one of Item and
	// Channel must be supplied.
	Channel string
	Caps    core.ClientCaps
	Intent  PlayIntent
}

type PlayHints

type PlayHints struct {
	ManualSubtitle    bool // explicit request or stored manual choice, before preferences
	Collection        string
	MediaIndex        int
	PartReleaseID     string
	AudioSelection    int
	SubtitleSelection int
	SubtitleSet       bool
	SubtitleStream    *core.StreamInfo
}

PlayHints carries Plex-specific selections that cannot be represented by neutral stream indexes. Only the Plex adapter should populate it.

type PlayIntent

type PlayIntent struct {
	Estimate bool
	Options  core.DecideOptions
	// ExactVersion treats PlanRequest.Version as a scoped opaque handle and
	// refuses any substitute release, including during later source failover.
	ExactVersion bool
	// Set flags distinguish omitted choices from stream index zero and
	// an explicit subtitle-off choice (SubtitleStream == -1).
	AudioSet    bool
	SubtitleSet bool
	// AudioOrdinal selects a zero-based audio-only position from the opened,
	// probed source. SubtitleStreamIndex is an absolute source stream index;
	// -1 explicitly disables subtitles. Nil preserves normal preferences.
	AudioOrdinal        *int
	SubtitleStreamIndex *int
	Position            time.Duration
	ClientSessionID     string
	PlaybackID          string
	// AllowTranscoding is nil for the existing default; false forbids video
	// or audio transcoding while retaining any allowed direct-stream remux.
	AllowTranscoding *bool
	// PreferRemux asks for a copy-only remux when source changes would
	// otherwise disrupt the client. The broker still decides whether it applies.
	PreferRemux bool
	// DeclaredCaps marks Caps built from this request's complete device
	// declaration (a Jellyfin/Emby PlaybackInfo DeviceProfile, a Silo
	// capability body). The broker keeps the latest such caps per device so
	// a later detail page can warm the title with exactly what Play sends
	// (DetailWarmer); generic caps are never remembered.
	DeclaredCaps bool
	Hints        *PlayHints
}

type PlayPlan

type PlayPlan struct {
	ID        string
	Estimated bool
	Media     core.MediaInfo
	Decision  core.Decision
	// Alternatives are evaluated against this same source and client policy.
	// DirectPlay, DirectStream, Transcoding are evaluated against this same source.
	DirectPlay, DirectStream, Transcoding bool
	// HLS reports whether this resolved source can be delivered as HLS under
	// the declared client profile. Encoder capacity is checked at stream start.
	HLS bool
	// HLSContainer is the authoritative segment container from the resolved HLS
	// output decision (mpegts, fmp4, or mkv). Empty means unknown or ineligible;
	// it is not the source container or an encoder-capacity reservation.
	HLSContainer string
	// ETag identifies the resolved immutable source when available; it is
	// empty when the backend cannot prove a stable source identity.
	ETag string
	// DetailSource is a scoped, expiring handle for the resolved source.
	DetailSource string
}

type PlayQueue

type PlayQueue struct {
	ID               int64
	UserID           int64
	ClientID         string
	Items            []QueueItem
	Original         []QueueItem // order before shuffle
	Selected         int         // index into items
	Shuffled         bool
	SourceURI        string
	PlaylistID       core.RatingKey
	PlaylistTitle    string
	Version          int
	LastAdded        int64
	UpdatedAt        time.Time
	SuppressItem     int64
	SuppressRows     bool // mutation response only
	SuppressMetadata bool
	ForceOffsetZero  bool
	LiveSession      string // live queues resolve through LiveTV, never the catalogue

	Rev      int64     // clustered: stored row revision
	LoadedAt time.Time // clustered: when the cached copy was read or written
}

func DecodeQueue

func DecodeQueue(id, userID, rev, updated int64, data string) (*PlayQueue, error)

func (*PlayQueue) ReanchorAdded

func (q *PlayQueue) ReanchorAdded()

writePlayQueue renders a queue window around the selected item.

func (*PlayQueue) Snapshot

func (q *PlayQueue) Snapshot() PlayQueue

type PlayQueuePersistence

type PlayQueuePersistence struct {
	DB           *sql.DB
	Counter      func(context.Context, string, int) (int64, error)
	Invalidate   func(int64)
	Warn         func(string, error)
	ExpireResult func(error)
}

PlayQueuePersistence connects shared queue transactions to node invalidation and outage reporting. Configure it before serving requests.

type PlayQueues

type PlayQueues interface {
	Preallocate(keys []core.RatingKey) ([]QueueItem, error)
	CreateWith(userID int64, clientID string, keys []core.RatingKey, now time.Time, fn func(q *PlayQueue)) (PlayQueue, error)
	With(id, userID int64, now time.Time, fn func(q *PlayQueue)) (PlayQueue, bool)
	Get(id, userID int64) (PlayQueue, bool)
	SelectItem(userID, itemID int64)
	Expire(now time.Time, ttl time.Duration)
	AddItems(q *PlayQueue, keys []core.RatingKey, pre []QueueItem, next bool)
	Forget(id int64)
	DropCache()
	Reshuffle(q *PlayQueue, shuffled bool)
	Take(id, userID int64, clientID string, now time.Time) (PlayQueue, bool)
	Configure(now func() time.Time, persistence *PlayQueuePersistence)
	Persistent() bool
	Len() int
	FollowingPlayable(userID int64, key core.RatingKey, playable func(core.RatingKey) bool) core.RatingKey
	TimelineQueue(user int64, client string, key core.RatingKey, raw string, present bool) core.RatingKey
}

PlayQueues is the play-queue store.

type PlaySession

type PlaySession = core.PlaySession

Playback session and decision values stay owned by core. Adapters observe and render them through these aliases.

type Playback

type Playback = core.Playback

type PlaybackAccessPolicy

type PlaybackAccessPolicy interface {
	CanPlay(*User, bool, time.Time) bool
}

PlaybackAccessPolicy is the optional playback admission check an access policy may expose. Absence means the caller applies no extra restriction.

type PlaybackActivity

type PlaybackActivity struct {
	ID                                                     string
	DecisionSeen                                           bool
	PlayingSeen                                            bool
	SessionKey                                             int
	User                                                   core.User
	ClientID, Product, Version, Platform, PlatformVersion  string
	Device, DeviceName, Model, Vendor, SessionID, RemoteIP string
	ProfileName                                            string
	Remote                                                 bool
	Key                                                    core.RatingKey
	State                                                  string
	Offset, Duration                                       time.Duration
	PlayQueueItemID                                        int64
	TranscodeID                                            string
	StartedAt, UpdatedAt                                   time.Time
}

PlaybackActivity is one Plex client's playback as the session list shows it. The broker is the only store. Cluster rows for these activities use protocol plex.

type PlaybackActivityStore

type PlaybackActivityStore interface {
	HasActivity(id string) bool
	EnsureActivity(id string, key int)
	UpsertActivity(id string, fn func(*PlaybackActivity)) PlaybackActivity
	RemoveActivity(id string) (PlaybackActivity, bool)
	ListActivities() []PlaybackActivity
	ExpireActivities(now time.Time, ttl time.Duration) []PlaybackActivity
}

PlaybackActivityStore is the broker's active session-list store.

type PlaybackConfirmationPolicy

type PlaybackConfirmationPolicy interface {
	ConfirmPlayback(context.Context, *User, bool, time.Time) (*User, error)
}

PlaybackConfirmationPolicy is the optional live-policy confirmation check an access policy may expose.

type PlaybackDefaults

type PlaybackDefaults = transcode.PlaybackDefaults

func PlaybackDefaultsFor

func PlaybackDefaultsFor(product, platform, device, model, version string, overrides []core.ClientCapabilityOverride) PlaybackDefaults

type PlaybackDeliveredSession

type PlaybackDeliveredSession interface {
	PlaybackDelivered() bool
}

PlaybackDeliveredSession reports whether an encoder session has delivered playable output.

type PlaybackOwners

type PlaybackOwners interface {
	Bind(user int64, client string, key core.RatingKey, id, playID string, decision bool, now time.Time)
	BindFor(surface string, user int64, client string, key core.RatingKey, id, playID string, decision bool, now time.Time)
	Stale(user int64, client string, key core.RatingKey, id string) bool
	StaleFor(surface string, user int64, client string, key core.RatingKey, id string) bool
	Expire(now time.Time, ttl time.Duration)
}

PlaybackOwners is the v39 playback owner history.

type PlaybackPreferenceRules

type PlaybackPreferenceRules = trackprefs.Rules

type PlaybackPreferenceSelection

type PlaybackPreferenceSelection = trackprefs.Selection

PlaybackPreferenceSelection and PlaybackPreferenceRules are persisted value contracts; preference lookup and selection remain host responsibilities.

type PlaybackPrepareWithin

type PlaybackPrepareWithin = core.PlaybackPrepareWithin

type PlaybackSourceHistory

type PlaybackSourceHistory = core.PlaybackSourceHistory

type PlaybackSourceKeyer

type PlaybackSourceKeyer interface {
	SourceKey(playID string) string
}

PlaybackSourceKeyer reports the resolved source identity for a playback session.

type Playlist

type Playlist = core.Playlist

type PlaylistEdit

type PlaylistEdit = core.PlaylistEdit

PlaylistEdit updates only explicitly supplied fields. Its storage stays owned by core.

type PlaylistEditor

type PlaylistEditor interface {
	EditPlaylist(context.Context, int64, RatingKey, PlaylistEdit) (*Playlist, error)
}

PlaylistEditor is the optional playlist field-edit capability a playlist store may expose.

type PlaylistHeaderLister

type PlaylistHeaderLister interface {
	ListHeaders(context.Context, int64) ([]Playlist, error)
}

PlaylistHeaderLister lists playlist headers without loading item membership.

type PlaylistLibrary

type PlaylistLibrary interface {
	Playlists(context.Context, *core.Viewer, PageQuery) (PlaylistPage, error)
	CreatePlaylist(context.Context, *core.Viewer, string, []core.RatingKey) (*core.Playlist, error)
	AddPlaylistItems(context.Context, *core.Viewer, core.RatingKey, []core.RatingKey) error
	RemovePlaylistItem(context.Context, *core.Viewer, core.RatingKey, int) error
	MovePlaylistItem(context.Context, *core.Viewer, core.RatingKey, int, int) error
	DeletePlaylist(context.Context, *core.Viewer, core.RatingKey) error
}

PlaylistLibrary is the viewer's playlists. Remove and move indexes are positions in the visible item list, never raw storage positions that include titles hidden from this viewer.

type PlaylistMutation

type PlaylistMutation = core.PlaylistMutation

PlaylistMutation addresses members by stable item identity. Its storage stays owned by core.

type PlaylistMutator

type PlaylistMutator interface {
	MutatePlaylist(context.Context, int64, RatingKey, PlaylistMutation) (*Playlist, int, error)
}

PlaylistMutator is the optional identity-addressed playlist mutation capability a playlist store may expose.

type PlaylistPage

type PlaylistPage struct {
	Items []core.Playlist
	Total int
}

PlaylistPage is one viewer's own playlists. Item keys are titles that viewer is allowed to see, in playlist order.

type PlaylistSelection

type PlaylistSelection interface {
	Get(ctx context.Context, viewer *core.User, key core.RatingKey) (*core.Playlist, error)
	Expand(ctx context.Context, viewer *core.User, key core.RatingKey) ([]core.RatingKey, error)
}

PlaylistSelection reads and expands playlists.

type PlaylistSelectionOptions

type PlaylistSelectionOptions struct {
	Playlists     core.Playlists
	Collections   core.Collections
	Visibility    Visibility
	Children      func(context.Context, core.RatingKey) ([]core.Title, error)
	Grandchildren func(context.Context, core.RatingKey) ([]core.Title, error)
}

PlaylistSelectionOptions configures a PlaylistSelection.

type Playlists

type Playlists = core.Playlists

type PostPlayPick

type PostPlayPick = core.PostPlayPick

PostPlayPick is one ranked post-play recommendation with its explained score components. The ranking stays owned by core.

type PostPlayRow

type PostPlayRow struct {
	Purpose core.RowPurpose
	Items   []core.Title
}

PostPlayRow is a viewer-scoped set of ranked recommendations. The presentation and protocol-specific identifiers belong to the

type PostPlaySelection

type PostPlaySelection interface {
	Row(ctx context.Context, viewer *core.User, count int, seen map[core.RatingKey]bool) PostPlayRow
	RelatedRows(ctx context.Context, viewer *core.User, count int, seen map[core.RatingKey]bool) ([]core.Hub, error)
}

PostPlaySelection loads post-play picks and related rows.

type PostPlaySelectionOptions

type PostPlaySelectionOptions struct {
	Visibility   Visibility
	Unrestricted bool
	Picks        func(context.Context, int) []core.PostPlayPick
	Related      func(context.Context, int) ([]core.Hub, error)
}

PostPlaySelectionOptions configures a PostPlaySelection.

type PostPlayer

type PostPlayer interface {
	PostPlay(ctx context.Context, user *User, justWatched RatingKey, hc HubContext, limit int) ([]PostPlayPick, error)
}

PostPlayer ranks a personalized post-play queue after a title.

type Preferences

Preferences stores presentation state for the bound surface. Viewer must be obtained from the current authenticated session. These values are not policy.

type PrerollClip

type PrerollClip = core.PrerollClip

type PrerollPlay

type PrerollPlay = core.PrerollPlay

type PrerollRequest

type PrerollRequest = core.PrerollRequest

Pre-roll request, clip and play values stay owned by core. Adapters exchange them through these aliases.

type Prerolls added in v0.3.3

type Prerolls interface {
	Intro(ctx context.Context, viewer *Viewer, device Device, item ItemDetail, away bool) (Extra, string, bool, error)
	Lookup(ctx context.Context, key RatingKey) (Extra, bool)
	Open(ctx context.Context, key RatingKey) (io.ReadSeekCloser, time.Time, error)
	Started(ctx context.Context, viewer *Viewer, device Device, key RatingKey)
	Active(ctx context.Context) bool
	Pick(ctx context.Context, req PrerollRequest) (PrerollClip, bool)
	Clip(ctx context.Context, key RatingKey) (PrerollClip, bool)
	Thumb(ctx context.Context, key RatingKey) (string, bool)
	RecordPlay(ctx context.Context, play PrerollPlay)
}

Prerolls are the owner's pre-rolls (#298), served as the first intro of a fresh movie or episode play. Intro reports the pre-roll before an item the front end already authorized (with its placement, PrerollBeforeTrailers or PrerollAfterTrailers), or false. Lookup and Open serve a ready pre-roll; it has no parent, and any signed-in viewer may play it. Started records a play once per viewer, pre-roll and feature.

type PrewarmOptions

type PrewarmOptions = core.PrewarmOptions

PrewarmOptions tune a speculative warm-up of a title before the viewer presses Play. The options stay owned by core.

type Prewarmer

type Prewarmer interface {
	Prewarm(ctx context.Context, user *User, key RatingKey, caps ClientCaps, opts PrewarmOptions) bool
}

Prewarmer is implemented by playback managers that can resolve, open, probe and pre-buffer a title ahead of Play. It reports whether a warm-up was scheduled.

type ProgressSample

type ProgressSample struct {
	InstallationID  string
	Sequence        uint64
	PositionSeconds float64
	Paused          bool
	// Stop finalizes playback under the same ownership gate as sample ordering.
	Stop bool
}

ProgressSample is the exact Silo v2 sample before conversion to duration. InstallationID is the server installation identity, not the device ID.

type ProgressiveFailureSession

type ProgressiveFailureSession interface {
	ProgressiveFailed() bool
}

ProgressiveFailureSession reports whether a progressive stream failed.

type Protocol

type Protocol = core.Protocol

Protocol identifies a surface independently of client product or platform.

type ProtocolStopper

type ProtocolStopper interface {
	StopProtocol(ctx context.Context, protocol Protocol) error
}

ProtocolStopper stops all active sessions for a frontend protocol.

type PublicArtwork

type PublicArtwork interface {
	PublicArtwork(ctx context.Context, device core.Device, item core.RatingKey) (images []Image, reader *core.Viewer, ok bool, err error)
}

PublicArtwork lists title artwork an unauthenticated image request may be served: artwork of a title visible to every active viewer under current policy (sections, content ratings, the owner's content policy and inherited show rules). ok is false when the title is missing, hidden from any viewer, or not a plain title (collections, playlists and extras are never public). reader is a real active viewer the bytes may be read as — every viewer passed, so any of them may read — and is never a requester identity: there is none. Implementations cache the intersection per policy epoch, so a restriction change takes effect without waiting for a TTL.

type PublicImageServer

type PublicImageServer interface {
	ServePublic(http.ResponseWriter, *http.Request, core.Device, core.RatingKey, Image)
}

PublicImageServer is the optional image-grant extension that serves one PublicArtwork-selected image to a request with no credential. It re-checks public visibility and that the image belongs to the item before writing bytes, mirroring Serve's re-authorization.

type PublicViewer

type PublicViewer struct {
	ID   int64
	Name string
	// HasConfiguredPassword is known only when the identity service can
	// establish it from its active local credential record.
	HasConfiguredPassword *bool
}

PublicViewer is the minimal identifier displayed by an owner-enabled picker.

type PublishedLibraryProvider

type PublishedLibraryProvider interface {
	PublishedLibraries() []PublishedLibrarySection
}

PublishedLibraryProvider is optionally implemented by a mounted Instance that exposes canonical library sections for remote directory registration.

type PublishedLibrarySection

type PublishedLibrarySection struct {
	ID       int
	Type     MediaType
	Title    string
	UUID     string
	Language string
}

PublishedLibrarySection describes a library section advertised to external account directories.

type QueueItem

type QueueItem struct {
	ID    int64
	Key   core.RatingKey
	Added bool // explicit Up Next addition, distinct from original queue members
}

type QuickConnectDetails

type QuickConnectDetails struct {
	Approved     bool
	Code, Secret string
	Device       core.Device
	CreatedAt    time.Time
	ExpiresAt    time.Time
}

QuickConnectDetails is returned only to the holder of the polling secret.

type RasterOptions

type RasterOptions = artwork.RasterOptions

RasterOptions configures an SVG-to-PNG/JPEG rasterization.

type RatingKey

type RatingKey = core.RatingKey

func EpisodeKey

func EpisodeKey(show int64, season, episode int) RatingKey

func MovieKey

func MovieKey(id int64) RatingKey

func ParseRatingKey

func ParseRatingKey(value string) (RatingKey, error)

func SeasonKey

func SeasonKey(show int64, season int) RatingKey

func ShowKey

func ShowKey(tmdb int64) RatingKey

type Recent

type Recent interface {
	Added(ctx context.Context, viewer *core.User, kind core.MediaType, count int, browse func(context.Context, core.BrowseQuery) (core.Page, error)) ([]core.Title, bool, error)
	Viewed(ctx context.Context, viewer *core.User, libraryID int, history func(context.Context, int64, time.Time, int) ([]core.HistoryEntry, error), titles func(context.Context, []core.RatingKey) []core.Title, libraryFor func(core.MediaType) (int, bool)) ([]core.Title, error)
}

Recent loads recently added and recently viewed rows.

type RecentOptions

type RecentOptions struct {
	Visibility   Visibility
	Unrestricted func(*core.User) bool
}

RecentOptions configures a Recent selector.

type RecentPageCatalog

type RecentPageCatalog interface {
	RecentPage(context.Context, BrowseQuery, []MediaType) (Page, error)
}

RecentPageCatalog pages recently added items directly from the catalogue store.

type RecentlyViewedSettingsState

type RecentlyViewedSettingsState interface {
	RecentlyViewedSettings(context.Context, int64, time.Time, int) ([]HistoryEntry, error)
}

RecentlyViewedSettingsState reads history filtered by recently-viewed settings.

type Recommender

type Recommender = core.Recommender

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry serializes lifecycle transitions so a protocol has at most one live instance. The host factory must bind identity to the requested surface.

func NewRegistry

func NewRegistry(host func(Protocol) Host) *Registry

func (*Registry) Descriptors

func (r *Registry) Descriptors() []Descriptor

func (*Registry) Instance

func (r *Registry) Instance(id Protocol) (Instance, bool)

func (*Registry) Mount

func (r *Registry) Mount(ctx context.Context, id Protocol) (Instance, error)

func (*Registry) Prune

func (r *Registry) Prune(ctx context.Context, id Protocol) (int64, error)

Prune runs DerivedPruner on a registered frontend or its mounted instance.

func (*Registry) Register

func (r *Registry) Register(f Frontend) error

func (*Registry) Shutdown

func (r *Registry) Shutdown(ctx context.Context) error

Shutdown marks the registry closed and releases process-retained state on registered frontends that implement Shutdowner.

func (*Registry) Unmount

func (r *Registry) Unmount(ctx context.Context, id Protocol) error

func (*Registry) ValidateSettings

func (r *Registry) ValidateSettings(id Protocol, settings Settings) (bool, error)

ValidateSettings checks settings against the frontend's descriptor schema, then delegates protocol-specific settings to the registered frontend. The bool reports whether validation beyond the host's common checks applies (a schema or a protocol validator).

type RelatedArtwork

type RelatedArtwork struct {
	People              []Image
	PeopleAuthoritative bool
	Season, Series      *ArtworkOwner
}

RelatedArtwork contains only artwork associated with an authorized item. Season is the episode's canonical season; Series is its show. People belong to the requested item, and Image.Subject identifies each credited person.

type RelatedArtworkProvider

type RelatedArtworkProvider interface {
	RelatedArtwork(context.Context, *Viewer, Device, RatingKey) (RelatedArtwork, error)
}

RelatedArtworkProvider supplies cache-only parent and credit artwork. Each descriptor must be granted using its owning item, and is revalidated by the image-grant service on issue and read.

type Release

type Release = core.Release

type ReleaseInfo

type ReleaseInfo = core.ReleaseInfo

type ReleaseVariant

type ReleaseVariant = core.ReleaseVariant

type ReportOutcome

type ReportOutcome string
const (
	ReportApplied  ReportOutcome = "applied"
	ReportReplayed ReportOutcome = "replayed"
	ReportStale    ReportOutcome = "stale_sample"
	ReportConflict ReportOutcome = "conflict"
)

type RequestMemo

type RequestMemo struct {
	Mu      sync.Mutex
	Viewer  *core.User
	Visible map[core.RatingKey]bool
	Aired   map[core.RatingKey]AiredMemo
}

RequestMemo keeps one viewer snapshot and one visibility decision per title for the rest of a single request.

func RequestMemoFrom

func RequestMemoFrom(ctx context.Context) *RequestMemo

RequestMemoFrom returns the memo installed by WithRequestMemo.

type ResolveRequest

type ResolveRequest = core.ResolveRequest

type ResolvedEventSubject

type ResolvedEventSubject struct {
	Ref           FavoriteRef
	PersonFacetID string
	Favorite      bool
	UserData      *core.WatchStatus
}

ResolvedEventSubject is viewer-authorized current data for an event entity. PersonFacetID shares the namespace used by person facets.

type ResolvedExtra

type ResolvedExtra struct {
	URL       string
	Headers   map[string]string
	Expires   time.Time
	Container string
}

ResolvedExtra is a playable location for an extra clip.

func (ResolvedExtra) Input

func (r ResolvedExtra) Input() string

Input returns the ffmpeg input.

type ResourceSample

type ResourceSample = hoststat.Sample

Statistics values are snapshots. Adapters parse protocol filters and render these values; the host owns device identity, aggregation and retention.

type ResourceStatistics

type ResourceStatistics interface {
	Query(span int, atMin, atMax, exactAt int64, hasExact, hasMin, hasMax bool) []ResourceSample
}

type Route

type Route = conform.Route

Route and RouteInventory describe adapter registration without domain services.

type RouteInventory

type RouteInventory = conform.RouteInventory

type RouteSource

type RouteSource interface{ Routes() []Route }

RouteSource exposes the exact routes registered by a mounted frontend. A missing implementation means inventory is unavailable, not empty.

type Row

type Row struct {
	ID, Title    string
	Purpose      RowPurpose
	Kind         string // Stable semantic producer kind, independent of protocol.
	Layout       RowLayout
	Style        string
	Promoted     bool
	Rank         int
	ImpressionID string
	// Handle is a server-issued row interaction capability.
	Handle string
	// Entries is the ordered heterogeneous row; Items remains for compatibility.
	Entries    []RowEntry
	Items      []core.Title
	More       bool
	Collection core.RatingKey
}

type RowDirectory

type RowDirectory struct {
	ID, Title, Description, Image string
	Kind                          string
}

RowDirectory identifies a browsable destination in the experience.

type RowEntry

type RowEntry struct {
	Kind        RowEntryKind
	Handle      string
	Title       *core.Title
	Collection  *core.Collection
	Playlist    *core.Playlist
	LiveChannel *RowLiveChannel
	Directory   *RowDirectory
}

RowEntry is a tagged union: Kind identifies the one non-nil payload. Handle is an opaque, server-issued interaction capability scoped to the viewer and device; it is not an account credential.

type RowEntryKind

type RowEntryKind string

RowEntryKind identifies a neutral entry independently of wire formats.

const (
	RowEntryTitle       RowEntryKind = "title"
	RowEntryCollection  RowEntryKind = "collection"
	RowEntryPlaylist    RowEntryKind = "playlist"
	RowEntryLiveChannel RowEntryKind = "liveChannel"
	RowEntryDirectory   RowEntryKind = "directory"
)

type RowFactsLoader

type RowFactsLoader interface {
	LoadRowFacts(context.Context, []Title) []Title
}

RowFactsLoader populates stored row-level facts on a slice of titles.

type RowInteraction

type RowInteraction struct {
	Viewer   *core.Viewer
	Device   core.Device
	Protocol Protocol
	Handle   string
	Kind     RowInteractionKind
}

type RowInteractionKind

type RowInteractionKind string

RowInteractionKind is a viewer action on an issued row or entry.

const (
	RowImpression RowInteractionKind = "impression"
	RowClick      RowInteractionKind = "click"
	RowPlay       RowInteractionKind = "play"
)

type RowInteractionReporter

type RowInteractionReporter interface {
	ReportRowInteraction(context.Context, RowInteraction) error
}

RowInteractionReporter validates issued handles, membership and device scope before recording actions. Clients must never construct handles or contexts.

type RowLayout

type RowLayout struct {
	Order  int
	Style  string
	Paint  RowPaint
	Always bool
}

RowLayout describes Home Designer presentation selected by experience.

type RowLiveChannel

type RowLiveChannel struct {
	GuideReference         string
	Current, Next          *RowProgramme
	Images                 []Image
}

RowLiveChannel contains viewer-visible channel metadata, never source URLs.

type RowPaint

type RowPaint struct {
	Background, Foreground, Accent string
	Artwork                        string
}

RowPaint carries optional presentation colors and artwork references.

type RowProgramme

type RowProgramme struct {
	ID, Title, EpisodeTitle string
	Start, End              time.Time
	Season, Episode         int
	Item                    core.RatingKey
}

RowProgramme describes one guide entry without an upstream stream URL.

type RowPurpose

type RowPurpose = core.RowPurpose

RowPurpose describes why a row exists, independent of wire-level hub IDs.

const (
	RowContinue         RowPurpose = "continue"
	RowNextUp           RowPurpose = "nextUp"
	RowRecentlyReleased RowPurpose = "recentlyReleased"
	RowRecentlyAdded    RowPurpose = "recentlyAdded"
	RowCollection       RowPurpose = "collection"
	RowRecommendation   RowPurpose = "recommendation"
	RowLive             RowPurpose = "live"
	RowWatchlist        RowPurpose = "watchlist"
)

type RowRequest

type RowRequest struct {
	Viewer    *core.Viewer
	Device    core.Device
	Placement Placement
	ViewID    string
	Item      core.RatingKey
	Limit     int
	// Purpose asks for one row. The zero value still returns the whole placement.
	Purpose RowPurpose
}

type RowSelection

type RowSelection interface {
	Items(ctx context.Context, viewer *core.User, row core.Hub) []core.Title
}

RowSelection filters one hub row's items for a viewer.

type RowSelectionOptions

type RowSelectionOptions struct {
	Visibility          Visibility
	PrioritizeAvailable func(context.Context, []core.Title) []core.Title
	SameDayUnavailable  func(context.Context, *core.Title) bool
}

RowSelectionOptions configures a RowSelection.

type RowView

type RowView struct {
	ID          string
	Title, Kind string
	Purpose     RowPurpose
	Layout      RowLayout
	Rank        int
}

RowView identifies one server-owned, viewer/device/surface-scoped visit. ID binds one immutable snapshot and changes on refresh.

type RowViewPage

type RowViewPage struct {
	Entries          []RowEntry
	ImpressionHandle string
	Total            int
	TotalExact       bool
	More             bool
	// Truncated means the snapshot is a bounded prefix of the source row.
	// More only indicates entries available in this snapshot.
	Truncated bool
}

type RowViewPageRequest

type RowViewPageRequest struct {
	Viewer        *Viewer
	Device        Device
	Protocol      Protocol
	ID            string
	Offset, Limit int
	Kinds         []RowEntryKind
}

type RowViewRequest

type RowViewRequest struct {
	Viewer    *Viewer
	Device    Device
	Protocol  Protocol
	Placement Placement
	ViewID    string
	Item      RatingKey
	// Refresh starts new snapshots and invalidates earlier page generations.
	Refresh bool
}

type RowViews

type RowViews interface {
	ListRowViews(context.Context, RowViewRequest) ([]RowView, error)
	ResolveRowView(context.Context, RowViewPageRequest) (RowViewPage, error)
}

RowViews is optional; IDs are not credentials. Implementations must reauthorize each call and issue page-scoped interaction handles.

type SQLAvailabilityCatalog

type SQLAvailabilityCatalog interface {
	BrowseAvailabilityInSQL() bool
}

SQLAvailabilityCatalog reports whether browse queries apply availability filtering in SQL.

type SQLPlaylistBrowseCatalog

type SQLPlaylistBrowseCatalog interface {
	BrowsePlaylistInSQL() bool
}

SQLPlaylistBrowseCatalog reports whether smart playlist browse queries execute in SQL.

type SVGRasterizer

type SVGRasterizer interface {
	Rasterize(ctx context.Context, reference string, data []byte, opts RasterOptions) ([]byte, string, error)
}

SVGRasterizer rasterizes SVG bytes or generated channel logos.

func NewSVGRasterizer

func NewSVGRasterizer() SVGRasterizer

NewSVGRasterizer constructs an SVG rasterizer.

type SampleReporter

type SampleReporter interface {
	ReportSample(context.Context, SessionAccess, string, ProgressSample) (ReportOutcome, error)
}

SampleReporter reports an idempotent sample and returns its durable outcome. It is additive to Sessions.Report, whose existing semantics stay unchanged.

type ScopedCollection

type ScopedCollection interface {
	Items(ctx context.Context, viewer *core.User, key core.RatingKey, deviceClass string) ([]core.Title, error)
	Get(ctx context.Context, viewer *core.User, key core.RatingKey, device string, count bool) (*core.Collection, error)
	Counts(ctx context.Context, viewer *core.User, collections []core.Collection, device string) []core.Collection
	Page(ctx context.Context, viewer *core.User, collection *core.Collection, key core.RatingKey, device string, offset, size int) (core.Page, error)
	Placeholder(ctx context.Context, viewer *core.User, key core.RatingKey, requested *core.RatingKey, device string) (*core.Title, core.RatingKey, error)
}

ScopedCollection reads collections through viewer policy.

type ScopedCollectionOptions

type ScopedCollectionOptions struct {
	Collections  core.Collections
	Visibility   Visibility
	Now          func() time.Time
	Unrestricted func(*core.User) bool
	TitleAllowed func(*core.User, *core.Title) bool
	Openable     func(context.Context, *core.User, []core.Title) []core.Title
}

ScopedCollectionOptions configures a ScopedCollection.

type ScopedMedia

type ScopedMedia interface {
	ServeMediaAccess(http.ResponseWriter, *http.Request, SessionAccess)
}

ScopedMedia serves a stream only to the authenticated device that owns it. The scoped URL's grant and current playback policy are also checked.

type ScopedTrackPreferenceService

type ScopedTrackPreferenceService interface {
	GetScoped(context.Context, *Viewer, TrackScope) (TrackPreferences, int, int, string, map[string]string, error)
	SetScoped(context.Context, *Viewer, string, string, TrackPreferencePatch) error
	DeleteScoped(context.Context, *Viewer, string, string, string) error
	SetAudio(context.Context, *Viewer, []string) error
	SetSubtitleLanguage(context.Context, *Viewer, []string) error
	SetSubtitleMode(context.Context, *Viewer, string) error
	SetAppearance(context.Context, *Viewer, json.RawMessage) error
	SetBitrate(context.Context, *Viewer, int) error
	SetHeight(context.Context, *Viewer, int, string) error
}

ScopedTrackPreferenceService is an optional extension for shared playback preferences; identifiers use the host's library and rating-key namespaces.

type Search interface {
	Find(ctx context.Context, viewer *core.User, query string, types []core.MediaType, limit int) ([]core.Title, error)
	Resolve(ctx context.Context, viewer *core.User, query string, types []core.MediaType, limit int, collections bool) (SearchResults, error)
	Keyword(ctx context.Context, viewer *core.User, query string, types []core.MediaType, limit int) ([]core.Title, error)
}

Search is the shared search seen through one frontend's visibility.

type SearchCacheRefiller

type SearchCacheRefiller interface {
	RefillSearchCache(*Title) <-chan struct{}
}

SearchCacheRefiller is the optional capability that refills a title's search cache in the background; the channel closes when it finishes.

type SearchCandidates

type SearchCandidates = core.SearchCandidates

type SearchListDetailsCatalog

type SearchListDetailsCatalog interface {
	SearchListDetails(context.Context, []Title) ([]Title, error)
}

SearchListDetailsCatalog enriches search results with list-level details in batch.

type SearchPage

type SearchPage struct {
	Page         core.Page
	TotalExact   bool
	Continuation Continuation
}

type SearchResults

type SearchResults struct {
	Collection       *core.Collection
	Items            []core.Title
	CollectionSearch bool
}

SearchResults retains whether an optional collection source handled the query. A handled empty result must not fall back to keyword search.

type SearchSources

type SearchSources struct {
	Catalog  func(context.Context, string, []core.MediaType, int) ([]core.Title, error)
	Natural  func(context.Context, *core.User, string, int) ([]core.Title, bool)
	Familiar func(context.Context, *core.User, []core.RatingKey) map[core.RatingKey]int
	Vibe     VibeSource
	// Details reads in full the titles a candidate search returned partial
	// (core.SearchCandidates). Nil leaves every search reading its results
	// in full.
	Details func(context.Context, []core.Title) ([]core.Title, error)
}

SearchSources are the parts of search every frontend shares: the catalogue (with the owner's availability rules applied), natural-language search, the viewer's affinity and collection readings. The app builds one set; each frontend adds only its own visibility, so a query finds the same titles in the same order on Plex, Jellyfin, Emby and the rest.

type SearchVisibilityCatalog

type SearchVisibilityCatalog interface {
	SearchVisible(*Title) bool
}

SearchVisibilityCatalog reports whether a search hit passes catalogue search visibility rules.

type SegmentDurationSession

type SegmentDurationSession interface {
	SegmentDuration() time.Duration
}

SegmentDurationSession reports the segment duration of an HLS session.

type SegmentedEncoder

type SegmentedEncoder interface {
	StartSegmentedHLS(ctx context.Context, viewer *core.User, playID, id string, req core.HLSRequest) (core.HLSSession, error)
	SegmentedHLSSession(id string) (core.HLSSession, bool)
	StopSegmentedHLS(id string) bool
}

SegmentedEncoder is the universal segmented transcode session interface.

type Selections

type Selections[T any] struct {
	// contains filtered or unexported fields
}

Selections stores per-viewer track choices. The adapter owns the value shape and translates wire stream identifiers before updating a choice.

func NewSelections

func NewSelections[T any]() *Selections[T]

func (*Selections[T]) Get

func (s *Selections[T]) Get(viewer, item int64) T

func (*Selections[T]) Update

func (s *Selections[T]) Update(viewer, item int64, fn func(*T))

type ServerIdentity

type ServerIdentity struct {
	MachineID       string
	FriendlyName    string
	Version         string
	Platform        string
	PlatformVersion string
}

ServerIdentity describes how this server presents its machine and build identity. Empty fields fall back to HostConfig or runtime defaults.

type Session

type Session struct {
	ID, MediaPath string
	Protocol      Protocol
	ViewerID      int64
	// ClientSessionID is a non-secret protocol installation/session identifier.
	ClientSessionID string
	Device          core.Device
	Item            core.RatingKey
	Channel         string
	Media           *core.MediaInfo
	StartedAt       time.Time
	Capabilities    *SessionCapabilities
}

type SessionAccess

type SessionAccess struct {
	Viewer   *core.Viewer
	Device   core.Device
	Protocol Protocol
	Owner    bool
}

SessionAccess binds client operations to an authenticated viewer and surface. Owner requests owner scope; it is not proof of authorization. The broker verifies the authenticated viewer is an active owner.

type SessionBusyError

type SessionBusyError struct{ RetryAfter time.Duration }

func (*SessionBusyError) Error

func (*SessionBusyError) Error() string

func (*SessionBusyError) Is

func (*SessionBusyError) Is(target error) bool

type SessionCapabilities

type SessionCapabilities struct {
	PlayableMediaTypes           []string
	SupportedCommands            []string
	SupportsMediaControl         *bool
	SupportsPersistentIdentifier *bool
	SupportsRemoteControl        *bool
	DeviceProfile                json.RawMessage
	AppStoreURL                  string
	IconURL                      string
}

SessionCapabilities are declared by an authenticated device on one surface. URL fields are metadata and must never be fetched by the broker.

type SessionMarkers

type SessionMarkers struct {
	Known      bool
	SourceETag string
	Markers    []Marker
}

SessionMarkers describes only a complete set bound to the current source. Known=false means the source has not established a complete marker set.

type SessionRuntime

type SessionRuntime interface {
	HasBroker() bool
	SegmentedEncoder() SegmentedEncoder
	Playback() Playback
	Transcoder() Transcoder
	Downloads() DownloadRemuxer
	SetDownloads(DownloadRemuxer)
	LatestDecision(key core.RatingKey) (core.DecisionTrace, bool)
	DB() *sql.DB
	Cluster() ClusterNode
	SessionHeartbeat() time.Duration
	PlaybackOwners() PlaybackOwners
	LifecycleGates() Lifecycle
	NewDecisionArms(ctx context.Context, db *sql.DB, now func() time.Time, node string, log *slog.Logger, wg *sync.WaitGroup) DecisionArms
	NewStartGuard() StartGuard
	NewPlayQueues() PlayQueues
	NewVersionFlows(ctx context.Context, db *sql.DB) VersionFlows
	NewDownloadQueueStore() DownloadQueueStore
	NewVariantIDs(db *sql.DB, now func() time.Time) VariantIDs
	NewDownloadJob(playback Playback, remuxer DownloadRemuxer) DownloadJob
	NewDownloadQueuePersistence(queue DownloadQueueStore, db *sql.DB, artifacts DownloadRemuxer, log *slog.Logger, expiry func() time.Duration, storageID func() string, users func(context.Context) ([]core.User, error)) DownloadQueuePersistence
	PrepareSource(ctx context.Context, viewer *core.User, key core.RatingKey, caps core.ClientCaps, release string, wait time.Duration) (*core.PlaySession, error)
	PartSource(viewer int64, client string, key core.RatingKey, release string) PartSource
	ServePartSource(w http.ResponseWriter, r *http.Request, sourceID string)
	ObserveStart(ctx context.Context, source HLSSession, id string) (StartObservation, bool)
	ActivityStore() PlaybackActivityStore
	BindStream(context.Context, SessionAccess, StreamBinding) (int64, error)
	ResolveStream(context.Context, SessionAccess, int64) (StreamBinding, error)
	OpenSidecar(context.Context, SessionAccess, auth.Acceptance, int64) (io.ReadCloser, core.StreamInfo, error)
	NotePlexEncoder(id string, format StreamFormat, decision core.Decision, offset time.Duration)
	PlexSessionForPlayback(ctx context.Context, a SessionAccess, item core.RatingKey, playbackID, transcodeID string) (string, error)
	PlexSessionForSource(ctx context.Context, a SessionAccess, item core.RatingKey, playID string) (string, error)
	PlexSessionSource(id string) (string, bool)
	ReportProgress(ctx context.Context, a SessionAccess, item core.RatingKey, t Timeline) error
	StopPlayback(ctx context.Context, playID string) bool
	StopProtocol(ctx context.Context, protocol Protocol) error
	RecordAuthorizedSubtitleIntent(ctx context.Context, viewer int64, key core.RatingKey, manual bool) error
	ConfirmAdmission(ctx context.Context, viewer *core.Viewer, remote bool) (*core.Viewer, error)
}

SessionRuntime provides the session-backed stores, source preparation, stream bindings, and playback/transcoder runtime for protocol adapters.

type SessionSubtitleArtifacts

type SessionSubtitleArtifacts interface {
	HasAuthoredASSSubtitle(ctx context.Context, access SessionAccess, id string, index int) bool
	ServeASSSubtitle(ctx context.Context, access SessionAccess, id string, index int, syncMS int, requireAuthored bool) (SubtitleASSArtifact, error)
	SubtitleFontBundle(ctx context.Context, access SessionAccess, id string, index int) ([]SubtitleFontBundleItem, error)
	SubtitleFontAttachment(ctx context.Context, access SessionAccess, id string, index int, fontIndex int) (SubtitleFontAttachment, error)
}

SessionSubtitleArtifacts is an optional host capability implemented by Sessions that can inspect and serve embedded ASS/SSA scripts and Matroska font attachments for an active playback session across both direct and HLS deliveries.

type Sessions

type Sessions interface {
	Plan(context.Context, PlanRequest) (PlayPlan, error)
	Open(context.Context, OpenRequest) (Session, error)
	// StartStream revalidates access to the session and returns its scoped URL.
	StartStream(context.Context, SessionAccess, string, StreamRequest) (string, error)
	// SubtitleURL returns a scoped URL for a subtitle stream index and format.
	SubtitleURL(context.Context, SessionAccess, string, int, string) (string, error)
	// Markers returns source-bound ranges for the authorized playback session.
	Markers(context.Context, SessionAccess, string) (SessionMarkers, error)
	// ServeMedia authorizes the scoped grant and serves direct, HLS or DASH data.
	ServeMedia(http.ResponseWriter, *http.Request)
	Report(context.Context, SessionAccess, string, Timeline) error
	Stop(context.Context, SessionAccess, string) error
	Command(context.Context, *core.Viewer, string, Command) error
	UpdateCapabilities(context.Context, SessionAccess, SessionCapabilities) error
	Capabilities(context.Context, SessionAccess) (SessionCapabilities, error)
	Sessions(context.Context, SessionAccess) ([]Session, error)
	Recover(context.Context, string, string, time.Duration) error
	TranscodeFor(context.Context, string) (core.HLSSession, bool)
	TrickplayAvailable(string) bool
	TrickplayBIF(string) ([]byte, bool)
	TrickplayFrame(string, time.Duration) ([]byte, bool)
	CancelTrickplay(string)
	// Events includes events from all cluster nodes, filters by viewer unless owner access is authorized, and ends on cancellation.
	Events(context.Context, EventScope) (<-chan Event, error)
}

Sessions owns playback across protocols. Open revalidates the broker-owned plan, protocol, viewer, device and admission; estimated plans cannot be opened. MediaPath is scoped and unguessable and never contains account credentials.

type Settings

type Settings map[string]any

type SettingsField added in v0.3.3

type SettingsField struct {
	Key     string   `json:"key"`
	Kind    string   `json:"kind"`
	More    bool     `json:"more,omitempty"`
	Min     *int     `json:"min,omitempty"`
	Max     *int     `json:"max,omitempty"`
	Options []string `json:"options,omitempty"`
}

SettingsField is one setting. Kind is one of: serverName (read-only name from General settings), port, bool, number, viewer (the DLNA browse-as picker), rowKinds (personalized row kind switches) or note (static text named by Key, for example "addon", "files" or "playlist").

type SettingsSchema added in v0.3.3

type SettingsSchema struct {
	Sections []SettingsSection `json:"sections"`
	// AccountConnect means devices connect through the viewer account page
	// (an addon address, a files address or a playlist), not a server
	// address on this page.
	AccountConnect bool `json:"accountConnect,omitempty"`
	// SignInHelp shows the "how people sign in" section (Quick Connect and
	// app passwords).
	SignInHelp bool `json:"signInHelp,omitempty"`
}

SettingsSchema describes a frontend's owner-console settings so the Apps page renders them without per-protocol code (WS1d). It carries field keys and kinds only; the console owns the translated copy for each known field key, section key and note key, exactly as it owns page components for descriptor IDs.

func AccountSchema added in v0.3.3

func AccountSchema(note string) SettingsSchema

AccountSchema is a surface with no port of its own; viewers get its address from their account page. note names the console copy.

func DLNASchema added in v0.3.3

func DLNASchema() SettingsSchema

DLNASchema browses the library as one chosen viewer.

func MediaBrowserSchema added in v0.3.3

func MediaBrowserSchema(quickConnect bool) SettingsSchema

MediaBrowserSchema is the settings schema the Jellyfin and Emby frontends share; quickConnect adds Jellyfin's Quick Connect switch.

func NamedServerSchema added in v0.3.3

func NamedServerSchema() SettingsSchema

NamedServerSchema is a server apps find by name and port, with discovery (Silo).

func PortSchema added in v0.3.3

func PortSchema() SettingsSchema

PortSchema is a frontend whose only protocol setting is its port (Plex, whose console settings live on their own page).

type SettingsSection added in v0.3.3

type SettingsSection struct {
	Key    string          `json:"key"`
	Fields []SettingsField `json:"fields"`
}

SettingsSection is one grouped block of fields. Key names the console copy: "find" (how apps find this server), "tv" (what the TV shows), "home" (personalized home rows) or "connect".

type SettingsValidator

type SettingsValidator interface{ ValidateSettings(Settings) error }

SettingsValidator lets a frontend validate its own protocol-specific options. The host also checks common listener options before persistence.

type ShowParentResolver

type ShowParentResolver interface {
	ResolveShowParents(context.Context, []RatingKey) (map[RatingKey]Title, error)
}

ShowParentResolver resolves parent show titles for episodes/seasons in batch.

type Shutdowner

type Shutdowner interface{ Shutdown(context.Context) error }

Shutdowner is optionally implemented by a Frontend that retains process-owned state across mounts so the host can release it once on runtime shutdown.

type SmartPlaylists

type SmartPlaylists interface {
	CreateSmartPlaylist(ctx context.Context, userID int64, title, uri string) (*Playlist, error)
}

SmartPlaylists persists a section query for evaluation at read time.

type SoftSubtitleServer

type SoftSubtitleServer interface {
	ServeSoftSubtitle(http.ResponseWriter, *http.Request, int) bool
}

SoftSubtitleServer serves soft ASS subtitles directly from an active HLS remux session.

type SortOrder

type SortOrder = core.SortOrder

type SortSpec

type SortSpec = core.SortSpec

type Source

type Source = core.Source

Release and variant-resolution values stay owned by core. Adapters describe and label versions through these aliases.

type SourceOffer

type SourceOffer struct {
	ID        string
	ExpiresAt time.Time
	Target    SourceOfferTarget
}

type SourceOfferTarget

type SourceOfferTarget struct {
	Item          RatingKey
	VersionHandle string
	DetailSource  string
	ETag          string
}

SourceOfferTarget contains one exact scoped selector, never an upstream ID. A resolved detail selector also carries its immutable source revision.

type SourceOffers

SourceOffers maps scoped selectors to bounded, expiring numeric protocol IDs. IDs are never credentials and must be resolved under current viewer policy.

type SourceRestorer

type SourceRestorer interface {
	RestoreSource(context.Context, string, core.PlaySession) error
}

SourceRestorer restores a PlaySession snapshot on a node after failover.

type StartGuard

type StartGuard interface {
	Observe(tid, state string, offset, ahead time.Duration, now time.Time) bool
	Forget(tid string)
	Remember(k StartHintKey, now time.Time)
	BaseOnly(k StartHintKey, now time.Time) bool
	Expire(now time.Time)
}

StartGuard watches stalled playback starts and start hints.

type StartHintKey

type StartHintKey struct {
	UserID   int64
	ClientID string
	Key      core.RatingKey
}

StartHintKey names one remembered fallback. A title Key is the Dolby Vision HDR10-base hint for that title; a zero Key is client-wide: this viewer's client stalled on surround audio copied into segmented output.

type StartObservation

type StartObservation interface {
	core.PlaybackPosition
	Decision() core.Decision
	Info() core.MediaInfo
}

StartObservation is the evidence used by stalled-start detection.

type State

type State = core.State

type StatisticsAccountRef

type StatisticsAccountRef struct {
	ID   int64
	Name string
}

StatisticsAccountRef labels an account id on a statistics page.

type StatisticsBandwidthRow

type StatisticsBandwidthRow struct {
	AccountID int64
	DeviceID  int64
	Timespan  int
	At        int64
	Lan       int
	Bytes     int64
}

StatisticsBandwidthRow is one StatisticsBandwidth series point.

type StatisticsDevice

type StatisticsDevice struct {
	ID               int64
	ClientIdentifier string
	Name             string
	Platform         string
	CreatedAt        int64
}

StatisticsDevice is one client the Dashboard can name.

type StatisticsMediaRow

type StatisticsMediaRow struct {
	AccountID    int64
	DeviceID     int64
	Timespan     int
	At           int64
	MetadataType int
	Count        int64
	Duration     int64 // sum of item lengths in seconds
}

StatisticsMediaRow is one StatisticsMedia series point.

type StatisticsPage

type StatisticsPage struct {
	Rows      []StatisticsBandwidthRow
	Media     []StatisticsMediaRow
	Devices   []StatisticsDevice
	Accounts  []StatisticsAccountRef
	TotalSize int
}

StatisticsPage is one statistics answer: the series window and the StatisticsDevice/Account lookup for ids that window names.

type StatisticsQuery

type StatisticsQuery struct {
	Timespans                     []int
	AccountID                     int64
	DeviceID                      int64
	HasAccount, HasDevice, HasLan bool
	Lan                           int
	AtMin, AtMax                  int64
	ExactAt                       int64
	HasExact, HasAtMin, HasAtMax  bool
	Offset                        int
	Limit                         int
	HasLimit                      bool
	Sort                          string
	Desc                          bool
}

StatisticsQuery is the parsed Dashboard filter. Timespans empty means "every kept rollup except per-second" for bandwidth/media (0..4).

type Status

type Status struct {
	Mounted          bool      `json:"mounted"`
	Addresses        []string  `json:"addresses"`
	ConnectURLs      []string  `json:"connectUrls,omitempty"`
	LAN              string    `json:"lan"`
	LANReason        string    `json:"lanReason,omitempty"`
	LANCheckedAt     time.Time `json:"lanCheckedAt,omitzero"`
	WAN              string    `json:"wan"`
	WANReason        string    `json:"wanReason,omitempty"`
	WANAddress       string    `json:"wanAddress,omitempty"`
	WANCheckedAt     time.Time `json:"wanCheckedAt,omitzero"`
	Clients24h       int       `json:"clients24h"`
	Clients24hKnown  bool      `json:"clients24hKnown"`
	LiveStreams      int       `json:"liveStreams"`
	LiveStreamsKnown bool      `json:"liveStreamsKnown"`
	TargetVersion    string    `json:"targetVersion"`
	Conformance      string    `json:"conformance"`
	Error            string    `json:"error,omitempty"`
	Warnings         []string  `json:"warnings,omitempty"`
}

type StoredTitleLookup

type StoredTitleLookup interface {
	StoredTitle(context.Context, RatingKey) (*Title, error)
}

StoredTitleLookup reads local metadata without remote discovery. Callers must apply their own authorization before exposing the returned title.

type StoredTitlePreloader

type StoredTitlePreloader interface {
	PreloadStored(context.Context, []RatingKey)
}

StoredTitlePreloader warms stored titles into the local title cache in one batch.

type StreamBinding

type StreamBinding struct {
	WireID    int64
	SessionID string
	Key       core.RatingKey
	Index     int
	Info      core.StreamInfo
}

StreamBinding is one Plex-visible stream id. WireID is zero on bind; BindStream assigns it. SessionID is empty for library metadata and is the broker session id after Open.

type StreamFormat

type StreamFormat string
const (
	StreamDirect StreamFormat = "direct"
	StreamHLS    StreamFormat = "hls"
	StreamDASH   StreamFormat = "dash"
	StreamHTTP   StreamFormat = "http"
)

type StreamGrantBinding

type StreamGrantBinding = streamgrant.GrantBinding

type StreamInfo

type StreamInfo = core.StreamInfo

type StreamRequest

type StreamRequest struct {
	Format          StreamFormat
	Position        time.Duration
	SegmentDuration time.Duration
}

StreamRequest describes output, not an upstream URL or credential. The broker owns the input, decision and stream grant.

type StringFilter

type StringFilter = core.StringFilter

type Subscriber

type Subscriber interface {
	Subscribe(context.Context, EventScope) (<-chan Event, error)
}

Subscriber delivers events across nodes until the context is cancelled.

type SubtitleASSArtifact

type SubtitleASSArtifact struct {
	Data     []byte
	Authored bool
}

SubtitleASSArtifact contains rendered or extracted ASS/SSA bytes and reports whether full authored styling was preserved from the source container.

type SubtitleCatalog

type SubtitleCatalog interface {
	Enabled() bool
	Search(context.Context, *core.Viewer, core.Device, core.RatingKey, string) ([]SubtitleOffer, error)
	Download(context.Context, *core.Viewer, core.Device, core.RatingKey, string) (int, error)
	OpenFormat(id, format string) (io.ReadCloser, string, error)
	OpenFormatFrom(id, format, source string) (io.ReadCloser, string, error)
	CachedSidecars(ctx context.Context, t *Title, u *User, embedded []StreamInfo) []StreamInfo
	SearchSubtitles(ctx context.Context, t *Title, u *User, lang, release string) ([]SubtitleSearchOffer, error)
	DownloadSubtitle(ctx context.Context, t *Title, u *User, id int64) (StreamInfo, error)
	UploadSubtitle(ctx context.Context, t *Title, u *User, filename, format, language string, body []byte) (StreamInfo, error)
	DeleteSubtitle(ctx context.Context, key RatingKey, u *User, stream StreamInfo) error
}

SubtitleCatalog searches and downloads sidecars. Download fetches only an offer Search returned for that title. It does not prefetch.

type SubtitleExtractor

type SubtitleExtractor interface {
	ExtractSubtitle(ctx context.Context, inputURL string, streamIndex int, codec string, w io.Writer) error
}

SubtitleExtractor extracts one embedded subtitle stream to a writer.

type SubtitleFontAttachment

type SubtitleFontAttachment struct {
	Index    int
	Name     string
	MIMEType string
	Data     []byte
}

SubtitleFontAttachment is a binary Matroska font attachment for an ASS/SSA subtitle stream.

type SubtitleFontBundleItem

type SubtitleFontBundleItem struct {
	Name string `json:"name"`
	Data string `json:"data"`
}

SubtitleFontBundleItem is a base64-encoded font attachment returned in a subtitle font bundle response.

type SubtitleOffer

type SubtitleOffer struct {
	ID, Language, Name, Provider, Format, Author     string
	Downloads                                        int
	Rating                                           float64
	HearingImpaired, Forced, HashMatch, AITranslated bool
}

SubtitleOffer is one subtitle search result. ID is the only value a later Download accepts, and only for the title Search returned it for.

type SubtitleSearchOffer

type SubtitleSearchOffer struct {
	ID              int64  // provider file id, passed back to DownloadSubtitle
	Language        string // ISO 639-1
	Title           string // release or file name
	Provider        string // "OpenSubtitles"
	Score           int
	HearingImpaired bool
	Forced          bool
	PerfectMatch    bool // matched the playing file's hash or release
}

SubtitleSearchOffer is one subtitle search result.

type SubtitleSidecarCatalog

type SubtitleSidecarCatalog interface {
	CachedSidecars(ctx context.Context, t *Title, u *User, embedded []StreamInfo) []StreamInfo
}

SubtitleSidecarCatalog is optionally implemented by Host.Subtitles: the sidecars already cached for a title and viewer, without network access, skipping streams embedded already lists (by ExternalURL) or covers (by language).

type SubtitleSidecarSearch

type SubtitleSidecarSearch interface {
	SearchSubtitles(ctx context.Context, t *Title, u *User, lang, release string) ([]SubtitleSearchOffer, error)
	// DownloadSubtitle fetches an offer returned by SearchSubtitles for t
	// and returns its sidecar stream; ErrNotFound for unknown offers.
	DownloadSubtitle(ctx context.Context, t *Title, u *User, id int64) (StreamInfo, error)
}

SubtitleSidecarSearch is optionally implemented by Host.Subtitles: on-demand subtitle search and pick returning a sidecar stream.

type SubtitleSidecarSource

type SubtitleSidecarSource interface {
	OpenFormat(string, string) (io.ReadCloser, string, error)
}

SubtitleSidecarSource resolves cached OpenSubtitles and synchronized sidecars.

type SubtitleSidecarUpload

type SubtitleSidecarUpload interface {
	UploadSubtitle(ctx context.Context, t *Title, u *User, filename, format, language string, body []byte) (StreamInfo, error)
}

SubtitleSidecarUpload is optionally implemented by Host.Subtitles: viewer-uploaded sidecar subtitles.

type SupportVisibilityCatalog

type SupportVisibilityCatalog interface {
	SupportVisibility(context.Context, RatingKey) (*Title, string, error)
}

SupportVisibilityCatalog reads a title and its visibility diagnostic state for support capture.

type SurfaceIdentity

type SurfaceIdentity interface {
	Resolve(context.Context, string) (*core.Viewer, error)
	// ViewerTimes revalidates the surface credential and allows only the same
	// viewer or an active owner to read another active viewer's timestamps.
	ViewerTimes(context.Context, string, int64) (ViewerTimes, error)
	PublicViewers(context.Context) ([]PublicViewer, error)
	SignIn(context.Context, string, string, core.Device) (string, error)
	IssueRefresh(context.Context, string, core.Device) (string, error)
	Refresh(context.Context, string, core.Device) (string, string, error)
	QuickConnectInitiate(context.Context, core.Device) (code, secret string, err error)
	QuickConnectStatus(context.Context, string) (approved bool, err error)
	QuickConnectDetails(context.Context, string) (QuickConnectDetails, error)
	QuickConnectPoll(context.Context, string) (string, error)
	QuickConnectApprove(context.Context, *core.Viewer, string) error
	Revoke(context.Context, string) error
	SetupComplete() bool
	Accept(context.Context, string) (*core.Viewer, CredentialAcceptance, error)
	ReceiptCurrent(context.Context, CredentialAcceptance) error
	IssueDelegation(context.Context, int64) (string, error)
	ActiveUser(context.Context, int64) (*core.User, error)
	Users(context.Context) ([]core.User, error)
}

SurfaceIdentity is bound to one protocol by the host factory. Quick Connect approval requires a viewer obtained from a successfully authenticated session; frontends must not construct a viewer from untrusted request data.

func BindAuth

func BindAuth(auth core.Auth) SurfaceIdentity

BindAuth adapts a core.Auth into a SurfaceIdentity for standalone servers and tests.

func BindIdentity

func BindIdentity(resolver core.Identity, surface Protocol) SurfaceIdentity

BindIdentity prevents a frontend from choosing a different authentication surface.

type Ticket

type Ticket struct {
	Viewer *Viewer
	Device Device
	// SourceHash identifies the issuing grant for host-side revalidation only.
	SourceHash string
}

Ticket is a one-use, purpose-bound authorization for a realtime handshake.

type Tickets

type Tickets interface {
	Issue(context.Context, string, Device, string) (string, error)
	Consume(context.Context, string, string) (Ticket, error)
	Active(context.Context, Ticket) (bool, error)
}

type Timeline

type Timeline struct {
	// Observed track indices are presence-aware client telemetry, not proof of
	// manual intent. In particular Jellyfin Web emits ordinary timeupdate events.
	AudioStreamIndex, SubtitleStreamIndex *int

	// PlaybackID may be empty for clients that do not send one. The broker
	// preserves its no-ID supersession semantics.
	PlaybackID      string
	ClientSessionID string
	// Sequence is optional; zero preserves the legacy unordered behavior.
	Sequence           uint64
	Position, Duration time.Duration
	State              string
}

type TimelinePersistenceResult

type TimelinePersistenceResult struct {
	PlaybackState      string
	ViewOffset         time.Duration
	ViewCount          int
	Changed, Completed bool
}

TimelinePersistenceResult describes committed state, rather than echoing a client's playhead.

func StoreTimeline

func StoreTimeline(ctx context.Context, writer TimelineWriter, now func() time.Time, restoreContinue func(context.Context, int64, core.RatingKey) error, user int64, key core.RatingKey, offset, duration time.Duration, status, queue string, offline *int) (context.Context, *TimelinePersistenceResult, error)

StoreTimeline persists one timeline report through the host writer and restores continuation only when persistence changed.

type TimelineWriter

type TimelineWriter interface {
	StoreTimeline(context.Context, int64, RatingKey, time.Duration, time.Duration, string, string, *int) (TimelinePersistenceResult, error)
}

type Title

type Title = core.Title

func LoadSeriesNextUp

func LoadSeriesNextUp(ctx context.Context, exp Experience, viewer *Viewer, device Device, series RatingKey, resumable bool) (*Title, error)

LoadSeriesNextUp loads one series' episodes through exp.Children and selects the next episode. Children is invoked only with that series key.

func SeriesNextUp

func SeriesNextUp(eps []Title, st map[RatingKey]WatchStatus, series RatingKey, resumable bool, unavailable func(*Title) bool) *Title

SeriesNextUp selects that series' next regular episode. Specials are skipped. When resumable, an in-progress episode wins; otherwise the first unwatched episode after the last completed one is returned, or S1E1 when none are watched. Episodes of any other series are ignored.

type TitleFacts

type TitleFacts = core.TitleFacts

type TitleOpenabilityCatalog

type TitleOpenabilityCatalog interface {
	TitleOpenable(*Title) bool
}

TitleOpenabilityCatalog reports whether a title's stored facts allow opening it.

type TitlePoster

type TitlePoster = artwork.TitlePoster

TitlePoster describes an Ether-generated fallback poster for a title.

type TitlePosterRenderer

type TitlePosterRenderer interface {
	Title(ctx context.Context, p TitlePoster) ([]byte, string, error)
}

TitlePosterRenderer renders Ether's fallback poster for a title with no artwork.

type TouchableSession

type TouchableSession interface {
	Touch()
}

TouchableSession refreshes an active transcode session's idle timer.

type TrackPreferencePatch

type TrackPreferencePatch struct {
	AudioLanguages, SubtitleLanguages *[]string
	SubtitleMode                      *string
	SubtitleAppearance                *json.RawMessage
	MaxBitrateKbps                    *int
	MaxHeight                         *int
	PreferredQuality                  *string
}

type TrackPreferenceSelector

type TrackPreferenceSelector interface {
	Select(ctx context.Context, viewer *core.User, key core.RatingKey, info core.MediaInfo, original string, selected TrackSelection) (TrackSelection, error)
	AudioFilters(ctx context.Context, viewer *core.User, info core.MediaInfo, selected TrackSelection) ([]string, error)
	SelectScoped(ctx context.Context, viewer *core.User, key core.RatingKey, info core.MediaInfo, original string, scope TrackScope, selected TrackSelection, scopedError func(error)) (TrackSelection, error)
	ScopedLimits(ctx context.Context, viewer *core.User, scope TrackScope, opts core.DecideOptions) (core.DecideOptions, error)
}

TrackPreferenceSelector applies persisted track choices beneath explicit client choices. (TrackPreferences in this package is the values struct.)

type TrackPreferenceSelectorOptions

type TrackPreferenceSelectorOptions struct {
	Source   TrackPreferenceSource
	GetTitle func(context.Context, core.RatingKey) (*core.Title, error)
}

TrackPreferenceSelectorOptions configures a TrackPreferenceSelector.

type TrackPreferenceService

type TrackPreferenceService interface {
	PlaybackTrackPreferences
	Get(context.Context, *Viewer) (TrackPreferences, error)
	SetSubtitle(context.Context, *Viewer, []string, string) error
}

type TrackPreferenceSource

type TrackPreferenceSource interface {
	Select(context.Context, int64, core.RatingKey, core.MediaInfo, string) (trackprefs.Selection, error)
	GetRules(context.Context, int64) (trackprefs.Rules, error)
}

TrackPreferenceSource supplies persisted viewer rules and show choices.

type TrackPreferences

type TrackPreferences struct {
	AudioLanguages, SubtitleLanguages []string
	SubtitleMode                      string
	PreferOriginal                    bool
	SubtitleAppearance                json.RawMessage
}

type TrackScope

type TrackScope struct{ Device, Series, Library string }

type TrackSelection

type TrackSelection struct {
	Audio, Subtitle       int
	AudioSet, SubtitleSet bool
}

TrackSelection holds positions in MediaInfo.Streams, not StreamInfo.Index. Set flags distinguish an omitted selection from position zero, and an explicit subtitle-off selection (-1) from an omitted subtitle choice.

func TranslatePlexTrackIdentity

func TranslatePlexTrackIdentity(issued IssuedTrackIdentity, probed core.MediaInfo) (TrackSelection, error)

TranslatePlexTrackIdentity maps an issued Plex selection onto the current probed MediaInfo the way plex resolvePlaySelection does, before viewer preferences and before applySelections.

A nil audio identity leaves AudioPosition unchanged, including when it is negative, out of range, or not an audio stream. Preferences still see a nonnegative legacy position as set. A non-nil audio identity is passed to ResolveAudio only when that position is nonnegative. An unmatched result is position -1 and AudioSet false so preferences can run. The identity's Type is not rechecked.

A nil subtitle identity leaves SubtitleSet and SubtitlePosition unchanged. SubtitleSet false becomes position -1. A non-nil subtitle identity is passed to ResolveSubtitle only when SubtitleSet is true. An unmatched result is position -1 and SubtitleSet false. Type is not rechecked.

The result positions are indexes in probed.Streams. Encoder indexes still come from the selected StreamInfo.Index.

type TranscodeCapacityError

type TranscodeCapacityError struct {
	RetryAfter time.Duration
	Cause      error
}

TranscodeCapacityError carries a suggested retry delay. Capacity is checked atomically at stream start and is not reserved by an earlier Plan.

func (*TranscodeCapacityError) Error

func (e *TranscodeCapacityError) Error() string

func (*TranscodeCapacityError) Is

func (e *TranscodeCapacityError) Is(target error) bool

func (*TranscodeCapacityError) Unwrap

func (e *TranscodeCapacityError) Unwrap() error

type TranscodePolicy

type TranscodePolicy = transcode.Policy

type Transcoder

type Transcoder = core.Transcoder

type TreeScrobbler

type TreeScrobbler interface {
	ScrobbleTree(context.Context, int64, RatingKey, []RatingKey, bool) error
}

TreeScrobbler marks a title and its descendants watched or unwatched while keeping parent counters independent of leaf totals.

type TrickplayCanceler

type TrickplayCanceler interface{ CancelTrickplay(string) }

TrickplayCanceler is the optional capability that cancels preview work for a trickplay cache key.

type TrickplayOffer

type TrickplayOffer struct {
	Width, Height int
	Columns, Rows int
	Count         int
	Interval      time.Duration
	Bandwidth     int
}

TrickplayOffer is Jellyfin sprite geometry for one generated width. Width and Height are one thumbnail in pixels. Columns and Rows are the grid inside each sheet. Interval is the time between thumbnails.

type TrickplayProvider

type TrickplayProvider = core.TrickplayProvider

type TrickplayTiles

type TrickplayTiles interface {
	TrickplayOffer(context.Context, SessionAccess, core.RatingKey) (TrickplayOffer, bool)
	TrickplaySheet(context.Context, SessionAccess, core.RatingKey, int) ([]byte, error)
}

TrickplayTiles serves preview sheets for an item the viewer may play. The broker owns release identity and generation. A false offer means no frame exists yet, which clients render as an empty trickplay map.

type UncachedError

type UncachedError = core.UncachedError

type UndatedSearchHitCatalog

type UndatedSearchHitCatalog interface {
	UndatedSearchHit(context.Context, RatingKey) bool
}

UndatedSearchHitCatalog reports whether a key corresponds to an undated search hit.

type UnsupportedPlexTrackIdentityError

type UnsupportedPlexTrackIdentityError struct {
	Reason string
}

UnsupportedPlexTrackIdentityError means the issued selection is not a shape plex resolvePlaySelection produces. Callers must handle it themselves. The returned TrackSelection is empty and must not be applied. Every value of this type matches errors.Is, whatever Reason is set.

func (UnsupportedPlexTrackIdentityError) Error

func (UnsupportedPlexTrackIdentityError) Is

type UntrustedImageFetcher

type UntrustedImageFetcher interface {
	GetUntrustedURL(ctx context.Context, rawURL string) ([]byte, string, error)
}

UntrustedImageFetcher fetches an untrusted remote image URL.

func NewUntrustedImageFetcher

func NewUntrustedImageFetcher(client *http.Client) UntrustedImageFetcher

NewUntrustedImageFetcher constructs an untrusted remote image fetcher.

type User

type User = core.User

type UserListSource

type UserListSource interface {
	Users(context.Context) ([]User, error)
}

UserListSource is the optional household account list an identity surface may expose to owner-level endpoints.

type UserPolicySource

type UserPolicySource interface{ UserPolicy(*User) *User }

UserPolicySource is the optional per-viewer policy view an access policy may expose. It returns the user as policy currently sees them.

type VariantIDs

type VariantIDs interface {
	IDFor(key core.RatingKey, releaseID string) int64
	Lookup(id int64) (VariantRef, bool)
	Start(ctx context.Context, wg *sync.WaitGroup)
	Flush(ctx context.Context) error
	Prune(ctx context.Context, liveIDs []int64, liveRefs []VariantRef) (int64, error)
}

VariantIDs assigns stable ids to release variants.

type VariantRef

type VariantRef struct {
	Key       core.RatingKey
	ReleaseID string
}

type VariantResolver

type VariantResolver = core.VariantResolver

type Version

type Version struct {
	ID, Name string
	// Edition is the release's named cut when the catalogue recorded one.
	Edition string
	// AddedAt follows date added. Movies and episodes use their own release
	// or air date. Series and seasons use the latest aired episode, then
	// the premiere. It is not a catalogue insertion, observation, or refresh.
	AddedAt time.Time
	Media   core.MediaInfo
	// Markers are ranges for this version's probed timeline. Nil means the
	// version has no separate timeline yet; a detail-level marker set is not
	// a substitute when several files are present.
	Markers []Marker
	// Source facts are absent unless they are known for this version. FileName
	// is a basename only; DateModified is never a catalogue fallback date.
	FileName     string     `json:"fileName,omitempty"`
	PartCount    *int       `json:"partCount,omitempty"`
	ETag         string     `json:"etag,omitempty"`
	DateModified *time.Time `json:"dateModified,omitempty"`
	PublishedAt  *time.Time `json:"publishedAt,omitempty"`
}

type VersionFlowKey

type VersionFlowKey struct {
	UserID   int64
	ClientID string
	Key      core.RatingKey
}

VersionFlowKey scopes issued versions to one viewer, client and title.

type VersionFlows

type VersionFlows interface {
	Call(ctx context.Context, k VersionFlowKey, vs []core.ReleaseVariant, mode int, now time.Time, ttl time.Duration) (VersionSnapshot, error)
	Run()
}

VersionFlows stores version-picker flow snapshots.

type VersionHandleBatch

type VersionHandleBatch interface {
	IssueBatch(context.Context, VersionScope, core.RatingKey, []string) (map[string]string, error)
}

VersionHandleBatch is an optional bounded batch capability. It validates the whole requested offer set once and issues all handles atomically.

type VersionHandles

type VersionHandles interface {
	Issue(context.Context, VersionScope, core.RatingKey, string) (string, error)
	Resolve(context.Context, VersionScope, string) (VersionTarget, error)
	// MatchSession verifies that a scoped handle denotes the source bound to
	// this authenticated local playback session.
	MatchSession(context.Context, VersionScope, string, string) error
}

type VersionScope

type VersionScope struct {
	Viewer   *core.Viewer
	Device   core.Device
	Protocol Protocol
	Caps     core.ClientCaps
}

VersionScope binds a version handle to an authenticated viewer, surface, device and host-built client capabilities. It grants no playback by itself.

type VersionSnapshot

type VersionSnapshot struct {
	Variants []core.ReleaseVariant
	Frozen   bool
	Until    time.Time
}

type VersionTarget

type VersionTarget struct {
	Item core.RatingKey
	// Release is the candidate id stored with the handle. Empty when the
	// handle was resolved by an older caller that only needed the parent.
	Release string
}

VersionTarget is the authorized parent associated with an opaque handle. A caller must still open playback and revalidate the selected source.

type VersionedPreferences

type VersionedPreferences interface {
	GetVersioned(context.Context, *core.Viewer, string, string) (json.RawMessage, int64, time.Time, error)
	PutVersioned(context.Context, *core.Viewer, string, string, json.RawMessage) (int64, time.Time, error)
}

VersionedPreferences provides cluster-safe per-record revisions for wire contracts that require a revision to advance on every write.

type VibeSearcher

type VibeSearcher interface {
	VibeCollection(ctx context.Context, user *User, query string) (c *Collection, items []Title, ok bool, err error)
	PromoteEphemeral(ctx context.Context, user *User, key RatingKey) (c *Collection, ok bool, err error)
}

VibeSearcher builds ephemeral collections from a natural-language query and promotes them to persisted personal smart collections.

type VibeSource

type VibeSource interface {
	VibeCollection(context.Context, *core.User, string) (*core.Collection, []core.Title, bool, error)
}

VibeSource returns a viewer-scoped ephemeral collection and candidate items.

type View

type View struct {
	ID   string
	Name string
	Type core.MediaType
	// Virtual is true only when the host asserts this library has no physical
	// locations. False means the host did not assert virtual origin.
	Virtual bool
	// LibraryID is the stable integer identity in the libraries store.
	LibraryID core.LibraryID
	// KindKey and PluginID are set for plugin-provided libraries (empty for
	// built-in and filter libraries).
	KindKey  string
	PluginID string
	// Native is the protocol-native presentation string on the bound protocol
	// (for example, MediaBrowser CollectionType or Plex base type).
	Native string
}

type Viewer

type Viewer = core.Viewer

Protocol adapters use these aliases to exchange host values without importing domain packages directly. Their implementations remain owned by core.

func AuthenticateStreamGrant

func AuthenticateStreamGrant(ctx context.Context, method, token string, binding StreamGrantBinding, active func(context.Context, int64) *Viewer) (*Viewer, bool)

AuthenticateStreamGrant verifies the bound media capability and rechecks the active viewer for each request, including already-cached media.

type ViewerCapabilities

type ViewerCapabilities struct {
	IsOwner           *bool     `json:"isOwner,omitempty"`
	CanPlayRemote     *bool     `json:"canPlayRemote,omitempty"`
	CanPlay           *bool     `json:"canPlay,omitempty"`
	RemoteBitrateKbps *int      `json:"remoteBitrateKbps,omitempty"`
	CanTranscode      *bool     `json:"canTranscode,omitempty"`
	CanTranscodeAudio *bool     `json:"canTranscodeAudio,omitempty"`
	CanTranscodeVideo *bool     `json:"canTranscodeVideo,omitempty"`
	CanRemux          *bool     `json:"canRemux,omitempty"`
	CanUseLiveTV      *bool     `json:"canUseLiveTV,omitempty"`
	CanManageLiveTV   *bool     `json:"canManageLiveTV,omitempty"`
	HasLocalPassword  *bool     `json:"hasLocalPassword,omitempty"`
	AllowedLibraries  *[]View   `json:"allowedLibraries,omitempty"`
	MaxRating         *string   `json:"maxRating,omitempty"`
	CanDownload       *bool     `json:"canDownload,omitempty"`
	MaxActiveSessions *int      `json:"maxActiveSessions,omitempty"`
	BlockedTags       *[]string `json:"blockedTags,omitempty"`
	PeerRemote        *bool     `json:"peerRemote,omitempty"`
}

ViewerCapabilities are informational only. Nil fields are unknown; all operations remain subject to their authoritative policy checks.

type ViewerCapabilitiesFunc

type ViewerCapabilitiesFunc func(context.Context, *Viewer, Device, netip.Addr) (ViewerCapabilities, error)

ViewerCapabilitiesFunc receives a verified network peer, never a client-supplied forwarding value.

type ViewerDiagnostics

type ViewerDiagnostics interface {
	SupportViewer(context.Context, *core.User) (diagnostics.ViewerFacts, error)
}

ViewerDiagnostics is optionally implemented by a mounted Instance that contributes protocol-specific viewer facts to owner support bundles.

type ViewerPolicy

type ViewerPolicy interface {
	AccessPolicy
	SetMaxRating(context.Context, *Viewer, string) error
}

ViewerPolicy evaluates and mutates household policy with host-side authorization.

type ViewerTimes

type ViewerTimes struct {
	LastLogin, LastActivity time.Time
}

ViewerTimes contains observed events; a zero time means unknown.

type VirtualPaths

type VirtualPaths interface {
	Path(context.Context, *Viewer, Device, RatingKey) (string, error)
	// Paths resolves at most 50 distinct keys (256 input entries), omitting
	// hidden or unsupported items and sharing viewer-scoped library scans.
	Paths(context.Context, *Viewer, Device, []RatingKey) (map[RatingKey]string, error)
	// Base returns the verified reachable WebDAV base URL, or an error when
	// WebDAV is disabled or unreachable for the requesting client.
	Base(context.Context, *http.Request) (string, error)
}

VirtualPaths resolves a viewer-authorized item to the same relative path used by the WebDAV tree, including stable collision disambiguation.

type Visibility

type Visibility struct {
	Policy          AccessPolicy
	SectionFor      func(core.MediaType) (int, bool)
	GetTitle        func(context.Context, core.RatingKey) (*core.Title, error)
	FilterAvailable func(context.Context, []core.Title) []core.Title
	// JudgedOnFacts returns, for one request, whether FilterAvailable judges
	// a title on its full facts rather than its row. Nil with FilterAvailable
	// set means every title may be.
	JudgedOnFacts func(context.Context) func(core.Title) bool
	Sessions      func() []*core.PlaySession
}

Visibility applies content, library and inherited show restrictions. The section lookup returns false for media types with no configured library.

func (Visibility) Available

func (v Visibility) Available(ctx context.Context, viewer *core.User, titles []core.Title) []core.Title

Available filters discovery evidence, retaining a viewer's open sources. Callers must separately enforce title policy.

func (Visibility) CollectionAllowed

func (v Visibility) CollectionAllowed(viewer *core.User, c *core.Collection) bool

CollectionAllowed checks the library restriction for a collection.

func (Visibility) FactJudge

func (v Visibility) FactJudge(ctx context.Context) (func(core.Title) bool, bool)

FactJudge is JudgedOnFacts for one request: nil when no title is, false when the visibility cannot tell.

func (Visibility) Playable

func (v Visibility) Playable(ctx context.Context, viewer *core.User, title *core.Title) bool

Playable checks inherited show policy without requiring discovery evidence.

func (Visibility) TitleAllowed

func (v Visibility) TitleAllowed(viewer *core.User, title *core.Title) bool

func (Visibility) TitleFacts

func (v Visibility) TitleFacts(viewer *core.User) core.TitleFacts

TitleFacts is what the access policy reads of a title beyond its row for viewer (core.TitleFacts). A policy that does not say may read any of them.

func (Visibility) TitlesAllowed

func (v Visibility) TitlesAllowed(viewer *core.User, titles []core.Title) []core.Title

TitlesAllowed filters the title/section guard without discovery filtering.

func (Visibility) UpcomingItems

func (v Visibility) UpcomingItems(ctx context.Context, viewer *core.User, items []core.Title, now func() time.Time) []core.Title

UpcomingItems retains the existing placeholder discovery rules for a page.

func (Visibility) Visible

func (v Visibility) Visible(ctx context.Context, viewer *core.User, title *core.Title) bool

Visible includes availability in addition to the playback policy.

type VisibilityRowsCatalog

type VisibilityRowsCatalog interface {
	CachedVisibilityRows(context.Context, []RatingKey, TitleFacts) (map[RatingKey]Title, error)
}

VisibilityRowsCatalog reads mirrored visibility rows with requested facts in one batch.

type WarmProbeControl

type WarmProbeControl interface {
	ParitySettlePending(context.Context) error
	ParitySettleWarm(context.Context, *core.Viewer, core.RatingKey, core.ClientCaps) error
	ParityProbeNow(context.Context, *core.Viewer, core.RatingKey, core.ClientCaps) error
}

WarmProbeControl settles or triggers detail warm-up probes on a Playback manager.

type WarmProbeWaiter

type WarmProbeWaiter interface {
	WaitWarmProbe(ctx context.Context, user *User, caps ClientCaps, key RatingKey, budget time.Duration) (MediaInfo, bool)
}

WarmProbeWaiter waits up to a bounded budget for an already-scheduled warm probe to finish.

type WarmProber

type WarmProber interface {
	WarmProbeInfo(user *User, caps ClientCaps, key RatingKey) (MediaInfo, bool)
}

WarmProber returns the probed media info a completed warm-up already produced for this user, client and title.

type WatchOrigin

type WatchOrigin struct {
	HistoryTitle        *Title
	Surface             Protocol
	SessionID, ClientID string
	DeviceID            int64
}

WatchOrigin identifies the authenticated surface and client responsible for a watch update. HistoryTitle retains display identity after catalogue removal.

func WatchOriginFrom

func WatchOriginFrom(ctx context.Context) WatchOrigin

type WatchPage

type WatchPage = core.WatchPage

type WatchParty

WatchParty is the shared party engine. Silo and Jellyfin adapters translate their own protocols onto it. A nil host field means the feature is off.

type WatchRefreshSubscriber

type WatchRefreshSubscriber func(refresh func(viewerID int64, key RatingKey), explicitOnly bool) (close func())

WatchRefreshSubscriber subscribes a mounted frontend to committed changes that invalidate viewer metadata. Closing must fence in-flight callbacks. explicitOnly excludes playback progress/completion refreshes for fixtures.

type WatchStatus

type WatchStatus = core.WatchStatus

Directories

Path Synopsis
Package compactids allocates durable compact protocol identifiers.
Package compactids allocates durable compact protocol identifiers.
Package frontendtest supplies configurable fakes for protocol implementations.
Package frontendtest supplies configurable fakes for protocol implementations.
kit
authhdr
Package authhdr parses client authentication headers without exposing tokens in URLs.
Package authhdr parses client authentication headers without exposing tokens in URLs.
caps
Package caps builds neutral client capabilities from protocol profiles.
Package caps builds neutral client capabilities from protocol profiles.
clientnet
Package clientnet classifies authenticated frontend peer and proxy addresses.
Package clientnet classifies authenticated frontend peer and proxy addresses.
conformance
Package conformance reads release-generated, embedded protocol evidence.
Package conformance reads release-generated, embedded protocol evidence.
faillog
Package faillog logs a repeating background failure (a heartbeat or sync loop that cannot reach the database) without flooding the log: the first failure is logged at WARN, later ones are summarised at most once per interval, and the recovery is logged once at INFO.
Package faillog logs a repeating background failure (a heartbeat or sync loop that cannot reach the database) without flooding the log: the first failure is logged at WARN, later ones are summarised at most once per interval, and the recovery is logged once at INFO.
hls
Package hls writes token-free playlists under random session paths.
Package hls writes token-free playlists under random session paths.
homefilter
Package homefilter shares bounded discovery suitability checks during one multi-request Home load.
Package homefilter shares bounded discovery suitability checks during one multi-request Home load.
ids
Package ids provides stable, stateless protocol identifiers.
Package ids provides stable, stateless protocol identifiers.
images
Package images contains protocol-independent artwork helpers.
Package images contains protocol-independent artwork helpers.
language
Package language exposes the shared language-tag validation to frontends.
Package language exposes the shared language-tag validation to frontends.
libpath
Package libpath defines the shared virtual library names exposed by clients.
Package libpath defines the shared virtual library names exposed by clients.
listcache
Package listcache keeps whole-library listings encoded on disk, so a protocol whose clients download a library in one response (Xtream's get_vod_streams) streams a file instead of reading, authorizing, signing and encoding the library again.
Package listcache keeps whole-library listings encoded on disk, so a protocol whose clients download a library in one response (Xtream's get_vod_streams) streams a file instead of reading, authorizing, signing and encoding the library again.
lru
Package lru provides a least-recently-used cache bounded by entry count and total cost.
Package lru provides a least-recently-used cache bounded by entry count and total cost.
mediasafety
Package mediasafety isolates untrusted media from the console origin.
Package mediasafety isolates untrusted media from the console origin.
paging
Package paging applies bounded offset/limit windows without integer overflow.
Package paging applies bounded offset/limit windows without integer overflow.
quality
Package quality exposes the transcoder's published H.264 rung targets without a frontend importing the transcoder.
Package quality exposes the transcoder's published H.264 rung targets without a frontend importing the transcoder.
reqmemo
Package reqmemo memoizes point reads for the length of one read request.
Package reqmemo memoizes point reads for the length of one read request.
route
Package route provides an enumerable case-insensitive protocol router.
Package route provides an enumerable case-insensitive protocol router.
rows
Package rows supplies helpers for rendering supported neutral row entries.
Package rows supplies helpers for rendering supported neutral row entries.
sort
Package sort translates protocol sort keys into Ether browse orders.
Package sort translates protocol sort keys into Ether browse orders.
support
Package support connects authenticated frontend requests to the owner's bounded diagnostics recorder.
Package support connects authenticated frontend requests to the owner's bounded diagnostics recorder.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL