youtube

package module
v0.0.0-...-15efdca Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2024 License: MIT Imports: 14 Imported by: 0

README

youtube

MIT License go.dev reference Discord Chat

A library for retrieving metadata and obtaining direct links to video-only/audio-only/muxed streams of videos on YouTube in Go.

Inspiration

I was always curious on how YouTube downloader sites and software worked. So, I took the time to trace and reverse-engineer how HTTP requests are made to YouTube to then allow for video/audio from YouTube to be played on mobile/in the browser.

As a result, this library in Go allows for you to retrieve direct links to video-only/audio-only/muxed streams to YouTube videos, retrieve metadata of YouTube videos, and make searches for videos on YouTube without any need for an API key and without any usage quota restrictions.

This library also exposes all of its methods for decoding encrypted direct links to media, and decoding/parsing both JSON and URL-encoded documents returned by YouTube.

Many thanks to the library and blog posts from Tyrrrz/YoutubeExplode for giving me a good direction on how to get down-and-dirty tracing and decoding HTTP requests on YouTube.

Features

  • Does not use require an API key or have any usage quotas.
  • Retrieve direct links to video-only/audio-only/muxed streams to YouTube videos.
  • Retrieve metadata of videos or playlists on YouTube.
  • Search for videos/audio on YouTube.
  • Set timeouts/deadlines for all methods.
  • Minimal dependencies.
  • Concurrency-safe.

Setup

$ go get github.com/lithdew/youtube

Example

This example uses my library lithdew/nicehttp for downloading video/audio from YouTube as fast as possible in fixed-sized chunks with multiple workers working in parallel.

It searches for the song The Glitch Mob - Animus Vox on YouTube and downloads its audio, video, and muxed versions to disk.

It additionally prints all metadata pertaining to the first video it finds.

package main

import (
	"fmt"
	"github.com/lithdew/nicehttp"
	"github.com/lithdew/youtube"
)

func check(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	// Search for the song Animus Vox by The Glitch Mob.

	results, err := youtube.Search("animus vox", 0)
	check(err)

	fmt.Printf("Got %d search result(s).\n\n", results.Hits)

	if len(results.Items) == 0 {
		check(fmt.Errorf("got zero search results"))
	}

	// Get the first search result and print out its details.

	details := results.Items[0]

	fmt.Printf(
		"ID: %q\n\nTitle: %q\nAuthor: %q\nDuration: %q\n\nView Count: %q\nLikes: %d\nDislikes: %d\n\n",
		details.ID,
		details.Title,
		details.Author,
		details.Duration,
		details.Views,
		details.Likes,
		details.Dislikes,
	)

	// Instantiate a player for the first search result.

	player, err := youtube.Load(details.ID)
	check(err)

	// Fetch audio-only direct link.

	stream, ok := player.SourceFormats().AudioOnly().BestAudio()
	if !ok {
		check(fmt.Errorf("no audio-only stream available"))
	}

	audioOnlyFilename := "audio." + stream.FileExtension()

	audioOnlyURL, err := player.ResolveURL(stream)
	check(err)

	fmt.Printf("Audio-only direct link: %q\n", audioOnlyURL)

	// Fetch video-only direct link.

	stream, ok = player.SourceFormats().VideoOnly().BestVideo()
	if !ok {
		check(fmt.Errorf("no video-only stream available"))
	}

	videoOnlyFilename := "video." + stream.FileExtension()

	videoOnlyURL, err := player.ResolveURL(stream)
	check(err)

	fmt.Printf("Video-only direct link: %q\n", videoOnlyURL)

	// Fetch muxed video/audio direct link.

	stream, ok = player.MuxedFormats().BestVideo()
	if !ok {
		check(fmt.Errorf("no muxed stream available"))
	}

	muxedFilename := "muxed." + stream.FileExtension()

	muxedURL, err := player.ResolveURL(stream)
	check(err)

	fmt.Printf("Muxed (video/audio) direct link: %q\n", muxedURL)

	// Download all the links.

	check(nicehttp.DownloadFile(audioOnlyFilename, audioOnlyURL))
	check(nicehttp.DownloadFile(videoOnlyFilename, videoOnlyURL))
	check(nicehttp.DownloadFile(muxedFilename, muxedURL))
}

