plex

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Jan 2, 2026 License: MIT Imports: 12 Imported by: 1

Documentation

Overview

Package plex provides a client for interacting with a Plex Media Server.

This package provides several ways to authenticate with a Plex Media Server:

  1. NewPMSClientWithToken creates a new Plex client using a given token. See Finding an authentication token / X-Plex-Token.
  2. NewPMSClient creates a new Plex client using plex.tv to authenticate itself.

The second option uses the plextv package to retrieve a token. It supports both the new (recommended) JWT authentication flow, and the legacy Credentials and PIN authentication flow.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Episode added in v0.3.0

type Episode struct {
	LastViewedAt          Timestamp `json:"lastViewedAt"`
	AddedAt               Timestamp `json:"addedAt"`
	UpdatedAt             Timestamp `json:"updatedAt"`
	RatingKey             string    `json:"ratingKey"`
	Key                   string    `json:"key"`
	ParentRatingKey       string    `json:"parentRatingKey"`
	GrandparentRatingKey  string    `json:"grandparentRatingKey"`
	Guid                  string    `json:"guid"`
	ParentGuid            string    `json:"parentGuid"`
	GrandparentGuid       string    `json:"grandparentGuid"`
	Type                  string    `json:"type"`
	Title                 string    `json:"title"`
	GrandparentKey        string    `json:"grandparentKey"`
	ParentKey             string    `json:"parentKey"`
	GrandparentTitle      string    `json:"grandparentTitle"`
	ParentTitle           string    `json:"parentTitle"`
	ContentRating         string    `json:"contentRating"`
	Summary               string    `json:"summary"`
	Thumb                 string    `json:"thumb"`
	Art                   string    `json:"art"`
	ParentThumb           string    `json:"parentThumb"`
	GrandparentThumb      string    `json:"grandparentThumb"`
	GrandparentArt        string    `json:"grandparentArt"`
	GrandparentTheme      string    `json:"grandparentTheme"`
	OriginallyAvailableAt string    `json:"originallyAvailableAt"`
	AudienceRatingImage   string    `json:"audienceRatingImage"`
	Media                 []Media   `json:"Media"`
	Director              []struct {
		Tag string `json:"tag"`
	} `json:"Director"`
	Writer []struct {
		Tag string `json:"tag"`
	} `json:"Writer"`
	Role []struct {
		Tag string `json:"tag"`
	} `json:"Role"`
	Index          int     `json:"index"`
	ParentIndex    int     `json:"parentIndex"`
	AudienceRating float64 `json:"audienceRating"`
	ViewCount      int     `json:"viewCount"`
	Year           int     `json:"year"`
	Duration       int     `json:"duration"`
}

type Identity

type Identity struct {
	MachineIdentifier string `json:"machineIdentifier"`
	Version           string `json:"version"`
	Size              int    `json:"size"`
	Claimed           bool   `json:"claimed"`
}

Identity contains the response of Plex's /identity API

type Library added in v0.3.0

type Library struct {
	UpdatedAt        Timestamp `json:"updatedAt"`
	CreatedAt        Timestamp `json:"createdAt"`
	ScannedAt        Timestamp `json:"scannedAt"`
	ContentChangedAt Timestamp `json:"contentChangedAt"`
	Art              string    `json:"art"`
	Composite        string    `json:"composite"`
	Thumb            string    `json:"thumb"`
	Key              string    `json:"key"`
	Type             string    `json:"type"`
	Title            string    `json:"title"`
	Agent            string    `json:"agent"`
	Scanner          string    `json:"scanner"`
	Language         string    `json:"language"`
	Uuid             string    `json:"uuid"`
	Location         []struct {
		Path string `json:"path"`
		Id   int    `json:"id"`
	} `json:"Location"`
	Hidden     int  `json:"hidden"`
	AllowSync  bool `json:"allowSync"`
	Filters    bool `json:"filters"`
	Refreshing bool `json:"refreshing"`
	Content    bool `json:"content"`
	Directory  bool `json:"directory"`
}

type Media added in v0.3.0

