chore: fix SABR example and update protos

+ SABR now requires PoTokens.
This commit is contained in:
Luan
2024-12-23 14:36:48 -03:00
parent 7a106dc5f4
commit d683f123c0
14 changed files with 792 additions and 230 deletions

View File

@@ -4,6 +4,7 @@ import type { WriteStream } from 'node:fs';
import { createWriteStream, unlink } from 'node:fs';
import { Innertube, UniversalCache } from 'youtubei.js';
import GoogleVideo, { type Format } from '../../dist/src/index.js';
import { generateWebPoToken } from './utils.js';
const progressBars = new cliProgress.MultiBar({
stopOnComplete: true,
@@ -13,6 +14,7 @@ const progressBars = new cliProgress.MultiBar({
const formatProgressBars = new Map<string, cliProgress.SingleBar>();
const innertube = await Innertube.create({ cache: new UniversalCache(true) });
const webPoTokenResult = await generateWebPoToken(innertube.session.context.client.visitorData || '');
const info = await innertube.getBasicInfo('wRNnMQEKo7o');
console.info(`
@@ -21,6 +23,7 @@ console.info(`
Views: ${info.basic_info.view_count}
Author: ${info.basic_info.author}
Video ID: ${info.basic_info.id}
WebPoToken: ${webPoTokenResult.poToken}
`);
const durationMs = (info.basic_info?.duration ?? 0) * 1000;
@@ -59,6 +62,7 @@ if (!serverAbrStreamingUrl)
const serverAbrStream = new GoogleVideo.ServerAbrStream({
fetch: innertube.session.http.fetch_function,
poToken: webPoTokenResult.poToken,
serverAbrStreamingUrl,
videoPlaybackUstreamerConfig: videoPlaybackUstreamerConfig,
durationMs
@@ -121,8 +125,8 @@ await serverAbrStream.init({
audioFormats: [ selectedAudioFormat ],
videoFormats: [ selectedVideoFormat ],
clientAbrState: {
startTimeMs: 0,
mediaType: 0 // 0 = BOTH, 1 = AUDIO (video-only is no longer supported by YouTube)
playerTimeMs: 0,
enabledTrackTypesBitfield: 0 // 0 = BOTH, 1 = AUDIO (video-only is no longer supported by YouTube)
}
});

View File

@@ -3,6 +3,7 @@ import type { WriteStream } from 'node:fs';
import { createWriteStream } from 'node:fs';
import { Innertube, UniversalCache } from 'youtubei.js';
import GoogleVideo, { type Format } from '../../dist/src/index.js';
import { generateWebPoToken } from './utils.js';
const progressBars = new cliProgress.MultiBar({
stopOnComplete: true,
@@ -12,6 +13,7 @@ const progressBars = new cliProgress.MultiBar({
const formatProgressBars = new Map<string, cliProgress.SingleBar>();
const innertube = await Innertube.create({ cache: new UniversalCache(true) });
const webPoTokenResult = await generateWebPoToken(innertube.session.context.client.visitorData || '');
const info = await innertube.getBasicInfo('mzqO7oKTJKI');
console.info(`
@@ -20,6 +22,7 @@ console.info(`
Views: ${info.basic_info.view_count}
Author: ${info.basic_info.author}
Video ID: ${info.basic_info.id}
WebPoToken: ${webPoTokenResult.poToken}
`);
const durationMs = (info.basic_info?.duration ?? 0) * 1000;
@@ -66,12 +69,12 @@ const determineFileExtension = (mimeType: string) => {
const getOutputStream = (isVideo: boolean, mimeType: string, formatId?: number) => {
const type = isVideo ? 'video' : 'audio';
const extension = determineFileExtension(mimeType);
const stream = createWriteStream(`${sanitizedTitle}.${formatId}.${type}.${extension}`);
return stream;
return createWriteStream(`${sanitizedTitle}.${formatId}.${type}.${extension}`);
};
const serverAbrStream = new GoogleVideo.ServerAbrStream({
fetch: innertube.session.http.fetch_function,
poToken: webPoTokenResult.poToken,
serverAbrStreamingUrl,
videoPlaybackUstreamerConfig: videoPlaybackUstreamerConfig,
durationMs
@@ -126,12 +129,12 @@ serverAbrStream.on('error', (error) => {
console.error(error);
});
await serverAbrStream.init({
await serverAbrStream.init({
audioFormats: [ selectedAudioFormat ],
videoFormats: [ selectedVideoFormat ],
clientAbrState: {
startTimeMs: 0,
mediaType: 0 // 0 = BOTH, 1 = AUDIO (video-only is no longer supported by YouTube)
playerTimeMs: 0,
enabledTrackTypesBitfield: 0 // 0 = BOTH, 1 = AUDIO (video-only is no longer supported by YouTube)
}
});

View File

@@ -9,14 +9,17 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"bgutils-js": "^3.1.0",
"cli-progress": "^3.12.0",
"fluent-ffmpeg": "^2.1.3",
"jsdom": "^25.0.1",
"shaka-player": "^4.11.2",
"youtubei.js": "^12.1.0"
"youtubei.js": "^12.2.0"
},
"devDependencies": {
"@types/cli-progress": "^3.11.6",
"@types/fluent-ffmpeg": "^2.1.26",
"@types/jsdom": "^21.1.7",
"typescript": "^5.6.2"
}
},
@@ -51,6 +54,18 @@
"@types/node": "*"
}
},
"node_modules/@types/jsdom": {
"version": "21.1.7",
"resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
"integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
"@types/tough-cookie": "*",
"parse5": "^7.0.0"
}
},
"node_modules/@types/node": {
"version": "22.5.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
@@ -60,10 +75,18 @@
"undici-types": "~6.19.2"
}
},
"node_modules/@types/tough-cookie": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
"integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
"dev": true,
"license": "MIT"
},
"node_modules/acorn": {
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -71,6 +94,15 @@
"node": ">=0.4.0"
}
},
"node_modules/agent-base": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
"license": "MIT",
"engines": {
"node": ">= 14"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -84,6 +116,21 @@
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/bgutils-js": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bgutils-js/-/bgutils-js-3.1.0.tgz",
"integrity": "sha512-2S80c/B4OQFubJLD5ddRRp74utrvjA70x9U0RsIVK7gJaDnaPrbw+bnXWxnEnc0euLznmO9jxOtTTC7FxGmv6w==",
"funding": [
"https://github.com/sponsors/LuanRT"
],
"license": "MIT"
},
"node_modules/cli-progress": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz",
@@ -95,6 +142,75 @@
"node": ">=4"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/cssstyle": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz",
"integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==",
"license": "MIT",
"dependencies": {
"rrweb-cssom": "^0.7.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/data-urls": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
"integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
"license": "MIT",
"dependencies": {
"whatwg-mimetype": "^4.0.0",
"whatwg-url": "^14.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/decimal.js": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
"integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
"license": "MIT"
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/eme-encryption-scheme-polyfill": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/eme-encryption-scheme-polyfill/-/eme-encryption-scheme-polyfill-2.1.5.tgz",
@@ -105,6 +221,18 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/fluent-ffmpeg": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
@@ -117,6 +245,70 @@
"node": ">=18"
}
},
"node_modules/form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/html-encoding-sniffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
"integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
"license": "MIT",
"dependencies": {
"whatwg-encoding": "^3.1.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.0",
"debug": "^4.3.4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/https-proxy-agent": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.2",
"debug": "4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -125,22 +317,147 @@
"node": ">=8"
}
},
"node_modules/is-potential-custom-element-name": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
"license": "MIT"
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"node_modules/jintr": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jintr/-/jintr-3.1.0.tgz",
"integrity": "sha512-azhCHApkRfBH8INpiUCwKBYaNCdB5G+x3NApsI2MxQXSlgFAx7rap3YwE3JAkN08GO8f3ilZsGB0Yvc+412ntQ==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jintr/-/jintr-3.2.0.tgz",
"integrity": "sha512-psD1yf05kMKDNsUdW1l5YhO59pHScQ6OIHHb8W5SKSM2dCOFPsqolmIuSHgVA8+3Dc47NJR181CXZ4alCAPTkA==",
"funding": [
"https://github.com/sponsors/LuanRT"
],
"license": "MIT",
"dependencies": {
"acorn": "^8.8.0"
}
},
"node_modules/jsdom": {
"version": "25.0.1",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz",
"integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==",
"license": "MIT",
"dependencies": {
"cssstyle": "^4.1.0",
"data-urls": "^5.0.0",
"decimal.js": "^10.4.3",
"form-data": "^4.0.0",
"html-encoding-sniffer": "^4.0.0",
"http-proxy-agent": "^7.0.2",
"https-proxy-agent": "^7.0.5",
"is-potential-custom-element-name": "^1.0.1",
"nwsapi": "^2.2.12",
"parse5": "^7.1.2",
"rrweb-cssom": "^0.7.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^5.0.0",
"w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^3.1.1",
"whatwg-mimetype": "^4.0.0",
"whatwg-url": "^14.0.0",
"ws": "^8.18.0",
"xml-name-validator": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"canvas": "^2.11.2"
},
"peerDependenciesMeta": {
"canvas": {
"optional": true
}
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/nwsapi": {
"version": "2.2.16",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz",
"integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==",
"license": "MIT"
},
"node_modules/parse5": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
"integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
"license": "MIT",
"dependencies": {
"entities": "^4.5.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/rrweb-cssom": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
"license": "MIT"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/saxes": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
"integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
"license": "ISC",
"dependencies": {
"xmlchars": "^2.2.0"
},
"engines": {
"node": ">=v12.22.7"
}
},
"node_modules/shaka-player": {
"version": "4.11.2",
"resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.11.2.tgz",
@@ -176,6 +493,54 @@
"node": ">=8"
}
},
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"license": "MIT"
},
"node_modules/tldts": {
"version": "6.1.69",
"resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.69.tgz",
"integrity": "sha512-Oh/CqRQ1NXNY7cy9NkTPUauOWiTro0jEYZTioGbOmcQh6EC45oribyIMJp0OJO3677r13tO6SKdWoGZUx2BDFw==",
"license": "MIT",
"dependencies": {
"tldts-core": "^6.1.69"
},
"bin": {
"tldts": "bin/cli.js"
}
},
"node_modules/tldts-core": {
"version": "6.1.69",
"resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.69.tgz",
"integrity": "sha512-nygxy9n2PBUFQUtAXAc122gGo+04/j5qr5TGQFZTHafTKYvmARVXt2cA5rgero2/dnXUfkdPtiJoKmrd3T+wdA==",
"license": "MIT"
},
"node_modules/tough-cookie": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz",
"integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==",
"license": "BSD-3-Clause",
"dependencies": {
"tldts": "^6.1.32"
},
"engines": {
"node": ">=16"
}
},
"node_modules/tr46": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
"integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
"license": "MIT",
"dependencies": {
"punycode": "^2.3.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
@@ -211,6 +576,61 @@
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true
},
"node_modules/w3c-xmlserializer": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
"integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
"license": "MIT",
"dependencies": {
"xml-name-validator": "^5.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-encoding": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"license": "MIT",
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
"node": ">=18"
}
},
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/whatwg-url": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz",
"integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==",
"license": "MIT",
"dependencies": {
"tr46": "^5.0.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -222,16 +642,53 @@
"which": "bin/which"
}
},
"node_modules/ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xml-name-validator": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
"integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"license": "MIT"
},
"node_modules/youtubei.js": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-12.1.0.tgz",
"integrity": "sha512-42SUw7zPpx4b7+XBm9QW+//T2/tixBRoEjJAbfOLmGCiyGZuvfW+oq/IngnXo2Keu+yD7YVAfYFc/NaFjFDxGg==",
"version": "12.2.0",
"resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-12.2.0.tgz",
"integrity": "sha512-G+50qrbJCToMYhu8jbaHiS3Vf+RRul+CcDbz3hEGwHkGPh+zLiWwD6SS+YhYF+2/op4ZU5zDYQJrGqJ+wKh7Gw==",
"funding": [
"https://github.com/sponsors/LuanRT"
],
"license": "MIT",
"dependencies": {
"@bufbuild/protobuf": "^2.0.0",
"jintr": "^3.1.0",
"jintr": "^3.2.0",
"tslib": "^2.5.0",
"undici": "^5.19.1"
}