You can run this example by running:

$ go run github.com/lithdew/youtube/cmd/example

An extended example is also provided for downloading to disk the highest quality audio-only stream of any YouTube video. It may be run by running:

$ go run github.com/lithdew/youtube/cmd/music https://www.youtube.com/watch?v=jPan651rVMs

What's missing?

Although this library is feature-complete for several use cases, there are a few things intentionally missing as I started this library as just a side project. The features missing are:

  1. Fetching video captions.
  2. Fetching video comments.
  3. DASH manifest support.
  4. Livestream support.

Should there be enough demand however, I'll look into taking some time to incorporate these features into this library :).

Open a Github issue to express your interest!

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	RegexWatchPlayerConfig = regexp.MustCompile(`ytplayer\.config = ({(?:"\w+":(?:.*?))*});`)
	RegexEmbedPlayerConfig = regexp.MustCompile(`yt\.setConfig\({'PLAYER_CONFIG': (.*?)}\)`)
)
View Source
var AudioQuality = map[string]int{
	"AUDIO_QUALITY_LOW":    0,
	"AUDIO_QUALITY_MEDIUM": 1,
	"AUDIO_QUALITY_HIGH":   2,
}
View Source
var ITags = [...]ITag{
	5: {
		Extension:     "flv",
		Resolution:    "240p",
		VideoEncoding: "Sorenson H.283",
		AudioEncoding: "mp3",
		AudioBitrate:  64,
	},
	6: {
		Extension:     "flv",
		Resolution:    "270p",
		VideoEncoding: "Sorenson H.263",
		AudioEncoding: "mp3",
		AudioBitrate:  64,
	},
	13: {
		Extension:     "3gp",
		VideoEncoding: "MPEG-4 Visual",
		AudioEncoding: "aac",
	},
	17: {
		Extension:     "3gp",
		Resolution:    "144p",
		VideoEncoding: "MPEG-4 Visual",
		AudioEncoding: "aac",
		AudioBitrate:  24,
	},
	18: {
		Extension:     "mp4",
		Resolution:    "360p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  96,
	},
	22: {
		Extension:     "mp4",
		Resolution:    "720p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  192,
	},
	34: {
		Extension:     "flv",
		Resolution:    "480p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  128,
	},
	35: {
		Extension:     "flv",
		Resolution:    "360p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  128,
	},
	36: {
		Extension:     "3gp",
		Resolution:    "240p",
		VideoEncoding: "MPEG-4 Visual",
		AudioEncoding: "aac",
		AudioBitrate:  36,
	},
	37: {
		Extension:     "mp4",
		Resolution:    "1080p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  192,
	},
	38: {
		Extension:     "mp4",
		Resolution:    "3072p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  192,
	},
	43: {
		Extension:     "webm",
		Resolution:    "360p",
		VideoEncoding: "VP8",
		AudioEncoding: "vorbis",
		AudioBitrate:  128,
	},
	44: {
		Extension:     "webm",
		Resolution:    "480p",
		VideoEncoding: "VP8",
		AudioEncoding: "vorbis",
		AudioBitrate:  128,
	},
	45: {
		Extension:     "webm",
		Resolution:    "720p",
		VideoEncoding: "VP8",
		AudioEncoding: "vorbis",
		AudioBitrate:  192,
	},
	46: {
		Extension:     "webm",
		Resolution:    "1080p",
		VideoEncoding: "VP8",
		AudioEncoding: "vorbis",
		AudioBitrate:  192,
	},
	82: {
		Extension:     "mp4",
		Resolution:    "360p",
		VideoEncoding: "H.264",
		AudioBitrate:  96,
	},
	83: {
		Extension:     "mp4",
		Resolution:    "240p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  96,
	},
	84: {
		Extension:     "mp4",
		Resolution:    "720p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  192,
	},
	85: {
		Extension:     "mp4",
		Resolution:    "1080p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  192,
	},
	100: {
		Extension:     "webm",
		Resolution:    "360p",
		VideoEncoding: "VP8",
		AudioEncoding: "vorbis",
		AudioBitrate:  128,
	},
	101: {
		Extension:     "webm",
		Resolution:    "360p",
		VideoEncoding: "VP8",
		AudioEncoding: "vorbis",
		AudioBitrate:  192,
	},
	102: {
		Extension:     "webm",
		Resolution:    "720p",
		VideoEncoding: "VP8",
		AudioEncoding: "vorbis",
		AudioBitrate:  192,
	},
	133: {
		Extension:     "mp4",
		Resolution:    "240p",
		VideoEncoding: "H.264",
	},
	134: {
		Extension:     "mp4",
		Resolution:    "360p",
		VideoEncoding: "H.264",
	},
	135: {
		Extension:     "mp4",
		Resolution:    "480p",
		VideoEncoding: "H.264",
	},
	136: {
		Extension:     "mp4",
		Resolution:    "720p",
		VideoEncoding: "H.264",
	},
	137: {
		Extension:     "mp4",
		Resolution:    "1080p",
		VideoEncoding: "H.264",
	},
	138: {
		Extension:     "mp4",
		Resolution:    "2160p",
		VideoEncoding: "H.264",
	},
	160: {
		Extension:     "mp4",
		Resolution:    "144p",
		VideoEncoding: "H.264",
	},
	242: {
		Extension:     "webm",
		Resolution:    "240p",
		VideoEncoding: "VP9",
	},
	243: {
		Extension:     "webm",
		Resolution:    "360p",
		VideoEncoding: "VP9",
	},
	244: {
		Extension:     "webm",
		Resolution:    "480p",
		VideoEncoding: "VP9",
	},
	247: {
		Extension:     "webm",
		Resolution:    "720p",
		VideoEncoding: "VP9",
	},
	248: {
		Extension:     "webm",
		Resolution:    "1080p",
		VideoEncoding: "VP9",
		AudioBitrate:  9,
	},
	264: {
		Extension:     "mp4",
		Resolution:    "1440p",
		VideoEncoding: "H.264",
	},
	266: {
		Extension:     "mp4",
		Resolution:    "2160p",
		VideoEncoding: "H.264",
	},
	271: {
		Extension:     "webm",
		Resolution:    "1440p",
		VideoEncoding: "VP9",
	},
	272: {
		Extension:     "webm",
		Resolution:    "2160p",
		VideoEncoding: "VP9",
	},
	278: {
		Extension:     "webm",
		Resolution:    "144p",
		VideoEncoding: "VP9",
	},
	298: {
		Extension:     "mp4",
		Resolution:    "720p",
		VideoEncoding: "H.264",
		FPS:           60,
	},
	299: {
		Extension:     "mp4",
		Resolution:    "1080p",
		VideoEncoding: "H.264",
		FPS:           60,
	},
	302: {
		Extension:     "webm",
		Resolution:    "720p",
		VideoEncoding: "VP9",
		FPS:           60,
	},
	303: {
		Extension:     "webm",
		Resolution:    "1080p",
		VideoEncoding: "VP9",
		FPS:           60,
	},
	308: {
		Extension:     "webm",
		Resolution:    "1440p",
		VideoEncoding: "VP9",
		FPS:           60,
	},
	313: {
		Extension:     "webm",
		Resolution:    "2160p",
		VideoEncoding: "VP9",
	},
	315: {
		Extension:     "webm",
		Resolution:    "2160p",
		VideoEncoding: "VP9",
		FPS:           60,
	},
	139: {
		Extension:     "mp4",
		AudioEncoding: "aac",
		AudioBitrate:  48,
	},
	140: {
		Extension:     "mp4",
		AudioEncoding: "aac",
		AudioBitrate:  128,
	},
	141: {
		Extension:     "mp4",
		AudioEncoding: "aac",
		AudioBitrate:  256,
	},
	171: {
		Extension:     "webm",
		AudioEncoding: "vorbis",
		AudioBitrate:  128,
	},
	172: {
		Extension:     "webm",
		AudioEncoding: "vorbis",
		AudioBitrate:  192,
	},
	249: {
		Extension:     "webm",
		AudioEncoding: "opus",
		AudioBitrate:  50,
	},
	250: {
		Extension:     "webm",
		AudioEncoding: "opus",
		AudioBitrate:  70,
	},
	251: {
		Extension:     "webm",
		AudioEncoding: "opus",
		AudioBitrate:  160,
	},
	92: {
		Extension:     "ts",
		Resolution:    "240p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  48,
	},
	93: {
		Extension:     "ts",
		Resolution:    "480p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  128,
	},
	94: {
		Extension:     "ts",
		Resolution:    "720p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  128,
	},
	95: {
		Extension:     "ts",
		Resolution:    "1080p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  256,
	},
	96: {
		Extension:     "ts",
		Resolution:    "720p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  256,
	},
	120: {
		Extension:     "flv",
		Resolution:    "720p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  128,
	},
	127: {
		Extension:     "ts",
		AudioEncoding: "aac",
		AudioBitrate:  96,
	},
	128: {
		Extension:     "ts",
		AudioEncoding: "aac",
		AudioBitrate:  96,
	},
	132: {
		Extension:     "ts",
		Resolution:    "240p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  48,
	},
	151: {
		Extension:     "ts",
		Resolution:    "720p",
		VideoEncoding: "H.264",
		AudioEncoding: "aac",
		AudioBitrate:  24,
	},
	394: {
		Extension:     "mp4",
		Resolution:    "144p",
		VideoEncoding: "AV1",
	},
	395: {
		Extension:     "mp4",
		Resolution:    "240p",
		VideoEncoding: "AV1",
	},
	396: {
		Extension:     "mp4",
		Resolution:    "360p",
		VideoEncoding: "AV1",
	},
	397: {
		Extension:     "mp4",
		Resolution:    "480p",
		VideoEncoding: "AV1",
	},
	398: {
		Extension:     "mp4",
		Resolution:    "720p",
		VideoEncoding: "AV1",
	},
	399: {
		Extension:     "mp4",
		Resolution:    "1080p",
		VideoEncoding: "AV1",
	},
	400: {
		Extension:     "mp4",
		Resolution:    "1440p",
		VideoEncoding: "AV1",
	},
	401: {
		Extension:     "mp4",
		Resolution:    "2160p",
		VideoEncoding: "AV1",
	},
	402: {
		Extension:     "mp4",
		Resolution:    "2880p",
		VideoEncoding: "AV1",
	},
}
View Source
var RegexStreamID = regexp.MustCompile(`(?i)([a-z0-9_-]{11})`)
View Source
var VideoQuality = map[string]int{
	"tiny":   0,
	"low":    1,
	"medium": 2,
	"large":  3,
	"hd1440": 4,
	"hd2160": 5,
}