type Media struct {
	AudioCodec            string      `json:"audioCodec"`
	VideoCodec            string      `json:"videoCodec"`
	VideoResolution       string      `json:"videoResolution"`
	Container             string      `json:"container"`
	VideoFrameRate        string      `json:"videoFrameRate"`
	AudioProfile          string      `json:"audioProfile,omitempty"`
	VideoProfile          string      `json:"videoProfile"`
	Part                  []MediaPart `json:"Part"`
	Id                    int         `json:"id"`
	Duration              int         `json:"duration"`
	Bitrate               int         `json:"bitrate"`
	Width                 int         `json:"width"`
	Height                int         `json:"height"`
	AspectRatio           float64     `json:"aspectRatio"`
	AudioChannels         int         `json:"audioChannels"`
	OptimizedForStreaming int         `json:"optimizedForStreaming,omitempty"`
	Has64BitOffsets       bool        `json:"has64bitOffsets,omitempty"`
}

type MediaPart added in v0.3.0

type MediaPart struct {
	Key                   string `json:"key"`
	File                  string `json:"file"`
	AudioProfile          string `json:"audioProfile,omitempty"`
	Container             string `json:"container"`
	VideoProfile          string `json:"videoProfile"`
	HasThumbnail          string `json:"hasThumbnail,omitempty"`
	Id                    int    `json:"id"`
	Duration              int    `json:"duration"`
	Size                  int64  `json:"size"`
	Has64BitOffsets       bool   `json:"has64bitOffsets,omitempty"`
	OptimizedForStreaming bool   `json:"optimizedForStreaming,omitempty"`
}

type MediaSessionPart

type MediaSessionPart struct {
	AudioProfile          string                   `json:"audioProfile"`
	ID                    string                   `json:"id"`
	VideoProfile          string                   `json:"videoProfile"`
	Container             string                   `json:"container"`
	Protocol              string                   `json:"protocol"`
	Decision              string                   `json:"decision"`
	Stream                []MediaSessionPartStream `json:"Stream"`
	Bitrate               int                      `json:"bitrate"`
	Duration              int                      `json:"duration"`
	Height                int                      `json:"height"`
	Width                 int                      `json:"width"`
	OptimizedForStreaming bool                     `json:"optimizedForStreaming"`
	Selected              bool                     `json:"selected"`
}

MediaSessionPart contains one record in a MediaSession's Part list

type MediaSessionPartStream

type MediaSessionPartStream struct {
	Codec                string  `json:"codec"`
	DisplayTitle         string  `json:"displayTitle"`
	ExtendedDisplayTitle string  `json:"extendedDisplayTitle"`
	ID                   string  `json:"id"`
	Language             string  `json:"language"`
	LanguageCode         string  `json:"languageCode"`
	LanguageTag          string  `json:"languageTag"`
	Decision             string  `json:"decision"`
	Location             string  `json:"location"`
	AudioChannelLayout   string  `json:"audioChannelLayout,omitempty"`
	BitrateMode          string  `json:"bitrateMode,omitempty"`
	Profile              string  `json:"profile,omitempty"`
	Title                string  `json:"title,omitempty"`
	Container            string  `json:"container,omitempty"`
	Format               string  `json:"format,omitempty"`
	Bitrate              int     `json:"bitrate,omitempty"`
	FrameRate            float64 `json:"frameRate,omitempty"`
	Height               int     `json:"height,omitempty"`
	StreamType           int     `json:"streamType"`
	Width                int     `json:"width,omitempty"`
	Channels             int     `json:"channels,omitempty"`
	SamplingRate         int     `json:"samplingRate,omitempty"`
	Default              bool    `json:"default"`
	Selected             bool    `json:"selected,omitempty"`
}

MediaSessionPartStream contains one stream (video, audio, subtitles) in a MediaSession's Part list

type Movie added in v0.3.0

