mirror of
https://github.com/LuanRT/YouTube.js.git
synced 2026-06-16 11:02:10 +00:00
Compare commits
2 Commits
v16.0.1-de
...
deno
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f21db117e8 | ||
|
|
cc09231db2 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "youtubei.js",
|
||||
"version": "16.0.1",
|
||||
"version": "17.0.1",
|
||||
"description": "A JavaScript client for YouTube's private API, known as InnerTube.",
|
||||
"type": "module",
|
||||
"types": "./dist/src/platform/lib.d.ts",
|
||||
@@ -108,14 +108,13 @@
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@types/estree": "^1.0.6",
|
||||
"@types/glob": "^8.1.0",
|
||||
"@types/node": "^24.0.14",
|
||||
"@types/node": "^25.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||
"@typescript-eslint/parser": "^8.46.0",
|
||||
"cpy-cli": "^6.0.0",
|
||||
"esbuild": "^0.25.6",
|
||||
"eslint": "^9.37.0",
|
||||
"globals": "^16.4.0",
|
||||
"globals": "^17.0.0",
|
||||
"replace": "^1.2.2",
|
||||
"rimraf": "^6.0.1",
|
||||
"ts-patch": "^3.0.2",
|
||||
@@ -141,4 +140,4 @@
|
||||
"downloader",
|
||||
"ytmusic"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: misc/common.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -56,25 +56,27 @@ export const HttpHeader: MessageFns<HttpHeader> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): HttpHeader {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseHttpHeader();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.name = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.value = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -105,32 +107,35 @@ export const FormatId: MessageFns<FormatId> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): FormatId {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseFormatId();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.itag = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.lastModified = longToNumber(reader.uint64());
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.xtags = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -158,25 +163,27 @@ export const InitRange: MessageFns<InitRange> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): InitRange {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseInitRange();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.start = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.end = reader.int32();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -204,25 +211,27 @@ export const IndexRange: MessageFns<IndexRange> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): IndexRange {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseIndexRange();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.start = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.end = reader.int32();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -250,25 +259,27 @@ export const KeyValuePair: MessageFns<KeyValuePair> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): KeyValuePair {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseKeyValuePair();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.key = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.value = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -293,18 +304,19 @@ export const FormatXTags: MessageFns<FormatXTags> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): FormatXTags {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseFormatXTags();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.xtags.push(KeyValuePair.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/attestation_response_data.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -59,53 +59,59 @@ export const AttestationResponseData: MessageFns<AttestationResponseData> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): AttestationResponseData {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAttestationResponseData();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.challenge = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.webResponse = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.androidResponse = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.iosResponse = reader.bytes();
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 40) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.error = reader.int32();
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.adblockReporting = AttestationResponseData_AdblockReporting.decode(reader, reader.uint32());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -133,25 +139,27 @@ export const AttestationResponseData_AdblockReporting: MessageFns<AttestationRes
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): AttestationResponseData_AdblockReporting {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAttestationResponseData_AdblockReporting();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.reportingStatus = longToNumber(reader.uint64());
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.broadSpectrumDetectionResult = longToNumber(reader.uint64());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/capability_info.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -45,39 +45,43 @@ export const CapabilityInfo: MessageFns<CapabilityInfo> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): CapabilityInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseCapabilityInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.profile = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.supportedCapabilities.push(InnerTubeCapability.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.disabledCapabilities.push(InnerTubeCapability.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 42) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.snapshot = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -108,32 +112,35 @@ export const InnerTubeCapability: MessageFns<InnerTubeCapability> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): InnerTubeCapability {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseInnerTubeCapability();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.capability = reader.uint32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.features = reader.uint32();
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.experimentFlags = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/get_watch_request.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -43,39 +43,43 @@ export const GetWatchRequest: MessageFns<GetWatchRequest> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GetWatchRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGetWatchRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.context = InnerTubeContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playerRequest = PlayerRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.watchNextRequest = WatchNextRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.reelItemWatchRequest = ReelItemWatchRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/innertube_context.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -107,88 +107,99 @@ export const InnerTubeContext: MessageFns<InnerTubeContext> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): InnerTubeContext {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseInnerTubeContext();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.client = ClientInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.user = UserInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.capabilities = CapabilityInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 42) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.request = RequestInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.clickTracking = InnerTubeContext_ClickTrackingInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 7:
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 58) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.thirdParty = ThirdPartyInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 8:
|
||||
}
|
||||
case 8: {
|
||||
if (tag !== 66) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.remoteClient = ClientInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 9:
|
||||
}
|
||||
case 9: {
|
||||
if (tag !== 74) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.adSignalsInfo = InnerTubeContext_AdSignalsInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 10:
|
||||
}
|
||||
case 10: {
|
||||
if (tag !== 82) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.experimentalData = InnerTubeContext_ExperimentalData.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 11:
|
||||
}
|
||||
case 11: {
|
||||
if (tag !== 90) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.clientScreenNonce = reader.string();
|
||||
continue;
|
||||
case 12:
|
||||
}
|
||||
case 12: {
|
||||
if (tag !== 98) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.activePlayers.push(InnerTubeContext_ActivePlayerInfo.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -213,18 +224,19 @@ export const InnerTubeContext_ExperimentalData: MessageFns<InnerTubeContext_Expe
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): InnerTubeContext_ExperimentalData {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseInnerTubeContext_ExperimentalData();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.params.push(KeyValuePair.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -249,18 +261,19 @@ export const InnerTubeContext_ActivePlayerInfo: MessageFns<InnerTubeContext_Acti
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): InnerTubeContext_ActivePlayerInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseInnerTubeContext_ActivePlayerInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playerContextParams = reader.bytes();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -285,18 +298,19 @@ export const InnerTubeContext_ClickTrackingInfo: MessageFns<InnerTubeContext_Cli
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): InnerTubeContext_ClickTrackingInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseInnerTubeContext_ClickTrackingInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 2:
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.clickTrackingParams = reader.bytes();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -347,60 +361,67 @@ export const InnerTubeContext_AdSignalsInfo: MessageFns<InnerTubeContext_AdSigna
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): InnerTubeContext_AdSignalsInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseInnerTubeContext_AdSignalsInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.params.push(KeyValuePair.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.bid = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.mutsuId = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.consentBumpState = reader.string();
|
||||
continue;
|
||||
case 7:
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 58) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.advertisingId = reader.string();
|
||||
continue;
|
||||
case 9:
|
||||
}
|
||||
case 9: {
|
||||
if (tag !== 72) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.limitAdTracking = reader.bool();
|
||||
continue;
|
||||
case 10:
|
||||
}
|
||||
case 10: {
|
||||
if (tag !== 82) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.attributionOsSupportedVersion = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/metadata_update_request.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -145,95 +145,107 @@ export const MetadataUpdateRequest: MessageFns<MetadataUpdateRequest> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.context = InnerTubeContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.encryptedVideoId = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.title = MetadataUpdateRequest_MdeTitleUpdateRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.description = MetadataUpdateRequest_MdeDescriptionUpdateRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 42) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.privacy = MetadataUpdateRequest_MdePrivacyUpdateRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.tags = MetadataUpdateRequest_MdeTagsUpdateRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 7:
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 58) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.category = MetadataUpdateRequest_MdeCategoryUpdateRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 8:
|
||||
}
|
||||
case 8: {
|
||||
if (tag !== 66) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.license = MetadataUpdateRequest_MdeLicenseUpdateRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 11:
|
||||
}
|
||||
case 11: {
|
||||
if (tag !== 90) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.ageRestriction = MetadataUpdateRequest_MdeAgeRestrictionUpdateRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 20:
|
||||
}
|
||||
case 20: {
|
||||
if (tag !== 162) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.videoStill = MetadataUpdateRequest_MdeVideoStillRequestParams.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 68:
|
||||
}
|
||||
case 68: {
|
||||
if (tag !== 546) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.madeForKids = MetadataUpdateRequest_MdeMadeForKidsUpdateRequestParams.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 69:
|
||||
}
|
||||
case 69: {
|
||||
if (tag !== 554) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.racy = MetadataUpdateRequest_MdeRacyRequestParams.decode(reader, reader.uint32());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -261,18 +273,19 @@ export const MetadataUpdateRequest_MdeTitleUpdateRequest: MessageFns<MetadataUpd
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeTitleUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeTitleUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newTitle = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -302,18 +315,19 @@ export const MetadataUpdateRequest_MdeDescriptionUpdateRequest: MessageFns<
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeDescriptionUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeDescriptionUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newDescription = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -345,25 +359,27 @@ export const MetadataUpdateRequest_MdePrivacyUpdateRequest: MessageFns<MetadataU
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdePrivacyUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdePrivacyUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newPrivacy = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.clearPrivacyDraft = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -388,18 +404,19 @@ export const MetadataUpdateRequest_MdeTagsUpdateRequest: MessageFns<MetadataUpda
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeTagsUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeTagsUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newTags.push(reader.string());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -429,18 +446,19 @@ export const MetadataUpdateRequest_MdeCategoryUpdateRequest: MessageFns<
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeCategoryUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeCategoryUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newCategoryId = reader.int32();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -469,18 +487,19 @@ export const MetadataUpdateRequest_MdeLicenseUpdateRequest: MessageFns<MetadataU
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeLicenseUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeLicenseUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newLicenseId = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -513,25 +532,27 @@ export const MetadataUpdateRequest_MdeMadeForKidsUpdateRequestParams: MessageFns
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeMadeForKidsUpdateRequestParams {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeMadeForKidsUpdateRequestParams();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.operation = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newMfk = reader.int32();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -559,25 +580,27 @@ export const MetadataUpdateRequest_MdeRacyRequestParams: MessageFns<MetadataUpda
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeRacyRequestParams {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeRacyRequestParams();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.operation = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newRacy = reader.int32();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -607,18 +630,19 @@ export const MetadataUpdateRequest_MdeAgeRestrictionUpdateRequest: MessageFns<
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeAgeRestrictionUpdateRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeAgeRestrictionUpdateRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newIsAgeRestricted = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -667,26 +691,28 @@ export const MetadataUpdateRequest_MdeVideoStillRequestParams: MessageFns<
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MetadataUpdateRequest_MdeVideoStillRequestParams {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeVideoStillRequestParams();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.operation = reader.int32();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.newStillId = reader.int32();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
@@ -696,7 +722,8 @@ export const MetadataUpdateRequest_MdeVideoStillRequestParams: MessageFns<
|
||||
reader.uint32(),
|
||||
);
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
@@ -706,7 +733,8 @@ export const MetadataUpdateRequest_MdeVideoStillRequestParams: MessageFns<
|
||||
reader.uint32(),
|
||||
);
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
@@ -718,6 +746,7 @@ export const MetadataUpdateRequest_MdeVideoStillRequestParams: MessageFns<
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -753,12 +782,12 @@ export const MetadataUpdateRequest_MdeVideoStillRequestParams_ThumbnailExperimen
|
||||
length?: number,
|
||||
): MetadataUpdateRequest_MdeVideoStillRequestParams_ThumbnailExperimentImageData {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeVideoStillRequestParams_ThumbnailExperimentImageData();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
@@ -768,6 +797,7 @@ export const MetadataUpdateRequest_MdeVideoStillRequestParams_ThumbnailExperimen
|
||||
reader.uint32(),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -809,39 +839,43 @@ export const MetadataUpdateRequest_MdeVideoStillRequestParams_CustomThumbnailIma
|
||||
length?: number,
|
||||
): MetadataUpdateRequest_MdeVideoStillRequestParams_CustomThumbnailImage {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMetadataUpdateRequest_MdeVideoStillRequestParams_CustomThumbnailImage();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.rawBytes = reader.bytes();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.dataUri = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 32) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.frameTimestampUs = longToNumber(reader.int64());
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 40) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isVertical = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/playback_context.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -94,18 +94,19 @@ export const PlaybackContext: MessageFns<PlaybackContext> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PlaybackContext {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePlaybackContext();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.contentPlaybackContext = PlaybackContext_ContentPlaybackContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -248,221 +249,251 @@ export const PlaybackContext_ContentPlaybackContext: MessageFns<PlaybackContext_
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PlaybackContext_ContentPlaybackContext {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePlaybackContext_ContentPlaybackContext();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.deviceSignals = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.revShareClientId = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 32) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.timeSinceLastAdSeconds = reader.uint32();
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 40) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.lactMilliseconds = longToNumber(reader.int64());
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 48) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.autoplaysSinceLastAd = reader.uint32();
|
||||
continue;
|
||||
case 8:
|
||||
}
|
||||
case 8: {
|
||||
if (tag !== 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.vis = reader.uint32();
|
||||
continue;
|
||||
case 9:
|
||||
}
|
||||
case 9: {
|
||||
if (tag !== 72) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.fling = reader.bool();
|
||||
continue;
|
||||
case 10:
|
||||
}
|
||||
case 10: {
|
||||
if (tag !== 80) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.splay = reader.bool();
|
||||
continue;
|
||||
case 11:
|
||||
}
|
||||
case 11: {
|
||||
if (tag !== 88) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.autoplay = reader.bool();
|
||||
continue;
|
||||
case 13:
|
||||
}
|
||||
case 13: {
|
||||
if (tag !== 104) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.timeOfLastInstreamPrerollAd = longToNumber(reader.uint64());
|
||||
continue;
|
||||
case 15:
|
||||
}
|
||||
case 15: {
|
||||
if (tag !== 122) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.currentUrl = reader.string();
|
||||
continue;
|
||||
case 16:
|
||||
}
|
||||
case 16: {
|
||||
if (tag !== 130) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.referer = reader.string();
|
||||
continue;
|
||||
case 23:
|
||||
}
|
||||
case 23: {
|
||||
if (tag !== 184) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.loadAnnotationsByDemand = reader.bool();
|
||||
continue;
|
||||
case 24:
|
||||
}
|
||||
case 24: {
|
||||
if (tag !== 192) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.autoCaptionsDefaultOn = reader.bool();
|
||||
continue;
|
||||
case 27:
|
||||
}
|
||||
case 27: {
|
||||
if (tag !== 216) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.slicedBread = reader.bool();
|
||||
continue;
|
||||
case 29:
|
||||
}
|
||||
case 29: {
|
||||
if (tag !== 232) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.autonav = reader.bool();
|
||||
continue;
|
||||
case 30:
|
||||
}
|
||||
case 30: {
|
||||
if (tag !== 240) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.trailer = reader.bool();
|
||||
continue;
|
||||
case 34:
|
||||
}
|
||||
case 34: {
|
||||
if (tag !== 272) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playerWidthPixels = reader.int32();
|
||||
continue;
|
||||
case 35:
|
||||
}
|
||||
case 35: {
|
||||
if (tag !== 280) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playerHeightPixels = reader.int32();
|
||||
continue;
|
||||
case 37:
|
||||
}
|
||||
case 37: {
|
||||
if (tag !== 296) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.snd = reader.int32();
|
||||
continue;
|
||||
case 38:
|
||||
}
|
||||
case 38: {
|
||||
if (tag !== 304) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.vnd = reader.int32();
|
||||
continue;
|
||||
case 41:
|
||||
}
|
||||
case 41: {
|
||||
if (tag !== 328) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.uao = reader.int32();
|
||||
continue;
|
||||
case 44:
|
||||
}
|
||||
case 44: {
|
||||
if (tag !== 352) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.mutedAutoplay = reader.bool();
|
||||
continue;
|
||||
case 46:
|
||||
}
|
||||
case 46: {
|
||||
if (tag !== 368) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.enablePrivacyFilter = reader.bool();
|
||||
continue;
|
||||
case 47:
|
||||
}
|
||||
case 47: {
|
||||
if (tag !== 376) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isLivingRoomDeeplink = reader.bool();
|
||||
continue;
|
||||
case 48:
|
||||
}
|
||||
case 48: {
|
||||
if (tag !== 384) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.signatureTimestamp = reader.uint32();
|
||||
continue;
|
||||
case 50:
|
||||
}
|
||||
case 50: {
|
||||
if (tag !== 400) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isInlinePlaybackNoAd = reader.bool();
|
||||
continue;
|
||||
case 51:
|
||||
}
|
||||
case 51: {
|
||||
if (tag !== 408) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isInlineUnmutedPlayback = reader.bool();
|
||||
continue;
|
||||
case 55:
|
||||
}
|
||||
case 55: {
|
||||
if (tag !== 440) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playPackageVersion = longToNumber(reader.int64());
|
||||
continue;
|
||||
case 60:
|
||||
}
|
||||
case 60: {
|
||||
if (tag !== 480) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isSequenceEntry = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/player_attestation_request_data.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -38,12 +38,12 @@ export const PlayerAttestationRequestData: MessageFns<PlayerAttestationRequestDa
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PlayerAttestationRequestData {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePlayerAttestationRequestData();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
@@ -53,13 +53,15 @@ export const PlayerAttestationRequestData: MessageFns<PlayerAttestationRequestDa
|
||||
reader.uint32(),
|
||||
);
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.omitBotguardData = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -89,18 +91,19 @@ export const PlayerAttestationRequestData_IosguardChallengeRequestData: MessageF
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PlayerAttestationRequestData_IosguardChallengeRequestData {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePlayerAttestationRequestData_IosguardChallengeRequestData();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.challengeRequest = reader.bytes();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/player_request.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -152,179 +152,203 @@ export const PlayerRequest: MessageFns<PlayerRequest> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PlayerRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePlayerRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.context = InnerTubeContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.videoId = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 24) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.contentCheckOk = reader.bool();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playbackContext = PlaybackContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 40) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.racyCheckOk = reader.bool();
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.id = reader.string();
|
||||
continue;
|
||||
case 7:
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 58) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.t = reader.string();
|
||||
continue;
|
||||
case 8:
|
||||
}
|
||||
case 8: {
|
||||
if (tag !== 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.forOffline = reader.bool();
|
||||
continue;
|
||||
case 9:
|
||||
}
|
||||
case 9: {
|
||||
if (tag !== 74) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playlistId = reader.string();
|
||||
continue;
|
||||
case 10:
|
||||
}
|
||||
case 10: {
|
||||
if (tag !== 80) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playlistIndex = reader.int32();
|
||||
continue;
|
||||
case 11:
|
||||
}
|
||||
case 11: {
|
||||
if (tag !== 88) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.startTimeSecs = reader.uint32();
|
||||
continue;
|
||||
case 12:
|
||||
}
|
||||
case 12: {
|
||||
if (tag !== 98) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.params = reader.string();
|
||||
continue;
|
||||
case 14:
|
||||
}
|
||||
case 14: {
|
||||
if (tag !== 114) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.offlineSharingWrappedKey = reader.bytes();
|
||||
continue;
|
||||
case 16:
|
||||
}
|
||||
case 16: {
|
||||
if (tag !== 130) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.attestationRequest = PlayerAttestationRequestData.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 17:
|
||||
}
|
||||
case 17: {
|
||||
if (tag !== 138) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.referringApp = reader.string();
|
||||
continue;
|
||||
case 18:
|
||||
}
|
||||
case 18: {
|
||||
if (tag !== 146) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.referrer = reader.string();
|
||||
continue;
|
||||
case 19:
|
||||
}
|
||||
case 19: {
|
||||
if (tag !== 154) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.serializedThirdPartyEmbedConfig = reader.string();
|
||||
continue;
|
||||
case 20:
|
||||
}
|
||||
case 20: {
|
||||
if (tag !== 160) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.proxiedByOnesie = reader.bool();
|
||||
continue;
|
||||
case 22:
|
||||
}
|
||||
case 22: {
|
||||
if (tag !== 178) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.hostAppToken = reader.string();
|
||||
continue;
|
||||
case 23:
|
||||
}
|
||||
case 23: {
|
||||
if (tag !== 186) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.cpn = reader.string();
|
||||
continue;
|
||||
case 25:
|
||||
}
|
||||
case 25: {
|
||||
if (tag !== 200) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.overrideMutedAtStart = reader.bool();
|
||||
continue;
|
||||
case 26:
|
||||
}
|
||||
case 26: {
|
||||
if (tag !== 210) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.captionParams = PlayerRequestCaptionParams.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 27:
|
||||
}
|
||||
case 27: {
|
||||
if (tag !== 218) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.serviceIntegrityDimensions = ServiceIntegrityDimensions.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 29:
|
||||
}
|
||||
case 29: {
|
||||
if (tag !== 234) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.deferredPlayerToken = reader.bytes();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/player_request_caption_params.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -49,46 +49,51 @@ export const PlayerRequestCaptionParams: MessageFns<PlayerRequestCaptionParams>
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PlayerRequestCaptionParams {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePlayerRequestCaptionParams();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.deviceCaptionsOn = reader.bool();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.deviceCaptionsLangPref = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.viewerSelectedCaptionLangs = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.ccLangPref = reader.string();
|
||||
continue;
|
||||
case 5:
|
||||
}
|
||||
case 5: {
|
||||
if (tag !== 40) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.ccLoadPolicyOn = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/reel_item_watch_request.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -41,39 +41,43 @@ export const ReelItemWatchRequest: MessageFns<ReelItemWatchRequest> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ReelItemWatchRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseReelItemWatchRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.context = InnerTubeContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playerRequest = PlayerRequest.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.params = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 32) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.disablePlayerResponse = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/request_info.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -156,144 +156,163 @@ export const RequestInfo: MessageFns<RequestInfo> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RequestInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRequestInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 6:
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.thirdPartyDigest = reader.string();
|
||||
continue;
|
||||
case 7:
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 56) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.useSsl = reader.bool();
|
||||
continue;
|
||||
case 9:
|
||||
}
|
||||
case 9: {
|
||||
if (tag !== 72) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.returnErrorDetail = reader.bool();
|
||||
continue;
|
||||
case 12:
|
||||
}
|
||||
case 12: {
|
||||
if (tag !== 98) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.ifNoneMatch = reader.string();
|
||||
continue;
|
||||
case 13:
|
||||
}
|
||||
case 13: {
|
||||
if (tag !== 104) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.returnLogEntry = reader.bool();
|
||||
continue;
|
||||
case 14:
|
||||
}
|
||||
case 14: {
|
||||
if (tag !== 112) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isPrefetch = reader.bool();
|
||||
continue;
|
||||
case 15:
|
||||
}
|
||||
case 15: {
|
||||
if (tag !== 122) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.internalExperimentFlags.push(KeyValuePair.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
case 16:
|
||||
}
|
||||
case 16: {
|
||||
if (tag !== 128) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.returnDebugData = reader.bool();
|
||||
continue;
|
||||
case 18:
|
||||
}
|
||||
case 18: {
|
||||
if (tag !== 146) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.innertubez = reader.string();
|
||||
continue;
|
||||
case 23:
|
||||
}
|
||||
case 23: {
|
||||
if (tag !== 184) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.traceProto = reader.bool();
|
||||
continue;
|
||||
case 24:
|
||||
}
|
||||
case 24: {
|
||||
if (tag !== 192) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.returnLogEntryJson = reader.bool();
|
||||
continue;
|
||||
case 25:
|
||||
}
|
||||
case 25: {
|
||||
if (tag !== 202) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.sherlogUsername = reader.string();
|
||||
continue;
|
||||
case 29:
|
||||
}
|
||||
case 29: {
|
||||
if (tag !== 234) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.reauthRequestInfo = RequestInfo_ReauthRequestInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 30:
|
||||
}
|
||||
case 30: {
|
||||
if (tag !== 242) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.sessionInfo = RequestInfo_SessionInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 31:
|
||||
}
|
||||
case 31: {
|
||||
if (tag !== 248) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.returnLogEntryProto = reader.bool();
|
||||
continue;
|
||||
case 32:
|
||||
}
|
||||
case 32: {
|
||||
if (tag !== 258) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.externalPrequestContext = reader.string();
|
||||
continue;
|
||||
case 34:
|
||||
}
|
||||
case 34: {
|
||||
if (tag !== 274) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.attestationResponseData = AttestationResponseData.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 35:
|
||||
}
|
||||
case 35: {
|
||||
if (tag !== 282) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.eats = reader.bytes();
|
||||
continue;
|
||||
case 36:
|
||||
}
|
||||
case 36: {
|
||||
if (tag !== 290) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.requestQos = RequestInfo_RequestQoS.decode(reader, reader.uint32());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -318,18 +337,19 @@ export const RequestInfo_RequestQoS: MessageFns<RequestInfo_RequestQoS> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RequestInfo_RequestQoS {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRequestInfo_RequestQoS();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.criticality = reader.int32() as any;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -354,18 +374,19 @@ export const RequestInfo_SessionInfo: MessageFns<RequestInfo_SessionInfo> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RequestInfo_SessionInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRequestInfo_SessionInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.token = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -390,18 +411,19 @@ export const RequestInfo_ReauthRequestInfo: MessageFns<RequestInfo_ReauthRequest
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RequestInfo_ReauthRequestInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRequestInfo_ReauthRequestInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.encodedReauthProofToken = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/service_integrity_dimensions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -27,18 +27,19 @@ export const ServiceIntegrityDimensions: MessageFns<ServiceIntegrityDimensions>
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ServiceIntegrityDimensions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseServiceIntegrityDimensions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.poToken = reader.bytes();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/third_party_info.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -60,53 +60,59 @@ export const ThirdPartyInfo: MessageFns<ThirdPartyInfo> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ThirdPartyInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseThirdPartyInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.developerKey = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.appName = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.appPublisher = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.embedUrl = reader.string();
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.appVersion = reader.string();
|
||||
continue;
|
||||
case 7:
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 58) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.embeddedPlayerContext = ThirdPartyInfo_EmbeddedPlayerContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -137,32 +143,35 @@ export const ThirdPartyInfo_EmbeddedPlayerContext: MessageFns<ThirdPartyInfo_Emb
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ThirdPartyInfo_EmbeddedPlayerContext {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseThirdPartyInfo_EmbeddedPlayerContext();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.ancestorOrigins = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.embeddedPlayerEncryptedContext = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
}
|
||||
case 3: {
|
||||
if (tag !== 24) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.ancestorOriginsSupported = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/user_info.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -81,74 +81,83 @@ export const UserInfo: MessageFns<UserInfo> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): UserInfo {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseUserInfo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 3:
|
||||
case 3: {
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.onBehalfOfUser = reader.string();
|
||||
continue;
|
||||
case 7:
|
||||
}
|
||||
case 7: {
|
||||
if (tag !== 56) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.enableSafetyMode = reader.bool();
|
||||
continue;
|
||||
case 12:
|
||||
}
|
||||
case 12: {
|
||||
if (tag !== 98) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.credentialTransferTokens.push(UserInfo_CredentialTransferToken.decode(reader, reader.uint32()));
|
||||
continue;
|
||||
case 13:
|
||||
}
|
||||
case 13: {
|
||||
if (tag !== 106) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.delegatePurchases = UserInfo_DelegatePurchases.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 14:
|
||||
}
|
||||
case 14: {
|
||||
if (tag !== 114) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.kidsParent = UserInfo_KidsParent.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 15:
|
||||
}
|
||||
case 15: {
|
||||
if (tag !== 120) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isIncognito = reader.bool();
|
||||
continue;
|
||||
case 16:
|
||||
}
|
||||
case 16: {
|
||||
if (tag !== 128) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.lockedSafetyMode = reader.bool();
|
||||
continue;
|
||||
case 17:
|
||||
}
|
||||
case 17: {
|
||||
if (tag !== 138) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.delegationContext = UserInfo_DelegationContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 18:
|
||||
}
|
||||
case 18: {
|
||||
if (tag !== 146) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.serializedDelegationContext = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -170,7 +179,7 @@ export const UserInfo_KidsParent: MessageFns<UserInfo_KidsParent> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): UserInfo_KidsParent {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseUserInfo_KidsParent();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -196,7 +205,7 @@ export const UserInfo_DelegatePurchases: MessageFns<UserInfo_DelegatePurchases>
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): UserInfo_DelegatePurchases {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseUserInfo_DelegatePurchases();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -222,7 +231,7 @@ export const UserInfo_DelegationContext: MessageFns<UserInfo_DelegationContext>
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): UserInfo_DelegationContext {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseUserInfo_DelegationContext();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -248,7 +257,7 @@ export const UserInfo_CredentialTransferToken: MessageFns<UserInfo_CredentialTra
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): UserInfo_CredentialTransferToken {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseUserInfo_CredentialTransferToken();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.0
|
||||
// protoc v5.29.2
|
||||
// protoc-gen-ts_proto v2.7.7
|
||||
// protoc v6.33.5
|
||||
// source: youtube/api/pfiinnertube/watch_next_request.proto
|
||||
|
||||
/* eslint-disable */
|
||||
@@ -170,214 +170,243 @@ export const WatchNextRequest: MessageFns<WatchNextRequest> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): WatchNextRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseWatchNextRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.context = InnerTubeContext.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.videoId = reader.string();
|
||||
continue;
|
||||
case 4:
|
||||
}
|
||||
case 4: {
|
||||
if (tag !== 34) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playlistId = reader.string();
|
||||
continue;
|
||||
case 6:
|
||||
}
|
||||
case 6: {
|
||||
if (tag !== 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.params = reader.string();
|
||||
continue;
|
||||
case 8:
|
||||
}
|
||||
case 8: {
|
||||
if (tag !== 66) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.continuation = reader.string();
|
||||
continue;
|
||||
case 9:
|
||||
}
|
||||
case 9: {
|
||||
if (tag !== 72) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isAdPlayback = reader.bool();
|
||||
continue;
|
||||
case 10:
|
||||
}
|
||||
case 10: {
|
||||
if (tag !== 80) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.mdxUseDevServer = reader.bool();
|
||||
continue;
|
||||
case 12:
|
||||
}
|
||||
case 12: {
|
||||
if (tag !== 98) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.referrer = reader.string();
|
||||
continue;
|
||||
case 13:
|
||||
}
|
||||
case 13: {
|
||||
if (tag !== 106) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.referringApp = reader.string();
|
||||
continue;
|
||||
case 16:
|
||||
}
|
||||
case 16: {
|
||||
if (tag !== 130) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.adParams = reader.string();
|
||||
continue;
|
||||
case 18:
|
||||
}
|
||||
case 18: {
|
||||
if (tag !== 144) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.requestMusicSequence = reader.bool();
|
||||
continue;
|
||||
case 21:
|
||||
}
|
||||
case 21: {
|
||||
if (tag !== 168) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.enableMdxAutoplay = reader.bool();
|
||||
continue;
|
||||
case 22:
|
||||
}
|
||||
case 22: {
|
||||
if (tag !== 176) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isMdxPlayback = reader.bool();
|
||||
continue;
|
||||
case 24:
|
||||
}
|
||||
case 24: {
|
||||
if (tag !== 192) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.racyCheckOk = reader.bool();
|
||||
continue;
|
||||
case 25:
|
||||
}
|
||||
case 25: {
|
||||
if (tag !== 200) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.contentCheckOk = reader.bool();
|
||||
continue;
|
||||
case 26:
|
||||
}
|
||||
case 26: {
|
||||
if (tag !== 208) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isAudioOnly = reader.bool();
|
||||
continue;
|
||||
case 27:
|
||||
}
|
||||
case 27: {
|
||||
if (tag !== 216) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.autonavEnabled = reader.bool();
|
||||
continue;
|
||||
case 30:
|
||||
}
|
||||
case 30: {
|
||||
if (tag !== 240) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.enablePersistentPlaylistPanel = reader.bool();
|
||||
continue;
|
||||
case 31:
|
||||
}
|
||||
case 31: {
|
||||
if (tag !== 250) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.playlistSetVideoId = reader.string();
|
||||
continue;
|
||||
case 35:
|
||||
}
|
||||
case 35: {
|
||||
if (tag !== 280) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.showRuInvalidTokenMessage = reader.bool();
|
||||
continue;
|
||||
case 37:
|
||||
}
|
||||
case 37: {
|
||||
if (tag !== 298) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.serializedThirdPartyEmbedConfig = reader.string();
|
||||
continue;
|
||||
case 38:
|
||||
}
|
||||
case 38: {
|
||||
if (tag !== 304) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.showContentOwnerOnly = reader.bool();
|
||||
continue;
|
||||
case 42:
|
||||
}
|
||||
case 42: {
|
||||
if (tag !== 336) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.isEmbedPreview = reader.bool();
|
||||
continue;
|
||||
case 43:
|
||||
}
|
||||
case 43: {
|
||||
if (tag !== 346) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.lastScrubbedInlinePlaybackVideoId = reader.string();
|
||||
continue;
|
||||
case 44:
|
||||
}
|
||||
case 44: {
|
||||
if (tag !== 354) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.lastAudioTurnedOnInlinePlaybackVideoId = reader.string();
|
||||
continue;
|
||||
case 45:
|
||||
}
|
||||
case 45: {
|
||||
if (tag !== 362) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.lastAudioTurnedOffInlinePlaybackVideoId = reader.string();
|
||||
continue;
|
||||
case 47:
|
||||
}
|
||||
case 47: {
|
||||
if (tag !== 376) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.captionsRequested = reader.bool();
|
||||
continue;
|
||||
case 50:
|
||||
}
|
||||
case 50: {
|
||||
if (tag !== 402) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.queueContextParams = reader.bytes();
|
||||
continue;
|
||||
case 55:
|
||||
}
|
||||
case 55: {
|
||||
if (tag !== 440) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.showShortsOnly = reader.bool();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
|
||||
@@ -7,13 +7,11 @@ message VisitorData {
|
||||
}
|
||||
|
||||
message SearchFilter {
|
||||
optional SortBy sort_by = 1;
|
||||
optional Prioritize prioritize = 1;
|
||||
|
||||
enum SortBy {
|
||||
enum Prioritize {
|
||||
RELEVANCE = 0;
|
||||
RATING = 1;
|
||||
UPLOAD_DATE = 2;
|
||||
VIEW_COUNT = 3;
|
||||
POPULARITY = 3;
|
||||
}
|
||||
|
||||
message Filters {
|
||||
@@ -36,7 +34,6 @@ message SearchFilter {
|
||||
|
||||
enum UploadDate {
|
||||
ANY_DATE = 0;
|
||||
HOUR = 1;
|
||||
TODAY = 2;
|
||||
WEEK = 3;
|
||||
MONTH = 4;
|
||||
@@ -49,13 +46,14 @@ message SearchFilter {
|
||||
CHANNEL = 2;
|
||||
PLAYLIST = 3;
|
||||
MOVIE = 4;
|
||||
SHORTS = 9;
|
||||
}
|
||||
|
||||
enum Duration {
|
||||
ANY_DURATION = 0;
|
||||
SHORT = 1;
|
||||
LONG = 2;
|
||||
MEDIUM = 3;
|
||||
OVER_TWENTY_MINS = 2;
|
||||
UNDER_THREE_MINS = 4;
|
||||
THREE_TO_TWENTY_MINS = 5;
|
||||
}
|
||||
|
||||
message MusicSearchType {
|
||||
|
||||
@@ -49,7 +49,7 @@ import {
|
||||
SearchFilter_Filters_Duration,
|
||||
SearchFilter_Filters_SearchType,
|
||||
SearchFilter_Filters_UploadDate,
|
||||
SearchFilter_SortBy
|
||||
SearchFilter_Prioritize
|
||||
} from '../protos/generated/misc/params.ts';
|
||||
|
||||
/**
|
||||
@@ -205,8 +205,8 @@ export default class Innertube {
|
||||
|
||||
search_filter.filters = {};
|
||||
|
||||
if (filters.sort_by) {
|
||||
search_filter.sortBy = SearchFilter_SortBy[filters.sort_by.toUpperCase() as keyof typeof SearchFilter_SortBy];
|
||||
if (filters.prioritize) {
|
||||
search_filter.prioritize = SearchFilter_Prioritize[filters.prioritize.toUpperCase() as keyof typeof SearchFilter_Prioritize];
|
||||
}
|
||||
|
||||
if (filters.upload_date) {
|
||||
@@ -364,12 +364,6 @@ export default class Innertube {
|
||||
return new History(this.actions, response);
|
||||
}
|
||||
|
||||
async getTrending(): Promise<TabbedFeed<IBrowseResponse>> {
|
||||
const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: 'FEtrending' } });
|
||||
const response = await browse_endpoint.call(this.#session.actions);
|
||||
return new TabbedFeed(this.actions, response);
|
||||
}
|
||||
|
||||
async getCourses(): Promise<Feed<IBrowseResponse>> {
|
||||
const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: 'FEcourses_destination' } });
|
||||
const response = await browse_endpoint.call(this.#session.actions, { parse: true });
|
||||
@@ -393,7 +387,7 @@ export default class Innertube {
|
||||
const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: id } });
|
||||
let response = await browse_endpoint.call<IBrowseResponse>(this.#session.actions, { parse: true });
|
||||
|
||||
if (response.on_response_received_actions?.[0].is(NavigateAction)) {
|
||||
if (response.on_response_received_actions?.[0]?.is(NavigateAction)) {
|
||||
response = await response.on_response_received_actions[0].endpoint.call<IBrowseResponse>(this.#session.actions, { parse: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,13 @@ import { Constants, BinarySerializer, Log } from '../utils/index.ts';
|
||||
import {
|
||||
getRandomUserAgent,
|
||||
getStringBetweenStrings,
|
||||
getNsigProcessorFn,
|
||||
Platform,
|
||||
PlayerError
|
||||
} from '../utils/Utils.ts';
|
||||
|
||||
import { JsExtractor, JsAnalyzer } from '../utils/index.ts';
|
||||
import { nMatcher, sigMatcher, timestampMatcher } from '../utils/javascript/matchers.ts';
|
||||
import { nsigMatcher, timestampMatcher } from '../utils/javascript/matchers.ts';
|
||||
|
||||
import type { ExtractionConfig } from '../utils/javascript/JsAnalyzer.ts';
|
||||
import type { BuildScriptResult } from '../utils/javascript/JsExtractor.ts';
|
||||
@@ -71,7 +72,7 @@ export default class Player {
|
||||
}
|
||||
}
|
||||
|
||||
const player_url = new URL(`/s/player/${player_id}/player_ias.vflset/en_US/base.js`, Constants.URLS.YT_BASE);
|
||||
const player_url = new URL(`/s/player/${player_id}/player_es6.vflset/en_US/base.js`, Constants.URLS.YT_BASE);
|
||||
|
||||
Log.info(TAG, `Could not find any cached player. Will download a new player from ${player_url}.`);
|
||||
|
||||
@@ -87,13 +88,11 @@ export default class Player {
|
||||
|
||||
const player_js = await player_res.text();
|
||||
|
||||
const sigFunctionName = 'sigFunction';
|
||||
const nFunctionName = 'nFunction';
|
||||
const nsigFunctionName = 'nsigFunction';
|
||||
const timestampVarName = 'signatureTimestampVar';
|
||||
|
||||
const extractions: ExtractionConfig[] = [
|
||||
{ friendlyName: sigFunctionName, match: sigMatcher },
|
||||
{ friendlyName: nFunctionName, match: nMatcher },
|
||||
{ friendlyName: nsigFunctionName, match: nsigMatcher },
|
||||
{ friendlyName: timestampVarName, match: timestampMatcher, collectDependencies: false }
|
||||
];
|
||||
|
||||
@@ -110,12 +109,8 @@ export default class Player {
|
||||
Log.warn(TAG, 'Failed to extract signature timestamp.');
|
||||
}
|
||||
|
||||
if (!result.exported.includes(sigFunctionName)) {
|
||||
Log.warn(TAG, 'Failed to extract signature decipher function.');
|
||||
}
|
||||
|
||||
if (!result.exported.includes(nFunctionName)) {
|
||||
Log.warn(TAG, 'Failed to extract n decipher function.');
|
||||
if (!result.exported.includes(nsigFunctionName)) {
|
||||
Log.warn(TAG, 'Failed to extract n/sig decipher function.');
|
||||
}
|
||||
|
||||
const signatureTimestamp = result.exportedRawValues?.[timestampVarName];
|
||||
@@ -145,10 +140,11 @@ export default class Player {
|
||||
const sp = args.get('sp');
|
||||
|
||||
if (this.data && ((signature_cipher || cipher) || n)) {
|
||||
const eval_args: { sig?: string | null; n?: string | null } = {};
|
||||
const eval_args: { sig?: string | null; n?: string | null; sp?: string | null } = {};
|
||||
|
||||
if (signature_cipher || cipher) {
|
||||
eval_args.sig = s;
|
||||
eval_args.sp = sp;
|
||||
}
|
||||
|
||||
if (n) {
|
||||
@@ -161,7 +157,12 @@ export default class Player {
|
||||
}
|
||||
|
||||
if (Object.keys(eval_args).length > 0) {
|
||||
const result = await Platform.shim.eval(this.data, eval_args) as Record<string, unknown>;
|
||||
// Shallow copy to avoid mutating the original data.
|
||||
const data = { ...this.data };
|
||||
|
||||
data.output = `${data.output}\n${getNsigProcessorFn(eval_args.n, eval_args.sp, eval_args.sig)}`;
|
||||
|
||||
const result = await Platform.shim.eval(data, eval_args) as Record<string, unknown>;
|
||||
|
||||
if (typeof result !== 'object' || result === null) {
|
||||
throw new PlayerError('Got invalid result from player script evaluation.');
|
||||
|
||||
@@ -26,6 +26,7 @@ export enum ClientType {
|
||||
MUSIC = 'WEB_REMIX',
|
||||
IOS = 'iOS',
|
||||
ANDROID = 'ANDROID',
|
||||
ANDROID_VR = 'ANDROID_VR',
|
||||
ANDROID_MUSIC = 'ANDROID_MUSIC',
|
||||
ANDROID_CREATOR = 'ANDROID_CREATOR',
|
||||
TV = 'TVHTML5',
|
||||
|
||||
@@ -5,21 +5,21 @@ import NavigationEndpoint from './NavigationEndpoint.ts';
|
||||
export default class ChannelSubMenu extends YTNode {
|
||||
static type = 'ChannelSubMenu';
|
||||
|
||||
content_type_sub_menu_items: {
|
||||
public content_type_sub_menu_items: {
|
||||
endpoint: NavigationEndpoint;
|
||||
selected: boolean;
|
||||
title: string;
|
||||
}[];
|
||||
|
||||
sort_setting;
|
||||
public sort_setting: YTNode;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.content_type_sub_menu_items = data.contentTypeSubMenuItems.map((item: RawNode) => ({
|
||||
this.content_type_sub_menu_items = data.sortSetting?.sortFilterSubMenuRenderer?.subMenuItems?.map((item: RawNode) => ({
|
||||
endpoint: new NavigationEndpoint(item.navigationEndpoint || item.endpoint),
|
||||
selected: item.selected,
|
||||
title: item.title
|
||||
}));
|
||||
})) || [];
|
||||
this.sort_setting = Parser.parseItem(data.sortSetting);
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,26 @@ import { YTNode } from '../helpers.ts';
|
||||
import { Parser, type RawNode } from '../index.ts';
|
||||
import ThumbnailView from './ThumbnailView.ts';
|
||||
|
||||
interface StackColor {
|
||||
light_theme?: number;
|
||||
dark_theme?: number;
|
||||
}
|
||||
|
||||
export default class CollectionThumbnailView extends YTNode {
|
||||
static type = 'CollectionThumbnailView';
|
||||
|
||||
primary_thumbnail: ThumbnailView | null;
|
||||
stack_color?: {
|
||||
light_theme: number;
|
||||
dark_theme: number;
|
||||
};
|
||||
public primary_thumbnail: ThumbnailView | null;
|
||||
public stack_color?: StackColor;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
|
||||
this.primary_thumbnail = Parser.parseItem(data.primaryThumbnail, ThumbnailView);
|
||||
if (data.stackColor) {
|
||||
|
||||
if ('stackColor' in data) {
|
||||
this.stack_color = {
|
||||
light_theme: data.stackColor.lightTheme,
|
||||
dark_theme: data.stackColor.darkTheme
|
||||
light_theme: data.stackColor?.lightTheme,
|
||||
dark_theme: data.stackColor?.darkTheme
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,16 @@ export default class ContentMetadataView extends YTNode {
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.metadata_rows = data.metadataRows.map((row: RawNode) => ({
|
||||
|
||||
this.metadata_rows = data.metadataRows?.map((row: RawNode) => ({
|
||||
metadata_parts: row.metadataParts?.map((part: RawNode) => ({
|
||||
text: part.text ? Text.fromAttributed(part.text) : null,
|
||||
avatar_stack: Parser.parseItem(part.avatarStack, AvatarStackView),
|
||||
enable_truncation: data.enableTruncation
|
||||
})),
|
||||
badges: Parser.parseArray(row.badges, BadgeView)
|
||||
}));
|
||||
})) || [];
|
||||
|
||||
this.delimiter = data.delimiter;
|
||||
}
|
||||
}
|
||||
@@ -26,13 +26,13 @@ export default class DescriptionPreviewView extends YTNode {
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
|
||||
if (Reflect.has(data, 'description'))
|
||||
if ('description' in data)
|
||||
this.description = Text.fromAttributed(data.description);
|
||||
|
||||
if (Reflect.has(data, 'maxLines'))
|
||||
if ('maxLines' in data)
|
||||
this.max_lines = parseInt(data.maxLines);
|
||||
|
||||
if (Reflect.has(data, 'truncationText'))
|
||||
if ('truncationText' in data)
|
||||
this.truncation_text = Text.fromAttributed(data.truncationText);
|
||||
|
||||
this.always_show_truncation_text = !!data.alwaysShowTruncationText;
|
||||
|
||||
@@ -5,6 +5,7 @@ import HorizontalCardList from './HorizontalCardList.ts';
|
||||
import HorizontalList from './HorizontalList.ts';
|
||||
import Text from './misc/Text.ts';
|
||||
import Thumbnail from './misc/Thumbnail.ts';
|
||||
import VideoSummaryContentView from './VideoSummaryContentView.ts';
|
||||
|
||||
export default class ExpandableMetadata extends YTNode {
|
||||
static type = 'ExpandableMetadata';
|
||||
@@ -16,7 +17,7 @@ export default class ExpandableMetadata extends YTNode {
|
||||
expanded_title: Text;
|
||||
};
|
||||
|
||||
expanded_content: HorizontalCardList | HorizontalList | null;
|
||||
expanded_content: VideoSummaryContentView | HorizontalCardList | HorizontalList | null;
|
||||
expand_button: Button | null;
|
||||
collapse_button: Button | null;
|
||||
|
||||
@@ -32,7 +33,7 @@ export default class ExpandableMetadata extends YTNode {
|
||||
};
|
||||
}
|
||||
|
||||
this.expanded_content = Parser.parseItem(data.expandedContent, [ HorizontalCardList, HorizontalList ]);
|
||||
this.expanded_content = Parser.parseItem(data.expandedContent, [ VideoSummaryContentView, HorizontalCardList, HorizontalList ]);
|
||||
this.expand_button = Parser.parseItem(data.expandButton, Button);
|
||||
this.collapse_button = Parser.parseItem(data.collapseButton, Button);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ import { type ObservedArray, YTNode } from '../helpers.ts';
|
||||
import { Parser, type RawNode } from '../index.ts';
|
||||
import ButtonView from './ButtonView.ts';
|
||||
import ToggleButtonView from './ToggleButtonView.ts';
|
||||
import SubscribeButtonView from './SubscribeButtonView.ts';
|
||||
|
||||
export type ActionRow = {
|
||||
actions: ObservedArray<ButtonView | ToggleButtonView>;
|
||||
actions: ObservedArray<ButtonView | ToggleButtonView | SubscribeButtonView>;
|
||||
};
|
||||
|
||||
export default class FlexibleActionsView extends YTNode {
|
||||
@@ -16,8 +17,8 @@ export default class FlexibleActionsView extends YTNode {
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.actions_rows = data.actionsRows.map((row: RawNode) => ({
|
||||
actions: Parser.parseArray(row.actions, [ ButtonView, ToggleButtonView ])
|
||||
actions: Parser.parseArray(row.actions, [ ButtonView, ToggleButtonView, SubscribeButtonView ])
|
||||
}));
|
||||
this.style = data.style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,22 +11,28 @@ import Text from './misc/Text.ts';
|
||||
export default class ListItemView extends YTNode {
|
||||
static type = 'ListItemView';
|
||||
|
||||
public title: Text;
|
||||
public subtitle: Text;
|
||||
public title?: Text;
|
||||
public subtitle?: Text;
|
||||
public leading_accessory: AvatarView | null;
|
||||
public renderer_context: RendererContext;
|
||||
public trailing_buttons?: ObservedArray<SubscribeButtonView>;
|
||||
public renderer_context?: RendererContext;
|
||||
public trailing_buttons: ObservedArray<SubscribeButtonView>;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
|
||||
this.title = Text.fromAttributed(data.title);
|
||||
this.subtitle = Text.fromAttributed(data.subtitle);
|
||||
this.leading_accessory = Parser.parseItem(data.leadingAccessory, AvatarView);
|
||||
this.renderer_context = new RendererContext(data.rendererContext);
|
||||
|
||||
if ('trailingButtons' in data) {
|
||||
this.trailing_buttons = Parser.parseArray(data.trailingButtons.buttons, SubscribeButtonView);
|
||||
if ('title' in data) {
|
||||
this.title = Text.fromAttributed(data.title);
|
||||
}
|
||||
|
||||
if ('subtitle' in data) {
|
||||
this.subtitle = Text.fromAttributed(data.subtitle);
|
||||
}
|
||||
|
||||
this.leading_accessory = Parser.parseItem(data.leadingAccessory, AvatarView);
|
||||
|
||||
if ('rendererContext' in data) {
|
||||
this.renderer_context = new RendererContext(data.rendererContext);
|
||||
}
|
||||
|
||||
this.trailing_buttons = Parser.parseArray(data.trailingButtons?.buttons, SubscribeButtonView);
|
||||
}
|
||||
}
|
||||
37
deno/src/parser/classes/PlayerCaptchaView.ts
Normal file
37
deno/src/parser/classes/PlayerCaptchaView.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { YTNode } from '../helpers.ts';
|
||||
import { Text } from '../misc.ts';
|
||||
import { type RawNode } from '../index.ts';
|
||||
|
||||
export default class PlayerCaptchaView extends YTNode {
|
||||
static type = 'PlayerCaptchaView';
|
||||
|
||||
public captcha_loading_message?: Text;
|
||||
public challenge_reason?: Text;
|
||||
public captcha_successful_message?: Text;
|
||||
public captcha_cookie_set_failure_message?: Text;
|
||||
public captcha_failed_message?: Text;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
|
||||
if ('captchaLoadingMessage' in data) {
|
||||
this.captcha_loading_message = Text.fromAttributed(data.captchaLoadingMessage);
|
||||
}
|
||||
|
||||
if ('challengeReason' in data) {
|
||||
this.challenge_reason = Text.fromAttributed(data.challengeReason);
|
||||
}
|
||||
|
||||
if ('captchaSuccessfulMessage' in data) {
|
||||
this.captcha_successful_message = Text.fromAttributed(data.captchaSuccessfulMessage);
|
||||
}
|
||||
|
||||
if ('captchaCookieSetFailureMessage' in data) {
|
||||
this.captcha_cookie_set_failure_message = Text.fromAttributed(data.captchaCookieSetFailureMessage);
|
||||
}
|
||||
|
||||
if ('captchaFailedMessage' in data) {
|
||||
this.captcha_failed_message = Text.fromAttributed(data.captchaFailedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ import VideoDescriptionCourseSection from './VideoDescriptionCourseSection.ts';
|
||||
import VideoAttributesSectionView from './VideoAttributesSectionView.ts';
|
||||
import HowThisWasMadeSectionView from './HowThisWasMadeSectionView.ts';
|
||||
import ReelShelf from './ReelShelf.ts';
|
||||
import ExpandableMetadata from './ExpandableMetadata.ts';
|
||||
import MerchandiseShelf from './MerchandiseShelf.ts';
|
||||
|
||||
export default class StructuredDescriptionContent extends YTNode {
|
||||
static type = 'StructuredDescriptionContent';
|
||||
@@ -18,7 +20,7 @@ export default class StructuredDescriptionContent extends YTNode {
|
||||
VideoDescriptionHeader | ExpandableVideoDescriptionBody | VideoDescriptionMusicSection |
|
||||
VideoDescriptionInfocardsSection | VideoDescriptionTranscriptSection |
|
||||
VideoDescriptionCourseSection | HorizontalCardList | ReelShelf | VideoAttributesSectionView |
|
||||
HowThisWasMadeSectionView
|
||||
HowThisWasMadeSectionView | ExpandableMetadata | MerchandiseShelf
|
||||
>;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
@@ -27,7 +29,7 @@ export default class StructuredDescriptionContent extends YTNode {
|
||||
VideoDescriptionHeader, ExpandableVideoDescriptionBody, VideoDescriptionMusicSection,
|
||||
VideoDescriptionInfocardsSection, VideoDescriptionCourseSection, VideoDescriptionTranscriptSection,
|
||||
VideoDescriptionTranscriptSection, HorizontalCardList, ReelShelf, VideoAttributesSectionView,
|
||||
HowThisWasMadeSectionView
|
||||
HowThisWasMadeSectionView, ExpandableMetadata, MerchandiseShelf
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -10,52 +10,65 @@ interface ButtonContent {
|
||||
endpoint: NavigationEndpoint;
|
||||
}
|
||||
|
||||
interface BellAccessibilityData {
|
||||
off_label?: string;
|
||||
all_label?: string;
|
||||
occasional_label?: string;
|
||||
disabled_label?: string;
|
||||
}
|
||||
|
||||
interface ButtonStyle {
|
||||
unsubscribed_state_style?: string;
|
||||
subscribed_state_style?: string;
|
||||
}
|
||||
|
||||
export default class SubscribeButtonView extends YTNode {
|
||||
static type = 'SubscribeButtonView';
|
||||
|
||||
public subscribe_button_content: ButtonContent;
|
||||
public unsubscribe_button_content: ButtonContent;
|
||||
public disable_notification_bell: boolean;
|
||||
public button_style: {
|
||||
unsubscribed_state_style: string;
|
||||
subscribed_state_style: string;
|
||||
};
|
||||
public button_style?: ButtonStyle;
|
||||
public is_signed_out: boolean;
|
||||
public background_style: string;
|
||||
public disable_subscribe_button: boolean;
|
||||
public on_show_subscription_options: NavigationEndpoint;
|
||||
public on_show_subscription_options?: NavigationEndpoint;
|
||||
public channel_id: string;
|
||||
public enable_subscribe_button_post_click_animation: boolean;
|
||||
public bell_accessiblity_data: {
|
||||
off_label: string;
|
||||
all_label: string;
|
||||
occasional_label: string;
|
||||
disabled_label: string;
|
||||
};
|
||||
public bell_accessibility_data?: BellAccessibilityData;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
|
||||
this.subscribe_button_content = this.#parseButtonContent(data.subscribeButtonContent);
|
||||
this.unsubscribe_button_content = this.#parseButtonContent(data.unsubscribeButtonContent);
|
||||
|
||||
this.disable_notification_bell = data.disableNotificationBell;
|
||||
this.button_style = {
|
||||
unsubscribed_state_style: data.buttonStyle.unsubscribedStateStyle,
|
||||
subscribed_state_style: data.buttonStyle.subscribedStateStyle
|
||||
};
|
||||
|
||||
if ('buttonStyle' in data) {
|
||||
this.button_style = {
|
||||
unsubscribed_state_style: data.buttonStyle?.unsubscribedStateStyle,
|
||||
subscribed_state_style: data.buttonStyle?.subscribedStateStyle
|
||||
};
|
||||
}
|
||||
|
||||
this.is_signed_out = data.isSignedOut;
|
||||
this.background_style = data.backgroundStyle;
|
||||
this.disable_subscribe_button = data.disableSubscribeButton;
|
||||
this.on_show_subscription_options = new NavigationEndpoint(data.onShowSubscriptionOptions);
|
||||
|
||||
if ('onShowSubscriptionOptions' in data) {
|
||||
this.on_show_subscription_options = new NavigationEndpoint(data.onShowSubscriptionOptions);
|
||||
}
|
||||
|
||||
this.channel_id = data.channelId;
|
||||
this.enable_subscribe_button_post_click_animation = data.enableSubscribeButtonPostClickAnimation;
|
||||
this.bell_accessiblity_data = {
|
||||
off_label: data.bellAccessibilityData.offLabel,
|
||||
all_label: data.bellAccessibilityData.allLabel,
|
||||
occasional_label: data.bellAccessibilityData.occasionalLabel,
|
||||
disabled_label: data.bellAccessibilityData.disabledLabel
|
||||
};
|
||||
|
||||
if ('bellAccessibilityData' in data) {
|
||||
this.bell_accessibility_data = {
|
||||
off_label: data.bellAccessibilityData?.offLabel,
|
||||
all_label: data.bellAccessibilityData?.allLabel,
|
||||
occasional_label: data.bellAccessibilityData?.occasionalLabel,
|
||||
disabled_label: data.bellAccessibilityData?.disabledLabel
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#parseButtonContent(data: RawNode): ButtonContent {
|
||||
|
||||
28
deno/src/parser/classes/VideoSummaryContentView.ts
Normal file
28
deno/src/parser/classes/VideoSummaryContentView.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { ObservedArray } from '../helpers.ts';
|
||||
import { YTNode } from '../helpers.ts';
|
||||
import { Parser, type RawNode } from '../index.ts';
|
||||
import DislikeButtonView from './DislikeButtonView.ts';
|
||||
import LikeButtonView from './LikeButtonView.ts';
|
||||
import VideoSummaryParagraphView from './VideoSummaryParagraphView.ts';
|
||||
|
||||
export default class VideoSummaryContentView extends YTNode {
|
||||
static type = 'VideoSummaryContentView';
|
||||
|
||||
public dislike_button_view?: DislikeButtonView | null;
|
||||
public like_button_view?: LikeButtonView | null;
|
||||
public paragraphs: ObservedArray<VideoSummaryParagraphView>;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
|
||||
if ('dislikeButtonViewModel' in data) {
|
||||
this.dislike_button_view = Parser.parseItem(data.dislikeButtonViewModel, DislikeButtonView);
|
||||
}
|
||||
|
||||
if ('likeButtonViewModel' in data) {
|
||||
this.like_button_view = Parser.parseItem(data.likeButtonViewModel, LikeButtonView);
|
||||
}
|
||||
|
||||
this.paragraphs = Parser.parseArray(data.paragraphs, VideoSummaryParagraphView);
|
||||
}
|
||||
}
|
||||
14
deno/src/parser/classes/VideoSummaryParagraphView.ts
Normal file
14
deno/src/parser/classes/VideoSummaryParagraphView.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { YTNode } from '../helpers.ts';
|
||||
import { type RawNode } from '../index.ts';
|
||||
import { Text } from '../misc.ts';
|
||||
|
||||
export default class VideoSummaryParagraphView extends YTNode {
|
||||
static type = 'VideoSummaryParagraphView';
|
||||
|
||||
public text: Text;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.text = Text.fromAttributed(data.text);
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,35 @@ import type { RawNode } from '../index.ts';
|
||||
export default class VideoViewCount extends YTNode {
|
||||
static type = 'VideoViewCount';
|
||||
|
||||
public original_view_count: string;
|
||||
public short_view_count: Text;
|
||||
public extra_short_view_count: Text;
|
||||
public view_count: Text;
|
||||
public original_view_count?: number;
|
||||
public unlabeled_view_count_value?: Text;
|
||||
public short_view_count?: Text;
|
||||
public extra_short_view_count?: Text;
|
||||
public view_count?: Text;
|
||||
public is_live: boolean;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.original_view_count = data.originalViewCount;
|
||||
this.short_view_count = new Text(data.shortViewCount);
|
||||
this.extra_short_view_count = new Text(data.extraShortViewCount);
|
||||
this.view_count = new Text(data.viewCount);
|
||||
if ('originalViewCount' in data) {
|
||||
this.original_view_count = parseInt(data.originalViewCount);
|
||||
}
|
||||
|
||||
if ('unlabeledViewCountValue' in data) {
|
||||
this.unlabeled_view_count_value = new Text(data.unlabeledViewCountValue);
|
||||
}
|
||||
|
||||
if ('shortViewCount' in data) {
|
||||
this.short_view_count = new Text(data.shortViewCount);
|
||||
}
|
||||
|
||||
if ('extraShortViewCount' in data) {
|
||||
this.extra_short_view_count = new Text(data.extraShortViewCount);
|
||||
}
|
||||
|
||||
if ('viewCount' in data) {
|
||||
this.view_count = new Text(data.viewCount);
|
||||
}
|
||||
|
||||
this.is_live = !!data.isLive;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,57 @@
|
||||
import Text from '../misc/Text.ts';
|
||||
import type Text from '../misc/Text.ts';
|
||||
import { YTNode } from '../../helpers.ts';
|
||||
import type { RawNode } from '../../index.ts';
|
||||
import { Parser, type RawNode } from '../../index.ts';
|
||||
import VideoViewCount from '../VideoViewCount.ts';
|
||||
|
||||
export default class UpdateViewershipAction extends YTNode {
|
||||
static type = 'UpdateViewershipAction';
|
||||
|
||||
view_count: Text;
|
||||
extra_short_view_count: Text;
|
||||
original_view_count: number;
|
||||
unlabeled_view_count_value: Text;
|
||||
is_live: boolean;
|
||||
public view_count_node: VideoViewCount | null;
|
||||
|
||||
/**
|
||||
* @deprecated Use `view_count_node.view_count` instead.
|
||||
*/
|
||||
get view_count(): Text | undefined {
|
||||
return this.view_count_node?.view_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `view_count_node.extra_short_view_count` instead.
|
||||
*/
|
||||
get extra_short_view_count(): Text | undefined {
|
||||
return this.view_count_node?.extra_short_view_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `view_count_node.short_view_count` instead.
|
||||
*/
|
||||
get short_view_count(): Text | undefined {
|
||||
return this.view_count_node?.short_view_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `view_count_node.original_view_count` instead.
|
||||
*/
|
||||
get original_view_count(): number | undefined {
|
||||
return this.view_count_node?.original_view_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `view_count_node.unlabeled_view_count_value` instead.
|
||||
*/
|
||||
get unlabeled_view_count_value(): Text | undefined {
|
||||
return this.view_count_node?.unlabeled_view_count_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `view_count_node.is_live` instead.
|
||||
*/
|
||||
get is_live(): boolean | undefined {
|
||||
return this.view_count_node?.is_live;
|
||||
}
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
const view_count_renderer = data.viewCount.videoViewCountRenderer;
|
||||
this.view_count = new Text(view_count_renderer.viewCount);
|
||||
this.extra_short_view_count = new Text(view_count_renderer.extraShortViewCount);
|
||||
this.original_view_count = parseInt(view_count_renderer.originalViewCount);
|
||||
this.unlabeled_view_count_value = new Text(view_count_renderer.unlabeledViewCountValue);
|
||||
this.is_live = view_count_renderer.isLive;
|
||||
this.view_count_node = Parser.parseItem(data.viewCount, VideoViewCount);
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,17 @@ import ButtonView from '../ButtonView.ts';
|
||||
import MenuServiceItem from './MenuServiceItem.ts';
|
||||
import DownloadButton from '../DownloadButton.ts';
|
||||
import MenuServiceItemDownload from './MenuServiceItemDownload.ts';
|
||||
import ListItemView from '../ListItemView.ts';
|
||||
|
||||
export default class MenuFlexibleItem extends YTNode {
|
||||
static type = 'MenuFlexibleItem';
|
||||
|
||||
public menu_item: MenuServiceItem | MenuServiceItemDownload | null;
|
||||
public menu_item: ListItemView | MenuServiceItem | MenuServiceItemDownload | null;
|
||||
public top_level_button: DownloadButton | ButtonView | Button | null;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.menu_item = Parser.parseItem(data.menuItem, [ MenuServiceItem, MenuServiceItemDownload ]);
|
||||
this.menu_item = Parser.parseItem(data.menuItem, [ ListItemView, MenuServiceItem, MenuServiceItemDownload ]);
|
||||
this.top_level_button = Parser.parseItem(data.topLevelButton, [ DownloadButton, ButtonView, Button ]);
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,8 @@ export default class Format {
|
||||
public loudness_db?: number;
|
||||
public signature_cipher?: string;
|
||||
public is_drc?: boolean;
|
||||
public is_vb?: boolean;
|
||||
public is_sr?: boolean;
|
||||
public drm_track_type?: string;
|
||||
public distinct_params?: string;
|
||||
public track_absolute_loudness_lkfs?: number;
|
||||
@@ -212,15 +214,16 @@ export default class Format {
|
||||
id: data.captionTrack.id
|
||||
};
|
||||
|
||||
if (this.has_audio || this.has_text) {
|
||||
const xtags = this.xtags
|
||||
? FormatXTags.decode(base64ToU8(decodeURIComponent(this.xtags).replace(/-/g, '+').replace(/_/g, '/'))).xtags
|
||||
: [];
|
||||
const xtags = this.xtags
|
||||
? FormatXTags.decode(base64ToU8(decodeURIComponent(this.xtags).replace(/-/g, '+').replace(/_/g, '/'))).xtags
|
||||
: [];
|
||||
|
||||
if (this.has_audio || this.has_text) {
|
||||
this.language = xtags.find((tag) => tag.key === 'lang')?.value || null;
|
||||
|
||||
if (this.has_audio) {
|
||||
this.is_drc = !!data.isDrc || xtags.some((tag) => tag.key === 'drc' && tag.value === '1');
|
||||
this.is_vb = !!data.isVb || xtags.some((tag) => tag.key === 'vb' && tag.value === '1');
|
||||
|
||||
const audio_content = xtags.find((tag) => tag.key === 'acont')?.value;
|
||||
this.is_dubbed = audio_content === 'dubbed';
|
||||
@@ -235,6 +238,10 @@ export default class Format {
|
||||
this.language = this.caption_track.language_code;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.has_video) {
|
||||
this.is_sr = xtags.some((tag) => tag.key === 'sr' && tag.value === '1');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -364,6 +364,7 @@ export { default as PageIntroduction } from './classes/PageIntroduction.ts';
|
||||
export { default as PanelFooterView } from './classes/PanelFooterView.ts';
|
||||
export { default as PivotButton } from './classes/PivotButton.ts';
|
||||
export { default as PlayerAnnotationsExpanded } from './classes/PlayerAnnotationsExpanded.ts';
|
||||
export { default as PlayerCaptchaView } from './classes/PlayerCaptchaView.ts';
|
||||
export { default as PlayerCaptionsTracklist } from './classes/PlayerCaptionsTracklist.ts';
|
||||
export { default as PlayerControlsOverlay } from './classes/PlayerControlsOverlay.ts';
|
||||
export { default as PlayerErrorMessage } from './classes/PlayerErrorMessage.ts';
|
||||
@@ -528,6 +529,8 @@ export { default as VideoMetadataCarouselView } from './classes/VideoMetadataCar
|
||||
export { default as VideoOwner } from './classes/VideoOwner.ts';
|
||||
export { default as VideoPrimaryInfo } from './classes/VideoPrimaryInfo.ts';
|
||||
export { default as VideoSecondaryInfo } from './classes/VideoSecondaryInfo.ts';
|
||||
export { default as VideoSummaryContentView } from './classes/VideoSummaryContentView.ts';
|
||||
export { default as VideoSummaryParagraphView } from './classes/VideoSummaryParagraphView.ts';
|
||||
export { default as VideoViewCount } from './classes/VideoViewCount.ts';
|
||||
export { default as ViewCountFactoid } from './classes/ViewCountFactoid.ts';
|
||||
export { default as WatchCardCompactVideo } from './classes/WatchCardCompactVideo.ts';
|
||||
|
||||
@@ -87,7 +87,8 @@ const IGNORED_LIST = new Set([
|
||||
'StatementBanner',
|
||||
'GuideSigninPromo',
|
||||
'AdsEngagementPanelContent',
|
||||
'MiniGameCardView'
|
||||
'MiniGameCardView',
|
||||
'GenAiFeedbackFormView'
|
||||
]);
|
||||
|
||||
const RUNTIME_NODES = new Map<string, YTNodeConstructor>(Object.entries(YTNodes));
|
||||
|
||||
@@ -5,7 +5,8 @@ import Button from '../classes/Button.ts';
|
||||
|
||||
import type { Actions, ApiResponse } from '../../core/index.ts';
|
||||
import type { IBrowseResponse } from '../types/index.ts';
|
||||
import type Video from '../classes/Video.ts';
|
||||
import Video from '../classes/Video.ts';
|
||||
import LockupView from '../classes/LockupView.ts';
|
||||
|
||||
// TODO: make feed actions usable
|
||||
export default class History extends Feed<IBrowseResponse> {
|
||||
@@ -33,20 +34,27 @@ export default class History extends Feed<IBrowseResponse> {
|
||||
*/
|
||||
async removeVideo(video_id: string, pages_to_load: number = 1): Promise<boolean> {
|
||||
let pagesToLoad = pages_to_load;
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
let currentHistory: History = this;
|
||||
|
||||
while (pagesToLoad > 0) {
|
||||
let feedbackToken;
|
||||
|
||||
for (const section of currentHistory.sections) {
|
||||
for (const section of this.sections) {
|
||||
for (const content of section.contents) {
|
||||
const video = content as Video;
|
||||
if (video.video_id === video_id && video.menu) {
|
||||
feedbackToken = video.menu.top_level_buttons[0].as(Button).endpoint.payload.feedbackToken;
|
||||
break;
|
||||
if (content.is(Video)) {
|
||||
if (content.video_id === video_id && content.menu) {
|
||||
feedbackToken = content.menu.top_level_buttons[0].as(Button).endpoint.payload.feedbackToken;
|
||||
break;
|
||||
}
|
||||
} else if (content.is(LockupView)) {
|
||||
if (content.content_id === video_id) {
|
||||
const listItems = content.metadata?.menu_button?.on_tap?.payload.panelLoadingStrategy.inlineContent.sheetViewModel.content.listViewModel.listItems;
|
||||
const listItem = listItems.find((video: { listItemViewModel: { title: { content: string; }; }; }) => video.listItemViewModel?.title.content === 'Remove from watch history');
|
||||
feedbackToken = listItem.listItemViewModel.rendererContext.commandContext.onTap.innertubeCommand.feedbackEndpoint.feedbackToken;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (feedbackToken) {
|
||||
break;
|
||||
}
|
||||
@@ -66,7 +74,7 @@ export default class History extends Feed<IBrowseResponse> {
|
||||
|
||||
if (--pagesToLoad > 0) {
|
||||
try {
|
||||
currentHistory = await currentHistory.getContinuation();
|
||||
Object.assign(this, await this.getContinuation());
|
||||
} catch {
|
||||
throw new Error('Unable to find video in watch history');
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import type { SessionOptions } from '../core/index.ts';
|
||||
|
||||
export type InnerTubeConfig = SessionOptions;
|
||||
export type InnerTubeClient = 'IOS' | 'WEB' | 'MWEB' | 'ANDROID' | 'YTMUSIC' | 'YTMUSIC_ANDROID' | 'YTSTUDIO_ANDROID' | 'TV' | 'TV_SIMPLY' |'TV_EMBEDDED' | 'YTKIDS' | 'WEB_EMBEDDED' | 'WEB_CREATOR';
|
||||
export type InnerTubeClient = 'IOS' | 'WEB' | 'MWEB' | 'ANDROID' | 'ANDROID_VR' | 'YTMUSIC' | 'YTMUSIC_ANDROID' | 'YTSTUDIO_ANDROID' | 'TV' | 'TV_SIMPLY' |'TV_EMBEDDED' | 'YTKIDS' | 'WEB_EMBEDDED' | 'WEB_CREATOR';
|
||||
export type EngagementType = 'ENGAGEMENT_TYPE_UNBOUND' | 'ENGAGEMENT_TYPE_VIDEO_LIKE' | 'ENGAGEMENT_TYPE_VIDEO_DISLIKE' | 'ENGAGEMENT_TYPE_SUBSCRIBE' | 'ENGAGEMENT_TYPE_PLAYBACK' | 'ENGAGEMENT_TYPE_YPC_GET_PREMIUM_PAGE' | 'ENGAGEMENT_TYPE_YPC_GET_DOWNLOAD_ACTION';
|
||||
|
||||
export type UploadDate = 'all' | 'hour' | 'today' | 'week' | 'month' | 'year';
|
||||
export type SearchType = 'all' | 'video' | 'channel' | 'playlist' | 'movie';
|
||||
export type Duration = 'all' | 'short' | 'medium' | 'long';
|
||||
export type SortBy = 'relevance' | 'rating' | 'upload_date' | 'view_count';
|
||||
export type UploadDate = 'all' | 'today' | 'week' | 'month' | 'year';
|
||||
export type SearchType = 'all' | 'video' | 'shorts' | 'channel' | 'playlist' | 'movie';
|
||||
export type Duration = 'all' | 'over_twenty_mins' | 'under_three_mins' | 'three_to_twenty_mins';
|
||||
export type Prioritize = 'relevance' | 'popularity';
|
||||
export type Feature = 'hd' | 'subtitles' | 'creative_commons' | '3d' | 'live' | 'purchased' | '4k' | '360' | 'location' | 'hdr' | 'vr180';
|
||||
|
||||
export type SearchFilters = {
|
||||
upload_date?: UploadDate;
|
||||
type?: SearchType;
|
||||
duration?: Duration;
|
||||
sort_by?: SortBy;
|
||||
prioritize?: Prioritize;
|
||||
features?: Feature[];
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export interface StreamingInfoOptions {
|
||||
*/
|
||||
captions_format?: 'vtt' | 'ttml';
|
||||
/**
|
||||
* The label to use for the non-DRC streams when a video has DRC and streams.
|
||||
* The label to use for the non-DRC/VB streams when a video has DRC and Voice Boost streams.
|
||||
*
|
||||
* Defaults to `"Original"`
|
||||
*/
|
||||
@@ -27,7 +27,19 @@ export interface StreamingInfoOptions {
|
||||
* Defaults to `(audio_track_display_name) => audio_track_display_name + " (Stable Volume)"`
|
||||
*/
|
||||
label_drc_multiple?: (audio_track_display_name: string) => string;
|
||||
|
||||
/**
|
||||
* The label to use for the VB (Voice Boost) streams when a video has VB streams.
|
||||
*
|
||||
* Defaults to `"Voice Boost"`
|
||||
*/
|
||||
label_vb?: string;
|
||||
/**
|
||||
* A function that generates the label to use for the Voice Boost streams when a video has multiple audio tracks and Voice Boost streams.
|
||||
* The non-Voice Boost streams use the unmodified audio track label provided by YouTube.
|
||||
*
|
||||
* Defaults to `(audio_track_display_name) => audio_track_display_name + " (Voice Boost)"`
|
||||
*/
|
||||
label_vb_multiple?: (audio_track_display_name: string) => string;
|
||||
/**
|
||||
* If `true`, the generated manifest will contain URLs that are suitable for use with the SABR protocol.
|
||||
*/
|
||||
|
||||
@@ -33,7 +33,7 @@ export const CLIENTS = {
|
||||
},
|
||||
WEB: {
|
||||
NAME: 'WEB',
|
||||
VERSION: '2.20250222.10.00',
|
||||
VERSION: '2.20260206.01.00',
|
||||
API_KEY: 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8',
|
||||
API_VERSION: 'v1',
|
||||
STATIC_VISITOR_ID: '6zpwvWUNAco',
|
||||
@@ -41,12 +41,12 @@ export const CLIENTS = {
|
||||
},
|
||||
MWEB: {
|
||||
NAME: 'MWEB',
|
||||
VERSION: '2.20250224.01.00',
|
||||
VERSION: '2.20260205.04.01',
|
||||
API_VERSION: 'v1'
|
||||
},
|
||||
WEB_KIDS: {
|
||||
NAME: 'WEB_KIDS',
|
||||
VERSION: '2.20250221.11.00'
|
||||
VERSION: '2.20260205.00.00'
|
||||
},
|
||||
YTMUSIC: {
|
||||
NAME: 'WEB_REMIX',
|
||||
@@ -54,9 +54,17 @@ export const CLIENTS = {
|
||||
},
|
||||
ANDROID: {
|
||||
NAME: 'ANDROID',
|
||||
VERSION: '19.35.36',
|
||||
SDK_VERSION: 33,
|
||||
USER_AGENT: 'com.google.android.youtube/19.35.36(Linux; U; Android 13; en_US; SM-S908E Build/TP1A.220624.014) gzip'
|
||||
VERSION: '21.03.36',
|
||||
SDK_VERSION: 36,
|
||||
USER_AGENT: 'com.google.android.youtube/21.03.36(Linux; U; Android 16; en_US; SM-S908E Build/TP1A.220624.014) gzip'
|
||||
},
|
||||
ANDROID_VR: {
|
||||
NAME: 'ANDROID_VR',
|
||||
VERSION: '1.65.10',
|
||||
SDK_VERSION: 32,
|
||||
DEVICE_MAKE: 'Oculus',
|
||||
DEVICE_MODEL: 'Quest 3',
|
||||
USER_AGENT: 'com.google.android.apps.youtube.vr.oculus/1.65.10 (Linux; U; Android 12L; eureka-user Build/SQ3A.220605.009.A1) gzip'
|
||||
},
|
||||
YTSTUDIO_ANDROID: {
|
||||
NAME: 'ANDROID_CREATOR',
|
||||
@@ -68,7 +76,7 @@ export const CLIENTS = {
|
||||
},
|
||||
TV: {
|
||||
NAME: 'TVHTML5',
|
||||
VERSION: '7.20250219.14.00',
|
||||
VERSION: '7.20260311.12.00',
|
||||
USER_AGENT: 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/Version'
|
||||
},
|
||||
TV_SIMPLY: {
|
||||
@@ -81,7 +89,7 @@ export const CLIENTS = {
|
||||
},
|
||||
WEB_EMBEDDED: {
|
||||
NAME: 'WEB_EMBEDDED_PLAYER',
|
||||
VERSION: '1.20250219.01.00',
|
||||
VERSION: '1.20260206.01.00',
|
||||
API_KEY: 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8',
|
||||
API_VERSION: 'v1',
|
||||
STATIC_VISITOR_ID: '6zpwvWUNAco'
|
||||
@@ -106,6 +114,7 @@ export const CLIENT_NAME_IDS = {
|
||||
ANDROID: '3',
|
||||
ANDROID_CREATOR: '14',
|
||||
ANDROID_MUSIC: '21',
|
||||
ANDROID_VR: '28',
|
||||
TVHTML5: '7',
|
||||
TVHTML5_SIMPLY: '74',
|
||||
TVHTML5_SIMPLY_EMBEDDED_PLAYER: '85',
|
||||
@@ -124,4 +133,4 @@ export const INNERTUBE_HEADERS_BASE = {
|
||||
'content-type': 'application/json'
|
||||
} as const;
|
||||
|
||||
export const SUPPORTED_CLIENTS = [ 'IOS', 'WEB', 'MWEB', 'YTKIDS', 'YTMUSIC', 'ANDROID', 'YTSTUDIO_ANDROID', 'YTMUSIC_ANDROID', 'TV', 'TV_SIMPLY', 'TV_EMBEDDED', 'WEB_EMBEDDED', 'WEB_CREATOR' ];
|
||||
export const SUPPORTED_CLIENTS = [ 'IOS', 'WEB', 'MWEB', 'YTKIDS', 'YTMUSIC', 'ANDROID', 'ANDROID_VR', 'YTSTUDIO_ANDROID', 'YTMUSIC_ANDROID', 'TV', 'TV_SIMPLY', 'TV_EMBEDDED', 'WEB_EMBEDDED', 'WEB_CREATOR' ];
|
||||
@@ -254,6 +254,18 @@ export default class HTTPClient {
|
||||
ctx.client.clientFormFactor = 'SMALL_FORM_FACTOR';
|
||||
ctx.client.clientName = Constants.CLIENTS.ANDROID.NAME;
|
||||
break;
|
||||
case 'ANDROID_VR':
|
||||
ctx.client.androidSdkVersion = 32;
|
||||
ctx.client.osName = 'Android';
|
||||
ctx.client.osVersion = '12L';
|
||||
ctx.client.platform = 'MOBILE';
|
||||
ctx.client.userAgent = Constants.CLIENTS.ANDROID_VR.USER_AGENT;
|
||||
ctx.client.deviceMake = Constants.CLIENTS.ANDROID_VR.DEVICE_MAKE;
|
||||
ctx.client.deviceModel = Constants.CLIENTS.ANDROID_VR.DEVICE_MODEL;
|
||||
ctx.client.clientVersion = Constants.CLIENTS.ANDROID_VR.VERSION;
|
||||
ctx.client.clientFormFactor = 'SMALL_FORM_FACTOR';
|
||||
ctx.client.clientName = Constants.CLIENTS.ANDROID_VR.NAME;
|
||||
break;
|
||||
case 'YTMUSIC_ANDROID':
|
||||
ctx.client.clientVersion = Constants.CLIENTS.YTMUSIC_ANDROID.VERSION;
|
||||
ctx.client.clientFormFactor = 'SMALL_FORM_FACTOR';
|
||||
|
||||
@@ -157,15 +157,22 @@ interface DrcLabels {
|
||||
label_drc_multiple: (audio_track_display_name: string) => string;
|
||||
}
|
||||
|
||||
interface VbLabels {
|
||||
label_original: string;
|
||||
label_vb: string;
|
||||
label_vb_multiple: (audio_track_display_name: string) => string;
|
||||
}
|
||||
|
||||
function getFormatGroupings(formats: Format[], is_post_live_dvr: boolean) {
|
||||
const group_info = new Map<string, Format[]>();
|
||||
|
||||
const has_multiple_audio_tracks = formats.some((fmt) => !!fmt.audio_track);
|
||||
|
||||
for (const format of formats) {
|
||||
if ((!format.index_range || !format.init_range) && !format.is_type_otf && !is_post_live_dvr) {
|
||||
if (((!format.index_range || !format.init_range) && !format.is_type_otf && !is_post_live_dvr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const mime_type = format.mime_type.split(';')[0];
|
||||
|
||||
// Codec without any profile or level information
|
||||
@@ -177,8 +184,9 @@ function getFormatGroupings(formats: Format[], is_post_live_dvr: boolean) {
|
||||
const audio_track_id = format.audio_track?.id || '';
|
||||
|
||||
const drc = format.is_drc ? 'drc' : '';
|
||||
const vb = format.is_vb ? 'vb' : '';
|
||||
|
||||
const group_id = `${mime_type}-${just_codec}-${color_info}-${audio_track_id}-${drc}`;
|
||||
const group_id = `${mime_type}-${just_codec}-${color_info}-${audio_track_id}-${drc}-${vb}`;
|
||||
|
||||
if (!group_info.has(group_id)) {
|
||||
group_info.set(group_id, []);
|
||||
@@ -324,7 +332,7 @@ async function getSegmentInfo(
|
||||
is_sabr?: boolean
|
||||
) {
|
||||
let transformed_url = '';
|
||||
|
||||
|
||||
if (is_sabr) {
|
||||
const formatKey = `${format.itag || ''}:${format.xtags || ''}`;
|
||||
transformed_url = `sabr://${format.has_video ? 'video' : 'audio'}?key=${formatKey}`;
|
||||
@@ -333,7 +341,7 @@ async function getSegmentInfo(
|
||||
url.searchParams.set('cpn', cpn || '');
|
||||
transformed_url = url_transformer(url).toString();
|
||||
}
|
||||
|
||||
|
||||
if (format.is_type_otf) {
|
||||
if (!actions)
|
||||
throw new InnertubeError('Unable to get segment durations for this OTF stream without an Actions instance', { format });
|
||||
@@ -417,6 +425,10 @@ async function getAudioRepresentation(
|
||||
uid_parts.push('drc');
|
||||
}
|
||||
|
||||
if (format.is_vb) {
|
||||
uid_parts.push('vb');
|
||||
}
|
||||
|
||||
const rep: AudioRepresentation = {
|
||||
uid: uid_parts.join('-'),
|
||||
bitrate: format.bitrate,
|
||||
@@ -444,7 +456,7 @@ function getTrackRoles(format: Format, has_drc_streams: boolean) {
|
||||
if (format.is_descriptive)
|
||||
roles.push('description');
|
||||
|
||||
if (format.is_drc)
|
||||
if (format.is_drc || format.is_vb)
|
||||
roles.push('enhanced-audio-intelligibility');
|
||||
|
||||
return roles;
|
||||
@@ -458,6 +470,7 @@ async function getAudioSet(
|
||||
cpn?: string,
|
||||
shared_post_live_dvr_info?: SharedPostLiveDvrInfo,
|
||||
drc_labels?: DrcLabels,
|
||||
vb_labels?: VbLabels,
|
||||
is_sabr?: boolean
|
||||
) {
|
||||
const first_format = formats[0];
|
||||
@@ -465,17 +478,27 @@ async function getAudioSet(
|
||||
const hoisted: string[] = [];
|
||||
|
||||
const has_drc_streams = !!drc_labels;
|
||||
const has_vb_streams = !!vb_labels;
|
||||
|
||||
let track_name;
|
||||
|
||||
if (audio_track) {
|
||||
if (has_drc_streams && first_format.is_drc) {
|
||||
track_name = drc_labels.label_drc_multiple(audio_track.display_name);
|
||||
} else if (has_vb_streams && first_format.is_vb) {
|
||||
track_name = vb_labels.label_vb_multiple(audio_track.display_name);
|
||||
} else {
|
||||
track_name = audio_track.display_name;
|
||||
}
|
||||
} else if (has_drc_streams) {
|
||||
track_name = first_format.is_drc ? drc_labels.label_drc : drc_labels.label_original;
|
||||
} else if (has_drc_streams || has_vb_streams) {
|
||||
if (has_drc_streams && first_format.is_drc) {
|
||||
track_name = drc_labels.label_drc;
|
||||
} else if (has_vb_streams && first_format.is_vb) {
|
||||
track_name = vb_labels.label_vb;
|
||||
} else {
|
||||
// Both use the same param, so it doesn't matter which one is defined here.
|
||||
track_name = (drc_labels || vb_labels)?.label_original;
|
||||
}
|
||||
}
|
||||
|
||||
const set: AudioSet = {
|
||||
@@ -868,8 +891,23 @@ export async function getStreamingInfo(
|
||||
});
|
||||
|
||||
let drc_labels: DrcLabels | undefined;
|
||||
let vb_labels: VbLabels | undefined;
|
||||
|
||||
if (audio_groups.flat().some((format) => format.is_drc)) {
|
||||
let hasDrc = false;
|
||||
let hasVb = false;
|
||||
|
||||
for (const ag of audio_groups.flat()) {
|
||||
if (hasDrc === false && ag.is_drc) {
|
||||
hasDrc = true;
|
||||
}
|
||||
|
||||
if (hasVb === false && ag.is_vb) {
|
||||
hasVb = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Put these audio fields in a shared object to reduce dups.
|
||||
if (hasDrc) {
|
||||
drc_labels = {
|
||||
label_original: options?.label_original || 'Original',
|
||||
label_drc: options?.label_drc || 'Stable Volume',
|
||||
@@ -877,7 +915,15 @@ export async function getStreamingInfo(
|
||||
};
|
||||
}
|
||||
|
||||
const audio_sets = await Promise.all(audio_groups.map((formats) => getAudioSet(formats, url_transformer, actions, player, cpn, shared_post_live_dvr_info, drc_labels, options?.is_sabr)));
|
||||
if (hasVb) {
|
||||
vb_labels = {
|
||||
label_original: options?.label_original || 'Original',
|
||||
label_vb: options?.label_vb || 'Voice Boost',
|
||||
label_vb_multiple: options?.label_vb_multiple || ((display_name) => `${display_name} (Voice Boost)`)
|
||||
};
|
||||
}
|
||||
|
||||
const audio_sets = await Promise.all(audio_groups.map((formats) => getAudioSet(formats, url_transformer, actions, player, cpn, shared_post_live_dvr_info, drc_labels, vb_labels, options?.is_sabr)));
|
||||
|
||||
const video_sets = await Promise.all(video_groups.map((formats) => getVideoSet(formats, url_transformer, player, actions, cpn, shared_post_live_dvr_info, options?.is_sabr)));
|
||||
|
||||
@@ -908,7 +954,7 @@ export async function getStreamingInfo(
|
||||
text_sets = getTextSets(caption_tracks, options.captions_format, url_transformer);
|
||||
}
|
||||
|
||||
const info : StreamingInfo = {
|
||||
const info: StreamingInfo = {
|
||||
getDuration,
|
||||
audio_sets,
|
||||
video_sets,
|
||||
|
||||
@@ -261,4 +261,34 @@ export function getCookie(cookies: string, name: string, matchWholeName = false)
|
||||
const regex = matchWholeName ? `(^|\\s?)\\b${name}\\b=([^;]+)` : `(^|s?)${name}=([^;]+)`;
|
||||
const match = cookies.match(new RegExp(regex));
|
||||
return match ? match[2] : undefined;
|
||||
}
|
||||
|
||||
export function getNsigProcessorFn(n?: string | null, sp?: string | null, s?: string | null) {
|
||||
return `function process(n = "", sp = "", s = "") {
|
||||
const mockStreamingURL = "https://ytjs.googlevideo.com/videoplayback?expire=1234567890&"+"n="+encodeURIComponent(n);
|
||||
const urlCtorFunction = exportedVars.nsigFunction || (() => { throw new Error('No n/sig decipher function extracted') });
|
||||
const urlCtor = urlCtorFunction(mockStreamingURL, sp, s);
|
||||
|
||||
const proto = Object.getPrototypeOf(urlCtor);
|
||||
const properties = Object.getOwnPropertyNames(proto);
|
||||
const methodBlacklist = ['constructor', 'clone', 'set', 'get'];
|
||||
|
||||
for (const prop of properties) {
|
||||
if (methodBlacklist.includes(prop))
|
||||
continue;
|
||||
|
||||
if (typeof urlCtor[prop] === 'function')
|
||||
urlCtor[prop]();
|
||||
}
|
||||
|
||||
const sigResult = urlCtor.get(sp);
|
||||
const nResult = urlCtor.get('n');
|
||||
|
||||
return {
|
||||
sig: sigResult ? decodeURIComponent(sigResult) : undefined,
|
||||
n: nResult ? decodeURIComponent(nResult) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
return process("${n || ''}", "${sp || ''}", "${s || ''}");`;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { ESTree } from 'meriyah';
|
||||
import { parseScript } from 'meriyah';
|
||||
import { WALK_STOP, jsBuiltIns, memberBaseName, memberToString, walkAst } from './helpers.ts';
|
||||
import { parseScript, type ESTree } from 'meriyah';
|
||||
import { jsBuiltIns, memberBaseName, memberToString, walkAst } from './helpers.ts';
|
||||
|
||||
export interface ExtractionConfig {
|
||||
/**
|
||||
@@ -14,9 +13,20 @@ export interface ExtractionConfig {
|
||||
collectDependencies?: boolean;
|
||||
/**
|
||||
* When `true`, traversal stops once the extraction is matched and all its dependencies (when `collectDependencies=true`) resolve.
|
||||
* Only useful for small functions/vars without too many dependencies.
|
||||
* Only useful for small functions/vars without too many dependencies. Deeper dependency trees will usually have the unresolvable
|
||||
* member expression here and there, for example:
|
||||
* ```js
|
||||
* var Vmi = g.dX.window, Wr = Vmi?.yt?.config_ || Vmi?.ytcfg?.data_ || {};
|
||||
* ```
|
||||
*
|
||||
* Since `Vmi.ytcfg` is a dependency, it will never resolve because it comes from `g.dX.window`, which is an external object we don't have access to.
|
||||
* In cases like this, `stopWhenReady` option does nothing useful.
|
||||
*/
|
||||
stopWhenReady?: boolean;
|
||||
/**
|
||||
* If `true`, dependency collection is limited to the match context node itself.
|
||||
*/
|
||||
onlyProcessMatchContext?: boolean;
|
||||
/**
|
||||
* Name for easier identification of extractions.
|
||||
*/
|
||||
@@ -35,6 +45,7 @@ export interface VariableMetadata {
|
||||
node?: any;
|
||||
dependencies: Set<string>;
|
||||
dependents: Set<string>;
|
||||
prototypeAliases: Map<string, Set<VariableMetadata>>;
|
||||
predeclared: boolean;
|
||||
}
|
||||
|
||||
@@ -64,9 +75,10 @@ export class JsAnalyzer {
|
||||
private readonly hasExtractions: boolean;
|
||||
private readonly extractionStates: ExtractionState[];
|
||||
private readonly dependentsTracker: Map<string, Set<string>> = new Map();
|
||||
private pendingPrototypeAliasBinding: [string, VariableMetadata] | null = null;
|
||||
|
||||
public declaredVariables: Map<string, VariableMetadata> = new Map();
|
||||
public iifeParamName: string | null = null;
|
||||
public readonly declaredVariables: Map<string, VariableMetadata> = new Map();
|
||||
|
||||
/**
|
||||
* Creates a new instance over the provided source.
|
||||
@@ -135,7 +147,37 @@ export class JsAnalyzer {
|
||||
const left = assignment.left;
|
||||
const right = assignment.right;
|
||||
|
||||
// Detect things like `a.b = g.c.prototype` so later `a.b.foo = ...` can be attributed back to `g.c`.
|
||||
if (
|
||||
right.type === 'MemberExpression' &&
|
||||
!right.computed &&
|
||||
right.property.type === 'Identifier' &&
|
||||
right.property.name === 'prototype'
|
||||
) {
|
||||
const prototypeSourceExpr = memberToString(right, this.source);
|
||||
const aliasTargetExpr = left.type === 'Identifier' ? left.name : memberToString(left, this.source);
|
||||
|
||||
if (prototypeSourceExpr) {
|
||||
const prototypeOwnerMeta = this.declaredVariables.get(
|
||||
prototypeSourceExpr.replace('.prototype', '')
|
||||
);
|
||||
|
||||
if (aliasTargetExpr && prototypeOwnerMeta) {
|
||||
const aliasedPrototypeMembers = new Set<VariableMetadata>();
|
||||
const aliasExpr = `${aliasTargetExpr}.`; // Had to add a dot here so we can detect it later when matching member expressions..
|
||||
|
||||
// Activate an alias binding context, so subsequent member assignments to the alias (`a.b.foo = ...`) can be tracked.
|
||||
// NOTE: This assumes that the alias members come right after this declaration and are grouped together in the code, hehe :)
|
||||
this.pendingPrototypeAliasBinding = [ aliasExpr, prototypeOwnerMeta ];
|
||||
|
||||
prototypeOwnerMeta.prototypeAliases.set(aliasExpr, aliasedPrototypeMembers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (left.type === 'Identifier') {
|
||||
// This identifier existing means it was a pre-declared and
|
||||
// we just got to it.
|
||||
const existingVariable = this.declaredVariables.get(left.name);
|
||||
if (!existingVariable) continue;
|
||||
|
||||
@@ -148,6 +190,33 @@ export class JsAnalyzer {
|
||||
if (this.onMatch(existingVariable.node, existingVariable)) return;
|
||||
} else if (assignment.left.type === 'MemberExpression') {
|
||||
const memberName = memberToString(assignment.left, this.source);
|
||||
const activeAliasExpr = this.pendingPrototypeAliasBinding?.[0];
|
||||
|
||||
// While an alias binding is active, collect member assignments made through the alias (`g.q.foo = ...`).
|
||||
if (activeAliasExpr && (memberName?.includes(activeAliasExpr) || memberName === activeAliasExpr.slice(0, -1))) {
|
||||
const aliasOwnerMeta = this.declaredVariables.get(this.pendingPrototypeAliasBinding?.[1].name || '');
|
||||
if (aliasOwnerMeta) {
|
||||
const existingAliasedMembers = aliasOwnerMeta.prototypeAliases.get(activeAliasExpr);
|
||||
|
||||
const aliasedMemberMeta: VariableMetadata = {
|
||||
name: memberName,
|
||||
node: currentNode,
|
||||
dependents: this.dependentsTracker.get(memberName) || new Set<string>(),
|
||||
predeclared: false,
|
||||
prototypeAliases: new Map<string, Set<VariableMetadata>>(),
|
||||
dependencies: this.findDependencies(right, memberName)
|
||||
};
|
||||
|
||||
if (existingAliasedMembers) {
|
||||
existingAliasedMembers.add(aliasedMemberMeta);
|
||||
} else {
|
||||
aliasOwnerMeta.prototypeAliases.set(activeAliasExpr, new Set([ aliasedMemberMeta ]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.pendingPrototypeAliasBinding = null;
|
||||
}
|
||||
|
||||
if (!memberName || this.declaredVariables.has(memberName)) continue;
|
||||
|
||||
const metadata: VariableMetadata = {
|
||||
@@ -155,6 +224,7 @@ export class JsAnalyzer {
|
||||
node: currentNode,
|
||||
dependents: this.dependentsTracker.get(memberName) || new Set<string>(),
|
||||
predeclared: false,
|
||||
prototypeAliases: new Map<string, Set<VariableMetadata>>(),
|
||||
dependencies: this.findDependencies(right, memberName)
|
||||
};
|
||||
|
||||
@@ -174,6 +244,8 @@ export class JsAnalyzer {
|
||||
break;
|
||||
}
|
||||
case 'VariableDeclaration': {
|
||||
this.pendingPrototypeAliasBinding = null;
|
||||
|
||||
for (const declaration of currentNode.declarations) {
|
||||
if (declaration.id.type !== 'Identifier') continue;
|
||||
|
||||
@@ -181,6 +253,7 @@ export class JsAnalyzer {
|
||||
name: declaration.id.name,
|
||||
node: declaration,
|
||||
dependents: this.dependentsTracker.get(declaration.id.name) || new Set<string>(),
|
||||
prototypeAliases: new Map<string, Set<VariableMetadata>>(),
|
||||
dependencies: new Set(),
|
||||
predeclared: false
|
||||
};
|
||||
@@ -188,9 +261,8 @@ export class JsAnalyzer {
|
||||
const init = declaration.init;
|
||||
|
||||
if (!init && currentNode.kind === 'var') {
|
||||
metadata.predeclared = true;
|
||||
metadata.predeclared = true; // "var x, y, z;"
|
||||
} else if (init && this.needsDependencyAnalysis(init)) {
|
||||
// "var x, y, z;"
|
||||
metadata.dependencies = this.findDependencies(init, metadata.name);
|
||||
}
|
||||
|
||||
@@ -225,6 +297,7 @@ export class JsAnalyzer {
|
||||
case 'ConditionalExpression':
|
||||
case 'ObjectExpression':
|
||||
case 'SequenceExpression':
|
||||
case 'ClassExpression':
|
||||
case 'Identifier':
|
||||
return true;
|
||||
default:
|
||||
@@ -248,9 +321,23 @@ export class JsAnalyzer {
|
||||
for (const state of this.extractionStates) {
|
||||
if (!state.node) {
|
||||
if (node.type === 'VariableDeclarator' && !node.init) continue;
|
||||
|
||||
result = state.config.match(node);
|
||||
|
||||
if (!result) continue;
|
||||
state.node = node;
|
||||
|
||||
matched = true;
|
||||
|
||||
if (metadata) {
|
||||
state.metadata = metadata;
|
||||
state.dependents = metadata.dependents;
|
||||
state.dependencies = metadata.dependencies;
|
||||
if (typeof result !== 'boolean')
|
||||
state.matchContext = result;
|
||||
}
|
||||
|
||||
this.refreshExtractionState(state);
|
||||
} else if (state.node !== node) {
|
||||
// Use this as a chance to refresh readiness in case dependencies were resolved since last time
|
||||
// we checked.
|
||||
@@ -259,21 +346,7 @@ export class JsAnalyzer {
|
||||
if (this.shouldStopTraversal()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
matched = true;
|
||||
|
||||
if (metadata) {
|
||||
state.metadata = metadata;
|
||||
state.dependents = metadata.dependents;
|
||||
state.dependencies = metadata.dependencies;
|
||||
if (typeof result !== 'boolean')
|
||||
state.matchContext = result;
|
||||
}
|
||||
|
||||
this.refreshExtractionState(state);
|
||||
}
|
||||
|
||||
if (!matched) return false;
|
||||
@@ -423,6 +496,9 @@ export class JsAnalyzer {
|
||||
walkAst(rootNode, {
|
||||
enter: (n, parent) => {
|
||||
switch (n.type) {
|
||||
// Note for anybody debugging this in the future:
|
||||
// *DO NOT* add MethodDefinition here.
|
||||
// MethodDefinition.value is a FunctionExpression, so it is already handled...
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression':
|
||||
case 'ArrowFunctionExpression': {
|
||||
@@ -456,9 +532,12 @@ export class JsAnalyzer {
|
||||
break;
|
||||
}
|
||||
case 'VariableDeclaration': {
|
||||
const scope = currentScope();
|
||||
// var hoists to function scope...
|
||||
const targetScope = n.kind === 'var'
|
||||
? scopeStack.findLast((s) => s.type === 'function') ?? currentScope()
|
||||
: currentScope();
|
||||
for (const d of n.declarations) {
|
||||
collectBindingIdentifiers(d.id, scope.names);
|
||||
collectBindingIdentifiers(d.id, targetScope.names);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -477,8 +556,10 @@ export class JsAnalyzer {
|
||||
|
||||
// Ignore if it's a property name (e.g., "obj.prop" or "{prop: 1}"", we don't care about the "prop" name itself).
|
||||
if (parent?.type === 'Property' && parent.key === n && !parent.computed) return;
|
||||
// Ignore class method names. They are declarations, not external dependencies.
|
||||
if (parent?.type === 'MethodDefinition' && parent.key === n && !parent.computed) return;
|
||||
if (parent?.type === 'MemberExpression' && parent.property === n && !parent.computed) {
|
||||
if (parent.object.type === 'ThisExpression') return; // Skip 'this.property' stuff.
|
||||
if (parent.object.type === 'ThisExpression') return; // Skip 'this.property', etc.
|
||||
|
||||
const full = memberToString(parent, this.source);
|
||||
if (!full) return;
|
||||
@@ -489,6 +570,7 @@ export class JsAnalyzer {
|
||||
dependencies.add(full);
|
||||
} else if (parent.object.type === 'Identifier') {
|
||||
const baseName = parent.object.name;
|
||||
|
||||
const declaredBaseVariable = this.declaredVariables.get(baseName);
|
||||
if (
|
||||
(declaredBaseVariable || baseName === this.iifeParamName) &&
|
||||
@@ -509,6 +591,10 @@ export class JsAnalyzer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent?.type === 'MetaProperty') {
|
||||
return; // Skip stuff like "new.target" or "import.meta"
|
||||
}
|
||||
|
||||
if (isInScope(n.name) || jsBuiltIns.has(n.name)) return;
|
||||
|
||||
// It's a free variable, so it's a dependency.
|
||||
@@ -528,6 +614,12 @@ export class JsAnalyzer {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'ForStatement':
|
||||
case 'ForInStatement':
|
||||
case 'ForOfStatement': {
|
||||
scopeStack.push({ names: new Set<string>(), type: 'block' });
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
leave: (n: any) => {
|
||||
@@ -537,6 +629,9 @@ export class JsAnalyzer {
|
||||
case 'ArrowFunctionExpression':
|
||||
case 'BlockStatement':
|
||||
case 'CatchClause':
|
||||
case 'ForStatement':
|
||||
case 'ForInStatement':
|
||||
case 'ForOfStatement':
|
||||
if (scopeStack.length > 1) scopeStack.pop();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -89,6 +89,8 @@ export class JsExtractor {
|
||||
if (!node) return true;
|
||||
|
||||
switch (node.type) {
|
||||
case 'ClassExpression':
|
||||
return true;
|
||||
case 'Literal': {
|
||||
const literal = node as ESTree.Literal & { regex?: unknown };
|
||||
return (
|
||||
@@ -168,6 +170,12 @@ export class JsExtractor {
|
||||
}
|
||||
return this.isSafeInitializer(node.object, mode);
|
||||
}
|
||||
|
||||
// Allow cases such as a.b = c.prototype;
|
||||
if (!node.computed && node.property.type === 'Identifier' && node.property.name === 'prototype') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
case 'LogicalExpression':
|
||||
@@ -269,16 +277,17 @@ export class JsExtractor {
|
||||
initSource = initializerFallback;
|
||||
} else {
|
||||
const left = assignmentTarget?.left;
|
||||
const isPrototypeAlias = init?.type === 'MemberExpression' && !init.computed && init.property.type === 'Identifier' && init.property.name === 'prototype';
|
||||
|
||||
// Often useless..
|
||||
// e.g. `xyz.someProp = ...`
|
||||
if (left?.type === 'MemberExpression' && init) {
|
||||
// Skip things we don't need.
|
||||
if (!isPrototypeAlias && left?.type === 'MemberExpression' && init) {
|
||||
if (
|
||||
canDisallow &&
|
||||
left.object.type === 'Identifier' &&
|
||||
init.type !== 'FunctionExpression' &&
|
||||
init.type !== 'ArrowFunctionExpression' &&
|
||||
init.type !== 'LogicalExpression'
|
||||
init.type !== 'LogicalExpression' &&
|
||||
init.type !== 'ClassExpression'
|
||||
) {
|
||||
return `${indent}// Skipped ${memberToString(left, source)} assignment.`;
|
||||
}
|
||||
@@ -287,7 +296,7 @@ export class JsExtractor {
|
||||
// e.g. `someVar = someOtherVarFuncOrCall`
|
||||
initSource = extractNodeSource(init, source)
|
||||
?.trim()
|
||||
.replace(/;\s*$/, '') || 'kk';
|
||||
.replace(/;\s*$/, '') || 'undefined // [JsExtractor] Failed to extract initializer source.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,10 +342,18 @@ export class JsExtractor {
|
||||
predeclaredVarSet.add(name);
|
||||
}
|
||||
|
||||
const visit = (metadata?: VariableMetadata, depth: number = 0) => {
|
||||
const visit = (metadata?: VariableMetadata, depth: number = 0, whitelistedDep?: string) => {
|
||||
if (!metadata || depth > maxDepth) return;
|
||||
|
||||
for (const dependency of metadata.dependencies) {
|
||||
if (whitelistedDep && whitelistedDep !== dependency) {
|
||||
// If we haven't yet encountered the whitelisted dependency, skip this one.
|
||||
// And if we have, delete the whitelist var so that all subsequent dependencies are included.
|
||||
if (!seen.has(whitelistedDep))
|
||||
continue;
|
||||
whitelistedDep = undefined;
|
||||
}
|
||||
|
||||
if (seen.has(dependency))
|
||||
continue;
|
||||
|
||||
@@ -352,13 +369,19 @@ export class JsExtractor {
|
||||
registerPredeclaredVar(dependency);
|
||||
}
|
||||
|
||||
// Usually not used by anything we care about. Less code = better.
|
||||
// e.g. `x.y = ...`
|
||||
if (!dependency.includes('.')) {
|
||||
visit(dependencyMetadata, depth + 1);
|
||||
}
|
||||
visit(dependencyMetadata, depth + 1, whitelistedDep);
|
||||
|
||||
snippets.push(this.renderNode(dependencyMetadata.node, shouldPredeclare, config));
|
||||
|
||||
if (dependencyMetadata.prototypeAliases.size > 0) {
|
||||
for (const [ , aliasMembers ] of dependencyMetadata.prototypeAliases) {
|
||||
for (const member of aliasMembers) {
|
||||
// This is deeper than the first visit, so no need to pass the whitelist, we want all deps of the member to be included.
|
||||
visit(member, depth);
|
||||
snippets.push(this.renderNode(member.node, shouldPredeclare, config));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -372,13 +395,26 @@ export class JsExtractor {
|
||||
snippets.push(`${indent}//#region --- start [${fname || 'Unknown'}] ---`);
|
||||
|
||||
const shouldPredeclare = (forceVarPredeclaration || extraction.metadata.predeclared) && !shouldSkip;
|
||||
const onlyProcessMatchContext = extraction.config.onlyProcessMatchContext;
|
||||
|
||||
if (shouldPredeclare) {
|
||||
registerPredeclaredVar(extraction.metadata.name);
|
||||
}
|
||||
|
||||
if (extraction.config.collectDependencies && !shouldSkip) {
|
||||
visit(extraction.metadata);
|
||||
let whitelistedDep;
|
||||
|
||||
const matchContextNode = extraction.matchContext;
|
||||
|
||||
if (matchContextNode?.type === 'NewExpression' && onlyProcessMatchContext) {
|
||||
if (matchContextNode.callee.type === 'Identifier') {
|
||||
whitelistedDep = matchContextNode.callee.name;
|
||||
} else if (matchContextNode.callee.type === 'MemberExpression') {
|
||||
whitelistedDep = memberToString(matchContextNode.callee, this.analyzer.getSource()) || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
visit(extraction.metadata, undefined, whitelistedDep);
|
||||
}
|
||||
|
||||
if (extraction.matchContext && fname) {
|
||||
@@ -402,7 +438,10 @@ export class JsExtractor {
|
||||
}
|
||||
|
||||
if (!shouldSkip) {
|
||||
snippets.push(this.renderNode(extraction.metadata.node, shouldPredeclare, config));
|
||||
if (!onlyProcessMatchContext) {
|
||||
snippets.push(this.renderNode(extraction.metadata.node, shouldPredeclare, config));
|
||||
}
|
||||
|
||||
snippets.push(`${indent}//#endregion --- end [${fname || 'Unknown'}] ---\n`);
|
||||
}
|
||||
}
|
||||
@@ -410,12 +449,16 @@ export class JsExtractor {
|
||||
|
||||
const output = [];
|
||||
|
||||
// Not required by any means, but add it anyway, "just in case".
|
||||
output.push('const window = Object.assign({}, globalThis);');
|
||||
output.push('const document = {};');
|
||||
output.push('const self = window;\n');
|
||||
output.push('const __jsExtractorGlobal = typeof globalThis !== \'undefined\' ? globalThis :');
|
||||
output.push(`${indent}typeof self !== 'undefined' ? self :`);
|
||||
output.push(`${indent}typeof window !== 'undefined' ? window :`);
|
||||
output.push(`${indent}typeof global !== 'undefined' ? global : {};\n`);
|
||||
|
||||
output.push(`const exportedVars = (function(${this.analyzer.iifeParamName}) {`);
|
||||
output.push(`${indent}const window = typeof __jsExtractorGlobal.window !== 'undefined' ? __jsExtractorGlobal.window : Object.create(null);`);
|
||||
output.push(`${indent}const document = typeof __jsExtractorGlobal.document !== 'undefined' ? __jsExtractorGlobal.document : {};`);
|
||||
output.push(`${indent}const self = typeof __jsExtractorGlobal.self !== 'undefined' ? __jsExtractorGlobal.self : window;\n`);
|
||||
|
||||
if (predeclaredVarSet.size > 0) {
|
||||
output.push(`${indent}var ${Array.from(predeclaredVarSet).join(', ')};\n`);
|
||||
}
|
||||
@@ -433,7 +476,7 @@ export class JsExtractor {
|
||||
if (decl?.node?.type === 'VariableDeclarator' && decl.node.init?.type === 'FunctionExpression') {
|
||||
currentFunctionNode = decl.node;
|
||||
}
|
||||
} else if (node.type === 'CallExpression') {
|
||||
} else if (node.type === 'CallExpression' || node.type === 'NewExpression' || node.type === 'VariableDeclarator') {
|
||||
currentFunctionNode = node;
|
||||
}
|
||||
|
||||
@@ -450,8 +493,9 @@ export class JsExtractor {
|
||||
const rawJson = JSON.stringify(exportedRawValues, null, indent.length);
|
||||
const rawJsonLines = rawJson.split('\n');
|
||||
|
||||
// Indent all lines except the first one...
|
||||
const formattedRawJson = `${rawJsonLines[0]}\n${rawJsonLines.slice(1).map((line) => indent + line).join('\n')}`;
|
||||
// Indent all lines except the first one..
|
||||
const formattedRawJson =
|
||||
`${rawJsonLines[0]}\n${rawJsonLines.slice(1).map((line) => indent + line).join('\n')}`;
|
||||
|
||||
output.push(`${indent}const rawValues = ${formattedRawJson};\n`);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ export interface AstVisitObject {
|
||||
export type AstVisitor = AstVisitFn | AstVisitObject;
|
||||
|
||||
/**
|
||||
* Performs a non-recursive traversal of an ESTree AST.
|
||||
* Performs traversal of an ESTree AST.
|
||||
* @param root - Root AST node to start the traversal from.
|
||||
* @param visitor - Callbacks invoked when nodes are entered or left.
|
||||
* @remarks
|
||||
@@ -132,7 +132,7 @@ export function getNodeSourceRange(node: ESTree.Node | null | undefined): [numbe
|
||||
if (Array.isArray(node.range)) return node.range;
|
||||
if (typeof node.start === 'number' && typeof node.end === 'number') return [ node.start, node.end ];
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts the source code corresponding to a given AST node.
|
||||
@@ -143,7 +143,7 @@ export function getNodeSourceRange(node: ESTree.Node | null | undefined): [numbe
|
||||
export function extractNodeSource(node: ESTree.Node | null | undefined, source: string): string | null {
|
||||
const range = getNodeSourceRange(node);
|
||||
return range ? source.slice(range[0], range[1]) : null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a member expression into its dot/bracket string form.
|
||||
@@ -183,7 +183,7 @@ export function memberToString(memberExpression: ESTree.Node, source: string): s
|
||||
}
|
||||
|
||||
return base ? base + segments.join('') : null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the base identifier for a member expression chain.
|
||||
@@ -203,7 +203,7 @@ export function memberBaseName(memberExpression: ESTree.MemberExpression, source
|
||||
if (target?.type === 'ThisExpression') return 'this';
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Analyzes an AST node to determine if it's a function call or a function
|
||||
@@ -233,6 +233,14 @@ export function createWrapperFunction(analyzer: JsAnalyzer, name: string, node:
|
||||
node.id.type === 'Identifier'
|
||||
) {
|
||||
return generateWrapper(name, node.id.name, parseFunctionArguments(analyzer, node.init.params));
|
||||
} else if (
|
||||
node.type === 'NewExpression' &&
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.type === 'Identifier'
|
||||
) {
|
||||
const targetFunction = memberToString(node.callee, analyzer.getSource());
|
||||
if (!targetFunction) return undefined;
|
||||
return generateWrapper(name, targetFunction, parseFunctionArguments(analyzer, node.arguments), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,10 +250,10 @@ export function createWrapperFunction(analyzer: JsAnalyzer, name: string, node:
|
||||
* @param targetFunction - The name of the target function to call.
|
||||
* @param args - The arguments to pass to the target function.
|
||||
*/
|
||||
function generateWrapper(functionName: string, targetFunction: string, args: string): string {
|
||||
function generateWrapper(functionName: string, targetFunction: string, args: string[], useNew: boolean = false): string {
|
||||
return [
|
||||
`${indent}function ${functionName}(input) {`,
|
||||
`${indent}${indent}return ${targetFunction}(${args});`,
|
||||
`${indent}function ${functionName}(${args.join(', ')}) {`,
|
||||
`${indent}${indent}return ${useNew ? 'new ' : ''}${targetFunction}(${args.join(', ')});`,
|
||||
`${indent}}`
|
||||
].join('\n');
|
||||
}
|
||||
@@ -264,9 +272,18 @@ function parseFunctionArguments(analyzer: JsAnalyzer, args: ESTree.Node[]) {
|
||||
params.push(arg.name);
|
||||
} else if (arg.type === 'Literal' && (typeof arg.value === 'string' || typeof arg.value === 'number')) {
|
||||
params.push(JSON.stringify(arg.value));
|
||||
} else if (arg.type === 'UnaryExpression') {
|
||||
const argSource = extractNodeSource(arg, analyzer.getSource());
|
||||
if (argSource) {
|
||||
params.push(argSource.trim());
|
||||
}
|
||||
} else if (arg.type === 'AssignmentPattern' && arg.left.type === 'Identifier') {
|
||||
params.push(arg.left.name);
|
||||
} else if (arg.type === 'Identifier') {
|
||||
params.push(arg.name);
|
||||
} else if (!params.includes('input'))
|
||||
params.push('input');
|
||||
}
|
||||
|
||||
return params.join(', ');
|
||||
return params;
|
||||
}
|
||||
@@ -1,68 +1,54 @@
|
||||
import type { ESTree } from 'meriyah';
|
||||
import { WALK_STOP, walkAst } from './helpers.ts';
|
||||
|
||||
export function sigMatcher(node: ESTree.Node) {
|
||||
if (node.type === 'VariableDeclarator' && node.id?.type === 'Identifier') {
|
||||
const idNode = node.id;
|
||||
const initNode = node.init;
|
||||
export function nsigMatcher(node: ESTree.Node) {
|
||||
if (node.type !== 'VariableDeclarator')
|
||||
return false;
|
||||
|
||||
if (idNode.type === 'Identifier' && initNode?.type === 'FunctionExpression' && initNode.params.length === 3) {
|
||||
const functionInitNode = initNode.body;
|
||||
if (!functionInitNode || functionInitNode.type !== 'BlockStatement') return false;
|
||||
const init = node.init;
|
||||
|
||||
for (const st of functionInitNode.body) {
|
||||
if (st?.type === 'ExpressionStatement') {
|
||||
const expression = st.expression;
|
||||
if (
|
||||
expression.type === 'LogicalExpression' &&
|
||||
expression.operator === '&&' &&
|
||||
expression.left.type === 'Identifier' &&
|
||||
expression.right.type === 'SequenceExpression'
|
||||
) {
|
||||
const firstExp = expression.right.expressions[0];
|
||||
if (
|
||||
firstExp.type === 'AssignmentExpression' &&
|
||||
firstExp.operator === '=' &&
|
||||
firstExp.left.type === 'Identifier' &&
|
||||
firstExp.right.type === 'CallExpression' &&
|
||||
firstExp.right.callee.type === 'Identifier'
|
||||
) {
|
||||
const rightArguments = firstExp.right.arguments;
|
||||
// sigFn(64, decodeURIComponent(sig))
|
||||
if (rightArguments.length >= 1) {
|
||||
const callExpression = rightArguments.find((exp) => exp.type === 'CallExpression');
|
||||
if (
|
||||
callExpression?.type === 'CallExpression' &&
|
||||
callExpression?.callee.type === 'Identifier' &&
|
||||
callExpression.callee.name === 'decodeURIComponent' &&
|
||||
callExpression.arguments[0].type === 'Identifier'
|
||||
) {
|
||||
return firstExp.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!init || init.type !== 'FunctionExpression')
|
||||
return false;
|
||||
|
||||
if (init.params.length < 3)
|
||||
return false;
|
||||
|
||||
const [ url, sigName, sigValue ] = init.params;
|
||||
|
||||
if (url.type !== 'Identifier' || sigName.type !== 'AssignmentPattern' || sigValue.type !== 'AssignmentPattern')
|
||||
return false;
|
||||
|
||||
const body = init.body;
|
||||
const blockStatementBody = body?.body || [];
|
||||
|
||||
let hasUrlCtor = false;
|
||||
let hasSetAlr = false;
|
||||
|
||||
for (const statement of blockStatementBody) {
|
||||
if (statement.type !== 'ExpressionStatement')
|
||||
continue;
|
||||
|
||||
const expr = statement.expression;
|
||||
|
||||
if (expr.type === 'AssignmentExpression' && expr.operator === '=' && expr.left.type === 'Identifier' && expr.left.name === url.name) {
|
||||
const right = expr.right;
|
||||
if (right.type === 'NewExpression' && right.callee.type === 'MemberExpression') {
|
||||
hasUrlCtor = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.type === 'CallExpression' && expr.callee.type === 'MemberExpression') {
|
||||
const args = expr.arguments;
|
||||
if (args.length === 2 && args[0].type === 'Literal' && args[0].value === 'alr' && args[1].type === 'Literal' && args[1].value === 'yes') {
|
||||
hasSetAlr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function nMatcher(node: ESTree.Node) {
|
||||
if (node.type !== 'VariableDeclarator')
|
||||
if (!hasUrlCtor || !hasSetAlr)
|
||||
return false;
|
||||
|
||||
if (
|
||||
node.id.type === 'Identifier' &&
|
||||
node.init?.type === 'ArrayExpression' &&
|
||||
node.init.elements[0]?.type === 'Identifier'
|
||||
) {
|
||||
return node.init.elements[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function timestampMatcher(node: ESTree.Node) {
|
||||
|
||||
Reference in New Issue
Block a user