plex

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: 56 Imported by: 0

Documentation

Overview

Package plex is Ether's Plex Media Server front end: the HTTP API that official Plex apps (Web, iOS, Apple TV, Android, TVs) talk to. Everything behind it is reached through internal/frontend host interfaces.

Index

Constants

View Source
const APIVersion = "1.2.3"

APIVersion is the PMS API version Ether implements (X-Plex-Pms-Api-Version).

View Source
const DefaultPMSVersion = "1.43.4.10903-e5521bd8c"

DefaultPMSVersion is reported when Identity.Version is empty. Clients gate features on the server version, so it must look like a current PMS build.

Variables

This section is empty.

Functions

func RouteInventory

func RouteInventory() frontend.RouteInventory

RouteInventory enumerates the same registration tree used by the server, without starting background workers or needing runtime dependencies.

Types

type AccessPolicy

type AccessPolicy = frontend.AccessPolicy

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

type CollectionArtworker

type CollectionArtworker interface {
	CollectionArtwork(ctx context.Context, user *frontend.Viewer, key frontend.RatingKey, element string, width int) (data []byte, contentType string, ok bool, err error)
}

CollectionArtworker is optionally implemented by Deps.Collections to serve generated collection posters (internal/collections renders them with internal/artwork). ok=false falls back to the TMDB artwork path.

type Deps

type Deps struct {
	Host       frontend.Host
	Playback   frontend.Playback
	Transcoder frontend.Transcoder

	// Sections overrides the default Movies (1) and TV Shows (2) sections.
	Sections []Section
	// DB persists artwork data and ordered shelf-generation keys. Clustered
	// nodes share this store so continuations survive failover and restarts.
	// Optional: without it, these caches remain process-local.
	DB *sql.DB
	// DisableEnrichment turns off the background title-detail and
	// UltraBlurColors work (the spike test library has nothing to fetch).
	DisableEnrichment bool
	// TracePlayback logs HLS/transcode requests when ETHER_TRACE_PLAYBACK=1.
	// It does not change responses.
	TracePlayback bool
}

Deps are the server's dependencies. Host.Experience, Host.Identity and Host.Sessions are required; the rest degrade gracefully when nil.

type Directive

type Directive struct {
	Verb string
	Args map[string]string
}

Directive is one parsed X-Plex-Client-Profile-Extra directive, e.g. add-limitation(scope=videoCodec&scopeName=h264&...).

func ParseProfileExtra

func ParseProfileExtra(s string) []Directive

ParseProfileExtra splits a profile-extra string into directives. The value may arrive URL-encoded; directives are separated by "+".

type DiscoveryFeatures

type DiscoveryFeatures = frontend.DiscoveryFeatures

DiscoveryFeatures is the shared discovery contract adapted by Plex.

type Frontend

type Frontend struct {
	NewServer    func() (*Server, error)
	Server       *Server
	WatchRefresh frontend.WatchRefreshSubscriber
	// ExplicitWatchOnly preserves spike mode: only cross-surface scrobbles refresh.
	ExplicitWatchOnly bool
	StatusFunc        func(context.Context) frontend.Status
	ListenersFunc     func() []frontend.ListenerSpec
	// contains filtered or unexported fields
}

Frontend adapts the PMS handler to the frontend registry. Unmount stops this mount's broker sessions, encoders, trickplay, and downloads, and drops its watch and home subscriptions. When constructed via NewFrontend, the process-owned server stays up across toggles so an in-flight request can finish and is closed on Shutdown.

func NewFrontend

func NewFrontend() Frontend

NewFrontend returns a Plex frontend that lazily builds its server from frontend.Host on first mount and retains it across toggles until Shutdown.

func (Frontend) Describe

func (f Frontend) Describe() frontend.Descriptor

func (Frontend) HasRetainedServer

func (f Frontend) HasRetainedServer() bool

HasRetainedServer reports whether this frontend has constructed an active server.

func (Frontend) Mount

func (f Frontend) Mount(ctx context.Context, host frontend.Host) (frontend.Instance, error)

func (Frontend) Prune

func (f Frontend) Prune(ctx context.Context) (int64, error)

Prune prunes derived rows owned by the retained server, if constructed.

func (Frontend) Shutdown

func (f Frontend) Shutdown(context.Context) error

Shutdown closes any retained server and prevents future mounts on this frontend.

type FrontendArtwork

