xtreamcodes

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 13 Imported by: 0

README

go.xtream-codes

Fork of tellytv/go.xtream-codes. Updates Go version and dependencies; reshapes structs to be more resilient to source variants.

License

MIT. See LICENSE.

Documentation

Overview

Package xtreamcodes provides a Golang interface to the Xtream-Codes IPTV Server API.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AuthError

type AuthError struct {
	StatusCode  int
	ContentType string
	Body        []byte
}

AuthError is returned by NewClient when authentication fails. Failure is detected via three signals: HTTP error status from the auth request, a 2xx response whose body fails the non-JSON heuristic, or a 2xx response whose parsed AuthenticationResponse lacks user_info (null envelope or missing field). StatusCode, ContentType, and Body capture the response for diagnosis.

func (*AuthError) Error

func (e *AuthError) Error() string

type AuthenticationResponse

type AuthenticationResponse struct {
	ServerInfo ServerInfo `json:"server_info"`
	UserInfo   UserInfo   `json:"user_info"`
}

AuthenticationResponse is a container for what the server returns after the initial authentication.

type Base64Value

type Base64Value []byte

Base64Value is a base64url encoded json object,

func New

func New(b []byte) *Base64Value

New returns a pointer to a Base64Value, cast from the given byte slice. This is a convenience function, handling the address creation that a direct cast would not allow.

func NewFromString

func NewFromString(encoded string) (*Base64Value, error)

NewFromString returns a Base64Value containing the decoded data in encoded. Tolerates both padded (StdEncoding) and unpadded (RawURLEncoding) base64; provider EPG payloads in the wild are typically padded.

func (*Base64Value) MarshalJSON

func (bv *Base64Value) MarshalJSON() ([]byte, error)

MarshalJSON returns the ba64url encoding of bv for JSON representation.

func (*Base64Value) String

func (bv *Base64Value) String() string

func (*Base64Value) UnmarshalJSON

func (bv *Base64Value) UnmarshalJSON(b []byte) error