Functions

This section is empty.

Types

type Assets

type Assets struct {
	CSS string `json:"css"`
	JS  string `json:"js"`
}

func LoadEmbedPlayerAssets

func LoadEmbedPlayerAssets(id StreamID) (Assets, error)

func LoadEmbedPlayerAssetsDeadline

func LoadEmbedPlayerAssetsDeadline(id StreamID, deadline time.Time) (Assets, error)

func LoadEmbedPlayerAssetsTimeout

func LoadEmbedPlayerAssetsTimeout(id StreamID, timeout time.Duration) (Assets, error)

func ParseAssetsJSON

func ParseAssetsJSON(v *fastjson.Value) Assets

func (Assets) LoadCSS

func (p Assets) LoadCSS(t Transport) (string, error)

func (Assets) LoadCSSDeadline

func (p Assets) LoadCSSDeadline(t Transport, deadline time.Time) (string, error)

func (Assets) LoadCSSTimeout

func (p Assets) LoadCSSTimeout(t Transport, timeout time.Duration) (string, error)

func (Assets) LoadJS

func (p Assets) LoadJS(t Transport) (string, error)

func (Assets) LoadJSDeadline

func (p Assets) LoadJSDeadline(t Transport, deadline time.Time) (string, error)

func (Assets) LoadJSTimeout

