youtube

package
v1.50.8 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2022 License: OSL-3.0 Imports: 13 Imported by: 3

README

YouTube

Android client

I was able to get YouTube working with Android API 24, using this method [1]. Doing that, I was able to test non-stock versions of YouTube. It seems anything starting with version 14.01.51 (2019) is doing this HTTP/3 or whatever voodoo. Anything older wont work at all, even without proxy, failing with error 400.

  1. https://android.stackexchange.com/a/245551

Device OAuth

How to get X-Goog-Api-Key

Make a request like this:

GET / HTTP/2
Host: www.youtube.com

in the response you should see something like this:

"INNERTUBE_API_KEY":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8"

https://cloud.google.com/apis/docs/system-parameters

How to get client_id and client_secret

Set User-Agent to [1]:

Mozilla/5.0 (ChromiumStylePlatform) Cobalt/Version

Then visit:

https://www.youtube.com/tv

Next open your browser menu, and click Web Developer, Network or similar. Then go back to the page, and click "Sign in", then "Sign in with a web browser". On the next page, dont bother with any of the instructions, just go back to Developer Tools, and after about five seconds you should see a JSON request like this:

POST /o/oauth2/token HTTP/1.1
Host: www.youtube.com

{"client_id":"861556708454-d6dlm3lh05idd8npek18k6be8ba3oc68.apps.googleusercontent.com",
"client_secret":"SboVhoG9s0rNafixCSGGKXAT",
"code":"AH-1Ng14qVvEj76OeM_h14Mgklgyhchbyc67MhULhCKPY6K-0DTYJqaKng2ULVFTmTzU...",
"grant_type":"http://oauth.net/grant_type/device/1.0"}

Needed for videos like this:

Cr381pDsSsA
  1. https://github.com/youtube/cobalt/blob/master/src/cobalt/browser/user_agent_string.cc

Image

Is maxres1 always available? No:

Is sd1 always available? No:

If hq1 always available? Yes:

http://i.ytimg.com/vi/hq2KgzKETBw/hq1.jpg

Why does this exist?

I use it myself:

https://youtube.com/watch?v=Ts1Tcgj6nbc

March 27 2022

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Clients = []Client{
	Mweb,
	{"ANDROID", "17.12.34"},
	{"ANDROID_EMBEDDED_PLAYER", "17.12.34"},
	{"TVHTML5", "7.20220323.10.00"},
	{"WEB", "2.20220325.00.00"},
	{"WEB_CREATOR", "1.20220324.00.00"},
	{"WEB_EMBEDDED_PLAYER", "1.20220323.01.00"},
	{"WEB_KIDS", "2.20220323.08.00"},
	{"WEB_REMIX", "1.20220321.01.00"},
}
View Source
var Duration = map[string]protobuf.Varint{
	"Under 4 minutes": 1,
	"4 - 20 minutes":  3,
	"Over 20 minutes": 2,
}
View Source
var Features = map[string]protobuf.Number{
	"360°":             15,
	"3D":               7,
	"4K":               14,
	"Creative Commons": 6,
	"HD":               4,
	"HDR":              25,
	"Live":             8,
	"Location":         23,
	"Purchased":        9,
	"Subtitles/CC":     5,
	"VR180":            26,
}
View Source
var Images = []Image{
	{Width: 120, Height: 90, Base: "default.jpg"},
	{Width: 120, Height: 90, Base: "1.jpg"},
	{Width: 120, Height: 90, Base: "2.jpg"},
	{Width: 120, Height: 90, Base: "3.jpg"},
	{Width: 120, Height: 90, Base: "default.webp"},
	{Width: 120, Height: 90, Base: "1.webp"},
	{Width: 120, Height: 90, Base: "2.webp"},
	{Width: 120, Height: 90, Base: "3.webp"},
	{Width: 320, Height: 180, Base: "mq1.jpg", Crop: true},
	{Width: 320, Height: 180, Base: "mq2.jpg", Crop: true},
	{Width: 320, Height: 180, Base: "mq3.jpg", Crop: true},
	{Width: 320, Height: 180, Base: "mqdefault.jpg"},
	{Width: 320, Height: 180, Base: "mq1.webp", Crop: true},
	{Width: 320, Height: 180, Base: "mq2.webp", Crop: true},
	{Width: 320, Height: 180, Base: "mq3.webp", Crop: true},
	{Width: 320, Height: 180, Base: "mqdefault.webp"},
	{Width: 480, Height: 360, Base: "0.jpg"},
	{Width: 480, Height: 360, Base: "hqdefault.jpg"},
	{Width: 480, Height: 360, Base: "hq1.jpg"},
	{Width: 480, Height: 360, Base: "hq2.jpg"},
	{Width: 480, Height: 360, Base: "hq3.jpg"},
	{Width: 480, Height: 360, Base: "0.webp"},
	{Width: 480, Height: 360, Base: "hqdefault.webp"},
	{Width: 480, Height: 360, Base: "hq1.webp"},
	{Width: 480, Height: 360, Base: "hq2.webp"},
	{Width: 480, Height: 360, Base: "hq3.webp"},
	{Width: 640, Height: 480, Base: "sddefault.jpg"},
	{Width: 640, Height: 480, Base: "sd1.jpg"},
	{Width: 640, Height: 480, Base: "sd2.jpg"},
	{Width: 640, Height: 480, Base: "sd3.jpg"},
	{Width: 640, Height: 480, Base: "sddefault.webp"},
	{Width: 640, Height: 480, Base: "sd1.webp"},
	{Width: 640, Height: 480, Base: "sd2.webp"},
	{Width: 640, Height: 480, Base: "sd3.webp"},
	{Width: 1280, Height: 720, Base: "hq720.jpg"},
	{Width: 1280, Height: 720, Base: "maxresdefault.jpg"},
	{Width: 1280, Height: 720, Base: "maxres1.jpg"},
	{Width: 1280, Height: 720, Base: "maxres2.jpg"},
	{Width: 1280, Height: 720, Base: "maxres3.jpg"},
	{Width: 1280, Height: 720, Base: "hq720.webp"},
	{Width: 1280, Height: 720, Base: "maxresdefault.webp"},
	{Width: 1280, Height: 720, Base: "maxres1.webp"},
	{Width: 1280, Height: 720, Base: "maxres2.webp"},
	{Width: 1280, Height: 720, Base: "maxres3.webp"},
}
View Source
var LogLevel format.LogLevel
View Source
var Mweb = Client{"MWEB", "2.20220322.05.00"}
View Source
var SortBy = map[string]protobuf.Varint{
	"Relevance":   0,
	"Upload date": 2,
	"View count":  3,
	"Rating":      1,
}
View Source
var Type = map[string]protobuf.Varint{
	"Video":    1,
	"Channel":  2,
	"Playlist": 3,
	"Movie":    4,
}
View Source
var UploadDate = map[string]protobuf.Varint{
	"Last hour":  1,
	"Today":      2,
	"This week":  3,
	"This month": 4,
	"This year":  5,
}

Functions

Types

type Client added in v1.16.9

type Client struct {
	Name    string `json:"clientName"`
	Version string `json:"clientVersion"`
}

func (Client) Player added in v1.18.8

func (c Client) Player(id string) (*Player, error)

func (Client) PlayerHeader added in v1.45.1

func (c Client) PlayerHeader(head http.Header, id string) (*Player, error)

func (Client) Search added in v1.45.1

func (c Client) Search(query string) (*Search, error)

type Exchange added in v1.20.3

type Exchange struct {
	Access_Token  string
	Error         string
	Refresh_Token string
}

func OpenExchange added in v1.44.5

func OpenExchange(elem ...string) (*Exchange, error)

func (Exchange) Create added in v1.44.5

func (x Exchange) Create(elem ...string) error

func (Exchange) Header added in v1.45.1

func (x Exchange) Header() http.Header

func (*Exchange) Refresh added in v1.20.3

func (x *Exchange) Refresh() error

type Filter added in v1.37.1

type Filter struct {
	protobuf.Message
}

func NewFilter added in v1.40.0

func NewFilter() Filter

func (Filter) Duration added in v1.37.1

func (f Filter) Duration(val protobuf.Varint)

func (Filter) Features added in v1.49.8

func (f Filter) Features(num protobuf.Number)

func (Filter) Type added in v1.37.1

func (f Filter) Type(val protobuf.Varint)

func (Filter) UploadDate added in v1.37.1

func (f Filter) UploadDate(val protobuf.Varint)

type Format

type Format struct {
	AudioQuality   string
	AverageBitrate int
	ContentLength  int64 `json:"contentLength,string"`
	Height         int
	MimeType       string
	QualityLabel   string
	URL            string
	Width          int
}

averageBitrate is a better marker for quality than bitrate. For example, if you look a video: 7WTEB7Qbt4U you get this:

itag | bitrate | averageBitrate | contentLength -----|---------|----------------|-------------- 136 | 1038025 | 286687 | 6891870 247 | 1192816 | 513601 | 12346788 398 | 1117347 | 349310 | 8397292

func (Format) Ext added in v1.17.8

func (f Format) Ext() (string, error)

func (Format) Format added in v1.48.4

func (f Format) Format(s fmt.State, verb rune)

func (Format) Write

func (f Format) Write(dst io.Writer) error

type Formats added in v1.17.9

type Formats []Format

func (Formats) Len added in v1.50.5

func (f Formats) Len() int

func (Formats) MediaType added in v1.50.5

func (f Formats) MediaType() error

func (Formats) Swap added in v1.50.5

func (f Formats) Swap(i, j int)

type Height added in v1.49.5

type Height struct {
	Formats
	Target int
}

We cannot use bitrate to sort, as you end up with different heights:

ID | 480 | 720 low | 720 high | 1080 ------------|--------|---------|----------|----- 7WTEB7Qbt4U | 285106 | 286687 | 513601 | 513675 RPjE9riEhtA | 584072 | 1169166 | 1693812 | 2151670

func (Height) Less added in v1.49.5

func (h Height) Less(i, j int) bool

type Image added in v1.15.8

type Image struct {
	Width  int
	Height int
	Base   string
	Crop   bool
}

func (Image) Format added in v1.16.3

func (i Image) Format(id string) string

type Item added in v1.24.9

type Item struct {
	CompactVideoRenderer *struct {
		Title struct {
			Runs []struct {
				Text string
			}
		}
		VideoID string
	}
}

type OAuth added in v1.20.4

type OAuth struct {
	Device_Code      string
	User_Code        string
	Verification_URL string
}

func NewOAuth added in v1.20.4

func NewOAuth() (*OAuth, error)

func (OAuth) Exchange added in v1.20.4

func (o OAuth) Exchange() (*Exchange, error)

func (OAuth) String added in v1.44.5

func (o OAuth) String() string

type Params added in v1.27.5

type Params struct {
	protobuf.Message
}

func NewParams added in v1.40.0

func NewParams() Params

func (Params) Encode added in v1.37.1

func (p Params) Encode() string

func (Params) Filter added in v1.37.1

func (p Params) Filter(val Filter)

func (Params) SortBy added in v1.37.1

func (p Params) SortBy(val protobuf.Varint)

type Player added in v1.13.0

type Player struct {
	PlayabilityStatus struct {
		Status string
		Reason string
	}
	VideoDetails struct {
		VideoID          string
		LengthSeconds    int64 `json:"lengthSeconds,string"`
		ViewCount        int64 `json:"viewCount,string"`
		Author           string
		Title            string
		ShortDescription string
	}
	Microformat struct {
		PlayerMicroformatRenderer struct {
			PublishDate string // 2013-06-11
		}
	}
	StreamingData struct {
		AdaptiveFormats Formats
		Formats         Formats
	}
}

func (Player) Base added in v1.49.6

func (p Player) Base() string

func (Player) Date added in v1.24.9

func (p Player) Date() (time.Time, error)

func (Player) Format added in v1.50.1

func (p Player) Format(f fmt.State, verb rune)

func (Player) Status added in v1.49.5

func (p Player) Status() string
type Search struct {
	Contents struct {
		SectionListRenderer struct {
			Contents []struct {
				ItemSectionRenderer *struct {
					Contents []Item
				}
			}
		}
	}
}

func (Search) Items added in v1.24.9

func (s Search) Items() []Item

Jump to

Keyboard shortcuts

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