Documentation
¶
Index ¶
- Variables
- func NewLogger(level string, encoding string) *slog.Logger
- type Addon
- func (a *Addon) AddEndpoint(method, path string, handler http.HandlerFunc)
- func (a *Addon) AddSubtitleHandler(handler SubtitleHandler)
- func (a *Addon) DecodeUserData(param string, r *http.Request) (any, error)
- func (a *Addon) RegisterUserData(userDataObject any)
- func (a *Addon) Run(stoppingChan chan bool)
- func (a *Addon) SetConfigurationHandler(handler ConfigurationHandler)
- func (a *Addon) SetConfigurationUI(ui *ConfigurationUI)
- func (a *Addon) SetManifestCallback(callback ManifestCallback)
- type BehaviorHints
- type CatalogHandler
- type CatalogItem
- type ConfigurationField
- func (f *ConfigurationField) SetDefault(defaultValue any) *ConfigurationField
- func (f *ConfigurationField) SetDescription(description string) *ConfigurationField
- func (f *ConfigurationField) SetMax(max any) *ConfigurationField
- func (f *ConfigurationField) SetMin(min any) *ConfigurationField
- func (f *ConfigurationField) SetOptions(options []any) *ConfigurationField
- func (f *ConfigurationField) SetPattern(pattern string) *ConfigurationField
- func (f *ConfigurationField) SetPlaceholder(placeholder string) *ConfigurationField
- func (f *ConfigurationField) SetRequired(required bool) *ConfigurationField
- func (f *ConfigurationField) SetStep(step any) *ConfigurationField
- type ConfigurationHandler
- type ConfigurationUI
- type ExtraItem
- type Manifest
- type ManifestCallback
- type MetaBehaviorHints
- type MetaFetcher
- type MetaItem
- type MetaLinkItem
- type MetaPreviewItem
- type Options
- type PrefixedFS
- type ResourceItem
- type SeasonItem
- type StreamBehaviorHints
- type StreamHandler
- type StreamItem
- type SubtitleHandler
- type SubtitleItem
- type SubtitleProvider
- type VideoItem
Constants ¶
This section is empty.
Variables ¶
var ( // ErrBadRequest signals that the client sent a bad request. // It leads to a "400 Bad Request" response. ErrBadRequest = errors.New("bad request") // ErrNotFound signals that the catalog/meta/stream was not found. // It leads to a "404 Not Found" response. ErrNotFound = errors.New("not found") )
var DefaultOptions = Options{
BindAddr: "0.0.0.0",
Port: 8080,
LoggingLevel: "info",
LogEncoding: "console",
}
DefaultOptions contains the default values for Options.
Functions ¶
Types ¶
type Addon ¶
type Addon struct {
// contains filtered or unexported fields
}
Addon represents a remote addon. You can create one with NewAddon() and then run it with Run().
func NewAddon ¶
func NewAddon(manifest Manifest, catalogHandlers map[string]CatalogHandler, streamHandlers map[string]StreamHandler, opts Options) (*Addon, error)
NewAddon creates a new Addon object that can be started with Run(). A proper manifest must be supplied, but manifestCallback and all but one handler can be nil in case you only want to handle specific requests and opts can be the zero value of Options.
func (*Addon) AddEndpoint ¶
func (a *Addon) AddEndpoint(method, path string, handler http.HandlerFunc)
AddEndpoint adds a custom endpoint (a route and its handler). If you want to be able to access custom user data, you can use a path like this: "/:userData/foo" and then either deal with the data yourself by using `r.URL.Query().Get("userData")` in the handler, or use the convenience method `DecodeUserData("userData", r)`.
func (*Addon) AddSubtitleHandler ¶
func (a *Addon) AddSubtitleHandler(handler SubtitleHandler)
AddSubtitleHandler adds a subtitle handler to the addon
func (*Addon) DecodeUserData ¶
DecodeUserData decodes the request's user data and returns the result. It's useful when you add custom endpoints to the addon that don't have a userData parameter like the ManifestCallback, CatalogHandler and StreamHandler have. The param value must match the URL parameter you used when creating the custom endpoint, for example when using `AddEndpoint("GET", "/:userData/ping", customEndpoint)` you must pass "userData".
func (*Addon) RegisterUserData ¶
RegisterUserData registers the type of userData, so the addon can automatically unmarshal user data into an object of this type and pass the object into the manifest callback or catalog and stream handlers.
func (*Addon) Run ¶
Run starts the remote addon. It sets up an HTTP server that handles requests to "/manifest.json" etc. and gracefully handles shutdowns. The call is *blocking*, so use the stoppingChan param if you want to be notified when the addon is about to shut down because of a system signal like Ctrl+C or `docker stop`. It should be a buffered channel with a capacity of 1.
func (*Addon) SetConfigurationHandler ¶
func (a *Addon) SetConfigurationHandler(handler ConfigurationHandler)
SetConfigurationHandler sets the configuration handler
func (*Addon) SetConfigurationUI ¶
func (a *Addon) SetConfigurationUI(ui *ConfigurationUI)
SetConfigurationUI sets the configuration UI for the addon
func (*Addon) SetManifestCallback ¶
func (a *Addon) SetManifestCallback(callback ManifestCallback)
SetManifestCallback sets the manifest callback
type BehaviorHints ¶
type BehaviorHints struct {
// Note: Must include `omitempty`, otherwise it will be included if this struct is used in another one, even if the field of the containing struct is marked as `omitempty`
Adult bool `json:"adult,omitempty"`
P2P bool `json:"p2p,omitempty"`
Configurable bool `json:"configurable,omitempty"`
// If you set this to true, it will be true for the "/manifest.json" endpoint, but false for the "/:userData/manifest.json" endpoint, because otherwise Stremio won't show the "Install" button in its UI.
ConfigurationRequired bool `json:"configurationRequired,omitempty"`
}
type CatalogHandler ¶
CatalogHandler is the callback for catalog requests for a specific type (like "movie"). The id parameter is the catalog ID that you specified yourself in the CatalogItem objects in the Manifest. The userData parameter depends on whether you called `RegisterUserData()` before: If not, a simple string will be passed. It's empty if the user didn't provide user data. If yes, a pointer to an object you registered will be passed. It's nil if the user didn't provide user data.
type CatalogItem ¶
type CatalogItem struct {
Type string `json:"type"`
ID string `json:"id"`
Name string `json:"name"`
// Optional
Extra []ExtraItem `json:"extra,omitempty"`
}
CatalogItem represents a catalog.
type ConfigurationField ¶
type ConfigurationField struct {
Type string `json:"type"` // The type of the field (e.g. "text", "number", "boolean", etc.)
Label string `json:"label"` // The label of the field
Description string `json:"description,omitempty"` // The description of the field
Default any `json:"default,omitempty"` // The default value of the field
Required bool `json:"required,omitempty"` // Whether the field is required
Options []any `json:"options,omitempty"` // The options for the field (for select fields)
Min any `json:"min,omitempty"` // The minimum value (for number fields)
Max any `json:"max,omitempty"` // The maximum value (for number fields)
Step any `json:"step,omitempty"` // The step value (for number fields)
Pattern string `json:"pattern,omitempty"` // The pattern for validation (for text fields)
Placeholder string `json:"placeholder,omitempty"` // The placeholder text (for text fields)
}
ConfigurationField represents a field in the configuration UI
func NewConfigurationField ¶
func NewConfigurationField(fieldType string, label string) *ConfigurationField
NewConfigurationField creates a ConfigurationField with the given type and label
func (*ConfigurationField) SetDefault ¶
func (f *ConfigurationField) SetDefault(defaultValue any) *ConfigurationField
SetDefault sets the default value of the field
func (*ConfigurationField) SetDescription ¶
func (f *ConfigurationField) SetDescription(description string) *ConfigurationField
SetDescription sets the description of the field
func (*ConfigurationField) SetMax ¶
func (f *ConfigurationField) SetMax(max any) *ConfigurationField
SetMax sets the maximum value for the field
func (*ConfigurationField) SetMin ¶
func (f *ConfigurationField) SetMin(min any) *ConfigurationField
SetMin sets the minimum value for the field
func (*ConfigurationField) SetOptions ¶
func (f *ConfigurationField) SetOptions(options []any) *ConfigurationField
SetOptions sets the options for the field
func (*ConfigurationField) SetPattern ¶
func (f *ConfigurationField) SetPattern(pattern string) *ConfigurationField
SetPattern sets the pattern for validation
func (*ConfigurationField) SetPlaceholder ¶
func (f *ConfigurationField) SetPlaceholder(placeholder string) *ConfigurationField
SetPlaceholder sets the placeholder text
func (*ConfigurationField) SetRequired ¶
func (f *ConfigurationField) SetRequired(required bool) *ConfigurationField
SetRequired sets whether the field is required
func (*ConfigurationField) SetStep ¶
func (f *ConfigurationField) SetStep(step any) *ConfigurationField
SetStep sets the step value for the field
type ConfigurationHandler ¶
ConfigurationHandler is the callback for configuration requests. The userData parameter depends on whether you called `RegisterUserData()` before: If not, a simple string will be passed. It's empty if the user didn't provide user data. If yes, a pointer to an object you registered will be passed. It's nil if the user didn't provide user data.
type ConfigurationUI ¶
type ConfigurationUI struct {
Type string `json:"type"` // The type of configuration UI (e.g. "form", "list", etc.)
Properties map[string]any `json:"properties"` // The properties of the configuration UI
Required []string `json:"required,omitempty"` // The required fields
Default any `json:"default,omitempty"` // The default values
}
ConfigurationUI represents the configuration UI for the addon
func NewConfigurationUI ¶
func NewConfigurationUI(uiType string, properties map[string]any) *ConfigurationUI
NewConfigurationUI creates a ConfigurationUI with the given type and properties
func (*ConfigurationUI) AddRequiredField ¶
func (c *ConfigurationUI) AddRequiredField(field string)
AddRequiredField adds a required field to the configuration UI
func (*ConfigurationUI) SetDefault ¶
func (c *ConfigurationUI) SetDefault(defaultValue any)
SetDefault sets the default value for the configuration UI
type Manifest ¶
type Manifest struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Version string `json:"version"`
// One of the following is required
// Note: Can only have one in code because of how Go (de-)serialization works
//Resources []string `json:"resources,omitempty"`
ResourceItems []ResourceItem `json:"resources,omitempty"`
Types []string `json:"types"` // Stremio supports "movie", "series", "channel" and "tv"
Catalogs []CatalogItem `json:"catalogs"`
// Optional
IDprefixes []string `json:"idPrefixes,omitempty"`
Background string `json:"background,omitempty"` // URL
Logo string `json:"logo,omitempty"` // URL
ContactEmail string `json:"contactEmail,omitempty"`
BehaviorHints BehaviorHints `json:"behaviorHints,omitempty"`
}
Manifest describes the capabilities of the addon. See https://github.com/Stremio/stremio-addon-sdk/blob/f6f1f2a8b627b9d4f2c62b003b251d98adadbebe/docs/api/responses/manifest.md
type ManifestCallback ¶
ManifestCallback is the callback for manifest requests, so mostly addon installations. You can use the callback for two things:
- To *prevent* users from installing your addon in Stremio. The userData parameter depends on whether you called `RegisterUserData()` before: If not, a simple string will be passed. It's empty if the user didn't provide user data. If yes, a pointer to an object you registered will be passed. It's nil if the user didn't provide user data. Return an HTTP status code >= 400 to stop further processing and let the addon return that exact status code. Any status code < 400 will lead to the manifest being returned with a 200 OK status code in the response.
- To *alter* the manifest before it's returned. This can be useful for example if you want to return some catalogs depending on the userData. Note that the manifest is only returned if the first return value is < 400 (see point 1.).
type MetaBehaviorHints ¶
type MetaBehaviorHints struct {
DefaultVideoID string `json:"defaultVideoId,omitempty"` // ID of the default video to play
DefaultSeason string `json:"defaultSeason,omitempty"` // Default season for TV shows
DefaultEpisode string `json:"defaultEpisode,omitempty"` // Default episode for TV shows
AutoPlay bool `json:"autoPlay,omitempty"` // Whether to auto-play the content
BingeWatch bool `json:"bingeWatch,omitempty"` // Whether the content supports binge watching
Proxy bool `json:"proxy,omitempty"` // Whether the content should be proxied
}
MetaBehaviorHints provides additional information about the meta item
type MetaFetcher ¶
type MetaFetcher interface {
GetMovie(ctx context.Context, imdbID string) (cinemeta.Meta, error)
GetTVShow(ctx context.Context, imdbID string, season int, episode int) (cinemeta.Meta, error)
}
MetaFetcher returns metadata for movies and TV shows. It's used when you configure that the media name should be logged or that metadata should be put into the context.
type MetaItem ¶
type MetaItem struct {
ID string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
// Optional
Genres []string `json:"genres,omitempty"` // Will be replaced by Links at some point
Director []string `json:"director,omitempty"` // Will be replaced by Links at some point
Cast []string `json:"cast,omitempty"` // Will be replaced by Links at some point
Links []MetaLinkItem `json:"links,omitempty"` // For genres, director, cast and potentially more
Poster string `json:"poster,omitempty"` // URL
PosterShape string `json:"posterShape,omitempty"`
Background string `json:"background,omitempty"` // URL
Logo string `json:"logo,omitempty"` // URL
Description string `json:"description,omitempty"`
ReleaseInfo string `json:"releaseInfo,omitempty"` // E.g. "2000" for movies and "2000-2014" or "2000-" for TV shows
IMDbRating string `json:"imdbRating,omitempty"`
Released string `json:"released,omitempty"` // Must be ISO 8601, e.g. "2010-12-06T05:00:00.000Z"
Videos []VideoItem `json:"videos,omitempty"`
Runtime string `json:"runtime,omitempty"`
Language string `json:"language,omitempty"`
Country string `json:"country,omitempty"`
Awards string `json:"awards,omitempty"`
Website string `json:"website,omitempty"` // URL
BehaviorHints MetaBehaviorHints `json:"behaviorHints,omitempty"`
Popularity float64 `json:"popularity,omitempty"`
VoteAverage float64 `json:"voteAverage,omitempty"`
VoteCount int `json:"voteCount,omitempty"`
Status string `json:"status,omitempty"` // For TV shows: "Returning Series", "Ended", etc.
Network string `json:"network,omitempty"` // For TV shows
EpisodeRunTime []int `json:"episodeRunTime,omitempty"` // For TV shows
InProduction bool `json:"inProduction,omitempty"` // For TV shows
LastAirDate string `json:"lastAirDate,omitempty"` // For TV shows
NumberOfSeasons int `json:"numberOfSeasons,omitempty"` // For TV shows
NumberOfEpisodes int `json:"numberOfEpisodes,omitempty"` // For TV shows
CreatedBy []string `json:"createdBy,omitempty"` // For TV shows
Seasons []SeasonItem `json:"seasons,omitempty"` // For TV shows
}
MetaItem represents a meta item and is meant to be used when info for a specific item was requested. See https://github.com/Stremio/stremio-addon-sdk/blob/f6f1f2a8b627b9d4f2c62b003b251d98adadbebe/docs/api/responses/meta.md
type MetaLinkItem ¶
type MetaLinkItem struct {
Name string `json:"name"`
Category string `json:"category"`
URL string `json:"url"` // // URL. Can be "Meta Links" (see https://github.com/Stremio/stremio-addon-sdk/blob/f6f1f2a8b627b9d4f2c62b003b251d98adadbebe/docs/api/responses/meta.links.md)
}
MetaLinkItem links to a page within Stremio. It will at some point replace the usage of `genres`, `director` and `cast`. Note: It's not fully supported by Stremio yet (not fully on PC and not at all on Android)!
type MetaPreviewItem ¶
type MetaPreviewItem struct {
ID string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Poster string `json:"poster"` // URL
// Optional
PosterShape string `json:"posterShape,omitempty"`
// Optional, used for the "Discover" page sidebar
Genres []string `json:"genres,omitempty"` // Will be replaced by Links at some point
Director []string `json:"director,omitempty"` // Will be replaced by Links at some point
Cast []string `json:"cast,omitempty"` // Will be replaced by Links at some point
Links []MetaLinkItem `json:"links,omitempty"` // For genres, director, cast and potentially more
IMDbRating string `json:"imdbRating,omitempty"`
ReleaseInfo string `json:"releaseInfo,omitempty"` // E.g. "2000" for movies and "2000-2014" or "2000-" for TV shows
Description string `json:"description,omitempty"`
Released string `json:"released,omitempty"` // Must be ISO 8601, e.g. "2010-12-06T05:00:00.000Z"
Runtime string `json:"runtime,omitempty"`
Language string `json:"language,omitempty"`
Country string `json:"country,omitempty"`
Awards string `json:"awards,omitempty"`
Website string `json:"website,omitempty"` // URL
BehaviorHints MetaBehaviorHints `json:"behaviorHints,omitzero"`
}
MetaPreviewItem represents a meta preview item and is meant to be used within catalog responses. See https://github.com/Stremio/stremio-addon-sdk/blob/f6f1f2a8b627b9d4f2c62b003b251d98adadbebe/docs/api/responses/meta.md#meta-preview-object
type Options ¶
type Options struct {
// Server options
BindAddr string
Port int
// Logging options
Logger *slog.Logger
LoggingLevel string // "debug", "info", "warn", "error"
LogEncoding string // "json", "console"
DisableRequestLogging bool
LogIPs bool
LogUserAgent bool
LogMediaName bool
// Caching options
CacheAgeCatalogs time.Duration
CacheAgeStreams time.Duration
// If true, the addon will send Cache-Control headers with the max-age set to CacheAgeCatalogs/Streams.
// This is useful when you have a CDN in front of your addon.
CachePublicCatalogs bool
CachePublicStreams bool
// If true, the addon will handle ETag headers for catalogs and streams.
// This is useful when you have a CDN in front of your addon.
HandleEtagCatalogs bool
HandleEtagStreams bool
// Meta options
MetaClient MetaFetcher
CinemetaTimeout time.Duration
PutMetaInContext bool
// Configuration options
ConfigureHTMLfs http.FileSystem
// Other options
Metrics bool
Profiling bool
RedirectURL string
// If true, the addon will expect user data to be base64 encoded.
UserDataIsBase64 bool
// If set, the addon will only handle stream requests with IDs matching this regex.
StreamIDregex string
}
Options contains all options for creating a new addon.
type PrefixedFS ¶
type PrefixedFS struct {
// Prefix for adding to the filename before looking it up in the FS.
// Forward slashes are added before and after the prefix and then the file name is cleaned up (removing duplicate slashes).
Prefix string
// Regular HTTP FS which you can create with `http.FS(embedFS)` for example.
FS http.FileSystem
}
PrefixedFS is a wrapper around a http.FileSystem which adds a prefix before looking up the file. This is useful if you use the Go 1.16 embed feature and the directory name doesn't match the request URL. For example if your embed.FS contains a "/web/index.html", but you want to serve it for "/configure" requests, the filesystem middleware already takes care of stripping the "/configure" prefix, but then we also need to add the "/web" prefix. This wrapper does that.
type ResourceItem ¶
type SeasonItem ¶
type SeasonItem struct {
ID string `json:"id"`
Season int `json:"season"`
Name string `json:"name"`
Overview string `json:"overview,omitempty"`
Poster string `json:"poster,omitempty"` // URL
AirDate string `json:"airDate,omitempty"` // Must be ISO 8601
EpisodeCount int `json:"episodeCount,omitempty"`
}
SeasonItem represents a season in a TV show
type StreamBehaviorHints ¶
type StreamBehaviorHints struct {
CountryWhitelist []string `json:"countryWhitelist,omitempty"` // Array of ISO 3166-1 alpha-3 country codes in lowercase in which the stream is accessible
NotWebReady bool `json:"notWebReady,omitempty"` // Set to true if the URL does not support https or is not an MP4 file
BingeGroup string `json:"bingeGroup,omitempty"` // Identifies the stream's nature within the addon for binge watching
ProxyHeaders map[string]any `json:"proxyHeaders,omitempty"` // Headers that should be used for the stream
VideoHash string `json:"videoHash,omitempty"` // Calculated OpenSubtitles hash of the video
VideoSize int64 `json:"videoSize,omitempty"` // Size of the video file in bytes
Filename string `json:"filename,omitempty"` // Filename of the video file
BingeWatch bool `json:"bingeWatch,omitempty"` // Whether the stream supports binge watching
AutoPlay bool `json:"autoPlay,omitempty"` // Whether the stream should auto-play
Proxy bool `json:"proxy,omitempty"` // Whether the stream should be proxied
}
StreamBehaviorHints provides additional information about the stream
type StreamHandler ¶
StreamHandler is the callback for stream requests for a specific type (like "movie"). The context parameter contains a meta object under the key "meta" if PutMetaInContext was set to true in the addon options. The id parameter can be for example an IMDb ID if your addon handles the "movie" type. The userData parameter depends on whether you called `RegisterUserData()` before: If not, a simple string will be passed. It's empty if the user didn't provide user data. If yes, a pointer to an object you registered will be passed. It's nil if the user didn't provide user data.
type StreamItem ¶
type StreamItem struct {
// One of the following is required
URL string `json:"url,omitempty"` // Direct URL to a video stream - must be an MP4 through https; others supported (other video formats over http/rtmp supported if notWebReady is set)
YoutubeID string `json:"ytId,omitempty"` // YouTube video ID, plays using the built-in YouTube player
InfoHash string `json:"infoHash,omitempty"` // Info hash of a torrent file
ExternalURL string `json:"externalUrl,omitempty"` // Meta Link or an external URL to the video, which should be opened in a browser
// Optional
Name string `json:"name,omitempty"` // Name of the stream; usually used for stream quality
Title string `json:"title,omitempty"` // Description of the stream (warning: will soon be deprecated in favor of description)
Description string `json:"description,omitempty"` // Description of the stream (previously stream.title)
FileIndex uint8 `json:"fileIdx,omitempty"` // Index of the video file within the torrent (from infoHash); if not specified, the largest file will be selected
Subtitles []SubtitleItem `json:"subtitles,omitempty"` // Array of Subtitle objects representing subtitles for this stream
Sources []string `json:"sources,omitempty"` // Array of strings representing torrent tracker URLs and DHT network nodes
BehaviorHints StreamBehaviorHints `json:"behaviorHints,omitzero"`
}
StreamItem represents a stream for a MetaItem. See https://github.com/Stremio/stremio-addon-sdk/blob/f6f1f2a8b627b9d4f2c62b003b251d98adadbebe/docs/api/responses/stream.md
type SubtitleHandler ¶
type SubtitleHandler func(ctx context.Context, videoID string, userData any) ([]SubtitleItem, error)
SubtitleHandler is the callback for subtitle requests
type SubtitleItem ¶
type SubtitleItem struct {
ID string `json:"id"`
URL string `json:"url"` // URL to the subtitle file
Language string `json:"language"` // ISO 639-1 language code
Label string `json:"label"` // Human readable label
}
SubtitleItem represents a subtitle track for a stream
type SubtitleProvider ¶
type SubtitleProvider interface {
// GetSubtitles returns subtitles for a given video ID
GetSubtitles(ctx context.Context, videoID string) ([]SubtitleItem, error)
}
SubtitleProvider represents a provider of subtitles
type VideoItem ¶
type VideoItem struct {
ID string `json:"id"`
Title string `json:"title"`
Released string `json:"released"` // Must be ISO 8601, e.g. "2010-12-06T05:00:00.000Z"
// Optional
Thumbnail string `json:"thumbnail,omitempty"` // URL
Streams []StreamItem `json:"streams,omitempty"`
Available bool `json:"available,omitempty"`
Episode string `json:"episode,omitempty"`
Season string `json:"season,omitempty"`
Trailer string `json:"trailer,omitempty"` // Youtube ID
Overview string `json:"overview,omitempty"`
}