func (p Assets) LoadJSTimeout(t Transport, timeout time.Duration) (string, error)

type Cipher

type Cipher struct {
	URL             string `json:"url"`
	Signature       string `json:"s"`
	SignaturePolicy string `json:"sp"`
}

func ParseCipherJSON

func ParseCipherJSON(v *fastjson.Value) Cipher

func (Cipher) DecodeURL

func (c Cipher) DecodeURL(script string) (string, error)

type Client

type Client struct {
	Transport
}

func NewClient

func NewClient() Client

func WrapClient

func WrapClient(transport Transport) Client

func (*Client) Load

func (c *Client) Load(id StreamID) (Player, error)

func (*Client) LoadDeadline

func (c *Client) LoadDeadline(id StreamID, deadline time.Time) (Player, error)

func (*Client) LoadEmbedPlayer

func (c *Client) LoadEmbedPlayer(id StreamID) (Player, error)

func (*Client) LoadEmbedPlayerAssets

func (c *Client) LoadEmbedPlayerAssets(id StreamID) (Assets, error)

func (*Client) LoadEmbedPlayerAssetsDeadline

func (c *Client) LoadEmbedPlayerAssetsDeadline(id StreamID, deadline time.Time) (Assets, error)

func (*Client) LoadEmbedPlayerAssetsTimeout