View File

@@ -12,14 +12,17 @@
"author": "",
"license": "ISC",
"dependencies": {
"bgutils-js": "^3.1.0",
"cli-progress": "^3.12.0",
"fluent-ffmpeg": "^2.1.3",
"jsdom": "^25.0.1",
"shaka-player": "^4.11.2",
"youtubei.js": "^12.1.0"
"youtubei.js": "^12.2.0"
},
"devDependencies": {
"@types/cli-progress": "^3.11.6",
"@types/fluent-ffmpeg": "^2.1.26",
"@types/jsdom": "^21.1.7",
"typescript": "^5.6.2"
}
}

View File

@@ -0,0 +1,48 @@
import { BG, type BgConfig } from 'bgutils-js';
import { JSDOM } from 'jsdom';
export async function generateWebPoToken(visitorData: string) {
const requestKey = 'O43z0dpjhgX20SCx4KAo';
if (!visitorData)
throw new Error('Could not get visitor data');
const dom = new JSDOM();
Object.assign(globalThis, {
window: dom.window,
document: dom.window.document
});
const bgConfig: BgConfig = {
fetch: (input: string | URL | globalThis.Request, init?: RequestInit) => fetch(input, init),
globalObj: globalThis,
identifier: visitorData,
requestKey
};
const bgChallenge = await BG.Challenge.create(bgConfig);
if (!bgChallenge)
throw new Error('Could not get challenge');
const interpreterJavascript = bgChallenge.interpreterJavascript.privateDoNotAccessOrElseSafeScriptWrappedValue;
if (interpreterJavascript) {
new Function(interpreterJavascript)();
} else throw new Error('Could not load VM');
const poTokenResult = await BG.PoToken.generate({
program: bgChallenge.program,
globalName: bgChallenge.globalName,
bgConfig
});
const placeholderPoToken = BG.PoToken.generatePlaceholder(visitorData);
return {
visitorData,
placeholderPoToken,
poToken: poTokenResult.poToken,
};
}