type Movie struct {
	LastViewedAt          Timestamp `json:"lastViewedAt,omitempty"`
	AddedAt               Timestamp `json:"addedAt"`
	UpdatedAt             Timestamp `json:"updatedAt"`
	RatingKey             string    `json:"ratingKey"`
	Key                   string    `json:"key"`
	Guid                  string    `json:"guid"`
	Studio                string    `json:"studio,omitempty"`
	Type                  string    `json:"type"`
	Title                 string    `json:"title"`
	ContentRating         string    `json:"contentRating,omitempty"`
	Summary               string    `json:"summary"`
	Tagline               string    `json:"tagline,omitempty"`
	Thumb                 string    `json:"thumb,omitempty"`
	Art                   string    `json:"art,omitempty"`
	OriginallyAvailableAt string    `json:"originallyAvailableAt,omitempty"`
	AudienceRatingImage   string    `json:"audienceRatingImage,omitempty"`
	PrimaryExtraKey       string    `json:"primaryExtraKey,omitempty"`
	RatingImage           string    `json:"ratingImage,omitempty"`
	ChapterSource         string    `json:"chapterSource,omitempty"`
	TitleSort             string    `json:"titleSort,omitempty"`
	Media                 []Media   `json:"Media"`
	Genre                 []struct {
		Tag string `json:"tag"`
	} `json:"Genre,omitempty"`
	Country []struct {
		Tag string `json:"tag"`
	} `json:"Country,omitempty"`
	Director []struct {
		Tag string `json:"tag"`
	} `json:"Director,omitempty"`
	Writer []struct {
		Tag string `json:"tag"`
	} `json:"Writer,omitempty"`
	Role []struct {
		Tag string `json:"tag"`
	} `json:"Role,omitempty"`
	Rating         float64 `json:"rating,omitempty"`
	AudienceRating float64 `json:"audienceRating,omitempty"`
	ViewCount      int     `json:"viewCount,omitempty"`
	Year           int     `json:"year,omitempty"`
	Duration       int     `json:"duration"`
	SkipCount      int     `json:"skipCount,omitempty"`
	UserRating     float64 `json:"userRating,omitempty"`
	LastRatedAt    int     `json:"lastRatedAt,omitempty"`
}

type Option added in v0.18.0

type Option func(*PMSClient)

func WithHTTPClient added in v0.18.0

func WithHTTPClient(httpClient *http.Client) Option

type PMSClient added in v0.19.0

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

PMSClient interacts with a Plex Media Server.

func NewPMSClient added in v0.19.0

func NewPMSClient(url string, plexTVClient PlexTVClient, opts ...Option) *PMSClient

NewPMSClient creates a new Plex client, located at the given URL.

Example (Jwt)
package main

import (
	"context"

	"github.com/clambin/mediaclients/plex"
	"github.com/clambin/mediaclients/plex/plextv"
	"github.com/clambin/mediaclients/plex/vault"
)

// config contains the attributes that will be registered for the device with the provided client id.
var config = plextv.DefaultConfig().
	WithClientID("my-unique-client-id").
	WithDevice(plextv.Device{
		Product:         "my product",
		Version:         "v0.0.4",
		Platform:        "my platform",
		PlatformVersion: "my platform version",
		Device:          "my device",
		Model:           "my device model",
		DeviceVendor:    "my device vendor name",
		DeviceName:      "my device name",
		Provides:        "controller",
	})

func main() {
	// jwt requires persistence to store the private key for the device's client id.
	// vault provides a basic encrypted file to securely store the device's private data.
	v := vault.New[plextv.JWTSecureData](config.ClientID+".enc", "my-secret-passphrase")

	// create a token source that will use the provided credentials to authenticate with plextv the first time.
	// it then registers a public key with plextv and requests a JWT token using the private key.
	src := config.TokenSource(
		plextv.WithCredentials("plex-username", "plex-password"),
		plextv.WithJWT(v),
	)

	// create a plex.tv client with the provided token source.
	ctx := context.Background()
	plexTVClient := config.Client(ctx, src)

	// create a PMS client that will use the provided token source to authenticate itself with plex.tv
	// and determine the token to interact with the Plex Media Server.
	plexPMSClient := plex.NewPMSClient("http://plex-hostname:32400", plexTVClient)

	_, _ = plexPMSClient.GetLibraries(ctx)
}

func NewPMSClientWithToken added in v0.19.0

func NewPMSClientWithToken(url string, token string, opts ...Option) *PMSClient

func (*PMSClient) GetEpisodes added in v0.19.0

func (c *PMSClient) GetEpisodes(ctx context.Context, key string) ([]Episode, error)

func (*PMSClient) GetIdentity added in v0.19.0