UnmarshalJSON sets bv to the bytes represented in the base64-encoded b. Tolerates both padded (StdEncoding) and unpadded (RawURLEncoding) input; provider EPG payloads observed in the wild (issue pierre-emmanuelJ/iptv-proxy#115 et al.) come padded, while the upstream library only accepted RawURLEncoding.

type Category

type Category struct {
	ID     FlexInt `json:"category_id"`
	Name   string  `json:"category_name"`
	Parent FlexInt `json:"parent_id"`

	// Set by us, not Xtream.
	Type string `json:"-"`
}

Category describes a grouping of Stream.

type ConvertibleBoolean

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

ConvertibleBoolean is a helper type to allow JSON documents using 0/1 or "true" and "false" be converted to bool.

func (ConvertibleBoolean) Bool

func (bit ConvertibleBoolean) Bool() bool

Bool returns the underlying bool value.

func (ConvertibleBoolean) IsZero

func (bit ConvertibleBoolean) IsZero() bool

IsZero reports whether the ConvertibleBoolean holds the zero value (false, unquoted). Combined with json `omitzero` (Go 1.24+) for targeted elision; do not apply to fields where false-vs-absent is a distinction the caller relies on.

func (ConvertibleBoolean) MarshalJSON

func (bit ConvertibleBoolean) MarshalJSON() ([]byte, error)

MarshalJSON returns a 0 or 1 depending on bool state.

func (ConvertibleBoolean) String

func (bit ConvertibleBoolean) String() string

String implements fmt.Stringer.

func (*ConvertibleBoolean) UnmarshalJSON

func (bit *ConvertibleBoolean) UnmarshalJSON(data []byte) error

UnmarshalJSON converts a 0, 1, true or false into a bool

type EPGInfo

type EPGInfo struct {
	ChannelID      string             `json:"channel_id"`
	Description    Base64Value        `json:"description"`
	End            string             `json:"end"`
	EPGID          FlexInt            `json:"epg_id"`
	HasArchive     ConvertibleBoolean `json:"has_archive"`
	ID             FlexInt            `json:"id"`
	Lang           string             `json:"lang"`
	NowPlaying     ConvertibleBoolean `json:"now_playing"`
	Start          string             `json:"start"`
	StartTimestamp Timestamp          `json:"start_timestamp"`
	StopTimestamp  Timestamp          `json:"stop_timestamp"`
	Title          Base64Value        `json:"title"`
}

EPGInfo describes electronic programming guide information of a stream.

type EpisodeInfo

type EpisodeInfo struct {
	AirDate        string           `json:"air_date,omitempty"`
	BackdropPath   *JSONStringSlice `json:"backdrop_path,omitempty"`
	Bitrate        FlexInt          `json:"bitrate,omitempty"`
	Crew           string           `json:"crew,omitempty"`
	DirectedBy     string           `json:"directed_by,omitempty"`
	Duration       string           `json:"duration,omitempty"`
	DurationSecs   FlexInt          `json:"duration_secs,omitempty"`
	ID             FlexInt          `json:"id,omitempty"`
	ImdbID         string           `json:"imdb_id,omitempty"`
	MovieImage     string           `json:"movie_image"`
	MovieImageTmdb string           `json:"movie_image_tmdb,omitempty"`
	Name           string           `json:"name,omitempty"`
	Overview       string           `json:"overview,omitempty"`
	Plot           string           `json:"plot"`
	Rating         FlexFloat        `json:"rating"`
	ReleaseDate    string           `json:"releasedate"`
	TmdbID         FlexInt          `json:"tmdb_id,omitempty"`
	TvdbID         FlexInt          `json:"tvdb_id,omitzero"`
}

EpisodeInfo contains the metadata block embedded within a SeriesEpisode.

func (*EpisodeInfo) UnmarshalJSON

func (e *EpisodeInfo) UnmarshalJSON(b []byte) error

UnmarshalJSON coalesces provider key variants:

  • releasedate / release_date — struct uses releasedate; C emits release_date
  • tmdb / tmdb_id, imdb / imdb_id, tvdb / tvdb_id — long form is canonical on this struct; short forms accepted for cross-provider tolerance.

type FlexFloat

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

FlexFloat unmarshals from JSON as either a quoted or unquoted float, preserving the original quoting form so round-trip marshaling is faithful.

func (FlexFloat) Float64

func (ff FlexFloat) Float64() float64

Float64 returns the underlying float64 value.

func (FlexFloat) MarshalJSON

func (ff FlexFloat) MarshalJSON() ([]byte, error)

func (FlexFloat) String

func (ff FlexFloat) String() string

String implements fmt.Stringer.

func (*FlexFloat) UnmarshalJSON

func (ff *FlexFloat) UnmarshalJSON(b []byte) error

type FlexInt

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

FlexInt unmarshals from JSON as either a quoted or unquoted integer, preserving the original quoting form so round-trip marshaling is faithful.

func NewFlexInt

func NewFlexInt(v int64) FlexInt

NewFlexInt creates a FlexInt from an int64 value.

func (FlexInt) Int

func (f FlexInt) Int() int

Int returns the underlying value as int.

func (FlexInt) Int64

func (f FlexInt) Int64() int64

Int64 returns the underlying int64 value.

func (FlexInt) IsZero

func (f FlexInt) IsZero() bool

IsZero reports whether the FlexInt holds the zero value. Combined with the json `omitzero` tag (Go 1.24+), this allows targeted elision of absent-equals-zero fields without affecting fields where a zero value carries semantic signal.

func (FlexInt) MarshalJSON

func (f FlexInt) MarshalJSON() ([]byte, error)

func (FlexInt) String

func (f FlexInt) String() string

String implements fmt.Stringer.

func (*FlexInt) UnmarshalJSON

func (f *FlexInt) UnmarshalJSON(data []byte) error

UnmarshalJSON is intentionally tolerant: malformed numerics coerce to zero rather than failing the enclosing record's decode. Providers in the wild emit empty strings, nulls, and occasional non-numeric strings on fields the contract treats as integers; record-level decode failure is worse than zero-coercion in this domain. Callers that need to distinguish "explicit zero" from "coerced bad input" should validate at a higher level.

type HTTPError

type HTTPError struct {
	StatusCode  int
	ContentType string
	Body        []byte
}

HTTPError is returned by the Xtream API client when a request returns an HTTP status >= 400, or when a 2xx response body for a JSON-expected endpoint fails the non-JSON error heuristic (empty body, leading '<' for HTML, exact-match sentinel words). 3xx redirects are followed by the underlying http.Client and do not surface as HTTPError. Callers can type-assert to access StatusCode, ContentType, and Body for diagnostic inspection.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type JSONStringSlice

type JSONStringSlice struct {
	Slice        []string `json:"-"`
	SingleString bool     `json:"-"`
}

JSONStringSlice is a struct containing a slice of strings. It is needed for cases in which we may get an array or may get a single string in a JSON response.

func (JSONStringSlice) MarshalJSON

func (b JSONStringSlice) MarshalJSON() ([]byte, error)

MarshalJSON returns b as the JSON encoding of b.

func (*JSONStringSlice) UnmarshalJSON

func (b *JSONStringSlice) UnmarshalJSON(data []byte) error

UnmarshalJSON sets *b to a copy of data.

type Season

type Season struct {
	AirDate      string  `json:"air_date"`
	Cover        string  `json:"cover"`
	CoverBig     string  `json:"cover_big"`
	CoverTmdb    string  `json:"cover_tmdb"`
	Duration     FlexInt `json:"duration"`
	EpisodeCount FlexInt `json:"episode_count"`
	ImdbID       string  `json:"imdb,omitempty"`
	Name         string  `json:"name"`
	Overview     string  `json:"overview"`
	ReleaseDate  string  `json:"releaseDate"`
	SeasonNumber FlexInt `json:"season_number"`
	TmdbID       FlexInt `json:"tmdb,omitempty"`
	TvdbID       FlexInt `json:"tvdb,omitzero"`
}

Season describes a single season within a series.

func (*Season) UnmarshalJSON

func (s *Season) UnmarshalJSON(b []byte) error

UnmarshalJSON coalesces releaseDate/release_date into ReleaseDate and accepts tmdb_id/imdb_id/tvdb_id as aliases for the canonical short-form tmdb/imdb/tvdb keys on this struct.

type Series

type Series struct {
	Episodes map[string][]SeriesEpisode `json:"episodes"`
	Info     SeriesInfo                 `json:"info"`
	Seasons  []Season                   `json:"seasons"`
}

type SeriesEpisode

type SeriesEpisode struct {
	Added              Timestamp   `json:"added"`
	ContainerExtension string      `json:"container_extension"`
	CustomSid          string      `json:"custom_sid"`
	DirectSource       string      `json:"direct_source"`
	EpisodeNum         FlexInt     `json:"episode_num"`
	ID                 FlexInt     `json:"id"`
	ImdbID             string      `json:"imdb,omitempty"`
	Info               EpisodeInfo `json:"info"`
	Season             FlexInt     `json:"season"`
	Title              string      `json:"title"`
	TmdbID             FlexInt     `json:"tmdb,omitempty"`
	TvdbID             FlexInt     `json:"tvdb,omitzero"`
}

func (*SeriesEpisode) UnmarshalJSON

func (s *SeriesEpisode) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts tmdb_id/imdb_id/tvdb_id as input aliases for the canonical short-form tmdb/imdb/tvdb keys on this struct.

type SeriesInfo

type SeriesInfo struct {
	Added          *Timestamp       `json:"added,omitempty"`
	BackdropPath   *JSONStringSlice `json:"backdrop_path,omitempty"`
	Cast           string           `json:"cast"`
	CategoryID     *FlexInt         `json:"category_id"`
	CategoryIDs    []FlexInt        `json:"category_ids,omitempty"`
	Cover          string           `json:"cover"`
	Director       string           `json:"director"`
	EpisodeRunTime FlexInt          `json:"episode_run_time"`
	Genre          string           `json:"genre"`
	ImdbID         string           `json:"imdb,omitempty"`
	LastModified   *Timestamp       `json:"last_modified,omitempty"`
	Name           string           `json:"name"`
	Num            FlexInt          `json:"num"`
	Plot           string           `json:"plot"`
	Rating         FlexFloat        `json:"rating"`
	Rating5        FlexFloat        `json:"rating_5based"`
	ReleaseDate    string           `json:"releaseDate"`
	SeriesID       FlexInt          `json:"series_id"`
	StreamType     string           `json:"stream_type"`
	TmdbID         FlexInt          `json:"tmdb,omitempty"`
	TvdbID         FlexInt          `json:"tvdb,omitzero"`
	YoutubeTrailer string           `json:"youtube_trailer"`
}

SeriesInfo contains information about a TV series.

func (*SeriesInfo) UnmarshalJSON

func (s *SeriesInfo) UnmarshalJSON(b []byte) error

UnmarshalJSON coalesces provider key variants:

  • releaseDate / release_date — ProviderA/B emit releaseDate, C emits release_date
  • tmdb / tmdb_id, imdb / imdb_id, tvdb / tvdb_id — short form is canonical on this struct (matches ProviderA/B); long forms accepted for ProviderC compatibility (Dispatcharr emits _id-suffixed forms on the list shape).

type ServerInfo

type ServerInfo struct {
	HTTPSPort    FlexInt            `json:"https_port"`
	IE           ConvertibleBoolean `json:"ie,omitzero"`
	IEAuth       ConvertibleBoolean `json:"ie_auth,omitzero"`
	Port         FlexInt            `json:"port"`
	Process      bool               `json:"process"`
	RTMPPort     FlexInt            `json:"rtmp_port"`
	Protocol     string             `json:"server_protocol"`
	TimeNow      string             `json:"time_now"`
	TimestampNow Timestamp          `json:"timestamp_now"`
	Timezone     string             `json:"timezone"`
	URL          string             `json:"url"`
	Version      string             `json:"version,omitempty"`
	Revision     string             `json:"revision,omitempty"`
	XUI          bool               `json:"xui,omitempty"`
}

ServerInfo describes the state of the Xtream-Codes server.

type Stream

type Stream struct {
	Added              *Timestamp         `json:"added"`
	CategoryID         FlexInt            `json:"category_id"`
	CategoryIDs        []FlexInt          `json:"category_ids,omitempty"`
	CategoryName       string             `json:"category_name"`
	ContainerExtension string             `json:"container_extension"`
	CustomSid          string             `json:"custom_sid"`
	DirectSource       string             `json:"direct_source,omitempty"`
	EPGChannelID       string             `json:"epg_channel_id"`
	Icon               string             `json:"stream_icon"`
	ID                 FlexInt            `json:"stream_id"`
	ImdbID             string             `json:"imdb,omitempty"`
	IsAdult            ConvertibleBoolean `json:"is_adult"`
	Live               ConvertibleBoolean `json:"live"`
	Name               string             `json:"name"`
	Number             FlexInt            `json:"num"`
	Rating             FlexFloat          `json:"rating"`
	Rating5based       FlexFloat          `json:"rating_5based"`
	SeriesNo           *FlexInt           `json:"series_no,omitempty"`
	TmdbID             FlexInt            `json:"tmdb,omitempty"`
	Trailer            string             `json:"trailer,omitempty"`
	TvdbID             FlexInt            `json:"tvdb,omitzero"`
	TVArchive          ConvertibleBoolean `json:"tv_archive"`
	TVArchiveDuration  *FlexInt           `json:"tv_archive_duration"`
	Type               string             `json:"stream_type"`
	TypeName           string             `json:"type_name,omitempty"`
}

Stream is a streamble video source.

func (*Stream) UnmarshalJSON

func (s *Stream) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts tmdb_id/imdb_id/tvdb_id as input aliases for the canonical short-form tmdb/imdb/tvdb keys — ProviderC (Dispatcharr) emits the long forms on stream records while A and B emit the short forms.

type Timestamp

type Timestamp struct {
	time.Time
	// contains filtered or unexported fields
}

Timestamp is a helper struct to convert unix timestamp ints and strings to time.Time.

func (Timestamp) MarshalJSON

func (t Timestamp) MarshalJSON() ([]byte, error)

MarshalJSON returns the Unix timestamp as a string.

func (*Timestamp) UnmarshalJSON

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

UnmarshalJSON converts the int or string to a Unix timestamp.

type UserInfo

type UserInfo struct {
	ActiveConnections    FlexInt            `json:"active_cons"`
	AllowedOutputFormats []string           `json:"allowed_output_formats"`
	Auth                 ConvertibleBoolean `json:"auth"`
	CreatedAt            Timestamp          `json:"created_at"`
	ExpDate              *Timestamp         `json:"exp_date"`
	IsTrial              ConvertibleBoolean `json:"is_trial"`
	MaxConnections       FlexInt            `json:"max_connections"`
	Message              string             `json:"message"`
	Password             string             `json:"password"`
	PlaylistName         string             `json:"playlist_name,omitempty"`
	Status               string             `json:"status"`
	Username             string             `json:"username"`
}

UserInfo is the current state of the user as it relates to the Xtream-Codes server.

type VODInfo

type VODInfo struct {
	Actors         string    `json:"actors"`
	Age            string    `json:"age"`
	BackdropPath   []string  `json:"backdrop_path"`
	Bitrate        FlexInt   `json:"bitrate"`
	Cast           string    `json:"cast"`
	Country        string    `json:"country"`
	Cover          string    `json:"cover,omitempty"`
	CoverBig       string    `json:"cover_big"`
	Description    string    `json:"description"`
	Director       string    `json:"director"`
	Duration       string    `json:"duration"`
	DurationSecs   FlexInt   `json:"duration_secs"`
	EpisodeRunTime *FlexInt  `json:"episode_run_time,omitempty"`
	Genre          string    `json:"genre"`
	ImdbID         string    `json:"imdb_id,omitempty"`
	KinopoiskURL   string    `json:"kinopoisk_url,omitempty"`
	MovieImage     string    `json:"movie_image"`
	Name           string    `json:"name"`
	OriginalName   string    `json:"o_name"`
	Plot           string    `json:"plot"`
	Rating         FlexFloat `json:"rating"`
	ReleaseDate    string    `json:"releasedate"`
	Runtime        string    `json:"runtime,omitempty"`
	Status         string    `json:"status"`
	TmdbID         FlexInt   `json:"tmdb_id"`
	TvdbID         FlexInt   `json:"tvdb_id,omitzero"`
	Year           FlexInt   `json:"year,omitempty"`
	YoutubeTrailer string    `json:"youtube_trailer"`
}

VODInfo is the metadata block within a VideoOnDemandInfo response.

func (*VODInfo) UnmarshalJSON

func (v *VODInfo) UnmarshalJSON(b []byte) error

UnmarshalJSON coalesces provider key variants:

  • releasedate / release_date — struct uses releasedate; C emits release_date
  • tmdb / tmdb_id, imdb / imdb_id, tvdb / tvdb_id — long form is canonical on this struct (matches existing tmdb_id precedent across providers); short forms accepted for cross-provider tolerance.

type VODMovieData

type VODMovieData struct {
	Added              Timestamp `json:"added"`
	CategoryID         FlexInt   `json:"category_id"`
	CategoryIDs        []FlexInt `json:"category_ids,omitempty"`
	ContainerExtension string    `json:"container_extension"`
	CustomSid          string    `json:"custom_sid"`
	DirectSource       string    `json:"direct_source"`
	Name               string    `json:"name"`
	StreamID           FlexInt   `json:"stream_id"`
}

VODMovieData is the stream identity block within a VideoOnDemandInfo response.

type VideoOnDemandInfo

type VideoOnDemandInfo struct {
	Info      VODInfo      `json:"info"`
	MovieData VODMovieData `json:"movie_data"`
}

VideoOnDemandInfo contains information about a video on demand stream.

func (*VideoOnDemandInfo) UnmarshalJSON

func (v *VideoOnDemandInfo) UnmarshalJSON(b []byte) error

UnmarshalJSON tolerates providers that emit "info": [] (empty array) when the metadata block is absent for a given record — treat as a zero-value VODInfo rather than failing the whole decode.

type XtreamClient

type XtreamClient struct {
	Username  string
	Password  string
	BaseURL   string
	UserAgent string

	ServerInfo ServerInfo
	UserInfo   UserInfo

	// Our HTTP client to communicate with Xtream
	HTTP    *http.Client
	Context context.Context
	// contains filtered or unexported fields
}

XtreamClient is the client used to communicate with a Xtream-Codes server.

func NewClient

func NewClient(username, password, baseURL string) (*XtreamClient, error)

NewClient returns an initialized XtreamClient with the given values.

func NewClientWithContext

func NewClientWithContext(ctx context.Context, username, password, baseURL string) (*XtreamClient, error)

NewClientWithContext returns an initialized XtreamClient with the given values.

func NewClientWithUserAgent

func NewClientWithUserAgent(ctx context.Context, username, password, baseURL, userAgent string) (*XtreamClient, error)

NewClientWithUserAgent returns an initialized XtreamClient with the given values. The User-Agent is applied before the authentication request, so a provider that gates on UA sees the supplied value on every request including auth.

func (*XtreamClient) GetCategories

func (c *XtreamClient) GetCategories(catType string) ([]Category, error)

GetCategories is a helper function used by GetLiveCategories, GetVideoOnDemandCategories and GetSeriesCategories to reduce duplicate code.

func (*XtreamClient) GetEPG

func (c *XtreamClient) GetEPG(streamID string) ([]EPGInfo, error)

GetEPG returns the full EPG for the given streamID.

func (*XtreamClient) GetLiveCategories

func (c *XtreamClient) GetLiveCategories() ([]Category, error)

GetLiveCategories will return a slice of categories for live streams.

func (*XtreamClient) GetLiveStreams

func (c *XtreamClient) GetLiveStreams(categoryID string) ([]Stream, error)

GetLiveStreams will return a slice of live streams. You can also optionally provide a categoryID to limit the output to members of that category.

func (*XtreamClient) GetSeries

func (c *XtreamClient) GetSeries(categoryID string) ([]SeriesInfo, error)

GetSeries will return a slice of all available Series. You can also optionally provide a categoryID to limit the output to members of that category.

func (*XtreamClient) GetSeriesCategories

func (c *XtreamClient) GetSeriesCategories() ([]Category, error)

GetSeriesCategories will return a slice of categories for series streams.

func (*XtreamClient) GetSeriesInfo

func (c *XtreamClient) GetSeriesInfo(seriesID string) (*Series, error)

GetSeriesInfo will return a series info for the given seriesID.

func (*XtreamClient) GetShortEPG

func (c *XtreamClient) GetShortEPG(streamID string, limit int) ([]EPGInfo, error)

GetShortEPG returns a short version of the EPG for the given streamID. If no limit is provided, the next 4 items in the EPG will be returned.

func (*XtreamClient) GetStreamURL

func (c *XtreamClient) GetStreamURL(streamID int, wantedFormat string) (string, error)

GetStreamURL will return a stream URL string for the given streamID and wantedFormat.

func (*XtreamClient) GetStreams

func (c *XtreamClient) GetStreams(streamAction, categoryID string) ([]Stream, error)

GetStreams is a helper function used by GetLiveStreams and GetVideoOnDemandStreams to reduce duplicate code.

func (*XtreamClient) GetVideoOnDemandCategories

func (c *XtreamClient) GetVideoOnDemandCategories() ([]Category, error)

GetVideoOnDemandCategories will return a slice of categories for VOD streams.

func (*XtreamClient) GetVideoOnDemandInfo

func (c *XtreamClient) GetVideoOnDemandInfo(vodID string) (*VideoOnDemandInfo, error)

GetVideoOnDemandInfo will return VOD info for the given vodID.

func (*XtreamClient) GetVideoOnDemandStreams

func (c *XtreamClient) GetVideoOnDemandStreams(categoryID string) ([]Stream, error)

GetVideoOnDemandStreams will return a slice of VOD streams. You can also optionally provide a categoryID to limit the output to members of that category.

func (*XtreamClient) GetXMLTV

func (c *XtreamClient) GetXMLTV() ([]byte, error)

GetXMLTV will return a slice of bytes for the XMLTV EPG file available from the provider.

Jump to

Keyboard shortcuts

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