View File

@@ -127,9 +127,9 @@ async function prepareOnesieRequest(args: OnesieRequestArgs): Promise<OnesieRequ
clientAbrState: {
timeSinceLastManualFormatSelectionMs: 0,
lastManualDirection: 0,
quality: QUALITY.HD720,
selectedQualityHeight: QUALITY.HD720,
startTimeMs: 0,
lastManualSelectedResolution: QUALITY.HD720,
stickyResolution: QUALITY.HD720,
playerTimeMs: 0,
visibility: 0
},
streamerContext: {

View File

@@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"youtubei.js": "^12.1.0"
"youtubei.js": "^12.2.0"
}
},
"node_modules/@bufbuild/protobuf": {
@@ -29,6 +29,7 @@
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -37,12 +38,13 @@
}
},
"node_modules/jintr": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jintr/-/jintr-3.1.0.tgz",
"integrity": "sha512-azhCHApkRfBH8INpiUCwKBYaNCdB5G+x3NApsI2MxQXSlgFAx7rap3YwE3JAkN08GO8f3ilZsGB0Yvc+412ntQ==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jintr/-/jintr-3.2.0.tgz",
"integrity": "sha512-psD1yf05kMKDNsUdW1l5YhO59pHScQ6OIHHb8W5SKSM2dCOFPsqolmIuSHgVA8+3Dc47NJR181CXZ4alCAPTkA==",
"funding": [
"https://github.com/sponsors/LuanRT"
],
"license": "MIT",
"dependencies": {
"acorn": "^8.8.0"
}
@@ -64,15 +66,16 @@
}
},
"node_modules/youtubei.js": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-12.1.0.tgz",
"integrity": "sha512-42SUw7zPpx4b7+XBm9QW+//T2/tixBRoEjJAbfOLmGCiyGZuvfW+oq/IngnXo2Keu+yD7YVAfYFc/NaFjFDxGg==",
"version": "12.2.0",
"resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-12.2.0.tgz",
"integrity": "sha512-G+50qrbJCToMYhu8jbaHiS3Vf+RRul+CcDbz3hEGwHkGPh+zLiWwD6SS+YhYF+2/op4ZU5zDYQJrGqJ+wKh7Gw==",
"funding": [
"https://github.com/sponsors/LuanRT"
],
"license": "MIT",
"dependencies": {
"@bufbuild/protobuf": "^2.0.0",
"jintr": "^3.1.0",
"jintr": "^3.2.0",
"tslib": "^2.5.0",
"undici": "^5.19.1"
}

View File

@@ -12,6 +12,6 @@
"author": "",
"license": "ISC",
"dependencies": {
"youtubei.js": "^12.1.0"
"youtubei.js": "^12.2.0"
}
}

View File

@@ -6,31 +6,32 @@
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { MediaCapabilities } from "./media_capabilities.js";
export const protobufPackage = "video_streaming";
export interface ClientAbrState {
timeSinceLastManualFormatSelectionMs?: number | undefined;
lastManualDirection?: number | undefined;
quality?: number | undefined;
lastManualSelectedResolution?: number | undefined;
detailedNetworkType?: number | undefined;
maxWidth?: number | undefined;
maxHeight?: number | undefined;
selectedQualityHeight?: number | undefined;
r7?: number | undefined;
startTimeMs?: number | undefined;
clientViewportWidth?: number | undefined;
clientViewportHeight?: number | undefined;
clientBitrateCap?: number | undefined;
stickyResolution?: number | undefined;
clientViewportIsFlexible?: boolean | undefined;
bandwidthEstimate?: number | undefined;
playerTimeMs?: number | undefined;
timeSinceLastSeek?: number | undefined;
dataSaverMode?: boolean | undefined;
visibility?: number | undefined;
timeSinceLastReq?: number | undefined;
mediaCapabilities?: MediaCapabilities | undefined;
timeSinceLastAction?:
| number
| undefined;
/** optional int32 Gw = 40; */
mediaType?: ClientAbrState_MediaType | undefined;
playbackRate?: number | undefined;
elapsedWallTimeMs?: number | undefined;
mediaCapabilities?: Uint8Array | undefined;
timeSinceLastActionMs?: number | undefined;
enabledTrackTypesBitfield?: number | undefined;
maxPacingRate?: number | undefined;
playerState?: number | undefined;
rangeCompression?: boolean | undefined;
drcEnabled?: boolean | undefined;
Jda?: number | undefined;
qw?: number | undefined;
Ky?: number | undefined;
@@ -47,73 +48,32 @@ export interface ClientAbrState {
sabrForceProxima?: number | undefined;
Tqb?: number | undefined;
sabrForceMaxNetworkInterruptionDurationMs?: number | undefined;
playbackRate?: number | undefined;
}
export enum ClientAbrState_MediaType {
MEDIA_TYPE_DEFAULT = 0,
MEDIA_TYPE_AUDIO = 1,
MEDIA_TYPE_VIDEO = 2,
USE_SERVER_FORMAT_FILTER = 3,
UNRECOGNIZED = -1,
}
export function clientAbrState_MediaTypeFromJSON(object: any): ClientAbrState_MediaType {
switch (object) {
case 0:
case "MEDIA_TYPE_DEFAULT":
return ClientAbrState_MediaType.MEDIA_TYPE_DEFAULT;
case 1:
case "MEDIA_TYPE_AUDIO":
return ClientAbrState_MediaType.MEDIA_TYPE_AUDIO;
case 2:
case "MEDIA_TYPE_VIDEO":
return ClientAbrState_MediaType.MEDIA_TYPE_VIDEO;
case 3:
case "USE_SERVER_FORMAT_FILTER":
return ClientAbrState_MediaType.USE_SERVER_FORMAT_FILTER;
case -1:
case "UNRECOGNIZED":
default:
return ClientAbrState_MediaType.UNRECOGNIZED;
}
}
export function clientAbrState_MediaTypeToJSON(object: ClientAbrState_MediaType): string {
switch (object) {
case ClientAbrState_MediaType.MEDIA_TYPE_DEFAULT:
return "MEDIA_TYPE_DEFAULT";
case ClientAbrState_MediaType.MEDIA_TYPE_AUDIO:
return "MEDIA_TYPE_AUDIO";
case ClientAbrState_MediaType.MEDIA_TYPE_VIDEO:
return "MEDIA_TYPE_VIDEO";
case ClientAbrState_MediaType.USE_SERVER_FORMAT_FILTER:
return "USE_SERVER_FORMAT_FILTER";
case ClientAbrState_MediaType.UNRECOGNIZED:
default:
return "UNRECOGNIZED";
}
}
function createBaseClientAbrState(): ClientAbrState {
return {
timeSinceLastManualFormatSelectionMs: 0,
lastManualDirection: 0,
quality: 0,
lastManualSelectedResolution: 0,
detailedNetworkType: 0,
maxWidth: 0,
maxHeight: 0,
selectedQualityHeight: 0,
r7: 0,
startTimeMs: 0,
clientViewportWidth: 0,
clientViewportHeight: 0,
clientBitrateCap: 0,
stickyResolution: 0,
clientViewportIsFlexible: false,
bandwidthEstimate: 0,
playerTimeMs: 0,
timeSinceLastSeek: 0,
dataSaverMode: false,
visibility: 0,
timeSinceLastReq: 0,
mediaCapabilities: undefined,
timeSinceLastAction: 0,
mediaType: 0,
playbackRate: 0,
elapsedWallTimeMs: 0,
mediaCapabilities: new Uint8Array(0),
timeSinceLastActionMs: 0,
enabledTrackTypesBitfield: 0,
maxPacingRate: 0,
playerState: 0,
rangeCompression: false,
drcEnabled: false,
Jda: 0,
qw: 0,
Ky: 0,
@@ -130,7 +90,6 @@ function createBaseClientAbrState(): ClientAbrState {
sabrForceProxima: 0,
Tqb: 0,
sabrForceMaxNetworkInterruptionDurationMs: 0,
playbackRate: 0,
};
}
@@ -144,50 +103,65 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
if (message.lastManualDirection !== undefined && message.lastManualDirection !== 0) {
writer.uint32(112).int32(message.lastManualDirection);
}
if (message.quality !== undefined && message.quality !== 0) {
writer.uint32(128).int32(message.quality);
if (message.lastManualSelectedResolution !== undefined && message.lastManualSelectedResolution !== 0) {
writer.uint32(128).int32(message.lastManualSelectedResolution);
}
if (message.detailedNetworkType !== undefined && message.detailedNetworkType !== 0) {
writer.uint32(136).int32(message.detailedNetworkType);
}
if (message.maxWidth !== undefined && message.maxWidth !== 0) {
writer.uint32(144).int32(message.maxWidth);
if (message.clientViewportWidth !== undefined && message.clientViewportWidth !== 0) {
writer.uint32(144).int32(message.clientViewportWidth);
}
if (message.maxHeight !== undefined && message.maxHeight !== 0) {
writer.uint32(152).int32(message.maxHeight);
if (message.clientViewportHeight !== undefined && message.clientViewportHeight !== 0) {
writer.uint32(152).int32(message.clientViewportHeight);
}
if (message.selectedQualityHeight !== undefined && message.selectedQualityHeight !== 0) {
writer.uint32(168).int32(message.selectedQualityHeight);
if (message.clientBitrateCap !== undefined && message.clientBitrateCap !== 0) {
writer.uint32(160).int64(message.clientBitrateCap);
}
if (message.r7 !== undefined && message.r7 !== 0) {
writer.uint32(184).int32(message.r7);
if (message.stickyResolution !== undefined && message.stickyResolution !== 0) {
writer.uint32(168).int32(message.stickyResolution);
}
if (message.startTimeMs !== undefined && message.startTimeMs !== 0) {
writer.uint32(224).int64(message.startTimeMs);
if (message.clientViewportIsFlexible !== undefined && message.clientViewportIsFlexible !== false) {
writer.uint32(176).bool(message.clientViewportIsFlexible);
}
if (message.bandwidthEstimate !== undefined && message.bandwidthEstimate !== 0) {
writer.uint32(184).int32(message.bandwidthEstimate);
}
if (message.playerTimeMs !== undefined && message.playerTimeMs !== 0) {
writer.uint32(224).int64(message.playerTimeMs);
}
if (message.timeSinceLastSeek !== undefined && message.timeSinceLastSeek !== 0) {
writer.uint32(232).int64(message.timeSinceLastSeek);
}
if (message.dataSaverMode !== undefined && message.dataSaverMode !== false) {
writer.uint32(240).bool(message.dataSaverMode);
}
if (message.visibility !== undefined && message.visibility !== 0) {
writer.uint32(272).int32(message.visibility);
}
if (message.timeSinceLastReq !== undefined && message.timeSinceLastReq !== 0) {
writer.uint32(288).int64(message.timeSinceLastReq);
if (message.playbackRate !== undefined && message.playbackRate !== 0) {
writer.uint32(285).float(message.playbackRate);
}
if (message.mediaCapabilities !== undefined) {
MediaCapabilities.encode(message.mediaCapabilities, writer.uint32(306).fork()).join();
if (message.elapsedWallTimeMs !== undefined && message.elapsedWallTimeMs !== 0) {
writer.uint32(288).int64(message.elapsedWallTimeMs);
}
if (message.timeSinceLastAction !== undefined && message.timeSinceLastAction !== 0) {
writer.uint32(312).int64(message.timeSinceLastAction);
if (message.mediaCapabilities !== undefined && message.mediaCapabilities.length !== 0) {
writer.uint32(306).bytes(message.mediaCapabilities);
}
if (message.mediaType !== undefined && message.mediaType !== 0) {
writer.uint32(320).int32(message.mediaType);
if (message.timeSinceLastActionMs !== undefined && message.timeSinceLastActionMs !== 0) {
writer.uint32(312).int64(message.timeSinceLastActionMs);
}
if (message.enabledTrackTypesBitfield !== undefined && message.enabledTrackTypesBitfield !== 0) {
writer.uint32(320).int32(message.enabledTrackTypesBitfield);
}
if (message.maxPacingRate !== undefined && message.maxPacingRate !== 0) {
writer.uint32(344).int32(message.maxPacingRate);
}
if (message.playerState !== undefined && message.playerState !== 0) {
writer.uint32(352).int64(message.playerState);
}
if (message.rangeCompression !== undefined && message.rangeCompression !== false) {
writer.uint32(368).bool(message.rangeCompression);
if (message.drcEnabled !== undefined && message.drcEnabled !== false) {
writer.uint32(368).bool(message.drcEnabled);
}
if (message.Jda !== undefined && message.Jda !== 0) {
writer.uint32(384).int32(message.Jda);
@@ -240,9 +214,6 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
) {
writer.uint32(544).int64(message.sabrForceMaxNetworkInterruptionDurationMs);
}
if (message.playbackRate !== undefined && message.playbackRate !== 0) {
writer.uint32(2285).float(message.playbackRate);
}
return writer;
},
@@ -272,7 +243,7 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
break;
}
message.quality = reader.int32();
message.lastManualSelectedResolution = reader.int32();
continue;
case 17:
if (tag !== 136) {
@@ -286,35 +257,49 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
break;
}
message.maxWidth = reader.int32();
message.clientViewportWidth = reader.int32();
continue;
case 19:
if (tag !== 152) {
break;
}
message.maxHeight = reader.int32();
message.clientViewportHeight = reader.int32();
continue;
case 20:
if (tag !== 160) {
break;
}
message.clientBitrateCap = longToNumber(reader.int64());
continue;
case 21:
if (tag !== 168) {
break;
}
message.selectedQualityHeight = reader.int32();
message.stickyResolution = reader.int32();
continue;
case 22:
if (tag !== 176) {
break;
}
message.clientViewportIsFlexible = reader.bool();
continue;
case 23:
if (tag !== 184) {
break;
}
message.r7 = reader.int32();
message.bandwidthEstimate = reader.int32();
continue;
case 28:
if (tag !== 224) {
break;
}
message.startTimeMs = longToNumber(reader.int64());
message.playerTimeMs = longToNumber(reader.int64());
continue;
case 29:
if (tag !== 232) {
@@ -323,6 +308,13 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
message.timeSinceLastSeek = longToNumber(reader.int64());
continue;
case 30:
if (tag !== 240) {
break;
}
message.dataSaverMode = reader.bool();
continue;
case 34:
if (tag !== 272) {
break;
@@ -330,33 +322,47 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
message.visibility = reader.int32();
continue;
case 35:
if (tag !== 285) {
break;
}
message.playbackRate = reader.float();
continue;
case 36:
if (tag !== 288) {
break;
}
message.timeSinceLastReq = longToNumber(reader.int64());
message.elapsedWallTimeMs = longToNumber(reader.int64());
continue;
case 38:
if (tag !== 306) {
break;
}
message.mediaCapabilities = MediaCapabilities.decode(reader, reader.uint32());
message.mediaCapabilities = reader.bytes();
continue;
case 39:
if (tag !== 312) {
break;
}
message.timeSinceLastAction = longToNumber(reader.int64());
message.timeSinceLastActionMs = longToNumber(reader.int64());
continue;
case 40:
if (tag !== 320) {
break;
}
message.mediaType = reader.int32() as any;
message.enabledTrackTypesBitfield = reader.int32();
continue;
case 43:
if (tag !== 344) {
break;
}
message.maxPacingRate = reader.int32();
continue;
case 44:
if (tag !== 352) {
@@ -370,7 +376,7 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
break;
}
message.rangeCompression = reader.bool();
message.drcEnabled = reader.bool();
continue;
case 48:
if (tag !== 384) {
@@ -484,13 +490,6 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
message.sabrForceMaxNetworkInterruptionDurationMs = longToNumber(reader.int64());
continue;
case 285:
if (tag !== 2285) {
break;
}
message.playbackRate = reader.float();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
@@ -506,23 +505,34 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
? globalThis.Number(object.timeSinceLastManualFormatSelectionMs)
: 0,
lastManualDirection: isSet(object.lastManualDirection) ? globalThis.Number(object.lastManualDirection) : 0,
quality: isSet(object.quality) ? globalThis.Number(object.quality) : 0,
lastManualSelectedResolution: isSet(object.lastManualSelectedResolution)
? globalThis.Number(object.lastManualSelectedResolution)
: 0,
detailedNetworkType: isSet(object.detailedNetworkType) ? globalThis.Number(object.detailedNetworkType) : 0,
maxWidth: isSet(object.maxWidth) ? globalThis.Number(object.maxWidth) : 0,
maxHeight: isSet(object.maxHeight) ? globalThis.Number(object.maxHeight) : 0,
selectedQualityHeight: isSet(object.selectedQualityHeight) ? globalThis.Number(object.selectedQualityHeight) : 0,
r7: isSet(object.r7) ? globalThis.Number(object.r7) : 0,
startTimeMs: isSet(object.startTimeMs) ? globalThis.Number(object.startTimeMs) : 0,
clientViewportWidth: isSet(object.clientViewportWidth) ? globalThis.Number(object.clientViewportWidth) : 0,
clientViewportHeight: isSet(object.clientViewportHeight) ? globalThis.Number(object.clientViewportHeight) : 0,
clientBitrateCap: isSet(object.clientBitrateCap) ? globalThis.Number(object.clientBitrateCap) : 0,
stickyResolution: isSet(object.stickyResolution) ? globalThis.Number(object.stickyResolution) : 0,
clientViewportIsFlexible: isSet(object.clientViewportIsFlexible)
? globalThis.Boolean(object.clientViewportIsFlexible)
: false,
bandwidthEstimate: isSet(object.bandwidthEstimate) ? globalThis.Number(object.bandwidthEstimate) : 0,
playerTimeMs: isSet(object.playerTimeMs) ? globalThis.Number(object.playerTimeMs) : 0,
timeSinceLastSeek: isSet(object.timeSinceLastSeek) ? globalThis.Number(object.timeSinceLastSeek) : 0,
dataSaverMode: isSet(object.dataSaverMode) ? globalThis.Boolean(object.dataSaverMode) : false,
visibility: isSet(object.visibility) ? globalThis.Number(object.visibility) : 0,
timeSinceLastReq: isSet(object.timeSinceLastReq) ? globalThis.Number(object.timeSinceLastReq) : 0,
playbackRate: isSet(object.playbackRate) ? globalThis.Number(object.playbackRate) : 0,
elapsedWallTimeMs: isSet(object.elapsedWallTimeMs) ? globalThis.Number(object.elapsedWallTimeMs) : 0,
mediaCapabilities: isSet(object.mediaCapabilities)
? MediaCapabilities.fromJSON(object.mediaCapabilities)
: undefined,
timeSinceLastAction: isSet(object.timeSinceLastAction) ? globalThis.Number(object.timeSinceLastAction) : 0,
mediaType: isSet(object.mediaType) ? clientAbrState_MediaTypeFromJSON(object.mediaType) : 0,
? bytesFromBase64(object.mediaCapabilities)
: new Uint8Array(0),
timeSinceLastActionMs: isSet(object.timeSinceLastActionMs) ? globalThis.Number(object.timeSinceLastActionMs) : 0,
enabledTrackTypesBitfield: isSet(object.enabledTrackTypesBitfield)
? globalThis.Number(object.enabledTrackTypesBitfield)
: 0,
maxPacingRate: isSet(object.maxPacingRate) ? globalThis.Number(object.maxPacingRate) : 0,
playerState: isSet(object.playerState) ? globalThis.Number(object.playerState) : 0,
rangeCompression: isSet(object.rangeCompression) ? globalThis.Boolean(object.rangeCompression) : false,
drcEnabled: isSet(object.drcEnabled) ? globalThis.Boolean(object.drcEnabled) : false,
Jda: isSet(object.Jda) ? globalThis.Number(object.Jda) : 0,
qw: isSet(object.qw) ? globalThis.Number(object.qw) : 0,
Ky: isSet(object.Ky) ? globalThis.Number(object.Ky) : 0,
@@ -549,7 +559,6 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
sabrForceMaxNetworkInterruptionDurationMs: isSet(object.sabrForceMaxNetworkInterruptionDurationMs)
? globalThis.Number(object.sabrForceMaxNetworkInterruptionDurationMs)
: 0,
playbackRate: isSet(object.playbackRate) ? globalThis.Number(object.playbackRate) : 0,
};
},
@@ -563,50 +572,65 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
if (message.lastManualDirection !== undefined && message.lastManualDirection !== 0) {
obj.lastManualDirection = Math.round(message.lastManualDirection);
}
if (message.quality !== undefined && message.quality !== 0) {
obj.quality = Math.round(message.quality);
if (message.lastManualSelectedResolution !== undefined && message.lastManualSelectedResolution !== 0) {
obj.lastManualSelectedResolution = Math.round(message.lastManualSelectedResolution);
}
if (message.detailedNetworkType !== undefined && message.detailedNetworkType !== 0) {
obj.detailedNetworkType = Math.round(message.detailedNetworkType);
}
if (message.maxWidth !== undefined && message.maxWidth !== 0) {
obj.maxWidth = Math.round(message.maxWidth);
if (message.clientViewportWidth !== undefined && message.clientViewportWidth !== 0) {
obj.clientViewportWidth = Math.round(message.clientViewportWidth);
}
if (message.maxHeight !== undefined && message.maxHeight !== 0) {
obj.maxHeight = Math.round(message.maxHeight);
if (message.clientViewportHeight !== undefined && message.clientViewportHeight !== 0) {
obj.clientViewportHeight = Math.round(message.clientViewportHeight);
}
if (message.selectedQualityHeight !== undefined && message.selectedQualityHeight !== 0) {
obj.selectedQualityHeight = Math.round(message.selectedQualityHeight);
if (message.clientBitrateCap !== undefined && message.clientBitrateCap !== 0) {
obj.clientBitrateCap = Math.round(message.clientBitrateCap);
}
if (message.r7 !== undefined && message.r7 !== 0) {
obj.r7 = Math.round(message.r7);
if (message.stickyResolution !== undefined && message.stickyResolution !== 0) {
obj.stickyResolution = Math.round(message.stickyResolution);
}
if (message.startTimeMs !== undefined && message.startTimeMs !== 0) {
obj.startTimeMs = Math.round(message.startTimeMs);
if (message.clientViewportIsFlexible !== undefined && message.clientViewportIsFlexible !== false) {
obj.clientViewportIsFlexible = message.clientViewportIsFlexible;
}
if (message.bandwidthEstimate !== undefined && message.bandwidthEstimate !== 0) {
obj.bandwidthEstimate = Math.round(message.bandwidthEstimate);
}
if (message.playerTimeMs !== undefined && message.playerTimeMs !== 0) {
obj.playerTimeMs = Math.round(message.playerTimeMs);
}
if (message.timeSinceLastSeek !== undefined && message.timeSinceLastSeek !== 0) {
obj.timeSinceLastSeek = Math.round(message.timeSinceLastSeek);
}
if (message.dataSaverMode !== undefined && message.dataSaverMode !== false) {
obj.dataSaverMode = message.dataSaverMode;
}
if (message.visibility !== undefined && message.visibility !== 0) {
obj.visibility = Math.round(message.visibility);
}
if (message.timeSinceLastReq !== undefined && message.timeSinceLastReq !== 0) {
obj.timeSinceLastReq = Math.round(message.timeSinceLastReq);
if (message.playbackRate !== undefined && message.playbackRate !== 0) {
obj.playbackRate = message.playbackRate;
}
if (message.mediaCapabilities !== undefined) {
obj.mediaCapabilities = MediaCapabilities.toJSON(message.mediaCapabilities);
if (message.elapsedWallTimeMs !== undefined && message.elapsedWallTimeMs !== 0) {
obj.elapsedWallTimeMs = Math.round(message.elapsedWallTimeMs);
}
if (message.timeSinceLastAction !== undefined && message.timeSinceLastAction !== 0) {
obj.timeSinceLastAction = Math.round(message.timeSinceLastAction);
if (message.mediaCapabilities !== undefined && message.mediaCapabilities.length !== 0) {
obj.mediaCapabilities = base64FromBytes(message.mediaCapabilities);
}
if (message.mediaType !== undefined && message.mediaType !== 0) {
obj.mediaType = clientAbrState_MediaTypeToJSON(message.mediaType);
if (message.timeSinceLastActionMs !== undefined && message.timeSinceLastActionMs !== 0) {
obj.timeSinceLastActionMs = Math.round(message.timeSinceLastActionMs);
}
if (message.enabledTrackTypesBitfield !== undefined && message.enabledTrackTypesBitfield !== 0) {
obj.enabledTrackTypesBitfield = Math.round(message.enabledTrackTypesBitfield);
}
if (message.maxPacingRate !== undefined && message.maxPacingRate !== 0) {
obj.maxPacingRate = Math.round(message.maxPacingRate);
}
if (message.playerState !== undefined && message.playerState !== 0) {
obj.playerState = Math.round(message.playerState);
}
if (message.rangeCompression !== undefined && message.rangeCompression !== false) {
obj.rangeCompression = message.rangeCompression;
if (message.drcEnabled !== undefined && message.drcEnabled !== false) {
obj.drcEnabled = message.drcEnabled;
}
if (message.Jda !== undefined && message.Jda !== 0) {
obj.Jda = Math.round(message.Jda);
@@ -659,9 +683,6 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
) {
obj.sabrForceMaxNetworkInterruptionDurationMs = Math.round(message.sabrForceMaxNetworkInterruptionDurationMs);
}
if (message.playbackRate !== undefined && message.playbackRate !== 0) {
obj.playbackRate = message.playbackRate;
}
return obj;
},
@@ -672,23 +693,26 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
const message = createBaseClientAbrState();
message.timeSinceLastManualFormatSelectionMs = object.timeSinceLastManualFormatSelectionMs ?? 0;
message.lastManualDirection = object.lastManualDirection ?? 0;
message.quality = object.quality ?? 0;
message.lastManualSelectedResolution = object.lastManualSelectedResolution ?? 0;
message.detailedNetworkType = object.detailedNetworkType ?? 0;
message.maxWidth = object.maxWidth ?? 0;
message.maxHeight = object.maxHeight ?? 0;
message.selectedQualityHeight = object.selectedQualityHeight ?? 0;
message.r7 = object.r7 ?? 0;
message.startTimeMs = object.startTimeMs ?? 0;
message.clientViewportWidth = object.clientViewportWidth ?? 0;
message.clientViewportHeight = object.clientViewportHeight ?? 0;
message.clientBitrateCap = object.clientBitrateCap ?? 0;
message.stickyResolution = object.stickyResolution ?? 0;
message.clientViewportIsFlexible = object.clientViewportIsFlexible ?? false;
message.bandwidthEstimate = object.bandwidthEstimate ?? 0;
message.playerTimeMs = object.playerTimeMs ?? 0;
message.timeSinceLastSeek = object.timeSinceLastSeek ?? 0;
message.dataSaverMode = object.dataSaverMode ?? false;
message.visibility = object.visibility ?? 0;
message.timeSinceLastReq = object.timeSinceLastReq ?? 0;
message.mediaCapabilities = (object.mediaCapabilities !== undefined && object.mediaCapabilities !== null)
? MediaCapabilities.fromPartial(object.mediaCapabilities)
: undefined;
message.timeSinceLastAction = object.timeSinceLastAction ?? 0;
message.mediaType = object.mediaType ?? 0;
message.playbackRate = object.playbackRate ?? 0;
message.elapsedWallTimeMs = object.elapsedWallTimeMs ?? 0;
message.mediaCapabilities = object.mediaCapabilities ?? new Uint8Array(0);
message.timeSinceLastActionMs = object.timeSinceLastActionMs ?? 0;
message.enabledTrackTypesBitfield = object.enabledTrackTypesBitfield ?? 0;
message.maxPacingRate = object.maxPacingRate ?? 0;
message.playerState = object.playerState ?? 0;
message.rangeCompression = object.rangeCompression ?? false;
message.drcEnabled = object.drcEnabled ?? false;
message.Jda = object.Jda ?? 0;
message.qw = object.qw ?? 0;
message.Ky = object.Ky ?? 0;
@@ -705,7 +729,6 @@ export const ClientAbrState: MessageFns<ClientAbrState> = {
message.sabrForceProxima = object.sabrForceProxima ?? 0;
message.Tqb = object.Tqb ?? 0;
message.sabrForceMaxNetworkInterruptionDurationMs = object.sabrForceMaxNetworkInterruptionDurationMs ?? 0;
message.playbackRate = object.playbackRate ?? 0;
return message;
},
};

View File

@@ -17,6 +17,7 @@ export interface VideoPlaybackAbrRequest {
clientAbrState?: ClientAbrState | undefined;
selectedFormatIds: FormatId[];
bufferedRanges: BufferedRange[];
playerTimeMs?: number | undefined;
videoPlaybackUstreamerConfig?: Uint8Array | undefined;
lo?: Lo | undefined;
selectedAudioFormatIds: FormatId[];
@@ -62,6 +63,7 @@ function createBaseVideoPlaybackAbrRequest(): VideoPlaybackAbrRequest {
clientAbrState: undefined,
selectedFormatIds: [],
bufferedRanges: [],
playerTimeMs: 0,
videoPlaybackUstreamerConfig: new Uint8Array(0),
lo: undefined,
selectedAudioFormatIds: [],
@@ -85,6 +87,9 @@ export const VideoPlaybackAbrRequest: MessageFns<VideoPlaybackAbrRequest> = {
for (const v of message.bufferedRanges) {
BufferedRange.encode(v!, writer.uint32(26).fork()).join();
}
if (message.playerTimeMs !== undefined && message.playerTimeMs !== 0) {
writer.uint32(32).int64(message.playerTimeMs);
}
if (message.videoPlaybackUstreamerConfig !== undefined && message.videoPlaybackUstreamerConfig.length !== 0) {
writer.uint32(42).bytes(message.videoPlaybackUstreamerConfig);
}
@@ -143,6 +148,13 @@ export const VideoPlaybackAbrRequest: MessageFns<VideoPlaybackAbrRequest> = {
message.bufferedRanges.push(BufferedRange.decode(reader, reader.uint32()));
continue;
case 4:
if (tag !== 32) {
break;
}
message.playerTimeMs = longToNumber(reader.int64());
continue;
case 5:
if (tag !== 42) {
break;
@@ -224,6 +236,7 @@ export const VideoPlaybackAbrRequest: MessageFns<VideoPlaybackAbrRequest> = {
bufferedRanges: globalThis.Array.isArray(object?.bufferedRanges)
? object.bufferedRanges.map((e: any) => BufferedRange.fromJSON(e))
: [],
playerTimeMs: isSet(object.playerTimeMs) ? globalThis.Number(object.playerTimeMs) : 0,
videoPlaybackUstreamerConfig: isSet(object.videoPlaybackUstreamerConfig)
? bytesFromBase64(object.videoPlaybackUstreamerConfig)
: new Uint8Array(0),
@@ -253,6 +266,9 @@ export const VideoPlaybackAbrRequest: MessageFns<VideoPlaybackAbrRequest> = {
if (message.bufferedRanges?.length) {
obj.bufferedRanges = message.bufferedRanges.map((e) => BufferedRange.toJSON(e));
}
if (message.playerTimeMs !== undefined && message.playerTimeMs !== 0) {
obj.playerTimeMs = Math.round(message.playerTimeMs);
}
if (message.videoPlaybackUstreamerConfig !== undefined && message.videoPlaybackUstreamerConfig.length !== 0) {
obj.videoPlaybackUstreamerConfig = base64FromBytes(message.videoPlaybackUstreamerConfig);
}
@@ -293,6 +309,7 @@ export const VideoPlaybackAbrRequest: MessageFns<VideoPlaybackAbrRequest> = {
: undefined;
message.selectedFormatIds = object.selectedFormatIds?.map((e) => FormatId.fromPartial(e)) || [];
message.bufferedRanges = object.bufferedRanges?.map((e) => BufferedRange.fromPartial(e)) || [];
message.playerTimeMs = object.playerTimeMs ?? 0;
message.videoPlaybackUstreamerConfig = object.videoPlaybackUstreamerConfig ?? new Uint8Array(0);
message.lo = (object.lo !== undefined && object.lo !== null) ? Lo.fromPartial(object.lo) : undefined;
message.selectedAudioFormatIds = object.selectedAudioFormatIds?.map((e) => FormatId.fromPartial(e)) || [];
@@ -774,6 +791,17 @@ type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToNumber(int64: { toString(): string }): number {
const num = globalThis.Number(int64.toString());
if (num > globalThis.Number.MAX_SAFE_INTEGER) {
throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
}
if (num < globalThis.Number.MIN_SAFE_INTEGER) {
throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER");
}
return num;
}
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}

View File

@@ -1,27 +1,29 @@
syntax = "proto2";
package video_streaming;
import "video_streaming/media_capabilities.proto";
message ClientAbrState {
optional int32 time_since_last_manual_format_selection_ms = 13;
optional int32 last_manual_direction = 14;
optional int32 quality = 16;
optional int32 last_manual_selected_resolution = 16;
optional int32 detailed_network_type = 17;
optional int32 max_width = 18;
optional int32 max_height = 19;
optional int32 selected_quality_height = 21;
optional int32 r7 = 23;
optional int64 start_time_ms = 28;
optional int32 client_viewport_width = 18;
optional int32 client_viewport_height = 19;
optional int64 client_bitrate_cap = 20;
optional int32 sticky_resolution = 21;
optional bool client_viewport_is_flexible = 22;
optional int32 bandwidth_estimate = 23;
optional int64 player_time_ms = 28;
optional int64 time_since_last_seek = 29;
optional bool data_saver_mode = 30;
optional int32 visibility = 34;
optional int64 time_since_last_req = 36;
optional MediaCapabilities media_capabilities = 38;
optional int64 time_since_last_action = 39;
// optional int32 Gw = 40;
optional MediaType media_type = 40;
optional float playback_rate = 35;
optional int64 elapsed_wall_time_ms = 36;
optional bytes media_capabilities = 38;
optional int64 time_since_last_action_ms = 39;
optional int32 enabled_track_types_bitfield = 40;
optional int32 max_pacing_rate = 43;
optional int64 player_state = 44;
optional bool range_compression = 46;
optional bool drc_enabled = 46;
optional int32 Jda = 48;
optional int32 qw = 50;
optional int32 Ky = 51;
@@ -38,12 +40,4 @@ message ClientAbrState {
optional int32 sabr_force_proxima = 66;
optional int32 Tqb = 67;
optional int64 sabr_force_max_network_interruption_duration_ms = 68;
optional float playback_rate = 285;
enum MediaType {
MEDIA_TYPE_DEFAULT = 0;
MEDIA_TYPE_AUDIO = 1;
MEDIA_TYPE_VIDEO = 2;
USE_SERVER_FORMAT_FILTER = 3;
}
}

View File

@@ -10,6 +10,7 @@ message VideoPlaybackAbrRequest {
optional ClientAbrState client_abr_state = 1;
repeated .misc.FormatId selected_format_ids = 2;
repeated BufferedRange buffered_ranges = 3;
optional int64 player_time_ms = 4;
optional bytes video_playback_ustreamer_config = 5;
optional Lo lo = 6;
repeated .misc.FormatId selected_audio_format_ids = 16;

View File

@@ -2,7 +2,6 @@ import { UMP } from './UMP.js';
import { ChunkedDataBuffer } from './ChunkedDataBuffer.js';
import { EventEmitterLike, PART, QUALITY, base64ToU8, getFormatKey } from '../utils/index.js';
import { ClientAbrState_MediaType } from '../../protos/generated/video_streaming/client_abr_state.js';
import { VideoPlaybackAbrRequest } from '../../protos/generated/video_streaming/video_playback_abr_request.js';
import { MediaHeader } from '../../protos/generated/video_streaming/media_header.js';
import { NextRequestPolicy } from '../../protos/generated/video_streaming/next_request_policy.js';
@@ -65,11 +64,11 @@ export class ServerAbrStream extends EventEmitterLike {
const clientAbrState: ClientAbrState = {
lastManualDirection: 0,
timeSinceLastManualFormatSelectionMs: 0,
quality: videoFormats.length === 1 ? firstVideoFormat?.height : DEFAULT_QUALITY,
selectedQualityHeight: videoFormats.length === 1 ? firstVideoFormat?.height : DEFAULT_QUALITY,
startTimeMs: 0,
lastManualSelectedResolution: videoFormats.length === 1 ? firstVideoFormat?.height : DEFAULT_QUALITY,
stickyResolution: videoFormats.length === 1 ? firstVideoFormat?.height : DEFAULT_QUALITY,
playerTimeMs: 0,
visibility: 0,
mediaType: ClientAbrState_MediaType.MEDIA_TYPE_DEFAULT,
enabledTrackTypesBitfield: 0,
...initialState
};
@@ -85,11 +84,11 @@ export class ServerAbrStream extends EventEmitterLike {
xtags: fmt.xtags
}));
if (typeof clientAbrState.startTimeMs !== 'number')
if (typeof clientAbrState.playerTimeMs !== 'number')
throw new Error('Invalid media start time');
try {
while (clientAbrState.startTimeMs < this.totalDurationMs) {
while (clientAbrState.playerTimeMs < this.totalDurationMs) {
const data = await this.fetchMedia({ clientAbrState, audioFormatIds, videoFormatIds });
this.emit('data', data);
@@ -97,7 +96,7 @@ export class ServerAbrStream extends EventEmitterLike {
if (data.sabrError) break;
const mainFormat =
clientAbrState.mediaType === ClientAbrState_MediaType.MEDIA_TYPE_DEFAULT
clientAbrState.enabledTrackTypesBitfield === 0
? data.initializedFormats.find((fmt) => fmt.mimeType?.includes('video'))
: data.initializedFormats[0];
@@ -114,11 +113,11 @@ export class ServerAbrStream extends EventEmitterLike {
break;
}
clientAbrState.startTimeMs += mainFormat.sequenceList.reduce((acc, seq) => acc + (seq.durationMs || 0), 0);
clientAbrState.playerTimeMs += mainFormat.sequenceList.reduce((acc, seq) => acc + (seq.durationMs || 0), 0);
}
} catch (error) {
this.emit('error', error);
clientAbrState.startTimeMs = Infinity;
clientAbrState.playerTimeMs = Infinity;
}
}

View File

@@ -19,5 +19,4 @@ export { ClientAbrState } from '../../protos/generated/video_streaming/client_ab
export { StreamerContext } from '../../protos/generated/video_streaming/streamer_context.js';
export { ProxyStatus } from '../../protos/generated/video_streaming/proxy_status.js';
export { MediaCapabilities } from '../../protos/generated/video_streaming/media_capabilities.js';
export { CryptoParams } from '../../protos/generated/video_streaming/crypto_params.js';
export { ClientAbrState_MediaType as MediaType } from '../../protos/generated/video_streaming/client_abr_state.js';
export { CryptoParams } from '../../protos/generated/video_streaming/crypto_params.js';