func (c *PMSClient) GetIdentity(ctx context.Context) (Identity, error)

GetIdentity calls Plex' /identity endpoint. Mainly useful to get the server's version.

func (*PMSClient) GetLibraries added in v0.19.0

func (c *PMSClient) GetLibraries(ctx context.Context) ([]Library, error)

func (*PMSClient) GetMovies added in v0.19.0

func (c *PMSClient) GetMovies(ctx context.Context, key string) ([]Movie, error)

func (*PMSClient) GetSeasons added in v0.19.0

func (c *PMSClient) GetSeasons(ctx context.Context, key string) ([]Season, error)

func (*PMSClient) GetSessions added in v0.19.0

func (c *PMSClient) GetSessions(ctx context.Context) ([]Session, error)

GetSessions retrieves session information from the server.

func (*PMSClient) GetShows added in v0.19.0

func (c *PMSClient) GetShows(ctx context.Context, key string) ([]Show, error)

type PlexTVClient added in v0.19.0

type PlexTVClient interface {
	User(ctx context.Context) (plextv.User, error)
	MediaServers(ctx context.Context) ([]plextv.RegisteredDevice, error)
}

type Season added in v0.3.0

type Season struct {
	LastViewedAt          Timestamp `json:"lastViewedAt"`
	AddedAt               Timestamp `json:"addedAt"`
	UpdatedAt             Timestamp `json:"updatedAt"`
	RatingKey             string    `json:"ratingKey"`
	Key                   string    `json:"key"`
	ParentRatingKey       string    `json:"parentRatingKey"`
	GrandparentRatingKey  string    `json:"grandparentRatingKey"`
	Guid                  string    `json:"guid"`
	ParentGuid            string    `json:"parentGuid"`
	GrandparentGuid       string    `json:"grandparentGuid"`
	Type                  string    `json:"type"`
	Title                 string    `json:"title"`
	GrandparentKey        string    `json:"grandparentKey"`
	ParentKey             string    `json:"parentKey"`
	GrandparentTitle      string    `json:"grandparentTitle"`
	ParentTitle           string    `json:"parentTitle"`
	ContentRating         string    `json:"contentRating"`
	Summary               string    `json:"summary"`
	Thumb                 string    `json:"thumb"`
	Art                   string    `json:"art"`
	ParentThumb           string    `json:"parentThumb"`
	GrandparentThumb      string    `json:"grandparentThumb"`
	GrandparentArt        string    `json:"grandparentArt"`
	GrandparentTheme      string    `json:"grandparentTheme"`
	OriginallyAvailableAt string    `json:"originallyAvailableAt"`
	AudienceRatingImage   string    `json:"audienceRatingImage"`
	Media                 []Media   `json:"Media"`
	Director              []struct {
		Tag string `json:"tag"`
	} `json:"Director"`
	Writer []struct {
		Tag string `json:"tag"`
	} `json:"Writer"`
	Role []struct {
		Tag string `json:"tag"`
	} `json:"Role"`
	Index          int     `json:"index"`
	ParentIndex    int     `json:"parentIndex"`
	AudienceRating float64 `json:"audienceRating"`
	ViewCount      int     `json:"viewCount"`
	Year           int     `json:"year"`
	Duration       int     `json:"duration"`
}

type Session