func (c *Client) LoadEmbedPlayerAssetsTimeout(id StreamID, timeout time.Duration) (Assets, error)

func (*Client) LoadEmbedPlayerDeadline

func (c *Client) LoadEmbedPlayerDeadline(id StreamID, deadline time.Time) (Player, error)

func (*Client) LoadEmbedPlayerStreams

func (c *Client) LoadEmbedPlayerStreams(id StreamID) (Streams, error)

func (*Client) LoadEmbedPlayerStreamsDeadline

func (c *Client) LoadEmbedPlayerStreamsDeadline(id StreamID, deadline time.Time) (Streams, error)

func (*Client) LoadEmbedPlayerStreamsTimeout

func (c *Client) LoadEmbedPlayerStreamsTimeout(id StreamID, timeout time.Duration) (Streams, error)

func (*Client) LoadEmbedPlayerTimeout

func (c *Client) LoadEmbedPlayerTimeout(id StreamID, timeout time.Duration) (Player, error)

func (*Client) LoadPlaylist

func (c *Client) LoadPlaylist(id string, offset uint) (PlaylistResult, error)

func (*Client) LoadPlaylistDeadline

func (c *Client) LoadPlaylistDeadline(id string, offset uint, deadline time.Time) (PlaylistResult, error)

func (*Client) LoadPlaylistTimeout

func (c *Client) LoadPlaylistTimeout(id string, offset uint, timeout time.Duration) (PlaylistResult, error)

func (*Client) LoadTimeout

func (c *Client) LoadTimeout(id StreamID, timeout time.Duration) (Player, error)

func (*Client) LoadWatchPlayer

func (c *Client) LoadWatchPlayer(id StreamID) (Player, error)

func (*Client) LoadWatchPlayerDeadline

func (c *Client) LoadWatchPlayerDeadline(id StreamID, deadline time.Time) (Player, error)

func (*Client) LoadWatchPlayerTimeout

func (c *Client) LoadWatchPlayerTimeout(id StreamID, timeout time.Duration) (Player, error)

func (*Client) Search

func (c *Client) Search(query string, page uint) (SearchResult, error)

func (*Client) SearchDeadline

func (c *Client) SearchDeadline(query string, page uint, deadline time.Time) (SearchResult, error)

func (*Client) SearchTimeout

func (c *Client) SearchTimeout(query string, page uint, timeout time.Duration) (SearchResult, error)

type ColorInfo

type ColorInfo struct {
	Primaries               string `json:"primaries"`
	TransferCharacteristics string `json:"transferCharacteristics"`
	MatrixCoefficients      string `json:"matrixCoefficients"`
}

func ParseColorInfoJSON

func ParseColorInfoJSON(v *fastjson.Value) ColorInfo

type Format

