Documentation
¶
Overview ¶
Bounded in-memory memo used by the long-lived MCP server.
The point is to stop the three-tools-three-player-fetches pattern, not to be a general-purpose cache: entries are byte-bounded and evicted oldest-expiry first.
Track selection and caption download/parsing.
Channel discovery: resolve a handle/URL to a channel id, then list recent uploads from the channel's RSS feed.
RSS is the backbone because it carries exact publish timestamps. The richer `browse` grid also has duration and views but only relative times ("1 hour ago"), which cannot serve as a watermark for "what changed since last check".
Chapters are authored structure that already travels inside the description. Parsing them costs one regex pass and turns a 50-minute talk into addressable sections, which is what reading and citation plans actually need.
Innertube (youtubei) access — the same internal API the YouTube apps use.
Since mid-2025, caption track URLs handed to WEB clients require a "proof of origin" token; ANDROID and IOS client contexts still receive directly-downloadable signed URLs. We therefore cascade through ANDROID → IOS → watch-page scrape so one blocked endpoint doesn't take the whole fetch down. Stdlib only.
Package youtube acquires video metadata, captions, and channel listings from YouTube's internal endpoints. It owns the cache and the typed failure model; rendering and search live in separate packages.
Index ¶
- Constants
- func ExtractVideoID(urlOrID string) (string, error)
- func ParseLanguages(csv string) []string
- func ParseSince(s string) (time.Time, error)
- type CaptionSummary
- type ChannelInfo
- type ChannelListing
- type ChannelOptions
- type ChannelVideo
- type Chapter
- type Client
- func (c *Client) Channel(ctx context.Context, input string, opts ChannelOptions) (*ChannelListing, error)
- func (c *Client) Doctor(ctx context.Context, probe string) DoctorReport
- func (c *Client) Info(ctx context.Context, videoID string, descriptionChars int) (*VideoInfo, error)
- func (c *Client) Player(ctx context.Context, videoID string) (*playerResponse, string, error)
- func (c *Client) Tracks(ctx context.Context, videoID string) (via string, tracks []Track, err error)
- func (c *Client) Transcript(ctx context.Context, videoID string, opts TranscriptOptions) (*transcript.Transcript, error)
- type Config
- type DoctorClient
- type DoctorReport
- type Memo
- type Track
- type TranscriptOptions
- type VideoInfo
Constants ¶
const ( DefaultChannelLimit = 10 DefaultSummaryChars = 200 )
const DefaultDescriptionChars = 500
DefaultDescriptionChars is the description excerpt used by the CLI and MCP adapter when the caller does not specify one.
const OriginalLanguageValue = "original"
OriginalLanguageValue is the sentinel an agent passes to ask for the video's own track with no machine translation.
const TotalDeadline = 45 * time.Second
TotalDeadline bounds one acquisition operation: player fetch plus caption download share it instead of each getting a fresh budget.
Variables ¶
This section is empty.
Functions ¶
func ExtractVideoID ¶
ExtractVideoID accepts a YouTube URL or a bare 11-character video id.
func ParseLanguages ¶
ParseLanguages parses a comma-separated language list and defaults to "en".
Types ¶
type CaptionSummary ¶
type ChannelInfo ¶
type ChannelListing ¶
type ChannelListing struct {
OK bool `json:"ok"`
Channel ChannelInfo `json:"channel"`
Videos []ChannelVideo `json:"videos"`
Count int `json:"count"`
Available int `json:"available"`
NewestPublished string `json:"newest_published,omitempty"`
Truncated bool `json:"truncated"`
Notes []string `json:"notes,omitempty"`
}
type ChannelOptions ¶
ChannelOptions are resolved at the CLI/MCP boundary: Limit 0 means "all" (the feed cap), SummaryChars 0 means "omit the description excerpt".
type ChannelVideo ¶
type Chapter ¶
type Chapter struct {
StartSeconds int `json:"start_seconds"`
Timestamp string `json:"timestamp"`
Title string `json:"title"`
}
Chapter is an author-supplied section marker.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a cached YouTube acquisition session.
func NewClient ¶
func NewClient() *Client
NewClient returns a client using the production endpoints.
func NewClientWithConfig ¶
NewClientWithConfig returns a client with any unset fields filled from DefaultConfig.
func (*Client) Channel ¶
func (c *Client) Channel(ctx context.Context, input string, opts ChannelOptions) (*ChannelListing, error)
Channel lists a channel's recent uploads, newest first.
func (*Client) Doctor ¶
func (c *Client) Doctor(ctx context.Context, probe string) DoctorReport
Doctor checks which Innertube clients and the watch page still work.
func (*Client) Info ¶
func (c *Client) Info(ctx context.Context, videoID string, descriptionChars int) (*VideoInfo, error)
Info returns metadata without downloading a caption track.
func (*Client) Player ¶
Player returns a player response, memoized per video. Negative results (private, not found, no captions) are cached briefly so a probing agent cannot turn the improved error path into a hot loop.
Concurrent misses for the same video are coalesced: every caller waits on one upstream fetch, but each still honors its own context deadline. The shared fetch is detached from the first caller's cancellation so an abandoned request cannot fail the others; it keeps its own TotalDeadline.
func (*Client) Tracks ¶
func (c *Client) Tracks(ctx context.Context, videoID string) (via string, tracks []Track, err error)
Tracks lists caption tracks and the acquisition source that produced them.
func (*Client) Transcript ¶
func (c *Client) Transcript(ctx context.Context, videoID string, opts TranscriptOptions) (*transcript.Transcript, error)
Transcript fetches and caches a caption track for a video.
type Config ¶
type Config struct {
InnertubeURL string
WatchPageURL string
ResolveURL string
FeedURL string
HTTPClient *http.Client
}
Config lets tests and embedders point acquisition at another origin.
type DoctorClient ¶
type DoctorClient struct {
Client string `json:"client"`
Version string `json:"version,omitempty"`
OK bool `json:"ok"`
Title string `json:"title,omitempty"`
CaptionTracks int `json:"caption_tracks,omitempty"`
MS int64 `json:"ms,omitempty"`
Code apperr.Code `json:"code,omitempty"`
Error string `json:"error,omitempty"`
}
DoctorClient is one acquisition path's health result.
type DoctorReport ¶
type DoctorReport struct {
ProbeVideo string `json:"probe_video"`
OKClients int `json:"ok_clients"`
TotalMS int64 `json:"total_ms"`
Results []DoctorClient `json:"results"`
Verdict string `json:"verdict"`
}
DoctorReport is the result of probing each acquisition path.
type Track ¶
type Track struct {
Language string
Kind string // "asr" = auto-generated
Translatable bool
Name string
}
Track is the public view of a caption track.
type TranscriptOptions ¶
TranscriptOptions controls caption-track selection.
type VideoInfo ¶
type VideoInfo struct {
OK bool `json:"ok"`
VideoID string `json:"video_id"`
Title string `json:"title"`
Channel string `json:"channel"`
ChannelID string `json:"channel_id"`
DurationSeconds int `json:"duration_seconds"`
ViewCount int64 `json:"view_count"`
IsLive bool `json:"is_live"`
IsLiveContent bool `json:"is_live_content"`
PublishedAt string `json:"published_at,omitempty"`
Category string `json:"category,omitempty"`
Keywords []string `json:"keywords,omitempty"`
Description string `json:"description"`
DescriptionTruncated bool `json:"description_truncated"`
Chapters []Chapter `json:"chapters,omitempty"`
Captions CaptionSummary `json:"captions"`
EstimatedTranscriptChars int `json:"estimated_transcript_chars"`
EstimatedTranscriptTokens int `json:"estimated_transcript_tokens"`
URL string `json:"url"`
Via string `json:"via"`
}