Help us shape the future of Go! Take the 2026 Go Developer Survey

markers

package
v0.3.2 Latest Latest
Warning

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

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

Documentation

Overview

Package markers supplies release-duration-specific skip ranges. Remote lookups are opt-in and cached; no submissions are ever sent.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Probe added in v0.3.0

func Probe(ctx context.Context, baseURL, apiKey string) error

Probe checks that TheIntroDB answers, and that apiKey is accepted when one is set. An empty key probes the public lookup. 404 still means the service accepted the request.

Types

type Coverage

type Coverage struct {
	ShowID          int64 `json:"showId"`
	CachedEpisodes  int   `json:"cachedEpisodes"`
	IntroEpisodes   int   `json:"introEpisodes"`
	CreditsEpisodes int   `json:"creditsEpisodes"`
	RecapEpisodes   int   `json:"recapEpisodes"`
}

type DialogueCue

type DialogueCue struct {
	Start, End time.Duration
}

DialogueCue is one already-available subtitle cue time (text not needed).

type Lookup added in v0.3.0

type Lookup struct {
	Enabled    bool
	APIKey     string
	IntroOff   bool
	CreditsOff bool
}

Lookup is the live skip-marker configuration. IntroOff and CreditsOff hide those buttons. The zero value offers both.

type Marker

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

func ApplyStingers

func ApplyStingers(markers []Marker, stingers []Stinger, duration time.Duration) []Marker

ApplyStingers cuts stinger ranges out of credits markers, splitting one credits marker into the pieces before and after each stinger. Pieces under two seconds are dropped (a breath of crawl is not skippable). Afterwards exactly the last credits marker may be Final, and only when it reaches the end of the media — the shape PMS emits.

func FromChapters

func FromChapters(info core.MediaInfo) []Marker

FromChapters uses explicit chapter labels only; generic Chapter 01 is not evidence.

type Options

type Options struct {
	Config func() Lookup // current IntroDB lookup and which skip buttons are offered

	Logger     *slog.Logger
	DB         *sql.DB
	Enabled    bool
	BaseURL    string
	APIKey     string
	HTTPClient *http.Client
	TTL        time.Duration
	Now        func() time.Time

	// Aligner, when set, shifts TheIntroDB markers from the reference
	// runtime they were submitted against into the played release's
	// timeline (dialogue-based, no video downloaded).
	Aligner core.TimelineAligner
	// AlignTimeout bounds one marker-shifting alignment (default 10s);
	// on failure the unshifted markers are kept.
	AlignTimeout time.Duration
	// Dialogue supplies already-available subtitle cue times for the
	// played release (cached sidecars), used for stinger detection.
	Dialogue func(ctx context.Context, key core.RatingKey, info core.MediaInfo) ([]DialogueCue, bool)
}

type Service

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

func New

func New(o Options) *Service

func (*Service) CachedMarkers added in v0.3.0

func (s *Service) CachedMarkers(ctx context.Context, key core.RatingKey, info core.MediaInfo) ([]Marker, error)

CachedMarkers uses chapters and locally cached ranges only. It never fetches or aligns remote markers, making it safe for non-resolving detail pages.

func (*Service) Coverage

func (s *Service) Coverage(ctx context.Context, show int64) (Coverage, error)

Coverage counts observed cached episodes; it does not imply coverage of the show's entire catalogue or that an official client displayed skip controls.

func (*Service) Handler

func (s *Service) Handler() http.Handler

Handler serves GET /shows/{TMDBID}, behind the owner's admin authentication.

func (*Service) Markers

func (s *Service) Markers(ctx context.Context, key core.RatingKey, info core.MediaInfo) ([]Marker, error)

Markers returns the skip ranges for one probed release: chapter and remote markers (shifted into this release's timeline when they were submitted against a different cut), with stinger scenes cut out of the credits ranges.

func (*Service) Prune

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

Prune deletes expired rows from the remote-lookup cache (markers_cache). An expired row is never served, so this only reclaims space; the next playback re-fetches as it would anyway.

func (*Service) Put

func (s *Service) Put(ctx context.Context, key core.RatingKey, d time.Duration, ranges []Marker) error

type Stinger

type Stinger struct {
	Start, End time.Duration
}

Stinger is a scene inside the credits range that must not be skipped.

func StingersFromChapters

func StingersFromChapters(info core.MediaInfo) []Stinger

StingersFromChapters finds post-credits scenes in the chapter layout: explicitly named stinger chapters, and the structural pattern of a short chapter sandwiched after a long credits chapter near the tail.

func StingersFromDialogue

func StingersFromDialogue(cues []DialogueCue, creditsStart, duration time.Duration) []Stinger

StingersFromDialogue finds dialogue clusters that resume well inside the credits range after a long cue gap: the shape of a mid-/post-credits scene. Lyrics running continuously from the credits start never qualify, because their first cue follows the credits start without a long gap and their cues continue without one.

Jump to

Keyboard shortcuts

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