type Session struct {
	LastViewedAt          Timestamp      `json:"lastViewedAt"`
	UpdatedAt             Timestamp      `json:"updatedAt"`
	User                  SessionUser    `json:"User"`
	Session               SessionStats   `json:"Session"`
	Art                   string         `json:"art"`
	AudienceRatingImage   string         `json:"audienceRatingImage"`
	ContentRating         string         `json:"contentRating"`
	GrandparentArt        string         `json:"grandparentArt"`
	GrandparentGUID       string         `json:"grandparentGuid"`
	GrandparentKey        string         `json:"grandparentKey"`
	GrandparentRatingKey  string         `json:"grandparentRatingKey"`
	GrandparentTheme      string         `json:"grandparentTheme"`
	GrandparentThumb      string         `json:"grandparentThumb"`
	GrandparentTitle      string         `json:"grandparentTitle"`
	GUID                  string         `json:"guid"`
	Key                   string         `json:"key"`
	LibrarySectionID      string         `json:"librarySectionID"`
	LibrarySectionKey     string         `json:"librarySectionKey"`
	LibrarySectionTitle   string         `json:"librarySectionTitle"`
	OriginallyAvailableAt string         `json:"originallyAvailableAt"`
	ParentGUID            string         `json:"parentGuid"`
	ParentKey             string         `json:"parentKey"`
	ParentRatingKey       string         `json:"parentRatingKey"`
	ParentThumb           string         `json:"parentThumb"`
	ParentTitle           string         `json:"parentTitle"`
	RatingKey             string         `json:"ratingKey"`
	SessionKey            string         `json:"sessionKey"`
	Summary               string         `json:"summary"`
	Thumb                 string         `json:"thumb"`
	Title                 string         `json:"title"`
	Type                  string         `json:"type"`
	Media                 []SessionMedia `json:"Media"`
	Director              []struct {
		Filter string `json:"filter"`
		ID     string `json:"id"`
		Tag    string `json:"tag"`
	} `json:"Director"`
	Writer []struct {
		Filter string `json:"filter"`
		ID     string `json:"id"`
		Tag    string `json:"tag"`
	} `json:"Writer"`
	Rating2 []struct {
		Image string `json:"image"`
		Type  string `json:"type"`
		Value string `json:"value"`
	} `json:"Rating"`
	Role []struct {
		Filter string `json:"filter"`
		ID     string `json:"id"`
		Role   string `json:"role"`
		Tag    string `json:"tag"`
		Thumb  string `json:"thumb,omitempty"`
	} `json:"Role"`
	Player           SessionPlayer     `json:"Player"`
	TranscodeSession SessionTranscoder `json:"TranscodeSession"`
	AddedAt          int               `json:"addedAt"`
	AudienceRating   float64           `json:"audienceRating"`
	Duration         int               `json:"duration"`
	Index            int               `json:"index"`
	ParentIndex      int               `json:"parentIndex"`
	Rating           float64           `json:"rating"`
	ViewOffset       int               `json:"viewOffset"`
}

Session contains one record in a Sessions

func (Session) GetProgress

func (s Session) GetProgress() float64

GetProgress returns the progress of the session, i.e. how much of the movie / tv episode has been watched. Returns a percentage between 0.0 and 1.0

func (Session) GetTitle

func (s Session) GetTitle() string

GetTitle returns the title of the movie, tv episode being played. For movies, this is just the title. For TV Shows, it returns the show, season & episode title.

func (Session) GetVideoMode

func (s Session) GetVideoMode() string

GetVideoMode returns the session's video mode (transcoding, direct play, etc).

type SessionMedia

type SessionMedia struct {
	AudioProfile          string             `json:"audioProfile"`
	ID                    string             `json:"id"`
	VideoProfile          string             `json:"videoProfile"`
	AudioCodec            string             `json:"audioCodec"`
	Container             string             `json:"container"`
	Protocol              string             `json:"protocol"`
	VideoCodec            string             `json:"videoCodec"`
	VideoFrameRate        string             `json:"videoFrameRate"`
	VideoResolution       string             `json:"videoResolution"`
	Part                  []MediaSessionPart `json:"Part"`
	AudioChannels         int                `json:"audioChannels"`
	Bitrate               int                `json:"bitrate"`
	Duration              int                `json:"duration"`
	Height                int                `json:"height"`
	Width                 int                `json:"width"`
	OptimizedForStreaming bool               `json:"optimizedForStreaming"`
	Selected              bool               `json:"selected"`
}

SessionMedia contains one record in a Session's Media list

type SessionPlayer

type SessionPlayer struct {
	Address             string `json:"address"`
	Device              string `json:"device"`
	MachineIdentifier   string `json:"machineIdentifier"`
	Model               string `json:"model"`
	Platform            string `json:"platform"`
	PlatformVersion     string `json:"platformVersion"`
	Product             string `json:"product"`
	Profile             string `json:"profile"`
	RemotePublicAddress string `json:"remotePublicAddress"`
	State               string `json:"state"`
	Title               string `json:"title"`
	Version             string `json:"version"`
	Local               bool   `json:"local"`
	Relayed             bool   `json:"relayed"`
	Secure              bool   `json:"secure"`
	UserID              int    `json:"userID"`
}

SessionPlayer contains the player details inside a Session

type SessionStats

type SessionStats struct {
	ID        string `json:"id"`
	Location  string `json:"location"`
	Bandwidth int    `json:"bandwidth"`
}

SessionStats contains the session details inside a Session

type SessionTranscoder

type SessionTranscoder struct {
	Key                     string  `json:"key"`
	Context                 string  `json:"context"`
	SourceVideoCodec        string  `json:"sourceVideoCodec"`
	SourceAudioCodec        string  `json:"sourceAudioCodec"`
	VideoDecision           string  `json:"videoDecision"`
	AudioDecision           string  `json:"audioDecision"`
	SubtitleDecision        string  `json:"subtitleDecision"`
	Protocol                string  `json:"protocol"`
	Container               string  `json:"container"`
	VideoCodec              string  `json:"videoCodec"`
	AudioCodec              string  `json:"audioCodec"`
	Progress                float64 `json:"progress"`
	Size                    int     `json:"size"`
	Speed                   float64 `json:"speed"`
	Duration                int     `json:"duration"`
	AudioChannels           int     `json:"audioChannels"`
	TimeStamp               float64 `json:"timeStamp"`
	Throttled               bool    `json:"throttled"`
	Complete                bool    `json:"complete"`
	Error                   bool    `json:"error"`
	TranscodeHwRequested    bool    `json:"transcodeHwRequested"`
	TranscodeHwFullPipeline bool    `json:"transcodeHwFullPipeline"`
}

SessionTranscoder contains the transcoder details inside a Session. If the session doesn't transcode any media streams, all fields will be blank.

type SessionUser

type SessionUser struct {
	ID    string `json:"id"`
	Thumb string `json:"thumb"`
	Title string `json:"title"`
}

SessionUser contains the user details inside a Session

type Show added in v0.3.0

type Show struct {
	LastViewedAt          Timestamp `json:"lastViewedAt,omitempty"`
	AddedAt               Timestamp `json:"addedAt"`
	UpdatedAt             Timestamp `json:"updatedAt"`
	RatingKey             string    `json:"ratingKey"`
	Key                   string    `json:"key"`
	Guid                  string    `json:"guid"`
	Studio                string    `json:"studio"`
	Type                  string    `json:"type"`
	Title                 string    `json:"title"`
	ContentRating         string    `json:"contentRating"`
	Summary               string    `json:"summary"`
	Thumb                 string    `json:"thumb"`
	Art                   string    `json:"art"`
	Theme                 string    `json:"theme,omitempty"`
	OriginallyAvailableAt string    `json:"originallyAvailableAt"`
	AudienceRatingImage   string    `json:"audienceRatingImage"`
	PrimaryExtraKey       string    `json:"primaryExtraKey,omitempty"`
	Tagline               string    `json:"tagline,omitempty"`
	TitleSort             string    `json:"titleSort,omitempty"`
	Genre                 []struct {
		Tag string `json:"tag"`
	} `json:"Genre"`
	Country []struct {
		Tag string `json:"tag"`
	} `json:"Country"`
	Role []struct {
		Tag string `json:"tag"`
	} `json:"Role"`
	Index           int     `json:"index"`
	AudienceRating  float64 `json:"audienceRating"`
	ViewCount       int     `json:"viewCount,omitempty"`
	Year            int     `json:"year"`
	Duration        int     `json:"duration"`
	LeafCount       int     `json:"leafCount"`
	ViewedLeafCount int     `json:"viewedLeafCount"`
	ChildCount      int     `json:"childCount"`
	SkipCount       int     `json:"skipCount,omitempty"`
}

type Timestamp

type Timestamp time.Time

func (*Timestamp) String

func (t *Timestamp) String() string

func (*Timestamp) UnmarshalJSON

func (t *Timestamp) UnmarshalJSON(buf []byte) error

Directories

Path Synopsis
internal
Package plextv provides two main components.
Package plextv provides two main components.
Package vault provides a simple means of storing secure data on disk.
Package vault provides a simple means of storing secure data on disk.

Jump to

Keyboard shortcuts

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