type FrontendArtwork struct {
	Server        *Server
	Variants      func(*frontend.Title, string) (*frontend.ArtworkImages, bool)
	Metadata      func(context.Context, frontend.ArtworkRequest, frontend.Image) frontend.Image
	VirtualSeason func(context.Context, *frontend.User, frontend.RatingKey) (*frontend.Title, error)
	URLImages     frontend.UntrustedImageFetcher
	Raster        frontend.SVGRasterizer
}

FrontendArtwork is a compatibility adapter for callers already holding a Plex server. Shared runtime constructs artworkservice.Source directly.

func (FrontendArtwork) ChannelImage

func (FrontendArtwork) ImageURLFunc

func (a FrontendArtwork) ImageURLFunc() frontend.ImageURLFunc

func (FrontendArtwork) List

func (FrontendArtwork) PaletteCache

func (a FrontendArtwork) PaletteCache() frontend.ArtworkPaletteCache

func (FrontendArtwork) PosterRenderer

func (a FrontendArtwork) PosterRenderer() frontend.TitlePosterRenderer

func (FrontendArtwork) Read

func (FrontendArtwork) RemoteCache

func (a FrontendArtwork) RemoteCache() frontend.ArtworkImageCache

func (FrontendArtwork) Warm

type Identity

type Identity struct {
	MachineIdentifier  string
	FriendlyName       string
	Version            string
	Platform           string
	PlatformVersion    string
	MyPlexSubscription bool
	OwnerFeatures      []string
}

Identity is how the server presents itself. Empty fields fall back to the config snapshot (friendly name, machine identifier) or sensible defaults.

type MarkerProvider

type MarkerProvider = frontend.MarkerRanges

type Request

type Request struct {
	Token           string
	ClientID        string // X-Plex-Client-Identifier
	Product         string // X-Plex-Product
	Version         string // X-Plex-Version
	Platform        string // X-Plex-Platform
	PlatformVersion string // X-Plex-Platform-Version
	Device          string // X-Plex-Device
	DeviceName      string // X-Plex-Device-Name
	Model           string // X-Plex-Model
	Vendor          string // X-Plex-Device-Vendor
	Language        string // X-Plex-Language

	Features     string // X-Plex-Features
	ProfileName  string // X-Plex-Client-Profile-Name
	ProfileExtra string // X-Plex-Client-Profile-Extra

	ClientCapabilities string // X-Plex-Client-Capabilities (legacy)
	SessionID          string // X-Plex-Session-Identifier

	// Paging (X-Plex-Container-Start/Size); HasPage is false when the client
	// did not ask for a window.
	Start   int
	Size    int
	HasPage bool

	Format model.Format

	RemoteIP netip.Addr
	Remote   bool // not on a private/loopback network

	User *frontend.User

	// Capability is set when authentication used a stream grant or other
	// session-scoped credential, not a user token. Only transcode
	// session/segment handlers may serve a capability-scoped request.
	Capability bool
	// contains filtered or unexported fields
}

Request is the parsed Plex request context: every X-Plex-* header (or its query-string equivalent), paging, the output format and the remote address.

func FromContext

func FromContext(ctx context.Context) *Request

FromContext returns the request context attached by the middleware.

func ParseRequest

func ParseRequest(r *http.Request, trusted ...netip.Prefix) *Request

ParseRequest builds the request context from an HTTP request. Forwarded addresses are considered only for a loopback peer (a local reverse proxy).

func (*Request) ClientCaps

func (pr *Request) ClientCaps(remoteMaxKbps int) frontend.ClientCaps

ClientCaps derives frontend.ClientCaps for the request. remoteMaxKbps caps the bitrate of remote clients (0 = unlimited).

func (*Request) ClientCapsWith

func (pr *Request) ClientCapsWith(remoteMaxKbps int, overrides []frontend.ClientCapabilityOverride) frontend.ClientCaps

ClientCapsWith is ClientCaps with owner registry overrides applied before the request's own profile and capability headers.

type Section

type Section struct {
	ID       int
	Type     frontend.MediaType // movie or show
	Title    string
	UUID     string // stable; derived from the machine identifier when empty
	Language string
}

Section is a library section exposed to clients.

type SegmentedEncoder

type SegmentedEncoder = frontend.SegmentedEncoder

SegmentedEncoder is an opt-in trusted host seam implemented by the shared broker. Starts occur only after existing Plex authentication, owner gates, preparation and admission. The broker must revalidate the exact source revision and retain uncertain execution responsibility. It may choose local execution only before remote allocation; a returned error is never permission for Plex to retry local. Session/Stop true means the broker owns responsibility, even when Session is nil because start is pending. Transport errors must never turn true into false.

