mirror of
https://github.com/LuanRT/googlevideo.git
synced 2026-07-01 02:15:36 +00:00
chore: Fix onesie request example and clean up
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import Innertube, { Constants, UniversalCache } from 'youtubei.js';
|
||||
import { type Context, YT } from 'youtubei.js';
|
||||
import Innertube, { Constants, type Context, UniversalCache, YT } from 'youtubei.js';
|
||||
import GoogleVideo, { base64ToU8, PART, Protos, QUALITY } from '../../dist/src/index.js';
|
||||
import { decryptResponse, encryptRequest } from './utils.js';
|
||||
|
||||
@@ -67,7 +66,7 @@ async function prepareOnesieRequest(args: OnesieRequestArgs): Promise<OnesieRequ
|
||||
// Change or remove these if you want to use a different client. I chose TVHTML5 purely for testing.
|
||||
clonedInnerTubeContext.client.clientName = Constants.CLIENTS.TV.NAME;
|
||||
clonedInnerTubeContext.client.clientVersion = Constants.CLIENTS.TV.VERSION;
|
||||
|
||||
|
||||
const params: Record<string, any> = {
|
||||
playbackContext: {
|
||||
contentPlaybackContext: {
|
||||
@@ -79,29 +78,31 @@ async function prepareOnesieRequest(args: OnesieRequestArgs): Promise<OnesieRequ
|
||||
},
|
||||
videoId
|
||||
};
|
||||
|
||||
|
||||
if (poToken) {
|
||||
params.serviceIntegrityDimensions = {};
|
||||
params.serviceIntegrityDimensions.poToken = poToken;
|
||||
}
|
||||
|
||||
|
||||
const playerRequestJson = {
|
||||
context: clonedInnerTubeContext,
|
||||
...params
|
||||
};
|
||||
|
||||
const headers = [ {
|
||||
name: 'Content-Type',
|
||||
value: 'application/json'
|
||||
},
|
||||
{
|
||||
name: 'User-Agent',
|
||||
value: innertube.session.context.client.userAgent
|
||||
},
|
||||
{
|
||||
name: 'X-Goog-Visitor-Id',
|
||||
value: innertube.session.context.client.visitorData
|
||||
} ];
|
||||
const headers = [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'application/json'
|
||||
},
|
||||
{
|
||||
name: 'User-Agent',
|
||||
value: innertube.session.context.client.userAgent
|
||||
},
|
||||
{
|
||||
name: 'X-Goog-Visitor-Id',
|
||||
value: innertube.session.context.client.visitorData
|
||||
}
|
||||
];
|
||||
|
||||
const onesieRequest = Protos.OnesiePlayerRequest.encode({
|
||||
url: 'https://youtubei.googleapis.com/youtubei/v1/player?key=AIzaSyDCU8hByM-4DrUqRUYnGn-3llEO78bcxq8',
|
||||
@@ -122,15 +123,13 @@ async function prepareOnesieRequest(args: OnesieRequestArgs): Promise<OnesieRequ
|
||||
* If you want to use an unencrypted player request:
|
||||
* unencryptedOnesiePlayerRequest: onesieRequest,
|
||||
*/
|
||||
enableCompression: false,
|
||||
enableCompression: true,
|
||||
hmac: hmac,
|
||||
iv: iv,
|
||||
TQ: true,
|
||||
useJsonformatterToParsePlayerResponse: false,
|
||||
serializeResponseAsJson: true // If false, the response will be serialized as protobuf.
|
||||
},
|
||||
clientAbrState: {
|
||||
timeSinceLastManualFormatSelectionMs: 0,
|
||||
lastManualDirection: 0,
|
||||
lastManualSelectedResolution: QUALITY.HD720,
|
||||
stickyResolution: QUALITY.HD720,
|
||||
playerTimeMs: 0,
|
||||
@@ -142,7 +141,7 @@ async function prepareOnesieRequest(args: OnesieRequestArgs): Promise<OnesieRequ
|
||||
poToken: poToken ? base64ToU8(poToken) : undefined,
|
||||
playbackCookie: undefined,
|
||||
clientInfo: {
|
||||
clientName: parseInt(Constants.CLIENTS.TV.NAME_ID),
|
||||
clientName: parseInt(Constants.CLIENT_NAME_IDS[clonedInnerTubeContext.client.clientName as keyof typeof Constants.CLIENT_NAME_IDS]),
|
||||
clientVersion: clonedInnerTubeContext.client.clientVersion
|
||||
}
|
||||
},
|
||||
@@ -190,7 +189,7 @@ async function getBasicInfo(innertube: Innertube, videoId: string): Promise<YT.V
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'accept': '*/*',
|
||||
'content-type': 'text/plain'
|
||||
'content-type': 'application/octet-stream'
|
||||
},
|
||||
referrer: 'https://www.youtube.com/',
|
||||
body: onesieRequest.body
|
||||
@@ -218,7 +217,7 @@ async function getBasicInfo(innertube: Innertube, videoId: string): Promise<YT.V
|
||||
}
|
||||
});
|
||||
|
||||
const onesiePlayerResponse = onesie.find((header) => header.type === Protos.OnesieHeaderType.PLAYER_RESPONSE);
|
||||
const onesiePlayerResponse = onesie.find((header) => header.type === Protos.OnesieHeaderType.ONESIE_PLAYER_RESPONSE);
|
||||
|
||||
if (onesiePlayerResponse) {
|
||||
if (!onesiePlayerResponse.cryptoParams)
|
||||
@@ -227,8 +226,23 @@ async function getBasicInfo(innertube: Innertube, videoId: string): Promise<YT.V
|
||||
const iv = onesiePlayerResponse.cryptoParams.iv;
|
||||
const hmac = onesiePlayerResponse.cryptoParams.hmac;
|
||||
|
||||
let responseData = onesiePlayerResponse.data;
|
||||
|
||||
// Decompress the response data if compression is enabled.
|
||||
if (responseData && onesiePlayerResponse.cryptoParams.compressionType === Protos.CompressionType.GZIP) {
|
||||
if (typeof window === 'undefined') {
|
||||
const zlib = await import('node:zlib');
|
||||
responseData = new Uint8Array(zlib.gunzipSync(responseData));
|
||||
} else {
|
||||
const ds = new DecompressionStream('gzip');
|
||||
const stream = new Blob([ responseData ]).stream().pipeThrough(ds);
|
||||
responseData = await new Response(stream).arrayBuffer().then((buf) => new Uint8Array(buf));
|
||||
}
|
||||
}
|
||||
|
||||
// If skipResponseEncryption is set to true in the request, the response will not be encrypted.
|
||||
const decryptedData = hmac?.length && iv?.length ? await decryptResponse(iv, hmac, onesiePlayerResponse.data, clientConfig.clientKeyData) : onesiePlayerResponse.data!;
|
||||
const decryptedData = hmac?.length && iv?.length ?
|
||||
await decryptResponse(iv, hmac, responseData, clientConfig.clientKeyData) : responseData!;
|
||||
const response = Protos.OnesiePlayerResponse.decode(decryptedData);
|
||||
|
||||
if (response.onesieProxyStatus !== Protos.OnesieProxyStatus.ONESIE_PROXY_STATUS_OK)
|
||||
@@ -253,4 +267,9 @@ const innertube = await Innertube.create({ cache: new UniversalCache(true) });
|
||||
|
||||
const videoInfo = await getBasicInfo(innertube, 'JAs6WyK-Kr0');
|
||||
console.log('Basic info:', videoInfo);
|
||||
console.log('Deciphered audio URL:', videoInfo.chooseFormat({ format: 'mp4', quality: 'best', type: 'audio' }).decipher(innertube.session.player));
|
||||
console.log('Deciphered audio URL:');
|
||||
console.log(videoInfo.chooseFormat({
|
||||
format: 'mp4',
|
||||
quality: 'best',
|
||||
type: 'audio'
|
||||
}).decipher(innertube.session.player));
|
||||
22
examples/onesie-request/package-lock.json
generated
22
examples/onesie-request/package-lock.json
generated
@@ -9,7 +9,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"youtubei.js": "^12.2.0"
|
||||
"youtubei.js": "^13.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@bufbuild/protobuf": {
|
||||
@@ -26,9 +26,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"version": "8.14.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
@@ -38,9 +38,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jintr": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jintr/-/jintr-3.2.0.tgz",
|
||||
"integrity": "sha512-psD1yf05kMKDNsUdW1l5YhO59pHScQ6OIHHb8W5SKSM2dCOFPsqolmIuSHgVA8+3Dc47NJR181CXZ4alCAPTkA==",
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/jintr/-/jintr-3.3.0.tgz",
|
||||
"integrity": "sha512-ZsaajJ4Hr5XR0tSPhOZOTjFhxA0qscKNSOs41NRjx7ZOGwpfdp8NKIBEUtvUPbA37JXyv1sJlgeOOZHjr3h76Q==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/LuanRT"
|
||||
],
|
||||
@@ -66,16 +66,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/youtubei.js": {
|
||||
"version": "12.2.0",
|
||||
"resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-12.2.0.tgz",
|
||||
"integrity": "sha512-G+50qrbJCToMYhu8jbaHiS3Vf+RRul+CcDbz3hEGwHkGPh+zLiWwD6SS+YhYF+2/op4ZU5zDYQJrGqJ+wKh7Gw==",
|
||||
"version": "13.3.0",
|
||||
"resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-13.3.0.tgz",
|
||||
"integrity": "sha512-tbl7rxltpgKoSsmfGUe9JqWUAzv6HFLqrOn0N85EbTn5DLt24EXrjClnXdxyr3PBARMJ3LC4vbll100a0ABsYw==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/LuanRT"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@bufbuild/protobuf": "^2.0.0",
|
||||
"jintr": "^3.2.0",
|
||||
"jintr": "^3.3.0",
|
||||
"tslib": "^2.5.0",
|
||||
"undici": "^5.19.1"
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"youtubei.js": "^12.2.0"
|
||||
"youtubei.js": "^13.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user