type Format struct {
	AverageBitrate   uint   `json:"averageBitrate"`
	ApproxDurationMs string `json:"approxDurationMs"`
	ContentLength    string `json:"contentLength"`
	Bitrate          uint   `json:"bitrate"`

	URL    *string `json:"url,omitempty"`
	Cipher *Cipher `json:"cipher,omitempty"`

	Quality      string `json:"quality"`
	QualityLabel string `json:"qualityLabel"`

	ITag     uint   `json:"itag"`
	MIMEType string `json:"mimeType"`

	Width  uint `json:"width"`
	Height uint `json:"height"`

	FPS       *uint      `json:"fps,omitempty"`
	ColorInfo *ColorInfo `json:"colorInfo,omitempty"`

	AudioQuality    *string `json:"audioQuality,omitempty"`
	AudioChannels   *uint   `json:"audioChannels,omitempty"`
	AudioSampleRate *string `json:"audioSampleRate,omitempty"`

	InitRange  *TimeRange `json:"initRange,omitempty"`
	IndexRange *TimeRange `json:"indexRange,omitempty"`

	LastModified    string `json:"lastModified"`
	HighReplication bool   `json:"highReplication,omitempty"`

	ProjectionType string `json:"projectionType"`
}

func ParseFormatJSON

func ParseFormatJSON(v *fastjson.Value) Format

func SearchForBestAudioQuality

func SearchForBestAudioQuality(formats Formats) (Format, bool)

func SearchForBestVideoQuality

func SearchForBestVideoQuality(formats Formats) (Format, bool)

func (Format) FileExtension

func (f Format) FileExtension() string

type Formats

type Formats []Format

func FilterAudioStreams

func FilterAudioStreams(formats Formats) Formats

func FilterVideoStreams

func FilterVideoStreams(formats Formats) Formats

func SortByAudioQuality

func SortByAudioQuality(formats Formats) Formats

func SortByVideoQuality

func SortByVideoQuality(formats Formats) Formats

func (Formats) AudioOnly

func (f Formats) AudioOnly() Formats

func (Formats) BestAudio

func (f Formats) BestAudio() (Format, bool)

func (Formats) BestVideo

func (f Formats) BestVideo() (Format, bool)

func (Formats) SortByAudioQuality

func (f Formats) SortByAudioQuality() Formats

func (Formats) SortByVideoQuality

func (f Formats) SortByVideoQuality() Formats

func (Formats) VideoOnly

func (f Formats) VideoOnly() Formats

type ITag

type ITag struct {
	Extension     string
	Resolution    string
	VideoEncoding string
	AudioEncoding string
	AudioBitrate  int
	FPS           int
}

type ListItem

type ListItem struct {
	ID StreamID `json:"encrypted_id"`

	Title       string `json:"title"`
	Description string `json:"description"`
	Thumbnail   string `json:"thumbnail"`

	Added       string    `json:"added"`
	TimeCreated time.Time `json:"time_created"`

	Rating   float64 `json:"rating"`
	Likes    uint    `json:"likes"`
	Dislikes uint    `json:"dislikes"`

	Views    string `json:"views"`
	Comments string `json:"comments"`

	Duration      string        `json:"duration"`
	LengthSeconds time.Duration `json:"length_seconds"`

	Author  string `json:"author"`
	UserID  string `json:"user_id"`
	Privacy string `json:"privacy"`

	CategoryID uint `json:"category_id"`

	IsHD bool `json:"is_hd"`
	IsCC bool `json:"is_cc"`

	CCLicense bool `json:"cc_license"`

	Keywords []string `json:"keywords"`
}

func ParseListItem

func ParseListItem(v *fastjson.Value) ListItem

type Player

type Player struct {
	Transport
	Assets
	Streams
}

func Load

func Load(id StreamID) (Player, error)

func LoadDeadline

func LoadDeadline(id StreamID, deadline time.Time) (Player, error)

func LoadEmbedPlayer

func LoadEmbedPlayer(id StreamID) (Player, error)

func LoadEmbedPlayerDeadline

func LoadEmbedPlayerDeadline(id StreamID, deadline time.Time) (Player, error)

func LoadEmbedPlayerTimeout

func LoadEmbedPlayerTimeout(id StreamID, timeout time.Duration) (Player, error)

func LoadTimeout

func LoadTimeout(id StreamID, timeout time.Duration) (Player, error)

func LoadWatchPlayer

func LoadWatchPlayer(id StreamID) (Player, error)

func LoadWatchPlayerDeadline

func LoadWatchPlayerDeadline(id StreamID, deadline time.Time) (Player, error)

func LoadWatchPlayerTimeout

func LoadWatchPlayerTimeout(id StreamID, timeout time.Duration) (Player, error)

func (Player) ResolveURL

func (p Player) ResolveURL(v Format) (string, error)

func (Player) ResolveURLDeadline

func (p Player) ResolveURLDeadline(v Format, deadline time.Time) (string, error)

func (Player) ResolveURLTimeout

func (p Player) ResolveURLTimeout(v Format, timeout time.Duration) (string, error)

type PlaylistResult

type PlaylistResult struct {
	Title       string `json:"title"`
	Author      string `json:"author"`
	Description string `json:"description"`
	Views       uint   `json:"views"`

	Items []ListItem `json:"video"`
}

func LoadPlaylist

func LoadPlaylist(id string, offset uint) (PlaylistResult, error)

func LoadPlaylistDeadline

func LoadPlaylistDeadline(id string, offset uint, deadline time.Time) (PlaylistResult, error)

func LoadPlaylistTimeout

func LoadPlaylistTimeout(id string, offset uint, timeout time.Duration) (PlaylistResult, error)

func ParsePlaylistResultJSON

func ParsePlaylistResultJSON(v *fastjson.Value) PlaylistResult

type SearchResult

type SearchResult struct {
	Hits  uint       `json:"hits"`
	Items []ListItem `json:"video"`
}

func ParseSearchResultJSON

func ParseSearchResultJSON(v *fastjson.Value) SearchResult
func Search(query string, page uint) (SearchResult, error)

func SearchDeadline

func SearchDeadline(query string, page uint, deadline time.Time) (SearchResult, error)

func SearchTimeout

func SearchTimeout(query string, page uint, timeout time.Duration) (SearchResult, error)

type StreamID

type StreamID string

func ExtractStreamID

func ExtractStreamID(url string) (StreamID, error)

func (StreamID) Valid

func (v StreamID) Valid() error

type Streams

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

func LoadEmbedPlayerStreams

func LoadEmbedPlayerStreams(id StreamID) (Streams, error)

func LoadEmbedPlayerStreamsDeadline

func LoadEmbedPlayerStreamsDeadline(id StreamID, deadline time.Time) (Streams, error)

func LoadEmbedPlayerStreamsTimeout

func LoadEmbedPlayerStreamsTimeout(id StreamID, timeout time.Duration) (Streams, error)

func (Streams) Author

func (s Streams) Author() string

func (Streams) AverageRating

func (s Streams) AverageRating() float64

func (Streams) ChannelID

func (s Streams) ChannelID() string

func (Streams) ContextParams

func (s Streams) ContextParams() string

func (Streams) ExpiresInSeconds

func (s Streams) ExpiresInSeconds() string

func (Streams) ID

func (s Streams) ID() StreamID

ID returns the unique ID pertaining to this stream.

func (Streams) Keywords

func (s Streams) Keywords() []string

func (Streams) MuxedFormats

func (s Streams) MuxedFormats() Formats

MuxedFormats returns premuxed (video/audio-combined) streaming formats. Premuxing comes at an expense of poorer video/audio quality.

func (Streams) PlayableInEmbed

func (s Streams) PlayableInEmbed() bool

func (Streams) Reason

func (s Streams) Reason() string

func (Streams) ShortDescription

func (s Streams) ShortDescription() string

func (Streams) SourceFormats

func (s Streams) SourceFormats() Formats

SourceFormats returns streaming formats that either video-only or audio-only at their highest quality. See the documentation for MuxedFormats for lower quality, premuxed streaming formats..

func (Streams) Status

func (s Streams) Status() string

func (Streams) Title

func (s Streams) Title() string

func (Streams) ViewCount

func (s Streams) ViewCount() string

type TimeRange

type TimeRange struct {
	Start string `json:"start"`
	End   string `json:"end"`
}

func ParseTimeRangeJSON

func ParseTimeRangeJSON(v *fastjson.Value) TimeRange

type Transport

type Transport interface {
	DownloadBytesDeadline(dst []byte, url string, deadline time.Time) ([]byte, error)
}

Transport represents the transport client used for youtube.Client.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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