type Server

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

Server is the PMS API handler. It is an http.Handler; call Close on shutdown to stop background work and notification streams.

func NewServer

func NewServer(d Deps) *Server

NewServer builds the PMS API handler.

func (*Server) BackgroundBusy

func (s *Server) BackgroundBusy() int

BackgroundBusy is how many Home screens are queued for or being rebuilt behind a response: the performance gate waits for none before each measured request.

func (*Server) Close

func (s *Server) Close() error

Close stops background goroutines and disconnects notification clients.

func (*Server) Closed

func (s *Server) Closed() bool

Closed reports whether Close has begun.

func (*Server) Done

func (s *Server) Done() <-chan struct{}

Done is closed when the server is closed.

func (*Server) DownloadsAllowed

func (s *Server) DownloadsAllowed(u *frontend.User) bool

DownloadsAllowed exposes the same admission decision for informational frontend capability reporting; the download handler still enforces it.

func (*Server) LibrarySections

func (s *Server) LibrarySections() []Section

LibrarySections returns the canonical section identities for account registration. Titles follow the live config so renames publish to plex.tv. The copy prevents publishers from changing local libraries.

func (*Server) NoteOwnerStop

func (s *Server) NoteOwnerStop(id, reason string)

NoteOwnerStop tells the Plex client why a stream is ending. The shared broker stops the source.

func (*Server) NotifyLiveLineup

func (s *Server) NotifyLiveLineup()

NotifyLiveLineup tells connected Plex clients to reload the DVR lineup and guide. Channel create and delete call it through LiveTV.SetOnChange.

func (*Server) NotifyLiveLineupFor

func (s *Server) NotifyLiveLineupFor(viewer int64)

NotifyLiveLineupFor confines personal guide invalidation to its viewer.

func (*Server) Prune

func (s *Server) Prune(ctx context.Context) (int64, error)

Prune removes Play Version ids unseen for 90 days and reports the rows removed. Ids a live session or a pinned version list holds are kept.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

func (*Server) SupportViewer

func (s *Server) SupportViewer(ctx context.Context, user *frontend.Viewer) (frontend.DiagnosticViewerFacts, error)

SupportViewer is a bounded snapshot at archive creation, not a replay of policy decisions made when an earlier response was generated.

func (*Server) ViewerHomeChanged

func (s *Server) ViewerHomeChanged(viewerID int64)

ViewerHomeChanged rebuilds the viewer's recently used Home screens in the background, so the next Home after playback stops is already current.

func (*Server) WatchStateChanged

func (s *Server) WatchStateChanged(userID int64, key frontend.RatingKey)

WatchStateChanged invalidates client library metadata after a committed watch update. A playing notification only updates session status; clients can keep their cached Continue Watching shelf until a library timeline event arrives.

type SessionToucher

type SessionToucher interface {
	Touch(sessionID string)
}

SessionToucher is optionally implemented by frontend.Playback to keep a play session alive on timeline updates.

type SubtitleCatalog

type SubtitleCatalog = frontend.SubtitleSidecarCatalog

SubtitleCatalog is optionally implemented by Deps.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 SubtitleOffer

type SubtitleOffer = frontend.SubtitleSearchOffer

SubtitleOffer is one subtitle search result.

type SubtitleSearch

type SubtitleSearch = frontend.SubtitleSidecarSearch

SubtitleSearch is optionally implemented by Deps.Subtitles: Plex's on-demand subtitle search and pick.

type SubtitleSource

type SubtitleSource = frontend.SubtitleSidecarSource

SubtitleSource resolves cached OpenSubtitles and synchronized sidecars.

type SubtitleUpload

type SubtitleUpload = frontend.SubtitleSidecarUpload

SubtitleUpload is optionally implemented by Deps.Subtitles: Plex Web's "Upload Subtitles" (POST /library/metadata/{key}/subtitles).

type TrackPreferences

type TrackPreferences = frontend.PlaybackTrackPreferences

TrackPreferences is optional. Selections are stream slice positions; saved show choices match language/flags so they survive changes in release order.

Source Files

Directories

Path Synopsis
Package model holds the Plex Media Server response models and the encoder that renders one model as either PMS-style XML or PMS-style JSON.
Package model holds the Plex Media Server response models and the encoder that renders one model as either PMS-style XML or PMS-style JSON.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL