youtube

package
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Sep 19, 2024 License: OSL-3.0 Imports: 12 Imported by: 0

README

YouTube

Device OAuth

How to get client_id and client_secret

Set User-Agent to [1]:

Mozilla/5.0 (ChromiumStylePlatform) Cobalt/Version

Open MITM Proxy or your browser tools, then visit:

https://www.youtube.com/tv

and click "Sign in". On the next page, dont bother with any of the instructions, just go back to the captured requests, 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"
}
  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

Android

setup device with Android API 32. earlier versions likely fail to load. YouTube should already be installed. Then install system certificate

adb shell am start -a android.intent.action.VIEW `
-d https://www.youtube.com/watch?v=40wkJJXfwQ0

https://play.google.com/store/apps/details?id=com.google.android.youtube

windows defender firewall:

  1. private profile
  2. on
  3. outbound rules
  4. new rule
  5. port
  6. UDP
  7. 443
  8. block the connection
  9. QUIC

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ClientName = []string{
	android,
	android_embedded_player,
	web,
}
View Source
var YtImgs = []YtImg{
	{Width: 120, Height: 90, Name: "default.jpg"},
	{Width: 120, Height: 90, Name: "1.jpg"},
	{Width: 120, Height: 90, Name: "2.jpg"},
	{Width: 120, Height: 90, Name: "3.jpg"},
	{Width: 120, Height: 90, Name: "default.webp"},
	{Width: 120, Height: 90, Name: "1.webp"},
	{Width: 120, Height: 90, Name: "2.webp"},
	{Width: 120, Height: 90, Name: "3.webp"},
	{Width: 320, Height: 180, Name: "mq1.jpg"},
	{Width: 320, Height: 180, Name: "mq2.jpg"},
	{Width: 320, Height: 180, Name: "mq3.jpg"},
	{Width: 320, Height: 180, Name: "mqdefault.jpg"},
	{Width: 320, Height: 180, Name: "mq1.webp"},
	{Width: 320, Height: 180, Name: "mq2.webp"},
	{Width: 320, Height: 180, Name: "mq3.webp"},
	{Width: 320, Height: 180, Name: "mqdefault.webp"},
	{Width: 480, Height: 360, Name: "0.jpg"},
	{Width: 480, Height: 360, Name: "hqdefault.jpg"},
	{Width: 480, Height: 360, Name: "hq1.jpg"},
	{Width: 480, Height: 360, Name: "hq2.jpg"},
	{Width: 480, Height: 360, Name: "hq3.jpg"},
	{Width: 480, Height: 360, Name: "0.webp"},
	{Width: 480, Height: 360, Name: "hqdefault.webp"},
	{Width: 480, Height: 360, Name: "hq1.webp"},
	{Width: 480, Height: 360, Name: "hq2.webp"},
	{Width: 480, Height: 360, Name: "hq3.webp"},
	{Width: 640, Height: 480, Name: "sddefault.jpg"},
	{Width: 640, Height: 480, Name: "sd1.jpg"},
	{Width: 640, Height: 480, Name: "sd2.jpg"},
	{Width: 640, Height: 480, Name: "sd3.jpg"},
	{Width: 640, Height: 480, Name: "sddefault.webp"},
	{Width: 640, Height: 480, Name: "sd1.webp"},
	{Width: 640, Height: 480, Name: "sd2.webp"},
	{Width: 640, Height: 480, Name: "sd3.webp"},
	{Width: 1280, Height: 720, Name: "hq720.jpg"},
	{Width: 1280, Height: 720, Name: "maxresdefault.jpg"},
	{Width: 1280, Height: 720, Name: "maxres1.jpg"},
	{Width: 1280, Height: 720, Name: "maxres2.jpg"},
	{Width: 1280, Height: 720, Name: "maxres3.jpg"},
	{Width: 1280, Height: 720, Name: "hq720.webp"},
	{Width: 1280, Height: 720, Name: "maxresdefault.webp"},
	{Width: 1280, Height: 720, Name: "maxres1.webp"},
	{Width: 1280, Height: 720, Name: "maxres2.webp"},
	{Width: 1280, Height: 720, Name: "maxres3.webp"},
}

Functions

This section is empty.

Types

type AdaptiveFormat added in v1.4.6

type AdaptiveFormat struct {
	AudioQuality  string
	Bitrate       int
	ContentLength int64 `json:",string"`
	Itag          int
	MimeType      string
	QualityLabel  string
	Url           string
}

func (AdaptiveFormat) CompareBitrate added in v1.4.6

func (a AdaptiveFormat) CompareBitrate(b AdaptiveFormat) int

func (*AdaptiveFormat) Ext added in v1.4.6

func (a *AdaptiveFormat) Ext() (string, error)

func (*AdaptiveFormat) Ranges added in v1.4.6

func (a *AdaptiveFormat) Ranges() []string

we need the length for progress meter, so cannot use a channel

func (*AdaptiveFormat) String added in v1.4.6

func (a *AdaptiveFormat) String() string

type AuthToken added in v1.4.6

type AuthToken struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
}

func (*AuthToken) Marshal added in v1.4.8

func (a *AuthToken) Marshal() ([]byte, error)

func (*AuthToken) Refresh added in v1.4.6

func (a *AuthToken) Refresh() error

func (*AuthToken) Unmarshal added in v1.4.6

func (a *AuthToken) Unmarshal(text []byte) error

type Date added in v1.4.8

type Date struct {
	Time time.Time
}

func (*Date) UnmarshalText added in v1.4.8

func (d *Date) UnmarshalText(text []byte) error

type DeviceCode

type DeviceCode struct {
	DeviceCode      string `json:"device_code"`
	UserCode        string `json:"user_code"`
	VerificationUrl string `json:"verification_url"`
}

func (*DeviceCode) Marshal added in v1.4.8

func (d *DeviceCode) Marshal() ([]byte, error)

func (*DeviceCode) New added in v1.4.6

func (d *DeviceCode) New() error

func (*DeviceCode) String

func (d *DeviceCode) String() string

func (*DeviceCode) Token

func (d *DeviceCode) Token() (*AuthToken, error)

func (*DeviceCode) Unmarshal added in v1.4.8

func (d *DeviceCode) Unmarshal(text []byte) error

type InnerTube added in v1.4.8

type InnerTube struct {
	ContentCheckOk bool `json:"contentCheckOk,omitempty"`
	Context        struct {
		Client struct {
			AndroidSdkVersion int    `json:"androidSdkVersion"`
			ClientName        string `json:"clientName"`
			ClientVersion     string `json:"clientVersion"`
			OsVersion         string `json:"osVersion"`
		} `json:"client"`
	} `json:"context"`
	RacyCheckOk bool   `json:"racyCheckOk,omitempty"`
	VideoId     string `json:"videoId"`
}

need `osVersion` this to get the correct: This video requires payment to watch instead of the invalid: This video can only be played on newer versions of Android or other supported devices.

func (*InnerTube) Player added in v1.4.8

func (i *InnerTube) Player(token *AuthToken) (*Player, error)

type Player

type Player struct {
	Microformat struct {
		PlayerMicroformatRenderer struct {
			PublishDate Date
		}
	}
	PlayabilityStatus struct {
		Status string
		Reason string
	}
	StreamingData struct {
		AdaptiveFormats []AdaptiveFormat
	}
	VideoDetails struct {
		Author           string
		LengthSeconds    int64 `json:",string"`
		ShortDescription string
		Title            string
		VideoId          string
		ViewCount        int64 `json:",string"`
	}
}

type VideoId added in v1.4.8

type VideoId string

func (*VideoId) Set added in v1.4.8

func (v *VideoId) Set(text string) error

func (VideoId) String added in v1.4.8

func (v VideoId) String() string

type YtImg added in v1.4.8

type YtImg struct {
	Height  int
	Name    string
	VideoId string
	Width   int
}

func (*YtImg) String added in v1.4.8

func (y *YtImg) String() string

Jump to

Keyboard shortcuts

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