getraw 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -104,14 +104,14 @@ export interface BrowseResponse {
104
104
  const CLIENTS: Record<string, ClientContext> = {
105
105
  WEB: {
106
106
  clientName: "WEB",
107
- clientVersion: "2.20240530.02.00",
108
- userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
107
+ clientVersion: "2.20250615.01.00",
108
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
109
109
  apiKey: "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
110
110
  },
111
111
  ANDROID: {
112
112
  clientName: "ANDROID",
113
- clientVersion: "19.29.37",
114
- userAgent: "com.google.android.youtube/19.29.37 (Linux; U; Android 14) gzip",
113
+ clientVersion: "19.44.38",
114
+ userAgent: "com.google.android.youtube/19.44.38 (Linux; U; Android 14) gzip",
115
115
  apiKey: "AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w",
116
116
  clientId: 3,
117
117
  },
@@ -122,6 +122,13 @@ const CLIENTS: Record<string, ClientContext> = {
122
122
  apiKey: "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
123
123
  clientId: 85,
124
124
  },
125
+ IOS: {
126
+ clientName: "IOS",
127
+ clientVersion: "19.45.4",
128
+ userAgent: "com.google.ios.youtube/19.45.4 (iPhone16,2; U; CPU iOS 17_5_1 like Mac OS X;)",
129
+ apiKey: "AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc",
130
+ clientId: 5,
131
+ },
125
132
  };
126
133
 
127
134
  const PLAYER_ENDPOINT = "https://www.youtube.com/youtubei/v1/player";
@@ -130,22 +137,28 @@ const BROWSE_ENDPOINT = "https://www.youtube.com/youtubei/v1/browse";
130
137
  export class InnerTubeClient {
131
138
  private clientName: string;
132
139
  private context: ClientContext;
140
+ private signatureTimestamp: number;
133
141
 
134
- constructor(clientName: "WEB" | "ANDROID" | "TVHTML5_EMBED" = "WEB") {
142
+ constructor(clientName: "WEB" | "ANDROID" | "TVHTML5_EMBED" | "IOS" = "WEB", signatureTimestamp = 20073) {
135
143
  this.clientName = clientName;
136
144
  this.context = CLIENTS[clientName];
145
+ this.signatureTimestamp = signatureTimestamp;
137
146
  }
138
147
 
139
- async getPlayerResponse(videoId: string, embedUrl?: string): Promise<PlayerResponse> {
140
- const body = this.buildPlayerBody(videoId, embedUrl);
148
+ async getPlayerResponse(videoId: string, embedUrl?: string, visitorData?: string): Promise<PlayerResponse> {
149
+ const body = this.buildPlayerBody(videoId, embedUrl, visitorData);
150
+ const headers: Record<string, string> = {
151
+ "Content-Type": "application/json",
152
+ "User-Agent": this.context.userAgent,
153
+ "X-YouTube-Client-Name": String(this.context.clientId ?? 1),
154
+ "X-YouTube-Client-Version": this.context.clientVersion,
155
+ };
156
+ if (visitorData) {
157
+ headers["X-Goog-Visitor-Id"] = visitorData;
158
+ }
141
159
  const response = await fetch(`${PLAYER_ENDPOINT}?key=${this.context.apiKey}&prettyPrint=false`, {
142
160
  method: "POST",
143
- headers: {
144
- "Content-Type": "application/json",
145
- "User-Agent": this.context.userAgent,
146
- "X-YouTube-Client-Name": String(this.context.clientId ?? 1),
147
- "X-YouTube-Client-Version": this.context.clientVersion,
148
- },
161
+ headers,
149
162
  body: JSON.stringify(body),
150
163
  });
151
164
 
@@ -193,26 +206,37 @@ export class InnerTubeClient {
193
206
  return response.json() as Promise<BrowseResponse>;
194
207
  }
195
208
 
196
- private buildPlayerBody(videoId: string, embedUrl?: string): Record<string, unknown> {
209
+ private buildPlayerBody(videoId: string, embedUrl?: string, visitorData?: string): Record<string, unknown> {
210
+ const clientContext: Record<string, unknown> = {
211
+ clientName: this.context.clientName,
212
+ clientVersion: this.context.clientVersion,
213
+ hl: "en",
214
+ gl: "US",
215
+ };
216
+ if (visitorData) {
217
+ clientContext.visitorData = visitorData;
218
+ }
197
219
  const body: Record<string, unknown> = {
198
220
  videoId,
199
221
  context: {
200
- client: {
201
- clientName: this.context.clientName,
202
- clientVersion: this.context.clientVersion,
203
- hl: "en",
204
- gl: "US",
205
- },
222
+ client: clientContext,
206
223
  },
207
224
  playbackContext: {
208
225
  contentPlaybackContext: {
209
- signatureTimestamp: 20073,
226
+ signatureTimestamp: this.signatureTimestamp,
210
227
  },
211
228
  },
212
229
  contentCheckOk: true,
213
230
  racyCheckOk: true,
214
231
  };
215
232
 
233
+ if (this.clientName === "IOS") {
234
+ clientContext.deviceMake = "Apple";
235
+ clientContext.deviceModel = "iPhone16,2";
236
+ clientContext.osName = "iPhone";
237
+ clientContext.osVersion = "17.5.1.21F90";
238
+ }
239
+
216
240
  if (this.clientName === "TVHTML5_EMBED" && embedUrl) {
217
241
  (body.context as Record<string, unknown>).thirdParty = {
218
242
  embedUrl,
@@ -310,8 +334,12 @@ export class InnerTubeClient {
310
334
  return { subtitles, automatic_captions };
311
335
  }
312
336
 
313
- static withClient(clientName: "WEB" | "ANDROID" | "TVHTML5_EMBED"): InnerTubeClient {
314
- return new InnerTubeClient(clientName);
337
+ setSignatureTimestamp(sts: number): void {
338
+ this.signatureTimestamp = sts;
339
+ }
340
+
341
+ static withClient(clientName: "WEB" | "ANDROID" | "TVHTML5_EMBED" | "IOS", signatureTimestamp?: number): InnerTubeClient {
342
+ return new InnerTubeClient(clientName, signatureTimestamp);
315
343
  }
316
344
  }
317
345