@@ -38,7 +38,7 @@ func (c *Client) GetVideoContext(ctx context.Context, url string) (*Video, error
3838}
3939
4040func (c * Client ) videoFromID (ctx context.Context , id string ) (* Video , error ) {
41- body , err := c .videoDataByInnertube (ctx , id , Web )
41+ body , err := c .videoDataByInnertube (ctx , id , webClient )
4242 if err != nil {
4343 return nil , err
4444 }
@@ -66,7 +66,7 @@ func (c *Client) videoFromID(ctx context.Context, id string) (*Video, error) {
6666
6767 // If the uploader marked the video as inappropriate for some ages, use embed player
6868 if err == ErrLoginRequired {
69- bodyEmbed , errEmbed := c .videoDataByInnertube (ctx , id , EmbeddedClient )
69+ bodyEmbed , errEmbed := c .videoDataByInnertube (ctx , id , embeddedClient )
7070 if errEmbed == nil {
7171 errEmbed = v .parseVideoInfo (bodyEmbed )
7272 }
@@ -115,14 +115,28 @@ type innertubeClient struct {
115115 ClientVersion string `json:"clientVersion"`
116116}
117117
118- type ClientType string
118+ type clientInfo struct {
119+ name string
120+ key string
121+ version string
122+ }
123+
124+ var (
125+ // might add ANDROID and other in future, but i don't see reason yet
126+ webClient = clientInfo {
127+ name : "WEB" ,
128+ version : "2.20210617.01.00" ,
129+ key : "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8" ,
130+ }
119131
120- const (
121- Web ClientType = "WEB"
122- EmbeddedClient ClientType = "WEB_EMBEDDED_PLAYER"
132+ embeddedClient = clientInfo {
133+ name : "WEB_EMBEDDED_PLAYER" ,
134+ version : "1.19700101" ,
135+ key : "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8" , // seems like same key works for both clients
136+ }
123137)
124138
125- func (c * Client ) videoDataByInnertube (ctx context.Context , id string , clientType ClientType ) ([]byte , error ) {
139+ func (c * Client ) videoDataByInnertube (ctx context.Context , id string , clientInfo clientInfo ) ([]byte , error ) {
126140 config , err := c .getPlayerConfig (ctx , id )
127141 if err != nil {
128142 return nil , err
@@ -134,63 +148,40 @@ func (c *Client) videoDataByInnertube(ctx context.Context, id string, clientType
134148 return nil , err
135149 }
136150
137- data , keyToken := prepareInnertubeVideoData (id , sts , clientType )
138- return c .httpPostBodyBytes (ctx , "https://www.youtube.com/youtubei/v1/player?key=" + keyToken , data )
139- }
140-
141- var innertubeClientInfo = map [ClientType ]map [string ]string {
142- // might add ANDROID and other in future, but i don't see reason yet
143- Web : {
144- "version" : "2.20210617.01.00" ,
145- "key" : "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8" ,
146- },
147- EmbeddedClient : {
148- "version" : "1.19700101" ,
149- // seems like same key works for both clients
150- "key" : "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8" ,
151- },
152- }
151+ context := prepareInnertubeContext (clientInfo )
153152
154- func prepareInnertubeContext (clientType ClientType ) (inntertubeContext , string ) {
155- cInfo , ok := innertubeClientInfo [clientType ]
156- if ! ok {
157- // if provided clientType not exist - use Web as fallback option
158- clientType = Web
159- cInfo = innertubeClientInfo [clientType ]
153+ data := innertubeRequest {
154+ VideoID : id ,
155+ Context : context ,
156+ PlaybackContext : playbackContext {
157+ ContentPlaybackContext : contentPlaybackContext {
158+ SignatureTimestamp : sts ,
159+ },
160+ },
160161 }
161162
163+ return c .httpPostBodyBytes (ctx , "https://www.youtube.com/youtubei/v1/player?key=" + clientInfo .key , data )
164+ }
165+
166+ func prepareInnertubeContext (clientInfo clientInfo ) inntertubeContext {
162167 return inntertubeContext {
163168 Client : innertubeClient {
164169 HL : "en" ,
165170 GL : "US" ,
166- ClientName : string ( clientType ) ,
167- ClientVersion : cInfo [ " version" ] ,
171+ ClientName : clientInfo . name ,
172+ ClientVersion : clientInfo . version ,
168173 },
169- }, cInfo ["key" ]
170- }
171-
172- func prepareInnertubeVideoData (videoID string , sts string , clientType ClientType ) (innertubeRequest , string ) {
173- context , key := prepareInnertubeContext (clientType )
174-
175- return innertubeRequest {
176- VideoID : videoID ,
177- Context : context ,
178- PlaybackContext : playbackContext {
179- ContentPlaybackContext : contentPlaybackContext {
180- SignatureTimestamp : sts ,
181- },
182- },
183- }, key
174+ }
184175}
185176
186- func prepareInnertubePlaylistData (ID string , continuation bool , clientType ClientType ) ( innertubeRequest , string ) {
187- context , key := prepareInnertubeContext (clientType )
177+ func prepareInnertubePlaylistData (ID string , continuation bool , clientInfo clientInfo ) innertubeRequest {
178+ context := prepareInnertubeContext (clientInfo )
188179
189180 if continuation {
190- return innertubeRequest {Context : context , Continuation : ID }, key
181+ return innertubeRequest {Context : context , Continuation : ID }
191182 }
192183
193- return innertubeRequest {Context : context , BrowseID : "VL" + ID }, key
184+ return innertubeRequest {Context : context , BrowseID : "VL" + ID }
194185}
195186
196187// GetPlaylist fetches playlist metadata
@@ -207,8 +198,8 @@ func (c *Client) GetPlaylistContext(ctx context.Context, url string) (*Playlist,
207198 return nil , fmt .Errorf ("extractPlaylistID failed: %w" , err )
208199 }
209200
210- data , key := prepareInnertubePlaylistData (id , false , Web )
211- body , err := c .httpPostBodyBytes (ctx , "https://www.youtube.com/youtubei/v1/browse?key=" + key , data )
201+ data := prepareInnertubePlaylistData (id , false , webClient )
202+ body , err := c .httpPostBodyBytes (ctx , "https://www.youtube.com/youtubei/v1/browse?key=" + webClient . key , data )
212203 if err != nil {
213204 return nil , err
214205 }
0 commit comments