From a508925216a7fa0b71ae1e122d0e0f77ded1c819 Mon Sep 17 00:00:00 2001 From: Luan Date: Fri, 13 Sep 2024 13:52:28 -0300 Subject: [PATCH] feat: init repo --- .editorconfig | 12 + .gitignore | 77 + .npmignore | 6 + LICENSE | 9 + deno.lock | 31 + dev-scripts/generate-proto.mjs | 54 + eslint.config.js | 101 + examples/browser/proxy/deno.ts | 87 + examples/browser/web/.gitignore | 24 + examples/browser/web/favicon.svg | 15 + examples/browser/web/index.html | 31 + examples/browser/web/package-lock.json | 381 ++ examples/browser/web/package.json | 20 + examples/browser/web/public/service-worker.js | 3 + .../browser/web/public/service-worker.js.map | 7 + examples/browser/web/public/vite.svg | 1 + examples/browser/web/src/assets/player.css | 423 +++ examples/browser/web/src/assets/style.css | 135 + examples/browser/web/src/main.ts | 408 ++ examples/browser/web/src/vite-env.d.ts | 1 + examples/browser/web/tsconfig.json | 20 + examples/downloader/main.ts | 128 + examples/downloader/package-lock.json | 113 + examples/downloader/package.json | 21 + examples/downloader/tsconfig.json | 110 + package-lock.json | 1841 +++++++++ package.json | 58 + protos/generated/misc/common.ts | 457 +++ protos/generated/misc/params.ts | 3340 +++++++++++++++++ .../format_initialization_metadata.ts | 260 ++ .../generated/video_streaming/media_header.ts | 488 +++ .../video_streaming/next_request_policy.ts | 175 + .../video_streaming/onesie_request.ts | 164 + .../video_streaming/playback_cookie.ts | 152 + .../video_streaming/playback_start_policy.ts | 209 ++ .../request_cancellation_policy.ts | 229 ++ .../generated/video_streaming/sabr_error.ts | 114 + .../video_streaming/sabr_redirect.ts | 96 + .../stream_protection_status.ts | 114 + .../video_playback_abr_request.ts | 2872 ++++++++++++++ protos/misc/common.proto | 28 + protos/misc/params.proto | 227 ++ .../format_initialization_metadata.proto | 17 + protos/video_streaming/media_header.proto | 35 + .../video_streaming/next_request_policy.proto | 12 + protos/video_streaming/onesie_request.proto | 13 + protos/video_streaming/playback_cookie.proto | 11 + .../playback_start_policy.proto | 12 + .../request_cancellation_policy.proto | 14 + protos/video_streaming/sabr_error.proto | 7 + protos/video_streaming/sabr_redirect.proto | 6 + .../stream_protection_status.proto | 7 + .../video_playback_abr_request.proto | 172 + src/core/ChunkedDataBuffer.ts | 106 + src/core/ServerAbrStream.ts | 300 ++ src/core/UMP.ts | 127 + src/core/index.ts | 3 + src/index.ts | 4 + src/utils/EventEmitterLike.ts | 47 + src/utils/Protos.ts | 10 + src/utils/helpers.ts | 65 + src/utils/index.ts | 4 + src/utils/types.ts | 133 + test.ts | 34 + tsconfig.json | 98 + 65 files changed, 14279 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 LICENSE create mode 100644 deno.lock create mode 100644 dev-scripts/generate-proto.mjs create mode 100644 eslint.config.js create mode 100644 examples/browser/proxy/deno.ts create mode 100644 examples/browser/web/.gitignore create mode 100644 examples/browser/web/favicon.svg create mode 100644 examples/browser/web/index.html create mode 100644 examples/browser/web/package-lock.json create mode 100644 examples/browser/web/package.json create mode 100644 examples/browser/web/public/service-worker.js create mode 100644 examples/browser/web/public/service-worker.js.map create mode 100644 examples/browser/web/public/vite.svg create mode 100644 examples/browser/web/src/assets/player.css create mode 100644 examples/browser/web/src/assets/style.css create mode 100644 examples/browser/web/src/main.ts create mode 100644 examples/browser/web/src/vite-env.d.ts create mode 100644 examples/browser/web/tsconfig.json create mode 100644 examples/downloader/main.ts create mode 100644 examples/downloader/package-lock.json create mode 100644 examples/downloader/package.json create mode 100644 examples/downloader/tsconfig.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 protos/generated/misc/common.ts create mode 100644 protos/generated/misc/params.ts create mode 100644 protos/generated/video_streaming/format_initialization_metadata.ts create mode 100644 protos/generated/video_streaming/media_header.ts create mode 100644 protos/generated/video_streaming/next_request_policy.ts create mode 100644 protos/generated/video_streaming/onesie_request.ts create mode 100644 protos/generated/video_streaming/playback_cookie.ts create mode 100644 protos/generated/video_streaming/playback_start_policy.ts create mode 100644 protos/generated/video_streaming/request_cancellation_policy.ts create mode 100644 protos/generated/video_streaming/sabr_error.ts create mode 100644 protos/generated/video_streaming/sabr_redirect.ts create mode 100644 protos/generated/video_streaming/stream_protection_status.ts create mode 100644 protos/generated/video_streaming/video_playback_abr_request.ts create mode 100644 protos/misc/common.proto create mode 100644 protos/misc/params.proto create mode 100644 protos/video_streaming/format_initialization_metadata.proto create mode 100644 protos/video_streaming/media_header.proto create mode 100644 protos/video_streaming/next_request_policy.proto create mode 100644 protos/video_streaming/onesie_request.proto create mode 100644 protos/video_streaming/playback_cookie.proto create mode 100644 protos/video_streaming/playback_start_policy.proto create mode 100644 protos/video_streaming/request_cancellation_policy.proto create mode 100644 protos/video_streaming/sabr_error.proto create mode 100644 protos/video_streaming/sabr_redirect.proto create mode 100644 protos/video_streaming/stream_protection_status.proto create mode 100644 protos/video_streaming/video_playback_abr_request.proto create mode 100644 src/core/ChunkedDataBuffer.ts create mode 100644 src/core/ServerAbrStream.ts create mode 100644 src/core/UMP.ts create mode 100644 src/core/index.ts create mode 100644 src/index.ts create mode 100644 src/utils/EventEmitterLike.ts create mode 100644 src/utils/Protos.ts create mode 100644 src/utils/helpers.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/types.ts create mode 100644 test.ts create mode 100644 tsconfig.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ebe51d3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..987be5c --- /dev/null +++ b/.gitignore @@ -0,0 +1,77 @@ +# YouTube player cache directory +cache/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# pnpm +.pnpm-debug.log* +pnpm-lock.yaml + +# Downloaded assets +*.mp4 +*.webm +*.mkv + +# Temporary files for testing +tmp/ + +# Build output +dist/ +bundle/*.js.* +bundle/*.js +bundle/*.cjs +bundle/*.cjs.* +deno/ + +# VSCode files +.vscode/ + +# MacOS +.DS_Store diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..a3a68df --- /dev/null +++ b/.npmignore @@ -0,0 +1,6 @@ +** + +src/ +!dist/** +!README.md +!bundle/** \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..87a02e2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2024 LuanRT + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..a783120 --- /dev/null +++ b/deno.lock @@ -0,0 +1,31 @@ +{ + "version": "3", + "remote": { + "https://deno.land/std@0.148.0/async/abortable.ts": "87aa7230be8360c24ad437212311c9e8d4328854baec27b4c7abb26e85515c06", + "https://deno.land/std@0.148.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0", + "https://deno.land/std@0.148.0/async/debounce.ts": "564273ef242bcfcda19a439132f940db8694173abffc159ea34f07d18fc42620", + "https://deno.land/std@0.148.0/async/deferred.ts": "bc18e28108252c9f67dfca2bbc4587c3cbf3aeb6e155f8c864ca8ecff992b98a", + "https://deno.land/std@0.148.0/async/delay.ts": "cbbdf1c87d1aed8edc7bae13592fb3e27e3106e0748f089c263390d4f49e5f6c", + "https://deno.land/std@0.148.0/async/mod.ts": "9852cd8ed897ab2d41a8fbee611d574e97898327db5c19d9d58e41126473f02c", + "https://deno.land/std@0.148.0/async/mux_async_iterator.ts": "5b4aca6781ad0f2e19ccdf1d1a1c092ccd3e00d52050d9c27c772658c8367256", + "https://deno.land/std@0.148.0/async/pool.ts": "ef9eb97b388543acbf0ac32647121e4dbe629236899586c4d4311a8770fbb239", + "https://deno.land/std@0.148.0/async/tee.ts": "bcfae0017ebb718cf4eef9e2420e8675d91cb1bcc0ed9b668681af6e6caad846", + "https://deno.land/std@0.148.0/http/server.ts": "0b0a9f3abfcfecead944b31ee9098a0c11a59b0495bf873ee200eb80e7441483" + }, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:@bufbuild/protobuf@^2.0.0", + "npm:@eslint/js@^9.9.0", + "npm:@stylistic/eslint-plugin@^2.6.4", + "npm:@types/eslint__js@^8.42.3", + "npm:eslint@^9.9.0", + "npm:globals@^15.9.0", + "npm:ts-proto@^2.2.0", + "npm:typescript-eslint@^8.2.0", + "npm:typescript@^5.5.4", + "npm:youtubei.js@^10.4.0" + ] + } + } +} diff --git a/dev-scripts/generate-proto.mjs b/dev-scripts/generate-proto.mjs new file mode 100644 index 0000000..6f476d9 --- /dev/null +++ b/dev-scripts/generate-proto.mjs @@ -0,0 +1,54 @@ +import { exec } from 'child_process'; +import { existsSync, mkdirSync, readdirSync, statSync } from 'fs'; +import { join } from 'path'; +import path from 'path'; +import url from 'url'; +import os from 'os'; + +const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); + +const protoDir = './protos'; +const outDir = './protos/generated'; + +if (!existsSync(outDir)) { + mkdirSync(outDir, { recursive: true }); +} + +const protocGenTs = path.join( + __dirname, + '../node_modules', + '.bin', + os.platform() === 'win32' ? 'protoc-gen-ts_proto.cmd' : 'protoc-gen-ts_proto' +); + +function listProtoFiles(dir) { + let protoFiles = []; + const items = readdirSync(dir); + + for (const item of items) { + const fullPath = join(dir, item); + if (statSync(fullPath).isDirectory()) { + protoFiles = protoFiles.concat(listProtoFiles(fullPath)); + } else if (item.endsWith('.proto')) { + protoFiles.push(fullPath); + } + } + + return protoFiles; +} + +const protoFiles = listProtoFiles(protoDir); + +if (!protoFiles.length) { + console.log('No .proto files found.'); + process.exit(0); +} + +protoFiles.forEach((file) => { + const command = `protoc --proto_path=${protoDir} --plugin=protoc-gen-ts=${protocGenTs} --ts_opt=env=browser --ts_opt=importSuffix=.js --ts_out=${outDir} ${file}`; + exec(command, (error, _stdout, stderr) => { + if (error) { + console.error(`Error compiling ${file}:`, stderr); + } + }); +}); \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..e3615f0 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,101 @@ +import pluginJs from "@eslint/js"; +import tseslint from "typescript-eslint"; + +export default [ + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + { + ignores: [ + "**/dist/", + "**/bundle/", + '**/examples/browser/proxy/', + "**/*.{js,mjs,cjs}", + ], + }, { + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + "max-len": ["error", { + code: 200, + ignoreComments: true, + ignoreTrailingComments: true, + ignoreStrings: true, + ignoreTemplateLiterals: true, + ignoreRegExpLiterals: true, + }], quotes: ["error", "single"], + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/consistent-type-imports": "error", + "@typescript-eslint/consistent-type-exports": "error", + 'no-sparse-arrays': 'off', + "no-template-curly-in-string": "error", + "no-unreachable-loop": "error", + "no-unused-private-class-members": "off", + "no-prototype-builtins": "off", + "no-async-promise-executor": "off", + "no-case-declarations": "off", + "no-return-assign": "off", + "no-floating-decimal": "error", + "no-implied-eval": "error", + "arrow-spacing": "error", + "no-invalid-this": "error", + "no-lone-blocks": "off", + "no-new-func": "off", + "no-new-wrappers": "error", + "no-new": "error", + "no-void": "error", + "no-octal-escape": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-throw-literal": "error", + "no-unmodified-loop-condition": "error", + "no-useless-call": "error", + "no-useless-concat": "error", + "no-useless-escape": "error", + "no-useless-return": "error", + "no-else-return": "error", + "no-lonely-if": "error", + "no-undef-init": "error", + "no-unneeded-ternary": "error", + "no-var": "error", + "no-multi-spaces": "error", + "no-multiple-empty-lines": ["error", { + max: 1, + maxEOF: 0, + }], + "no-tabs": "error", + "brace-style": "error", + "new-parens": "error", + "space-infix-ops": "error", + "template-curly-spacing": "error", + "wrap-regex": "error", + "capitalized-comments": "error", + "prefer-template": "error", + "keyword-spacing": ["error", { + before: true, + }], + "object-curly-spacing": ["warn", "always"], + "array-bracket-spacing": ["error", "always"], + "arrow-parens": ["error", "always"], + "comma-dangle": ["error", "never"], + "comma-spacing": ["error", { + before: false, + after: true, + }], + "computed-property-spacing": ["error", "never"], + "func-call-spacing": ["error", "never"], + indent: ["error", 2, { + SwitchCase: 1, + }], + "key-spacing": ["error", { + beforeColon: false, + }], + semi: ["error", "always"], + "operator-assignment": ["error", "always"], + }, + } +]; \ No newline at end of file diff --git a/examples/browser/proxy/deno.ts b/examples/browser/proxy/deno.ts new file mode 100644 index 0000000..14b7313 --- /dev/null +++ b/examples/browser/proxy/deno.ts @@ -0,0 +1,87 @@ +import { serve } from 'https://deno.land/std@0.148.0/http/server.ts'; + +const port = 8080; + +function copyHeader(headerName: string, to: Headers, from: Headers) { + const hdrVal = from.get(headerName); + if (hdrVal) { + to.set(headerName, hdrVal); + } +} + +const handler = async (request: Request): Promise => { + // If options send do CORS preflight + if (request.method === 'OPTIONS') { + const response = new Response('', { + status: 200, + headers: new Headers({ + 'Access-Control-Allow-Origin': request.headers.get('origin') || '*', + 'Access-Control-Allow-Methods': '*', + 'Access-Control-Allow-Headers': + 'Origin, X-Requested-With, Content-Type, Accept, Authorization, x-goog-visitor-id, x-goog-api-key, x-origin, x-youtube-client-version, x-youtube-client-name, x-goog-api-format-version, x-user-agent, Accept-Language, Range, Referer', + 'Access-Control-Max-Age': '86400', + 'Access-Control-Allow-Credentials': 'true' + }) + }); + return response; + } + + const url = new URL(request.url, 'http://localhost/'); + if (!url.searchParams.has('__host')) { + return new Response( + 'Request is formatted incorrectly. Please include __host in the query string.', + { status: 400 } + ); + } + + // Set the URL host to the __host parameter + url.host = url.searchParams.get('__host')!; + url.protocol = 'https'; + url.port = '443'; + url.searchParams.delete('__host'); + + // Copy headers from the request to the new request + const request_headers = new Headers( + JSON.parse(url.searchParams.get('__headers') || '{}') + ); + copyHeader('range', request_headers, request.headers); + + if (!request_headers.has('user-agent')) + copyHeader('user-agent', request_headers, request.headers); + + url.searchParams.delete('__headers'); + + // Make the request to YouTube + const fetchRes = await fetch(url, { + method: request.method, + headers: request_headers, + body: request.body + }); + + // Construct the return headers + const headers = new Headers(); + + // Copy content headers + copyHeader('content-length', headers, fetchRes.headers); + copyHeader('content-type', headers, fetchRes.headers); + copyHeader('content-disposition', headers, fetchRes.headers); + copyHeader('accept-ranges', headers, fetchRes.headers); + copyHeader('content-range', headers, fetchRes.headers); + + // Add cors headers + headers.set( + 'Access-Control-Allow-Origin', + request.headers.get('origin') || '*' + ); + headers.set('Access-Control-Allow-Headers', '*'); + headers.set('Access-Control-Allow-Methods', '*'); + headers.set('Access-Control-Allow-Credentials', 'true'); + + // Return the proxied response + return new Response(fetchRes.body, { + status: fetchRes.status, + headers: headers + }); +}; + +await serve(handler, { port }); diff --git a/examples/browser/web/.gitignore b/examples/browser/web/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/examples/browser/web/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/browser/web/favicon.svg b/examples/browser/web/favicon.svg new file mode 100644 index 0000000..de4aedd --- /dev/null +++ b/examples/browser/web/favicon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/browser/web/index.html b/examples/browser/web/index.html new file mode 100644 index 0000000..d35acde --- /dev/null +++ b/examples/browser/web/index.html @@ -0,0 +1,31 @@ + + + + + + + + + YouTube.js Example + + +
+ + +
+
+
+
+ +
+

+
+
+
+
+ + + + \ No newline at end of file diff --git a/examples/browser/web/package-lock.json b/examples/browser/web/package-lock.json new file mode 100644 index 0000000..c1dde2e --- /dev/null +++ b/examples/browser/web/package-lock.json @@ -0,0 +1,381 @@ +{ + "name": "web", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "web", + "version": "0.0.0", + "dependencies": { + "bgutils-js": "^2.0.1", + "shaka-player": "^4.11.2", + "youtubei.js": "github:LuanRT/YouTube.js#do-not-merge/ump-debugging" + }, + "devDependencies": { + "typescript": "^4.6.4", + "vite": "^3.0.0" + } + }, + "../../..": { + "name": "pot-gen", + "version": "1.0.0", + "extraneous": true, + "license": "MIT", + "dependencies": { + "jsdom": "^24.1.1" + }, + "devDependencies": { + "esbuild": "^0.14.0", + "typescript": "^4.4.4" + } + }, + "../../../../../codeberg/googlevideo": { + "version": "1.0.0", + "extraneous": true, + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "license": "MIT", + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "youtubei.js": "^10.4.0" + }, + "devDependencies": { + "@eslint/js": "^9.9.0", + "@stylistic/eslint-plugin": "^2.6.4", + "eslint": "^9.9.0", + "globals": "^15.9.0", + "ts-proto": "^2.2.0", + "typescript": "^5.5.4", + "typescript-eslint": "^8.2.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/bgutils-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bgutils-js/-/bgutils-js-2.0.1.tgz", + "integrity": "sha512-Cf0eidVlipmnEBJw/T3gjj3C/4s1eKLyNZF8MDzb/5XRCn52rW0WjJlMf9xF6xyn5nqt8wO9BiQIcBymKOJZNQ==", + "funding": [ + "https://github.com/sponsors/LuanRT" + ] + }, + "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", + "integrity": "sha512-z9BKXV4TCYjmar0wiZLObZ0J8HE13VIg7Zq/iyPWdbEfROtxVXEJalknWKtBR5XNezzy15/zWS964TGbcAWlPg==" + }, + "node_modules/esbuild": { + "version": "0.15.18", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.15.18", + "@esbuild/linux-loong64": "0.15.18", + "esbuild-android-64": "0.15.18", + "esbuild-android-arm64": "0.15.18", + "esbuild-darwin-64": "0.15.18", + "esbuild-darwin-arm64": "0.15.18", + "esbuild-freebsd-64": "0.15.18", + "esbuild-freebsd-arm64": "0.15.18", + "esbuild-linux-32": "0.15.18", + "esbuild-linux-64": "0.15.18", + "esbuild-linux-arm": "0.15.18", + "esbuild-linux-arm64": "0.15.18", + "esbuild-linux-mips64le": "0.15.18", + "esbuild-linux-ppc64le": "0.15.18", + "esbuild-linux-riscv64": "0.15.18", + "esbuild-linux-s390x": "0.15.18", + "esbuild-netbsd-64": "0.15.18", + "esbuild-openbsd-64": "0.15.18", + "esbuild-sunos-64": "0.15.18", + "esbuild-windows-32": "0.15.18", + "esbuild-windows-64": "0.15.18", + "esbuild-windows-arm64": "0.15.18" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.18", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jintr": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jintr/-/jintr-2.1.1.tgz", + "integrity": "sha512-89cwX4ouogeDGOBsEVsVYsnWWvWjchmwXBB4kiBhmjOKw19FiOKhNhMhpxhTlK2ctl7DS+d/ethfmuBpzoNNgA==", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "dependencies": { + "acorn": "^8.8.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.33", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.79.1", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/shaka-player": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.11.2.tgz", + "integrity": "sha512-KhmEVHlxPn0XPY8uYd/83OVWCJoMZ6kgvZezPOu/HzTQJIh2DGarYMfWM1d9Mlz8WETP+c81W4GjawLR3strzQ==", + "dependencies": { + "eme-encryption-scheme-polyfill": "^2.1.5" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/typescript": { + "version": "4.9.5", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/vite": { + "version": "3.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.15.9", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/youtubei.js": { + "version": "10.3.0", + "resolved": "git+ssh://git@github.com/LuanRT/YouTube.js.git#f7ed7b2f5a5928543df516fd6eb2363ee033d0ce", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "dependencies": { + "jintr": "^2.1.1", + "tslib": "^2.5.0", + "undici": "^5.19.1" + } + } + } +} diff --git a/examples/browser/web/package.json b/examples/browser/web/package.json new file mode 100644 index 0000000..bd50f9c --- /dev/null +++ b/examples/browser/web/package.json @@ -0,0 +1,20 @@ +{ + "name": "web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "typescript": "^4.6.4", + "vite": "^3.0.0" + }, + "dependencies": { + "bgutils-js": "^2.0.1", + "shaka-player": "^4.11.2", + "youtubei.js": "github:LuanRT/YouTube.js#do-not-merge/ump-debugging" + } +} diff --git a/examples/browser/web/public/service-worker.js b/examples/browser/web/public/service-worker.js new file mode 100644 index 0000000..c594f73 --- /dev/null +++ b/examples/browser/web/public/service-worker.js @@ -0,0 +1,3 @@ +/* eslint-disable */ +var u=new Set(["www.youtube.com","music.youtube.com","suggestqueries.google.com","youtubei.googleapis.com","youtubei.googleapis.com","green-youtubei.sandbox.googleapis.com","release-youtubei.sandbox.googleapis.com","test-youtubei.sandbox.googleapis.com","cami-youtubei.sandbox.googleapis.com","uytfe.sandbox.google.com"]);self.addEventListener("fetch",o=>{try{let s=new URL(o.request.url).hostname;if(!u.has(s))return}catch(s){return}let e=new URL(o.request.url);e.searchParams.set("__host",e.host),e.host=e.searchParams.get("__proxy");let t=new Request(e,o.request);o.respondWith(fetch(t))}); +//# sourceMappingURL=service-worker.js.map diff --git a/examples/browser/web/public/service-worker.js.map b/examples/browser/web/public/service-worker.js.map new file mode 100644 index 0000000..576d753 --- /dev/null +++ b/examples/browser/web/public/service-worker.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../browser/client/service-worker.ts"], + "sourcesContent": ["// We need to proxy requests to youtube to our own server to avoid CORS issues\n\n/// \n\n// export empty type because of tsc --isolatedModules flag\nexport type {};\ndeclare const self: ServiceWorkerGlobalScope;\n\nconst hosts = new Set([\n \"www.youtube.com\",\n \"music.youtube.com\",\n \"suggestqueries.google.com\",\n \"youtubei.googleapis.com\",\n \"youtubei.googleapis.com\",\n \"green-youtubei.sandbox.googleapis.com\",\n \"release-youtubei.sandbox.googleapis.com\",\n \"test-youtubei.sandbox.googleapis.com\",\n \"cami-youtubei.sandbox.googleapis.com\",\n \"uytfe.sandbox.google.com\"\n]);\n\nself.addEventListener('fetch', event => {\n try {\n const host = new URL(event.request.url).hostname;\n if (!hosts.has(host))\n return;\n } catch {\n return;\n }\n const url = new URL(event.request.url);\n url.searchParams.set('__host', url.host);\n url.host = url.searchParams.get('__proxy')!;\n\n // we should proxy this to our own server\n const request = new Request(url, event.request);\n\n event.respondWith(fetch(request));\n});\n"], + "mappings": ";AAQA,GAAM,GAAQ,GAAI,KAAI,CAClB,kBACA,oBACA,4BACA,0BACA,0BACA,wCACA,0CACA,uCACA,uCACA,0BACJ,CAAC,EAED,KAAK,iBAAiB,QAAS,GAAS,CACpC,GAAI,CACA,GAAM,GAAO,GAAI,KAAI,EAAM,QAAQ,GAAG,EAAE,SACxC,GAAI,CAAC,EAAM,IAAI,CAAI,EACf,MACR,OAAQ,EAAN,CACE,MACJ,CACA,GAAM,GAAO,GAAI,KAAI,EAAM,QAAQ,GAAG,EACtC,EAAI,aAAa,IAAI,SAAU,EAAI,IAAI,EACvC,EAAI,KAAO,EAAI,aAAa,IAAI,SAAS,EAGzC,GAAM,GAAU,GAAI,SAAQ,EAAK,EAAM,OAAO,EAE9C,EAAM,YAAY,MAAM,CAAO,CAAC,CACpC,CAAC", + "names": [] +} diff --git a/examples/browser/web/public/vite.svg b/examples/browser/web/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/examples/browser/web/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/browser/web/src/assets/player.css b/examples/browser/web/src/assets/player.css new file mode 100644 index 0000000..ce4a420 --- /dev/null +++ b/examples/browser/web/src/assets/player.css @@ -0,0 +1,423 @@ +@import url(https://fonts.googleapis.com/css?family=Material+Icons+Sharp); + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v27/KFOmCnqEu92Fr1Me5Q.ttf) format('truetype'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v27/KFOlCnqEu92Fr1MmEU9vAw.ttf) format('truetype'); +} + +.shaka-container { + font-family: 'Roboto', sans-serif; +} + +.shaka-container .shaka-bottom-controls { + width: 100%; + padding: 0; + padding-bottom: 0; + z-index: 1; +} + +.shaka-container .shaka-bottom-controls { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +.shaka-container .shaka-ad-controls { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; +} + +.shaka-container .shaka-spinner .shaka-spinner-path { + stroke: #ffffff; +} + +.shaka-container .shaka-scrim-container { + margin: 0; + width: 100%; + height: 100%; + flex-shrink: 1; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + opacity: 0; + transition: opacity cubic-bezier(.4, 0, .6, 1) .6s; + background: linear-gradient(to top, hsla(0, 0%, 0%, 0.61), transparent 15%); +} + +.shaka-container .shaka-play-button { + width: 100px; + height: 100px; + border-radius: 0; + background-color: transparent; + filter: invert(); + box-shadow: none; + -webkit-box-ordinal-group: -3; + -ms-flex-order: -4; + order: -4; +} + +.shaka-container .shaka-small-play-button { + -webkit-box-ordinal-group: -2; + -ms-flex-order: -3; + order: -3; +} + +.shaka-container .shaka-mute-button { + -webkit-box-ordinal-group: -1; + -ms-flex-order: -2; + order: -2; +} + +.shaka-container .shaka-controls-button-panel>* { + margin: 0; + padding: 3px 8px; + color: #EEE; + height: 40px; +} + +.shaka-container .shaka-controls-button-panel>*:hover { + color: #FFF; +} + +.shaka-container .shaka-controls-button-panel .shaka-volume-bar-container { + position: relative; + z-index: 10; + left: -1px; + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + opacity: 0; + width: 0px; + -webkit-transition: width 0.2s cubic-bezier(0.4, 0, 1, 1); + height: 3px; + transition: width 0.2s cubic-bezier(0.4, 0, 1, 1); + padding: 0; +} + +.shaka-container .shaka-controls-button-panel .shaka-volume-bar-container:hover, +.shaka-container .shaka-controls-button-panel .shaka-volume-bar-container:focus { + display: block; + width: 50px; + opacity: 1; + padding: 0 6px; +} + +.shaka-container .shaka-mute-button:hover+div { + opacity: 1; + width: 50px; + padding: 0 6px; +} + +.shaka-container .shaka-current-time { + padding: 0 10px; + font-size: 12px; +} + +.shaka-container .shaka-seek-bar-container { + height: 3px; + position: relative; + top: -1px; + border-radius: 0; + margin-bottom: 0; +} + +.shaka-container .shaka-seek-bar-container .shaka-range-element { + opacity: 0; + transition: opacity 0.2s cubic-bezier(0.4, 0, 1, 1); +} + +.shaka-container .shaka-seek-bar-container:hover { + height: 5px; + top: 0; + cursor: pointer; +} + +.shaka-container .shaka-seek-bar-container:hover .shaka-range-element { + opacity: 1; + cursor: pointer; +} + +.shaka-container .shaka-seek-bar-container input[type=range]::-webkit-slider-thumb { + background: #FF0000; + cursor: pointer; +} + +.shaka-container .shaka-seek-bar-container input[type=range]::-moz-range-thumb { + background: #FF0000; + cursor: pointer; +} + +.shaka-container .shaka-seek-bar-container input[type=range]::-ms-thumb { + background: #FF0000; + cursor: pointer; +} + +.shaka-container .shaka-video-container * { + font-family: 'Roboto', sans-serif; +} + +.shaka-container .shaka-video-container .material-icons-round { + font-family: 'Material Icons Sharp'; +} + +.shaka-container .shaka-overflow-menu, +.shaka-container .shaka-settings-menu { + border-radius: 2px; + background: rgba(37, 37, 37, 0.9); + text-shadow: 0 0 2px rgb(0 0 0%); + -webkit-transition: opacity 0.1s cubic-bezier(0, 0, 0.2, 1); + transition: opacity 0.1s cubic-bezier(0, 0, 0.2, 1); + -moz-user-select: none; + -ms-user-select: none; + animation: fade 0.3s; + -webkit-user-select: none; + right: 10px; + bottom: 50px; + padding: 0; + min-width: 200px; +} + +@keyframes fade { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +.shaka-container .shaka-settings-menu { + padding: 0 0 8px; +} + +.shaka-container .shaka-settings-menu button { + font-size: 12px; +} + +.shaka-container .shaka-settings-menu button span { + margin-left: 33px; + font-size: 13px; +} + +.shaka-container .shaka-settings-menu button[aria-selected="true"] { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} + +.shaka-container .shaka-settings-menu button[aria-selected="true"] span { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + margin-left: 0; +} + +.shaka-container .shaka-settings-menu button[aria-selected="true"] i { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + font-size: 18px; + padding-left: 5px; +} + +.shaka-container .shaka-overflow-menu button { + padding: 0; +} + +.shaka-container .shaka-overflow-menu button i { + display: none; +} + +.shaka-container .shaka-overflow-menu button .shaka-overflow-button-label { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: default; + outline: none; + height: 40px; + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; +} + +.shaka-container .shaka-overflow-menu button .shaka-overflow-button-label span { + -ms-flex-negative: initial; + flex-shrink: initial; + padding-left: 15px; + font-size: 13px; + font-weight: 500; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.shaka-container .shaka-overflow-menu span+span { + color: #FFF; + font-weight: 400 !important; + font-size: 12px !important; + padding-right: 8px; + padding-left: 0 !important; +} + +.shaka-container .shaka-overflow-menu span+span:after { + content: "navigate_next"; + font-family: 'Material Icons Sharp'; + font-size: 20px; +} + +.shaka-container .shaka-overflow-menu .shaka-pip-button span+span { + padding-right: 15px !important; +} + +.shaka-container .shaka-overflow-menu .shaka-pip-button span+span:after { + content: ""; +} + +.shaka-container .shaka-back-to-overflow-button { + padding: 8px 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + font-size: 12px; + color: #eee; + height: 40px; +} + +.shaka-container .shaka-back-to-overflow-button .material-icons-round { + font-size: 15px; + padding-right: 10px; +} + +.shaka-container .shaka-back-to-overflow-button span { + margin-left: 3px !important; +} + +.shaka-container .shaka-overflow-menu button:hover, +.shaka-container .shaka-settings-menu button:hover { + background-color: rgba(255, 255, 255, 0.1); + cursor: pointer; +} + +.shaka-container .shaka-overflow-menu button:hover label, +.shaka-container .shaka-settings-menu button:hover label { + cursor: pointer; +} + +.shaka-container .shaka-overflow-menu button, +.shaka-container .shaka-settings-menu button { + color: #EEE; +} + +.shaka-container .shaka-captions-off { + color: #BFBFBF; +} + +.shaka-container .shaka-overflow-menu-button { + font-size: 18px; + margin-right: 5px; +} + +.shaka-container .shaka-fullscreen-button:hover { + font-size: 25px; + -webkit-transition: font-size 0.1s cubic-bezier(0, 0, 0.2, 1); + transition: font-size 0.1s cubic-bezier(0, 0, 0.2, 1); +} + +.shaka-container .shaka-overflow-menu, +.shaka-container .shaka-settings-menu { + border-radius: 10px; +} + +@media (prefers-color-scheme: light) { + + .shaka-container .shaka-overflow-menu, + .shaka-container .shaka-settings-menu { + background: rgba(255, 255, 255, 0.9); + } + + .shaka-container .shaka-overflow-menu span+span, + .shaka-container .shaka-overflow-menu button, + .shaka-container .shaka-settings-menu button { + color: #000000; + } +} + +@media (min-width: 800px) { + .shaka-container .shaka-controls-button-panel { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + height: 40px; + padding: 0 10px; + } +} + +@media (max-width: 800px) { + .shaka-container .shaka-scrim-container { + background: rgba(0, 0, 0, 0.5); + } + + .shaka-container .shaka-range-container { + margin: 0; + top: 0; + } + + .shaka-container .shaka-mute-button { + display: none; + } + + .shaka-container .shaka-overflow-menu, + .shaka-container .shaka-settings-menu { + bottom: 0; + top: 0; + left: 0; + right: 0; + width: 80%; + margin: 10px; + border-radius: 10px; + } + + .shaka-container .shaka-overflow-menu button, + .shaka-container .shaka-settings-menu button { + width: 100%; + height: 40px; + padding: 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + } + + .shaka-container .shaka-overflow-menu button span, + .shaka-container .shaka-settings-menu button span { + margin-left: 0; + padding-left: 15px; + } +} \ No newline at end of file diff --git a/examples/browser/web/src/assets/style.css b/examples/browser/web/src/assets/style.css new file mode 100644 index 0000000..62f455a --- /dev/null +++ b/examples/browser/web/src/assets/style.css @@ -0,0 +1,135 @@ +body { + display: flex; + flex-direction: column; + align-items: center; + background-color: #202020; + color: rgb(255, 255, 255); + line-height: 1.6; + font-family: Roboto, Arial, sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-tap-highlight-color: transparent; +} + +hr { + width: 100%; + border: 1px solid transparent; + background-color: rgb(68, 68, 68); +} + +form { + margin: 0.5rem 0; + display: none; + border-radius: 0.3rem; + background-color: rgb(68, 68, 68); +} + +form input { + padding: 0.5rem; + border: none; + color: rgb(255, 255, 255); +} + +form input[type="text"] { + background: transparent; +} + +form input[type="text"]:focus { + outline: none; +} + +form input[type="submit"] { + color: rgb(255, 255, 255); + background-color: rgba(0, 0, 0, 0.244); + cursor: pointer; +} + +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +input:-webkit-autofill:active { + -webkit-background-clip: text; + -webkit-text-fill-color: #ffffff; + transition: background-color 5000s ease-in-out 0s; +} + +#loader { + display: block; + border: 10px solid rgb(68, 68, 68); + border-top: 10px solid rgb(255, 255, 255); + border-radius: 50%; + width: 50px; + height: 50px; + align-self: center; + animation: spin 1s linear infinite; + margin: 0.5rem 0; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +#shaka-container { + height: 40vw; +} + +#video-container { + display: none; + flex-direction: column; + position: relative; + width: 70vw !important; + margin: 0.5rem 0; +} + +#metadata { + display: flex; + flex-direction: row; + align-self: left; + margin: 0.5rem 0; +} + +#metadata>#metadata-item { + margin: 0 0.3rem; + background-color: #ffffff; + color: rgba(0, 0, 0, 0.757); + font-weight: 600; + padding: 0.2rem 0.5rem; + border-radius: 0.3rem; +} + +#video-container>#description { + align-self: left; + margin-left: 0.5rem; + font-size: medium; +} + +video { + width: 100%; + height: 100%; +} + +footer { + margin: 0.5rem 0; +} + +@media screen and (max-width: 768px) { + video { + height: auto; + } + + #shaka-container { + height: auto; + } + + #video-container { + width: 100% !important; + } +} \ No newline at end of file diff --git a/examples/browser/web/src/main.ts b/examples/browser/web/src/main.ts new file mode 100644 index 0000000..28a09cb --- /dev/null +++ b/examples/browser/web/src/main.ts @@ -0,0 +1,408 @@ +import { BG } from 'bgutils-js'; +import GoogleVideo, { PART, Protos } from '../../../..'; +import { Innertube, Proto, UniversalCache, Utils, YTNodes } from 'youtubei.js/web'; + +// @ts-expect-error - x +import shaka from 'shaka-player/dist/shaka-player.ui'; + +import 'shaka-player/dist/controls.css'; + +function fetchFn(input: RequestInfo | URL, init?: RequestInit) { + const url = typeof input === 'string' + ? new URL(input) + : input instanceof URL + ? input + : new URL(input.url); + + // Transform the url for use with our proxy. + url.searchParams.set('__host', url.host); + url.host = 'localhost:8080'; + url.protocol = 'http'; + + const headers = init?.headers + ? new Headers(init.headers) + : input instanceof Request + ? input.headers + : new Headers(); + + // Now serialize the headers. + url.searchParams.set('__headers', JSON.stringify([ ...headers ])); + + if (input instanceof Request) { + // @ts-expect-error - x + input.duplex = 'half'; + } + + // Copy over the request. + const request = new Request( + url, + input instanceof Request ? input : undefined + ); + + headers.delete('user-agent'); + + return fetch(request, init ? { + ...init, + headers + } : { + headers + }); +} + +const title = document.getElementById('title') as HTMLHeadingElement; +const description = document.getElementById('description') as HTMLDivElement; +const metadata = document.getElementById('metadata') as HTMLDivElement; +const loader = document.getElementById('loader') as HTMLDivElement; +const form = document.querySelector('form') as HTMLFormElement; + +async function getPo(identifier: string): Promise { + const requestKey = 'O43z0dpjhgX20SCx4KAo'; + + const bgConfig = { + fetch: fetchFn, + globalObj: window, + requestKey, + identifier + }; + + const challenge = await BG.Challenge.create(bgConfig); + + if (!challenge) + throw new Error('Could not get challenge'); + + if (challenge.script) { + const script = challenge.script.find((sc) => sc !== null); + if (script) + new Function(script)(); + } else { + console.warn('Unable to load VM.'); + } + + const poToken = await BG.PoToken.generate({ + program: challenge.challenge, + globalName: challenge.globalName, + bgConfig + }); + + return poToken; +} + +async function main() { + const oauthCreds = undefined; + // Const oauthCreds = { + // Access_token: 'ya29.abcd', + // Refresh_token: '1//0abcd', + // Scope: 'https://www.googleapis.com/auth/youtube-paid-content https://www.googleapis.com/auth/youtube', + // Token_type: 'Bearer', + // Expiry_date: '2024-08-13T04:41:34.757Z' + // }; + + const visitorData = Proto.encodeVisitorData(Utils.generateRandomString(11), Math.floor(Date.now() / 1000)); + const poToken = await getPo(visitorData); + + let yt = await Innertube.create({ + po_token: poToken, + visitor_data: visitorData, + fetch: fetchFn, + generate_session_locally: true, + cache: new UniversalCache(false) + }); + + if (oauthCreds) + await yt.session.signIn(oauthCreds); + + form.animate({ opacity: [ 0, 1 ] }, { duration: 300, easing: 'ease-in-out' }); + form.style.display = 'block'; + + showUI({ hidePlayer: true }); + + let player: shaka.Player | undefined; + let ui: shaka.ui.Overlay | undefined; + + form.addEventListener('submit', async (e) => { + e.preventDefault(); + + if (player) { + player.destroy(); + } + + hideUI(); + + let videoId; + + const videoIdOrURL = document.querySelector('input[type=text]')?.value; + + if (!videoIdOrURL) { + title.textContent = 'No video id or URL provided'; + showUI({ hidePlayer: true }); + return; + } + + try { + if (videoIdOrURL.match(/(http|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])/)) { + const endpoint = await yt.resolveURL(videoIdOrURL); + + if (!endpoint.payload.videoId) { + title.textContent = 'Could not resolve URL'; + showUI({ hidePlayer: true }); + return; + } + + videoId = endpoint.payload.videoId; + } else { + videoId = videoIdOrURL; + } + + if (yt.session.logged_in) { + const user = await yt.account.getInfo(); + const accountItemSections = user.page.contents_memo?.getType(YTNodes.AccountItemSection); + + if (accountItemSections) { + const accountItemSection = accountItemSections.first(); + const accountItem = accountItemSection.contents.first(); + const datasyncIdToken = `${accountItem.endpoint.payload.directSigninIdentity.effectiveObfuscatedGaiaId}||`; + const poToken = await getPo(datasyncIdToken); + + yt = await Innertube.create({ + po_token: poToken, + visitor_data: visitorData, + fetch: fetchFn, + generate_session_locally: true, + cache: new UniversalCache(false) + }); + + await yt.session.signIn(oauthCreds); + } + } + + const info = await yt.getInfo(videoId); + + title.textContent = info.basic_info.title || null; + description.innerHTML = info.secondary_info?.description.toHTML() || ''; + title.textContent = info.basic_info.title || null; + + document.title = info.basic_info.title || ''; + + metadata.innerHTML = ''; + metadata.innerHTML += `
${info.primary_info?.published.toHTML()}
`; + metadata.innerHTML += `
${info.primary_info?.view_count.toHTML()}
`; + metadata.innerHTML += `
${info.basic_info.like_count} likes
`; + + showUI({ hidePlayer: false }); + + const dash = await info.toDash(); + + const uri = `data:application/dash+xml;charset=utf-8;base64,${btoa(dash)}`; + + if (player) { + await player.destroy(); + player = undefined; + } + + if (ui) { + ui.destroy(); + ui = undefined; + } + + const videoEl = document.getElementById('videoel') as HTMLVideoElement; + const shakaContainer = document.getElementById('shaka-container') as HTMLDivElement; + + shakaContainer + .querySelectorAll('div') + .forEach((node) => node.remove()); + + shaka.polyfill.installAll(); + + if (shaka.Player.isBrowserSupported()) { + videoEl.poster = info.basic_info.thumbnail![0].url; + + player = new shaka.Player(); + await player.attach(videoEl); + ui = new shaka.ui.Overlay(player, shakaContainer, videoEl); + + const config = { + seekBarColors: { + base: 'rgba(255,255,255,.2)', + buffered: 'rgba(255,255,255,.4)', + played: 'rgb(255,0,0)' + }, + fadeDelay: 0 + }; + + ui.configure(config); + + const overflowMenuButton = document.querySelector('.shaka-overflow-menu-button'); + if (overflowMenuButton) { + overflowMenuButton.innerHTML = 'settings'; + } + + const backToOverflowButton = document.querySelector('.shaka-back-to-overflow-button .material-icons-round'); + if (backToOverflowButton) { + backToOverflowButton.innerHTML = 'arrow_back_ios_new'; + } + + player.configure({ + streaming: { + bufferingGoal: (info.page[0].player_config?.media_common_config.dynamic_readahead_config.max_read_ahead_media_time_ms || 0) / 1000, + rebufferingGoal: (info.page[0].player_config?.media_common_config.dynamic_readahead_config.read_ahead_growth_rate_ms || 0) / 1000, + bufferBehind: 300, + autoLowLatencyMode: true + }, + abr: { + enabled: true, + restrictions: { + maxBandwidth: Number(info.page[0].player_config?.stream_selection_config.max_bitrate) + } + } + }); + + let rn = 0; + + player.getNetworkingEngine()?.registerRequestFilter((_type: unknown, request: Record) => { + const uri = request.uris[0]; + const url = new URL(uri); + const headers = request.headers; + + if (url.host.endsWith('.googlevideo.com') || headers.Range) { + url.searchParams.set('__host', url.host); + url.host = 'localhost:8080'; + url.protocol = 'http'; + } + + request.method = 'POST'; + request.body = new Uint8Array([ 120, 0 ]); + + if (url.pathname === '/videoplayback') { + if (headers.Range) { + request.headers = {}; + url.searchParams.set('range', headers.Range.split('=')[1]); + url.searchParams.set('ump', '1'); + url.searchParams.set('srfvp', '1'); + url.searchParams.set('rn', rn.toString()); + delete headers.Range; + } + + rn += 1; + } + + request.uris[0] = url.toString(); + }); + + const RequestType = shaka.net.NetworkingEngine.RequestType; + + player.getNetworkingEngine()?.registerResponseFilter(async (type: unknown, response: Record) => { + let mediaData = new Uint8Array(0); + + const handleRedirect = async (redirectData: Protos.SabrRedirect) => { + const redirectRequest = shaka.net.NetworkingEngine.makeRequest([ redirectData.url ], player!.getConfiguration().streaming.retryParameters); + const requestOperation = player!.getNetworkingEngine()!.request(type, redirectRequest); + const redirectResponse = await requestOperation.promise; + + response.data = redirectResponse.data; + response.headers = redirectResponse.headers; + response.uri = redirectResponse.uri; + }; + + const handleMediaData = async (data: Uint8Array) => { + const combinedLength = mediaData.length + data.length; + const tempMediaData = new Uint8Array(combinedLength); + + tempMediaData.set(mediaData); + tempMediaData.set(data, mediaData.length); + + mediaData = tempMediaData; + }; + + if (type == RequestType.SEGMENT) { + const dataBuffer = new GoogleVideo.ChunkedDataBuffer([ new Uint8Array(response.data) ]); + + const googUmp = new GoogleVideo.UMP(dataBuffer); + + let redirect: Protos.SabrRedirect | undefined; + + googUmp.parse((part) => { + try { + const data = part.data.chunks[0]; + switch (part.type) { + case PART.MEDIA_HEADER: { + const mediaHeader = Protos.MediaHeader.decode(data); + console.info('[MediaHeader]:', mediaHeader); + break; + } + case PART.MEDIA: { + handleMediaData(part.data.split(1).remainingBuffer.chunks[0]); + break; + } + case PART.SABR_REDIRECT: { + redirect = Protos.SabrRedirect.decode(data); + console.info('[SabrRedirect]:', redirect); + break; + } + case PART.STREAM_PROTECTION_STATUS: { + const streamProtectionStatus = Protos.StreamProtectionStatus.decode(data); + switch (streamProtectionStatus.status) { + case 1: + console.info('[StreamProtectionStatus]: Good'); + break; + case 2: + console.error('[StreamProtectionStatus]: Attestation pending'); + break; + case 3: + console.error('[StreamProtectionStatus]: Attestation required'); + break; + default: + break; + } + break; + } + } + } catch (error) { + console.error('An error occurred while processing the part:', error); + } + }); + + if (redirect) + return handleRedirect(redirect); + + if (mediaData.length) + response.data = mediaData; + } + }); + + try { + await player.load(uri); + } catch (e) { + console.error('Could not load manifest', e); + } + } else { + console.error('Browser not supported!'); + } + } catch (error) { + title.textContent = 'An error occurred (see console)'; + showUI({ hidePlayer: true }); + console.error(error); + } + }); +} + +function showUI(args: { hidePlayer?: boolean } = { + hidePlayer: true +}) { + const ytplayer = document.getElementById('shaka-container') as HTMLDivElement; + + ytplayer.style.display = args.hidePlayer ? 'none' : 'block'; + + const video_container = document.getElementById('video-container') as HTMLDivElement; + video_container.animate({ opacity: [ 0, 1 ] }, { duration: 300, easing: 'ease-in-out' }); + video_container.style.display = 'block'; + + loader.style.display = 'none'; +} + +function hideUI() { + const video_container = document.getElementById('video-container') as HTMLDivElement; + video_container.style.display = 'none'; + loader.style.display = 'block'; +} + +main(); \ No newline at end of file diff --git a/examples/browser/web/src/vite-env.d.ts b/examples/browser/web/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/examples/browser/web/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/browser/web/tsconfig.json b/examples/browser/web/tsconfig.json new file mode 100644 index 0000000..3cacf7e --- /dev/null +++ b/examples/browser/web/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "moduleResolution": "Node", + "strict": true, + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "noEmit": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "skipLibCheck": true + }, + "include": ["src"] +} diff --git a/examples/downloader/main.ts b/examples/downloader/main.ts new file mode 100644 index 0000000..8d0d5a5 --- /dev/null +++ b/examples/downloader/main.ts @@ -0,0 +1,128 @@ +import type { WriteStream } from 'node:fs'; +import { createWriteStream } from 'node:fs'; +import { Innertube, UniversalCache } from 'youtubei.js'; +import GoogleVideo, { MediaType } from '../../dist/src/index.js'; + +const innertube = await Innertube.create({ cache: new UniversalCache(true) }); + +const determineFileExtension = (mimeType: string) => { + if (mimeType.includes('video')) + return mimeType.includes('webm') ? 'webm' : 'mp4'; + else if (mimeType.includes('audio')) + return mimeType.includes('webm') ? 'webm' : 'm4a'; +}; + +const info = await innertube.getBasicInfo('qQ_-toSu29Q'); + +console.log('\n'); +console.info(`Title: ${info.basic_info.title}`); +console.info(`Duration: ${info.basic_info.duration}`); +console.info(`Views: ${info.basic_info.view_count}`); +console.info(`Author: ${info.basic_info.author}`); +console.info(`Video ID: ${info.basic_info.id}`); + +const sanitizedTitle = info.basic_info.title?.replace(/[^a-z0-9]/gi, '_'); + +let wroteAudioInitSegment = false; +let wroteVideoInitSegment = false; + +let audioOutput: WriteStream | undefined; +let videoOutput: WriteStream | undefined; + +const durationMs = info.basic_info?.duration ? info.basic_info.duration * 1000 : 0; + +const audioFormat = info.chooseFormat({ + quality: 'best', + format: 'webm', + type: 'audio' +}); + +const videoFormat = info.chooseFormat({ + quality: '720p', + format: 'mp4', + type: 'video' +}); + +console.info(`Selected audio format: ${audioFormat.itag} (${audioFormat.audio_quality})`); +console.info(`Selected video format: ${videoFormat.itag} (${videoFormat.quality_label})`); +console.log('\n'); + +const videoPlaybackUstreamerConfig = info.page[0].player_config?.media_common_config.media_ustreamer_request_config?.video_playback_ustreamer_config; + +if (!videoPlaybackUstreamerConfig) + throw new Error('ustreamerConfig not found'); + +const serverAbrStreamingUrl = innertube.session.player?.decipher(info.page[0].streaming_data?.server_abr_streaming_url); + +if (!serverAbrStreamingUrl) + throw new Error('serverAbrStreamingUrl not found'); + +const serverAbrStream = new GoogleVideo.ServerAbrStream({ + fetch: innertube.session.http.fetch_function, + server_abr_streaming_url: serverAbrStreamingUrl, + video_playback_ustreamer_config: videoPlaybackUstreamerConfig, + duration_ms: durationMs +}); + +serverAbrStream.on('data', (data) => { + let progressText = ''; + + for (const initializedFormat of data.initialized_formats) { + const isVideo = initializedFormat.mime_type?.includes('video'); + const mediaFormat = info.streaming_data?.adaptive_formats.find((f) => f.itag === initializedFormat.format_id.itag); + + if (isVideo && initializedFormat.media_data) { + if (!videoOutput) + videoOutput = createWriteStream(`${sanitizedTitle}.${initializedFormat.format_id.itag}.${determineFileExtension(initializedFormat.mime_type || '')}`); + + if (initializedFormat.init_segment && !wroteVideoInitSegment) { + videoOutput.write(initializedFormat.init_segment); + wroteVideoInitSegment = true; + } + + videoOutput.write(initializedFormat.media_data); + } else if (initializedFormat.media_data) { + if (!audioOutput) + audioOutput = createWriteStream(`${sanitizedTitle}.${initializedFormat.format_id.itag}.${determineFileExtension(initializedFormat.mime_type || '')}`); + + if (initializedFormat.init_segment && !wroteAudioInitSegment) { + audioOutput.write(initializedFormat.init_segment); + wroteAudioInitSegment = true; + } + + audioOutput.write(initializedFormat.media_data); + } + + const fmtIdentifier = `${initializedFormat.format_id.itag}_${initializedFormat.mime_type?.split(';')[0]}`; + + const percentage = Math.round((initializedFormat.sequence_list.at(-1)?.start_data_range ?? 0) / (mediaFormat?.content_length ?? 0) * 100); + + if (percentage !== undefined) + progressText += `${fmtIdentifier}: ${percentage}% | `; + } + + process.stdout.clearLine(0); + process.stdout.cursorTo(0); + process.stdout.write(progressText); +}); + +serverAbrStream.on('error', (error) => { + console.error(error); +}); + +await serverAbrStream.init({ + audio_formats: [ audioFormat ], + video_formats: [ videoFormat ], + media_info: { + mediaType: MediaType.MEDIA_TYPE_DEFAULT, + startTimeMs: 0 + } +}); + +process.stdout.write('Done!'); + +if (audioOutput) + audioOutput.end(); + +if (videoOutput) + videoOutput.end(); \ No newline at end of file diff --git a/examples/downloader/package-lock.json b/examples/downloader/package-lock.json new file mode 100644 index 0000000..b6e8ee2 --- /dev/null +++ b/examples/downloader/package-lock.json @@ -0,0 +1,113 @@ +{ + "name": "downloader", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "downloader", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "shaka-player": "^4.11.2", + "youtubei.js": "github:LuanRT/YouTube.js#refactor/update-protos" + }, + "devDependencies": { + "typescript": "^5.6.2" + } + }, + "node_modules/@bufbuild/protobuf": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.0.0.tgz", + "integrity": "sha512-sw2JhwJyvyL0zlhG61aDzOVryEfJg2PDZFSV7i7IdC7nAE41WuXCru3QWLGiP87At0BMzKOoKO/FqEGoKygGZQ==" + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "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", + "integrity": "sha512-z9BKXV4TCYjmar0wiZLObZ0J8HE13VIg7Zq/iyPWdbEfROtxVXEJalknWKtBR5XNezzy15/zWS964TGbcAWlPg==" + }, + "node_modules/jintr": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jintr/-/jintr-2.1.1.tgz", + "integrity": "sha512-89cwX4ouogeDGOBsEVsVYsnWWvWjchmwXBB4kiBhmjOKw19FiOKhNhMhpxhTlK2ctl7DS+d/ethfmuBpzoNNgA==", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "dependencies": { + "acorn": "^8.8.0" + } + }, + "node_modules/shaka-player": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.11.2.tgz", + "integrity": "sha512-KhmEVHlxPn0XPY8uYd/83OVWCJoMZ6kgvZezPOu/HzTQJIh2DGarYMfWM1d9Mlz8WETP+c81W4GjawLR3strzQ==", + "dependencies": { + "eme-encryption-scheme-polyfill": "^2.1.5" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, + "node_modules/typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/youtubei.js": { + "version": "10.4.0", + "resolved": "git+ssh://git@github.com/LuanRT/YouTube.js.git#9bcbdb06b834067886689d25a82f890a96fcf0f7", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "jintr": "^2.1.1", + "tslib": "^2.5.0", + "undici": "^5.19.1" + } + } + } +} diff --git a/examples/downloader/package.json b/examples/downloader/package.json new file mode 100644 index 0000000..22dc89b --- /dev/null +++ b/examples/downloader/package.json @@ -0,0 +1,21 @@ +{ + "name": "downloader", + "version": "1.0.0", + "description": "", + "type": "module", + "module": "main.js", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "shaka-player": "^4.11.2", + "youtubei.js": "github:LuanRT/YouTube.js#refactor/update-protos" + }, + "devDependencies": { + "typescript": "^5.6.2" + } +} diff --git a/examples/downloader/tsconfig.json b/examples/downloader/tsconfig.json new file mode 100644 index 0000000..2068b30 --- /dev/null +++ b/examples/downloader/tsconfig.json @@ -0,0 +1,110 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "NodeNext", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5718ec2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1841 @@ +{ + "name": "googlevideo", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "googlevideo", + "version": "1.0.0", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "license": "MIT", + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "youtubei.js": "^10.4.0" + }, + "devDependencies": { + "@eslint/js": "^9.9.0", + "@stylistic/eslint-plugin": "^2.6.4", + "@types/eslint__js": "^8.42.3", + "eslint": "^9.9.0", + "globals": "^15.9.0", + "ts-proto": "^2.2.0", + "typescript": "^5.5.4", + "typescript-eslint": "^8.2.0" + } + }, + "node_modules/@bufbuild/protobuf": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.0.0.tgz", + "integrity": "sha512-sw2JhwJyvyL0zlhG61aDzOVryEfJg2PDZFSV7i7IdC7nAE41WuXCru3QWLGiP87At0BMzKOoKO/FqEGoKygGZQ==" + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-array/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==", + "dev": true + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/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==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz", + "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==", + "dev": true, + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.8.0.tgz", + "integrity": "sha512-Ufvk7hP+bf+pD35R/QfunF793XlSRIC7USr3/EdgduK9j13i2JjmsM0LUz3/foS+jDYp2fzyWZA9N44CPur0Ow==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^8.4.0", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint__js": { + "version": "8.42.3", + "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", + "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", + "dev": true, + "dependencies": { + "@types/eslint": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.5.0.tgz", + "integrity": "sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.5.0", + "@typescript-eslint/type-utils": "8.5.0", + "@typescript-eslint/utils": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.5.0.tgz", + "integrity": "sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.5.0", + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/typescript-estree": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/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==", + "dev": true + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz", + "integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.5.0.tgz", + "integrity": "sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.5.0", + "@typescript-eslint/utils": "8.5.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/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==", + "dev": true + }, + "node_modules/@typescript-eslint/types": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz", + "integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz", + "integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/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==", + "dev": true + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz", + "integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.5.0", + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/typescript-estree": "8.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz", + "integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.5.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/case-anything": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.13.tgz", + "integrity": "sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==", + "dev": true, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dprint-node": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/dprint-node/-/dprint-node-1.0.8.tgz", + "integrity": "sha512-iVKnUtYfGrYcW1ZAlfR/F59cUVL8QIhWoBJoSjkkdua/dkWIgjZfiLMeTjiB06X0ZLkQ0M2C1VbUj/CxkIf1zg==", + "dev": true, + "dependencies": { + "detect-libc": "^1.0.3" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz", + "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.10.0", + "@eslint/plugin-kit": "^0.1.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/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==", + "dev": true + }, + "node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jintr": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jintr/-/jintr-2.1.1.tgz", + "integrity": "sha512-89cwX4ouogeDGOBsEVsVYsnWWvWjchmwXBB4kiBhmjOKw19FiOKhNhMhpxhTlK2ctl7DS+d/ethfmuBpzoNNgA==", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "dependencies": { + "acorn": "^8.8.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-poet": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.9.0.tgz", + "integrity": "sha512-roe6W6MeZmCjRmppyfOURklO5tQFQ6Sg7swURKkwYJvV7dbGCrK28um5+51iW3twdPRKtwarqFAVMU6G1mvnuQ==", + "dev": true, + "dependencies": { + "dprint-node": "^1.0.8" + } + }, + "node_modules/ts-proto": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-2.2.0.tgz", + "integrity": "sha512-xzmnyrarUjPnY+Py4RyTh3lYmL9w5t/oTtRTo2rKF8laAAahpGZ/ELxkXFEZns5JVbgkYke3C17HN5iNvZOs4g==", + "dev": true, + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "case-anything": "^2.1.13", + "ts-poet": "^6.7.0", + "ts-proto-descriptors": "2.0.0" + }, + "bin": { + "protoc-gen-ts_proto": "protoc-gen-ts_proto" + } + }, + "node_modules/ts-proto-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-2.0.0.tgz", + "integrity": "sha512-wHcTH3xIv11jxgkX5OyCSFfw27agpInAd6yh89hKG6zqIXnjW9SYqSER2CVQxdPj4czeOhGagNvZBEbJPy7qkw==", + "dev": true, + "dependencies": { + "@bufbuild/protobuf": "^2.0.0" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.5.0.tgz", + "integrity": "sha512-uD+XxEoSIvqtm4KE97etm32Tn5MfaZWgWfMMREStLxR6JzvHkc2Tkj7zhTEK5XmtpTmKHNnG8Sot6qDfhHtR1Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.5.0", + "@typescript-eslint/parser": "8.5.0", + "@typescript-eslint/utils": "8.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/youtubei.js": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-10.4.0.tgz", + "integrity": "sha512-FZahkkg5ROyH/FgJ4czy/xDNkqHbJTCUQzumQlnR+2Q7m6HaWghAFWWJUTcexemGuu7t/5EuyQz98eBgKQRMog==", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "dependencies": { + "jintr": "^2.1.1", + "tslib": "^2.5.0", + "undici": "^5.19.1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..adbf1b1 --- /dev/null +++ b/package.json @@ -0,0 +1,58 @@ +{ + "name": "googlevideo", + "version": "1.0.0", + "description": "A set of utilities for working with Google Video APIs.", + "main": "dist/index.js", + "type": "module", + "types": "./dist/src/index.d.ts", + "module": "./dist/src/index.js", + "scripts": { + "lint": "npx eslint ./src/**/*.ts", + "lint:fix": "npx eslint --fix ./src/**/*.ts", + "clean": "npx rimraf ./dist ./bundle ./protos/generated", + "build": "npm run clean && npm run lint && npm run build:proto && npm run build:esm && npm run bundle:node", + "build:esm": "npx tsc", + "build:proto": "node ./dev-scripts/generate-proto.mjs", + "bundle:node": "npx esbuild ./dist/src/index.js --bundle --outfile=./bundle/index.cjs --platform=node --target=node10 --format=cjs --sourcemap --banner:js=\"/* eslint-disable */\"", + "prepare": "npm run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/LuanRT/GoogleVideo.git" + }, + "keywords": [ + "BotGuard", + "PoToken", + "YouTube" + ], + "author": "LuanRT (https://github.com/LuanRT)", + "license": "MIT", + "bugs": { + "url": "https://github.com/LuanRT/GoogleVideo/issues" + }, + "homepage": "https://github.com/LuanRT/GoogleVideo#readme", + "funding": [ + "https://github.com/sponsors/LuanRT" + ], + "devDependencies": { + "@eslint/js": "^9.9.0", + "@stylistic/eslint-plugin": "^2.6.4", + "@types/eslint__js": "^8.42.3", + "eslint": "^9.9.0", + "globals": "^15.9.0", + "ts-proto": "^2.2.0", + "typescript": "^5.5.4", + "typescript-eslint": "^8.2.0" + }, + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js", + "require": "./bundle/index.cjs" + } + }, + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "youtubei.js": "^10.4.0" + } +} diff --git a/protos/generated/misc/common.ts b/protos/generated/misc/common.ts new file mode 100644 index 0000000..e5fadfb --- /dev/null +++ b/protos/generated/misc/common.ts @@ -0,0 +1,457 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: misc/common.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "misc"; + +export interface HttpHeader { + name?: string | undefined; + value?: string | undefined; +} + +export interface FormatId { + itag?: number | undefined; + lastModified?: number | undefined; + xtags?: string | undefined; +} + +export interface InitRange { + start?: number | undefined; + end?: number | undefined; +} + +export interface IndexRange { + start?: number | undefined; + end?: number | undefined; +} + +export interface KeyValuePair { + key?: string | undefined; + value?: string | undefined; +} + +function createBaseHttpHeader(): HttpHeader { + return { name: undefined, value: undefined }; +} + +export const HttpHeader: MessageFns = { + encode(message: HttpHeader, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.name !== undefined) { + writer.uint32(10).string(message.name); + } + if (message.value !== undefined) { + writer.uint32(18).string(message.value); + } + return writer; + }, + + 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 message = createBaseHttpHeader(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.name = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.value = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HttpHeader { + return { + name: isSet(object.name) ? globalThis.String(object.name) : undefined, + value: isSet(object.value) ? globalThis.String(object.value) : undefined, + }; + }, + + toJSON(message: HttpHeader): unknown { + const obj: any = {}; + if (message.name !== undefined) { + obj.name = message.name; + } + if (message.value !== undefined) { + obj.value = message.value; + } + return obj; + }, + + create, I>>(base?: I): HttpHeader { + return HttpHeader.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): HttpHeader { + const message = createBaseHttpHeader(); + message.name = object.name ?? undefined; + message.value = object.value ?? undefined; + return message; + }, +}; + +function createBaseFormatId(): FormatId { + return { itag: undefined, lastModified: undefined, xtags: undefined }; +} + +export const FormatId: MessageFns = { + encode(message: FormatId, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.itag !== undefined) { + writer.uint32(8).int32(message.itag); + } + if (message.lastModified !== undefined) { + writer.uint32(16).uint64(message.lastModified); + } + if (message.xtags !== undefined) { + writer.uint32(26).string(message.xtags); + } + return writer; + }, + + 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 message = createBaseFormatId(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.itag = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.lastModified = longToNumber(reader.uint64()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.xtags = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): FormatId { + return { + itag: isSet(object.itag) ? globalThis.Number(object.itag) : undefined, + lastModified: isSet(object.lastModified) ? globalThis.Number(object.lastModified) : undefined, + xtags: isSet(object.xtags) ? globalThis.String(object.xtags) : undefined, + }; + }, + + toJSON(message: FormatId): unknown { + const obj: any = {}; + if (message.itag !== undefined) { + obj.itag = Math.round(message.itag); + } + if (message.lastModified !== undefined) { + obj.lastModified = Math.round(message.lastModified); + } + if (message.xtags !== undefined) { + obj.xtags = message.xtags; + } + return obj; + }, + + create, I>>(base?: I): FormatId { + return FormatId.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): FormatId { + const message = createBaseFormatId(); + message.itag = object.itag ?? undefined; + message.lastModified = object.lastModified ?? undefined; + message.xtags = object.xtags ?? undefined; + return message; + }, +}; + +function createBaseInitRange(): InitRange { + return { start: undefined, end: undefined }; +} + +export const InitRange: MessageFns = { + encode(message: InitRange, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.start !== undefined) { + writer.uint32(8).int32(message.start); + } + if (message.end !== undefined) { + writer.uint32(16).int32(message.end); + } + return writer; + }, + + 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 message = createBaseInitRange(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.start = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.end = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): InitRange { + return { + start: isSet(object.start) ? globalThis.Number(object.start) : undefined, + end: isSet(object.end) ? globalThis.Number(object.end) : undefined, + }; + }, + + toJSON(message: InitRange): unknown { + const obj: any = {}; + if (message.start !== undefined) { + obj.start = Math.round(message.start); + } + if (message.end !== undefined) { + obj.end = Math.round(message.end); + } + return obj; + }, + + create, I>>(base?: I): InitRange { + return InitRange.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): InitRange { + const message = createBaseInitRange(); + message.start = object.start ?? undefined; + message.end = object.end ?? undefined; + return message; + }, +}; + +function createBaseIndexRange(): IndexRange { + return { start: undefined, end: undefined }; +} + +export const IndexRange: MessageFns = { + encode(message: IndexRange, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.start !== undefined) { + writer.uint32(8).int32(message.start); + } + if (message.end !== undefined) { + writer.uint32(16).int32(message.end); + } + return writer; + }, + + 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 message = createBaseIndexRange(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.start = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.end = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): IndexRange { + return { + start: isSet(object.start) ? globalThis.Number(object.start) : undefined, + end: isSet(object.end) ? globalThis.Number(object.end) : undefined, + }; + }, + + toJSON(message: IndexRange): unknown { + const obj: any = {}; + if (message.start !== undefined) { + obj.start = Math.round(message.start); + } + if (message.end !== undefined) { + obj.end = Math.round(message.end); + } + return obj; + }, + + create, I>>(base?: I): IndexRange { + return IndexRange.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): IndexRange { + const message = createBaseIndexRange(); + message.start = object.start ?? undefined; + message.end = object.end ?? undefined; + return message; + }, +}; + +function createBaseKeyValuePair(): KeyValuePair { + return { key: undefined, value: undefined }; +} + +export const KeyValuePair: MessageFns = { + encode(message: KeyValuePair, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.key !== undefined) { + writer.uint32(10).string(message.key); + } + if (message.value !== undefined) { + writer.uint32(18).string(message.value); + } + return writer; + }, + + 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 message = createBaseKeyValuePair(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.key = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.value = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): KeyValuePair { + return { + key: isSet(object.key) ? globalThis.String(object.key) : undefined, + value: isSet(object.value) ? globalThis.String(object.value) : undefined, + }; + }, + + toJSON(message: KeyValuePair): unknown { + const obj: any = {}; + if (message.key !== undefined) { + obj.key = message.key; + } + if (message.value !== undefined) { + obj.value = message.value; + } + return obj; + }, + + create, I>>(base?: I): KeyValuePair { + return KeyValuePair.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): KeyValuePair { + const message = createBaseKeyValuePair(); + message.key = object.key ?? undefined; + message.value = object.value ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: 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; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/misc/params.ts b/protos/generated/misc/params.ts new file mode 100644 index 0000000..a0b7d22 --- /dev/null +++ b/protos/generated/misc/params.ts @@ -0,0 +1,3340 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: misc/params.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "misc"; + +export interface VisitorData { + id: string; + timestamp: number; +} + +export interface SearchFilter { + sortBy?: SearchFilter_SortBy | undefined; + filters?: SearchFilter_Filters | undefined; +} + +export enum SearchFilter_SortBy { + RELEVANCE = 0, + RATING = 1, + UPLOAD_DATE = 2, + VIEW_COUNT = 3, + UNRECOGNIZED = -1, +} + +export function searchFilter_SortByFromJSON(object: any): SearchFilter_SortBy { + switch (object) { + case 0: + case "RELEVANCE": + return SearchFilter_SortBy.RELEVANCE; + case 1: + case "RATING": + return SearchFilter_SortBy.RATING; + case 2: + case "UPLOAD_DATE": + return SearchFilter_SortBy.UPLOAD_DATE; + case 3: + case "VIEW_COUNT": + return SearchFilter_SortBy.VIEW_COUNT; + case -1: + case "UNRECOGNIZED": + default: + return SearchFilter_SortBy.UNRECOGNIZED; + } +} + +export function searchFilter_SortByToJSON(object: SearchFilter_SortBy): string { + switch (object) { + case SearchFilter_SortBy.RELEVANCE: + return "RELEVANCE"; + case SearchFilter_SortBy.RATING: + return "RATING"; + case SearchFilter_SortBy.UPLOAD_DATE: + return "UPLOAD_DATE"; + case SearchFilter_SortBy.VIEW_COUNT: + return "VIEW_COUNT"; + case SearchFilter_SortBy.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export interface SearchFilter_Filters { + uploadDate?: SearchFilter_Filters_UploadDate | undefined; + type?: SearchFilter_Filters_SearchType | undefined; + duration?: SearchFilter_Filters_Duration | undefined; + musicSearchType?: SearchFilter_Filters_MusicSearchType | undefined; + featuresHd?: boolean | undefined; + featuresSubtitles?: boolean | undefined; + featuresCreativeCommons?: boolean | undefined; + features3d?: boolean | undefined; + featuresLive?: boolean | undefined; + featuresPurchased?: boolean | undefined; + features4k?: boolean | undefined; + features360?: boolean | undefined; + featuresLocation?: boolean | undefined; + featuresHdr?: boolean | undefined; + featuresVr180?: boolean | undefined; +} + +export enum SearchFilter_Filters_UploadDate { + ANY_DATE = 0, + HOUR = 1, + TODAY = 2, + WEEK = 3, + MONTH = 4, + YEAR = 5, + UNRECOGNIZED = -1, +} + +export function searchFilter_Filters_UploadDateFromJSON(object: any): SearchFilter_Filters_UploadDate { + switch (object) { + case 0: + case "ANY_DATE": + return SearchFilter_Filters_UploadDate.ANY_DATE; + case 1: + case "HOUR": + return SearchFilter_Filters_UploadDate.HOUR; + case 2: + case "TODAY": + return SearchFilter_Filters_UploadDate.TODAY; + case 3: + case "WEEK": + return SearchFilter_Filters_UploadDate.WEEK; + case 4: + case "MONTH": + return SearchFilter_Filters_UploadDate.MONTH; + case 5: + case "YEAR": + return SearchFilter_Filters_UploadDate.YEAR; + case -1: + case "UNRECOGNIZED": + default: + return SearchFilter_Filters_UploadDate.UNRECOGNIZED; + } +} + +export function searchFilter_Filters_UploadDateToJSON(object: SearchFilter_Filters_UploadDate): string { + switch (object) { + case SearchFilter_Filters_UploadDate.ANY_DATE: + return "ANY_DATE"; + case SearchFilter_Filters_UploadDate.HOUR: + return "HOUR"; + case SearchFilter_Filters_UploadDate.TODAY: + return "TODAY"; + case SearchFilter_Filters_UploadDate.WEEK: + return "WEEK"; + case SearchFilter_Filters_UploadDate.MONTH: + return "MONTH"; + case SearchFilter_Filters_UploadDate.YEAR: + return "YEAR"; + case SearchFilter_Filters_UploadDate.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export enum SearchFilter_Filters_SearchType { + ANY_TYPE = 0, + VIDEO = 1, + CHANNEL = 2, + PLAYLIST = 3, + MOVIE = 4, + UNRECOGNIZED = -1, +} + +export function searchFilter_Filters_SearchTypeFromJSON(object: any): SearchFilter_Filters_SearchType { + switch (object) { + case 0: + case "ANY_TYPE": + return SearchFilter_Filters_SearchType.ANY_TYPE; + case 1: + case "VIDEO": + return SearchFilter_Filters_SearchType.VIDEO; + case 2: + case "CHANNEL": + return SearchFilter_Filters_SearchType.CHANNEL; + case 3: + case "PLAYLIST": + return SearchFilter_Filters_SearchType.PLAYLIST; + case 4: + case "MOVIE": + return SearchFilter_Filters_SearchType.MOVIE; + case -1: + case "UNRECOGNIZED": + default: + return SearchFilter_Filters_SearchType.UNRECOGNIZED; + } +} + +export function searchFilter_Filters_SearchTypeToJSON(object: SearchFilter_Filters_SearchType): string { + switch (object) { + case SearchFilter_Filters_SearchType.ANY_TYPE: + return "ANY_TYPE"; + case SearchFilter_Filters_SearchType.VIDEO: + return "VIDEO"; + case SearchFilter_Filters_SearchType.CHANNEL: + return "CHANNEL"; + case SearchFilter_Filters_SearchType.PLAYLIST: + return "PLAYLIST"; + case SearchFilter_Filters_SearchType.MOVIE: + return "MOVIE"; + case SearchFilter_Filters_SearchType.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export enum SearchFilter_Filters_Duration { + ANY_DURATION = 0, + SHORT = 1, + LONG = 2, + MEDIUM = 3, + UNRECOGNIZED = -1, +} + +export function searchFilter_Filters_DurationFromJSON(object: any): SearchFilter_Filters_Duration { + switch (object) { + case 0: + case "ANY_DURATION": + return SearchFilter_Filters_Duration.ANY_DURATION; + case 1: + case "SHORT": + return SearchFilter_Filters_Duration.SHORT; + case 2: + case "LONG": + return SearchFilter_Filters_Duration.LONG; + case 3: + case "MEDIUM": + return SearchFilter_Filters_Duration.MEDIUM; + case -1: + case "UNRECOGNIZED": + default: + return SearchFilter_Filters_Duration.UNRECOGNIZED; + } +} + +export function searchFilter_Filters_DurationToJSON(object: SearchFilter_Filters_Duration): string { + switch (object) { + case SearchFilter_Filters_Duration.ANY_DURATION: + return "ANY_DURATION"; + case SearchFilter_Filters_Duration.SHORT: + return "SHORT"; + case SearchFilter_Filters_Duration.LONG: + return "LONG"; + case SearchFilter_Filters_Duration.MEDIUM: + return "MEDIUM"; + case SearchFilter_Filters_Duration.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export interface SearchFilter_Filters_MusicSearchType { + song?: boolean | undefined; + video?: boolean | undefined; + album?: boolean | undefined; + artist?: boolean | undefined; + playlist?: boolean | undefined; +} + +export interface ChannelAnalytics { + params: ChannelAnalytics_Params | undefined; +} + +export interface ChannelAnalytics_Params { + channelId: string; +} + +export interface SoundInfoParams { + sound: SoundInfoParams_Sound | undefined; +} + +export interface SoundInfoParams_Sound { + params: SoundInfoParams_Sound_Params | undefined; +} + +export interface SoundInfoParams_Sound_Params { + ids: SoundInfoParams_Sound_Params_Ids | undefined; +} + +export interface SoundInfoParams_Sound_Params_Ids { + id1: string; + id2: string; + id3: string; +} + +export interface NotificationPreferences { + channelId: string; + prefId: NotificationPreferences_Preference | undefined; + number0?: number | undefined; + number1?: number | undefined; +} + +export interface NotificationPreferences_Preference { + index: number; +} + +export interface LiveMessageParams { + params: LiveMessageParams_Params | undefined; + number0?: number | undefined; + number1?: number | undefined; +} + +export interface LiveMessageParams_Params { + ids: LiveMessageParams_Params_Ids | undefined; +} + +export interface LiveMessageParams_Params_Ids { + channelId: string; + videoId: string; +} + +export interface GetCommentsSectionParams { + ctx: GetCommentsSectionParams_Context | undefined; + unkParam: number; + params: GetCommentsSectionParams_Params | undefined; +} + +export interface GetCommentsSectionParams_Context { + videoId: string; +} + +export interface GetCommentsSectionParams_Params { + unkToken?: string | undefined; + opts?: GetCommentsSectionParams_Params_Options | undefined; + repliesOpts?: GetCommentsSectionParams_Params_RepliesOptions | undefined; + page?: number | undefined; + target: string; +} + +export interface GetCommentsSectionParams_Params_Options { + videoId: string; + sortBy: number; + type: number; + commentId?: string | undefined; +} + +export interface GetCommentsSectionParams_Params_RepliesOptions { + commentId: string; + unkopts: GetCommentsSectionParams_Params_RepliesOptions_UnkOpts | undefined; + channelId?: string | undefined; + videoId: string; + unkParam1: number; + unkParam2: number; +} + +export interface GetCommentsSectionParams_Params_RepliesOptions_UnkOpts { + unkParam: number; +} + +export interface CreateCommentParams { + videoId: string; + params: CreateCommentParams_Params | undefined; + number: number; +} + +export interface CreateCommentParams_Params { + index: number; +} + +export interface PeformCommentActionParams { + type: number; + commentId: string; + videoId: string; + unkNum?: number | undefined; + channelId?: string | undefined; + translateCommentParams?: PeformCommentActionParams_TranslateCommentParams | undefined; +} + +export interface PeformCommentActionParams_TranslateCommentParams { + params: PeformCommentActionParams_TranslateCommentParams_Params | undefined; + commentId: string; + targetLanguage: string; +} + +export interface PeformCommentActionParams_TranslateCommentParams_Params { + comment: PeformCommentActionParams_TranslateCommentParams_Params_Comment | undefined; +} + +export interface PeformCommentActionParams_TranslateCommentParams_Params_Comment { + text: string; +} + +export interface Hashtag { + params: Hashtag_Params | undefined; +} + +export interface Hashtag_Params { + hashtag: string; + type: number; +} + +export interface ReelSequence { + shortId: string; + params: ReelSequence_Params | undefined; + feature2: number; + feature3: number; +} + +export interface ReelSequence_Params { + number: number; +} + +export interface ShortsParam { + f1?: ShortsParam_Field1 | undefined; + p59?: number | undefined; +} + +export interface ShortsParam_Field1 { + p1?: number | undefined; +} + +function createBaseVisitorData(): VisitorData { + return { id: "", timestamp: 0 }; +} + +export const VisitorData: MessageFns = { + encode(message: VisitorData, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.timestamp !== 0) { + writer.uint32(40).int32(message.timestamp); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VisitorData { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVisitorData(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.timestamp = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VisitorData { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + timestamp: isSet(object.timestamp) ? globalThis.Number(object.timestamp) : 0, + }; + }, + + toJSON(message: VisitorData): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.timestamp !== 0) { + obj.timestamp = Math.round(message.timestamp); + } + return obj; + }, + + create, I>>(base?: I): VisitorData { + return VisitorData.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): VisitorData { + const message = createBaseVisitorData(); + message.id = object.id ?? ""; + message.timestamp = object.timestamp ?? 0; + return message; + }, +}; + +function createBaseSearchFilter(): SearchFilter { + return { sortBy: undefined, filters: undefined }; +} + +export const SearchFilter: MessageFns = { + encode(message: SearchFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.sortBy !== undefined) { + writer.uint32(8).int32(message.sortBy); + } + if (message.filters !== undefined) { + SearchFilter_Filters.encode(message.filters, writer.uint32(18).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SearchFilter { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSearchFilter(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.sortBy = reader.int32() as any; + continue; + case 2: + if (tag !== 18) { + break; + } + + message.filters = SearchFilter_Filters.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SearchFilter { + return { + sortBy: isSet(object.sortBy) ? searchFilter_SortByFromJSON(object.sortBy) : undefined, + filters: isSet(object.filters) ? SearchFilter_Filters.fromJSON(object.filters) : undefined, + }; + }, + + toJSON(message: SearchFilter): unknown { + const obj: any = {}; + if (message.sortBy !== undefined) { + obj.sortBy = searchFilter_SortByToJSON(message.sortBy); + } + if (message.filters !== undefined) { + obj.filters = SearchFilter_Filters.toJSON(message.filters); + } + return obj; + }, + + create, I>>(base?: I): SearchFilter { + return SearchFilter.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SearchFilter { + const message = createBaseSearchFilter(); + message.sortBy = object.sortBy ?? undefined; + message.filters = (object.filters !== undefined && object.filters !== null) + ? SearchFilter_Filters.fromPartial(object.filters) + : undefined; + return message; + }, +}; + +function createBaseSearchFilter_Filters(): SearchFilter_Filters { + return { + uploadDate: undefined, + type: undefined, + duration: undefined, + musicSearchType: undefined, + featuresHd: undefined, + featuresSubtitles: undefined, + featuresCreativeCommons: undefined, + features3d: undefined, + featuresLive: undefined, + featuresPurchased: undefined, + features4k: undefined, + features360: undefined, + featuresLocation: undefined, + featuresHdr: undefined, + featuresVr180: undefined, + }; +} + +export const SearchFilter_Filters: MessageFns = { + encode(message: SearchFilter_Filters, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.uploadDate !== undefined) { + writer.uint32(8).int32(message.uploadDate); + } + if (message.type !== undefined) { + writer.uint32(16).int32(message.type); + } + if (message.duration !== undefined) { + writer.uint32(24).int32(message.duration); + } + if (message.musicSearchType !== undefined) { + SearchFilter_Filters_MusicSearchType.encode(message.musicSearchType, writer.uint32(138).fork()).join(); + } + if (message.featuresHd !== undefined) { + writer.uint32(32).bool(message.featuresHd); + } + if (message.featuresSubtitles !== undefined) { + writer.uint32(40).bool(message.featuresSubtitles); + } + if (message.featuresCreativeCommons !== undefined) { + writer.uint32(48).bool(message.featuresCreativeCommons); + } + if (message.features3d !== undefined) { + writer.uint32(56).bool(message.features3d); + } + if (message.featuresLive !== undefined) { + writer.uint32(64).bool(message.featuresLive); + } + if (message.featuresPurchased !== undefined) { + writer.uint32(72).bool(message.featuresPurchased); + } + if (message.features4k !== undefined) { + writer.uint32(112).bool(message.features4k); + } + if (message.features360 !== undefined) { + writer.uint32(120).bool(message.features360); + } + if (message.featuresLocation !== undefined) { + writer.uint32(184).bool(message.featuresLocation); + } + if (message.featuresHdr !== undefined) { + writer.uint32(200).bool(message.featuresHdr); + } + if (message.featuresVr180 !== undefined) { + writer.uint32(208).bool(message.featuresVr180); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SearchFilter_Filters { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSearchFilter_Filters(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.uploadDate = reader.int32() as any; + continue; + case 2: + if (tag !== 16) { + break; + } + + message.type = reader.int32() as any; + continue; + case 3: + if (tag !== 24) { + break; + } + + message.duration = reader.int32() as any; + continue; + case 17: + if (tag !== 138) { + break; + } + + message.musicSearchType = SearchFilter_Filters_MusicSearchType.decode(reader, reader.uint32()); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.featuresHd = reader.bool(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.featuresSubtitles = reader.bool(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.featuresCreativeCommons = reader.bool(); + continue; + case 7: + if (tag !== 56) { + break; + } + + message.features3d = reader.bool(); + continue; + case 8: + if (tag !== 64) { + break; + } + + message.featuresLive = reader.bool(); + continue; + case 9: + if (tag !== 72) { + break; + } + + message.featuresPurchased = reader.bool(); + continue; + case 14: + if (tag !== 112) { + break; + } + + message.features4k = reader.bool(); + continue; + case 15: + if (tag !== 120) { + break; + } + + message.features360 = reader.bool(); + continue; + case 23: + if (tag !== 184) { + break; + } + + message.featuresLocation = reader.bool(); + continue; + case 25: + if (tag !== 200) { + break; + } + + message.featuresHdr = reader.bool(); + continue; + case 26: + if (tag !== 208) { + break; + } + + message.featuresVr180 = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SearchFilter_Filters { + return { + uploadDate: isSet(object.uploadDate) ? searchFilter_Filters_UploadDateFromJSON(object.uploadDate) : undefined, + type: isSet(object.type) ? searchFilter_Filters_SearchTypeFromJSON(object.type) : undefined, + duration: isSet(object.duration) ? searchFilter_Filters_DurationFromJSON(object.duration) : undefined, + musicSearchType: isSet(object.musicSearchType) + ? SearchFilter_Filters_MusicSearchType.fromJSON(object.musicSearchType) + : undefined, + featuresHd: isSet(object.featuresHd) ? globalThis.Boolean(object.featuresHd) : undefined, + featuresSubtitles: isSet(object.featuresSubtitles) ? globalThis.Boolean(object.featuresSubtitles) : undefined, + featuresCreativeCommons: isSet(object.featuresCreativeCommons) + ? globalThis.Boolean(object.featuresCreativeCommons) + : undefined, + features3d: isSet(object.features3d) ? globalThis.Boolean(object.features3d) : undefined, + featuresLive: isSet(object.featuresLive) ? globalThis.Boolean(object.featuresLive) : undefined, + featuresPurchased: isSet(object.featuresPurchased) ? globalThis.Boolean(object.featuresPurchased) : undefined, + features4k: isSet(object.features4k) ? globalThis.Boolean(object.features4k) : undefined, + features360: isSet(object.features360) ? globalThis.Boolean(object.features360) : undefined, + featuresLocation: isSet(object.featuresLocation) ? globalThis.Boolean(object.featuresLocation) : undefined, + featuresHdr: isSet(object.featuresHdr) ? globalThis.Boolean(object.featuresHdr) : undefined, + featuresVr180: isSet(object.featuresVr180) ? globalThis.Boolean(object.featuresVr180) : undefined, + }; + }, + + toJSON(message: SearchFilter_Filters): unknown { + const obj: any = {}; + if (message.uploadDate !== undefined) { + obj.uploadDate = searchFilter_Filters_UploadDateToJSON(message.uploadDate); + } + if (message.type !== undefined) { + obj.type = searchFilter_Filters_SearchTypeToJSON(message.type); + } + if (message.duration !== undefined) { + obj.duration = searchFilter_Filters_DurationToJSON(message.duration); + } + if (message.musicSearchType !== undefined) { + obj.musicSearchType = SearchFilter_Filters_MusicSearchType.toJSON(message.musicSearchType); + } + if (message.featuresHd !== undefined) { + obj.featuresHd = message.featuresHd; + } + if (message.featuresSubtitles !== undefined) { + obj.featuresSubtitles = message.featuresSubtitles; + } + if (message.featuresCreativeCommons !== undefined) { + obj.featuresCreativeCommons = message.featuresCreativeCommons; + } + if (message.features3d !== undefined) { + obj.features3d = message.features3d; + } + if (message.featuresLive !== undefined) { + obj.featuresLive = message.featuresLive; + } + if (message.featuresPurchased !== undefined) { + obj.featuresPurchased = message.featuresPurchased; + } + if (message.features4k !== undefined) { + obj.features4k = message.features4k; + } + if (message.features360 !== undefined) { + obj.features360 = message.features360; + } + if (message.featuresLocation !== undefined) { + obj.featuresLocation = message.featuresLocation; + } + if (message.featuresHdr !== undefined) { + obj.featuresHdr = message.featuresHdr; + } + if (message.featuresVr180 !== undefined) { + obj.featuresVr180 = message.featuresVr180; + } + return obj; + }, + + create, I>>(base?: I): SearchFilter_Filters { + return SearchFilter_Filters.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SearchFilter_Filters { + const message = createBaseSearchFilter_Filters(); + message.uploadDate = object.uploadDate ?? undefined; + message.type = object.type ?? undefined; + message.duration = object.duration ?? undefined; + message.musicSearchType = (object.musicSearchType !== undefined && object.musicSearchType !== null) + ? SearchFilter_Filters_MusicSearchType.fromPartial(object.musicSearchType) + : undefined; + message.featuresHd = object.featuresHd ?? undefined; + message.featuresSubtitles = object.featuresSubtitles ?? undefined; + message.featuresCreativeCommons = object.featuresCreativeCommons ?? undefined; + message.features3d = object.features3d ?? undefined; + message.featuresLive = object.featuresLive ?? undefined; + message.featuresPurchased = object.featuresPurchased ?? undefined; + message.features4k = object.features4k ?? undefined; + message.features360 = object.features360 ?? undefined; + message.featuresLocation = object.featuresLocation ?? undefined; + message.featuresHdr = object.featuresHdr ?? undefined; + message.featuresVr180 = object.featuresVr180 ?? undefined; + return message; + }, +}; + +function createBaseSearchFilter_Filters_MusicSearchType(): SearchFilter_Filters_MusicSearchType { + return { song: undefined, video: undefined, album: undefined, artist: undefined, playlist: undefined }; +} + +export const SearchFilter_Filters_MusicSearchType: MessageFns = { + encode(message: SearchFilter_Filters_MusicSearchType, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.song !== undefined) { + writer.uint32(8).bool(message.song); + } + if (message.video !== undefined) { + writer.uint32(16).bool(message.video); + } + if (message.album !== undefined) { + writer.uint32(24).bool(message.album); + } + if (message.artist !== undefined) { + writer.uint32(32).bool(message.artist); + } + if (message.playlist !== undefined) { + writer.uint32(40).bool(message.playlist); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SearchFilter_Filters_MusicSearchType { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSearchFilter_Filters_MusicSearchType(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.song = reader.bool(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.video = reader.bool(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.album = reader.bool(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.artist = reader.bool(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.playlist = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SearchFilter_Filters_MusicSearchType { + return { + song: isSet(object.song) ? globalThis.Boolean(object.song) : undefined, + video: isSet(object.video) ? globalThis.Boolean(object.video) : undefined, + album: isSet(object.album) ? globalThis.Boolean(object.album) : undefined, + artist: isSet(object.artist) ? globalThis.Boolean(object.artist) : undefined, + playlist: isSet(object.playlist) ? globalThis.Boolean(object.playlist) : undefined, + }; + }, + + toJSON(message: SearchFilter_Filters_MusicSearchType): unknown { + const obj: any = {}; + if (message.song !== undefined) { + obj.song = message.song; + } + if (message.video !== undefined) { + obj.video = message.video; + } + if (message.album !== undefined) { + obj.album = message.album; + } + if (message.artist !== undefined) { + obj.artist = message.artist; + } + if (message.playlist !== undefined) { + obj.playlist = message.playlist; + } + return obj; + }, + + create, I>>( + base?: I, + ): SearchFilter_Filters_MusicSearchType { + return SearchFilter_Filters_MusicSearchType.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): SearchFilter_Filters_MusicSearchType { + const message = createBaseSearchFilter_Filters_MusicSearchType(); + message.song = object.song ?? undefined; + message.video = object.video ?? undefined; + message.album = object.album ?? undefined; + message.artist = object.artist ?? undefined; + message.playlist = object.playlist ?? undefined; + return message; + }, +}; + +function createBaseChannelAnalytics(): ChannelAnalytics { + return { params: undefined }; +} + +export const ChannelAnalytics: MessageFns = { + encode(message: ChannelAnalytics, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.params !== undefined) { + ChannelAnalytics_Params.encode(message.params, writer.uint32(258).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ChannelAnalytics { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseChannelAnalytics(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 32: + if (tag !== 258) { + break; + } + + message.params = ChannelAnalytics_Params.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ChannelAnalytics { + return { params: isSet(object.params) ? ChannelAnalytics_Params.fromJSON(object.params) : undefined }; + }, + + toJSON(message: ChannelAnalytics): unknown { + const obj: any = {}; + if (message.params !== undefined) { + obj.params = ChannelAnalytics_Params.toJSON(message.params); + } + return obj; + }, + + create, I>>(base?: I): ChannelAnalytics { + return ChannelAnalytics.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ChannelAnalytics { + const message = createBaseChannelAnalytics(); + message.params = (object.params !== undefined && object.params !== null) + ? ChannelAnalytics_Params.fromPartial(object.params) + : undefined; + return message; + }, +}; + +function createBaseChannelAnalytics_Params(): ChannelAnalytics_Params { + return { channelId: "" }; +} + +export const ChannelAnalytics_Params: MessageFns = { + encode(message: ChannelAnalytics_Params, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.channelId !== "") { + writer.uint32(8010).string(message.channelId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ChannelAnalytics_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseChannelAnalytics_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1001: + if (tag !== 8010) { + break; + } + + message.channelId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ChannelAnalytics_Params { + return { channelId: isSet(object.channelId) ? globalThis.String(object.channelId) : "" }; + }, + + toJSON(message: ChannelAnalytics_Params): unknown { + const obj: any = {}; + if (message.channelId !== "") { + obj.channelId = message.channelId; + } + return obj; + }, + + create, I>>(base?: I): ChannelAnalytics_Params { + return ChannelAnalytics_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ChannelAnalytics_Params { + const message = createBaseChannelAnalytics_Params(); + message.channelId = object.channelId ?? ""; + return message; + }, +}; + +function createBaseSoundInfoParams(): SoundInfoParams { + return { sound: undefined }; +} + +export const SoundInfoParams: MessageFns = { + encode(message: SoundInfoParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.sound !== undefined) { + SoundInfoParams_Sound.encode(message.sound, writer.uint32(754).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SoundInfoParams { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSoundInfoParams(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 94: + if (tag !== 754) { + break; + } + + message.sound = SoundInfoParams_Sound.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SoundInfoParams { + return { sound: isSet(object.sound) ? SoundInfoParams_Sound.fromJSON(object.sound) : undefined }; + }, + + toJSON(message: SoundInfoParams): unknown { + const obj: any = {}; + if (message.sound !== undefined) { + obj.sound = SoundInfoParams_Sound.toJSON(message.sound); + } + return obj; + }, + + create, I>>(base?: I): SoundInfoParams { + return SoundInfoParams.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SoundInfoParams { + const message = createBaseSoundInfoParams(); + message.sound = (object.sound !== undefined && object.sound !== null) + ? SoundInfoParams_Sound.fromPartial(object.sound) + : undefined; + return message; + }, +}; + +function createBaseSoundInfoParams_Sound(): SoundInfoParams_Sound { + return { params: undefined }; +} + +export const SoundInfoParams_Sound: MessageFns = { + encode(message: SoundInfoParams_Sound, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.params !== undefined) { + SoundInfoParams_Sound_Params.encode(message.params, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SoundInfoParams_Sound { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSoundInfoParams_Sound(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.params = SoundInfoParams_Sound_Params.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SoundInfoParams_Sound { + return { params: isSet(object.params) ? SoundInfoParams_Sound_Params.fromJSON(object.params) : undefined }; + }, + + toJSON(message: SoundInfoParams_Sound): unknown { + const obj: any = {}; + if (message.params !== undefined) { + obj.params = SoundInfoParams_Sound_Params.toJSON(message.params); + } + return obj; + }, + + create, I>>(base?: I): SoundInfoParams_Sound { + return SoundInfoParams_Sound.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SoundInfoParams_Sound { + const message = createBaseSoundInfoParams_Sound(); + message.params = (object.params !== undefined && object.params !== null) + ? SoundInfoParams_Sound_Params.fromPartial(object.params) + : undefined; + return message; + }, +}; + +function createBaseSoundInfoParams_Sound_Params(): SoundInfoParams_Sound_Params { + return { ids: undefined }; +} + +export const SoundInfoParams_Sound_Params: MessageFns = { + encode(message: SoundInfoParams_Sound_Params, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.ids !== undefined) { + SoundInfoParams_Sound_Params_Ids.encode(message.ids, writer.uint32(18).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SoundInfoParams_Sound_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSoundInfoParams_Sound_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + if (tag !== 18) { + break; + } + + message.ids = SoundInfoParams_Sound_Params_Ids.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SoundInfoParams_Sound_Params { + return { ids: isSet(object.ids) ? SoundInfoParams_Sound_Params_Ids.fromJSON(object.ids) : undefined }; + }, + + toJSON(message: SoundInfoParams_Sound_Params): unknown { + const obj: any = {}; + if (message.ids !== undefined) { + obj.ids = SoundInfoParams_Sound_Params_Ids.toJSON(message.ids); + } + return obj; + }, + + create, I>>(base?: I): SoundInfoParams_Sound_Params { + return SoundInfoParams_Sound_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SoundInfoParams_Sound_Params { + const message = createBaseSoundInfoParams_Sound_Params(); + message.ids = (object.ids !== undefined && object.ids !== null) + ? SoundInfoParams_Sound_Params_Ids.fromPartial(object.ids) + : undefined; + return message; + }, +}; + +function createBaseSoundInfoParams_Sound_Params_Ids(): SoundInfoParams_Sound_Params_Ids { + return { id1: "", id2: "", id3: "" }; +} + +export const SoundInfoParams_Sound_Params_Ids: MessageFns = { + encode(message: SoundInfoParams_Sound_Params_Ids, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id1 !== "") { + writer.uint32(10).string(message.id1); + } + if (message.id2 !== "") { + writer.uint32(18).string(message.id2); + } + if (message.id3 !== "") { + writer.uint32(26).string(message.id3); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SoundInfoParams_Sound_Params_Ids { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSoundInfoParams_Sound_Params_Ids(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.id1 = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.id2 = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.id3 = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SoundInfoParams_Sound_Params_Ids { + return { + id1: isSet(object.id1) ? globalThis.String(object.id1) : "", + id2: isSet(object.id2) ? globalThis.String(object.id2) : "", + id3: isSet(object.id3) ? globalThis.String(object.id3) : "", + }; + }, + + toJSON(message: SoundInfoParams_Sound_Params_Ids): unknown { + const obj: any = {}; + if (message.id1 !== "") { + obj.id1 = message.id1; + } + if (message.id2 !== "") { + obj.id2 = message.id2; + } + if (message.id3 !== "") { + obj.id3 = message.id3; + } + return obj; + }, + + create, I>>( + base?: I, + ): SoundInfoParams_Sound_Params_Ids { + return SoundInfoParams_Sound_Params_Ids.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): SoundInfoParams_Sound_Params_Ids { + const message = createBaseSoundInfoParams_Sound_Params_Ids(); + message.id1 = object.id1 ?? ""; + message.id2 = object.id2 ?? ""; + message.id3 = object.id3 ?? ""; + return message; + }, +}; + +function createBaseNotificationPreferences(): NotificationPreferences { + return { channelId: "", prefId: undefined, number0: undefined, number1: undefined }; +} + +export const NotificationPreferences: MessageFns = { + encode(message: NotificationPreferences, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.channelId !== "") { + writer.uint32(10).string(message.channelId); + } + if (message.prefId !== undefined) { + NotificationPreferences_Preference.encode(message.prefId, writer.uint32(18).fork()).join(); + } + if (message.number0 !== undefined) { + writer.uint32(24).int32(message.number0); + } + if (message.number1 !== undefined) { + writer.uint32(32).int32(message.number1); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): NotificationPreferences { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNotificationPreferences(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.channelId = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.prefId = NotificationPreferences_Preference.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.number0 = reader.int32(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.number1 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): NotificationPreferences { + return { + channelId: isSet(object.channelId) ? globalThis.String(object.channelId) : "", + prefId: isSet(object.prefId) ? NotificationPreferences_Preference.fromJSON(object.prefId) : undefined, + number0: isSet(object.number0) ? globalThis.Number(object.number0) : undefined, + number1: isSet(object.number1) ? globalThis.Number(object.number1) : undefined, + }; + }, + + toJSON(message: NotificationPreferences): unknown { + const obj: any = {}; + if (message.channelId !== "") { + obj.channelId = message.channelId; + } + if (message.prefId !== undefined) { + obj.prefId = NotificationPreferences_Preference.toJSON(message.prefId); + } + if (message.number0 !== undefined) { + obj.number0 = Math.round(message.number0); + } + if (message.number1 !== undefined) { + obj.number1 = Math.round(message.number1); + } + return obj; + }, + + create, I>>(base?: I): NotificationPreferences { + return NotificationPreferences.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): NotificationPreferences { + const message = createBaseNotificationPreferences(); + message.channelId = object.channelId ?? ""; + message.prefId = (object.prefId !== undefined && object.prefId !== null) + ? NotificationPreferences_Preference.fromPartial(object.prefId) + : undefined; + message.number0 = object.number0 ?? undefined; + message.number1 = object.number1 ?? undefined; + return message; + }, +}; + +function createBaseNotificationPreferences_Preference(): NotificationPreferences_Preference { + return { index: 0 }; +} + +export const NotificationPreferences_Preference: MessageFns = { + encode(message: NotificationPreferences_Preference, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.index !== 0) { + writer.uint32(8).int32(message.index); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): NotificationPreferences_Preference { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNotificationPreferences_Preference(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.index = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): NotificationPreferences_Preference { + return { index: isSet(object.index) ? globalThis.Number(object.index) : 0 }; + }, + + toJSON(message: NotificationPreferences_Preference): unknown { + const obj: any = {}; + if (message.index !== 0) { + obj.index = Math.round(message.index); + } + return obj; + }, + + create, I>>( + base?: I, + ): NotificationPreferences_Preference { + return NotificationPreferences_Preference.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): NotificationPreferences_Preference { + const message = createBaseNotificationPreferences_Preference(); + message.index = object.index ?? 0; + return message; + }, +}; + +function createBaseLiveMessageParams(): LiveMessageParams { + return { params: undefined, number0: undefined, number1: undefined }; +} + +export const LiveMessageParams: MessageFns = { + encode(message: LiveMessageParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.params !== undefined) { + LiveMessageParams_Params.encode(message.params, writer.uint32(10).fork()).join(); + } + if (message.number0 !== undefined) { + writer.uint32(16).int32(message.number0); + } + if (message.number1 !== undefined) { + writer.uint32(24).int32(message.number1); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LiveMessageParams { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLiveMessageParams(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.params = LiveMessageParams_Params.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.number0 = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.number1 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LiveMessageParams { + return { + params: isSet(object.params) ? LiveMessageParams_Params.fromJSON(object.params) : undefined, + number0: isSet(object.number0) ? globalThis.Number(object.number0) : undefined, + number1: isSet(object.number1) ? globalThis.Number(object.number1) : undefined, + }; + }, + + toJSON(message: LiveMessageParams): unknown { + const obj: any = {}; + if (message.params !== undefined) { + obj.params = LiveMessageParams_Params.toJSON(message.params); + } + if (message.number0 !== undefined) { + obj.number0 = Math.round(message.number0); + } + if (message.number1 !== undefined) { + obj.number1 = Math.round(message.number1); + } + return obj; + }, + + create, I>>(base?: I): LiveMessageParams { + return LiveMessageParams.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): LiveMessageParams { + const message = createBaseLiveMessageParams(); + message.params = (object.params !== undefined && object.params !== null) + ? LiveMessageParams_Params.fromPartial(object.params) + : undefined; + message.number0 = object.number0 ?? undefined; + message.number1 = object.number1 ?? undefined; + return message; + }, +}; + +function createBaseLiveMessageParams_Params(): LiveMessageParams_Params { + return { ids: undefined }; +} + +export const LiveMessageParams_Params: MessageFns = { + encode(message: LiveMessageParams_Params, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.ids !== undefined) { + LiveMessageParams_Params_Ids.encode(message.ids, writer.uint32(42).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LiveMessageParams_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLiveMessageParams_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 5: + if (tag !== 42) { + break; + } + + message.ids = LiveMessageParams_Params_Ids.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LiveMessageParams_Params { + return { ids: isSet(object.ids) ? LiveMessageParams_Params_Ids.fromJSON(object.ids) : undefined }; + }, + + toJSON(message: LiveMessageParams_Params): unknown { + const obj: any = {}; + if (message.ids !== undefined) { + obj.ids = LiveMessageParams_Params_Ids.toJSON(message.ids); + } + return obj; + }, + + create, I>>(base?: I): LiveMessageParams_Params { + return LiveMessageParams_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): LiveMessageParams_Params { + const message = createBaseLiveMessageParams_Params(); + message.ids = (object.ids !== undefined && object.ids !== null) + ? LiveMessageParams_Params_Ids.fromPartial(object.ids) + : undefined; + return message; + }, +}; + +function createBaseLiveMessageParams_Params_Ids(): LiveMessageParams_Params_Ids { + return { channelId: "", videoId: "" }; +} + +export const LiveMessageParams_Params_Ids: MessageFns = { + encode(message: LiveMessageParams_Params_Ids, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.channelId !== "") { + writer.uint32(10).string(message.channelId); + } + if (message.videoId !== "") { + writer.uint32(18).string(message.videoId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LiveMessageParams_Params_Ids { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLiveMessageParams_Params_Ids(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.channelId = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.videoId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LiveMessageParams_Params_Ids { + return { + channelId: isSet(object.channelId) ? globalThis.String(object.channelId) : "", + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : "", + }; + }, + + toJSON(message: LiveMessageParams_Params_Ids): unknown { + const obj: any = {}; + if (message.channelId !== "") { + obj.channelId = message.channelId; + } + if (message.videoId !== "") { + obj.videoId = message.videoId; + } + return obj; + }, + + create, I>>(base?: I): LiveMessageParams_Params_Ids { + return LiveMessageParams_Params_Ids.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): LiveMessageParams_Params_Ids { + const message = createBaseLiveMessageParams_Params_Ids(); + message.channelId = object.channelId ?? ""; + message.videoId = object.videoId ?? ""; + return message; + }, +}; + +function createBaseGetCommentsSectionParams(): GetCommentsSectionParams { + return { ctx: undefined, unkParam: 0, params: undefined }; +} + +export const GetCommentsSectionParams: MessageFns = { + encode(message: GetCommentsSectionParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.ctx !== undefined) { + GetCommentsSectionParams_Context.encode(message.ctx, writer.uint32(18).fork()).join(); + } + if (message.unkParam !== 0) { + writer.uint32(24).int32(message.unkParam); + } + if (message.params !== undefined) { + GetCommentsSectionParams_Params.encode(message.params, writer.uint32(50).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetCommentsSectionParams { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetCommentsSectionParams(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + if (tag !== 18) { + break; + } + + message.ctx = GetCommentsSectionParams_Context.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.unkParam = reader.int32(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.params = GetCommentsSectionParams_Params.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetCommentsSectionParams { + return { + ctx: isSet(object.ctx) ? GetCommentsSectionParams_Context.fromJSON(object.ctx) : undefined, + unkParam: isSet(object.unkParam) ? globalThis.Number(object.unkParam) : 0, + params: isSet(object.params) ? GetCommentsSectionParams_Params.fromJSON(object.params) : undefined, + }; + }, + + toJSON(message: GetCommentsSectionParams): unknown { + const obj: any = {}; + if (message.ctx !== undefined) { + obj.ctx = GetCommentsSectionParams_Context.toJSON(message.ctx); + } + if (message.unkParam !== 0) { + obj.unkParam = Math.round(message.unkParam); + } + if (message.params !== undefined) { + obj.params = GetCommentsSectionParams_Params.toJSON(message.params); + } + return obj; + }, + + create, I>>(base?: I): GetCommentsSectionParams { + return GetCommentsSectionParams.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): GetCommentsSectionParams { + const message = createBaseGetCommentsSectionParams(); + message.ctx = (object.ctx !== undefined && object.ctx !== null) + ? GetCommentsSectionParams_Context.fromPartial(object.ctx) + : undefined; + message.unkParam = object.unkParam ?? 0; + message.params = (object.params !== undefined && object.params !== null) + ? GetCommentsSectionParams_Params.fromPartial(object.params) + : undefined; + return message; + }, +}; + +function createBaseGetCommentsSectionParams_Context(): GetCommentsSectionParams_Context { + return { videoId: "" }; +} + +export const GetCommentsSectionParams_Context: MessageFns = { + encode(message: GetCommentsSectionParams_Context, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.videoId !== "") { + writer.uint32(18).string(message.videoId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetCommentsSectionParams_Context { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetCommentsSectionParams_Context(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + if (tag !== 18) { + break; + } + + message.videoId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetCommentsSectionParams_Context { + return { videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : "" }; + }, + + toJSON(message: GetCommentsSectionParams_Context): unknown { + const obj: any = {}; + if (message.videoId !== "") { + obj.videoId = message.videoId; + } + return obj; + }, + + create, I>>( + base?: I, + ): GetCommentsSectionParams_Context { + return GetCommentsSectionParams_Context.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GetCommentsSectionParams_Context { + const message = createBaseGetCommentsSectionParams_Context(); + message.videoId = object.videoId ?? ""; + return message; + }, +}; + +function createBaseGetCommentsSectionParams_Params(): GetCommentsSectionParams_Params { + return { unkToken: undefined, opts: undefined, repliesOpts: undefined, page: undefined, target: "" }; +} + +export const GetCommentsSectionParams_Params: MessageFns = { + encode(message: GetCommentsSectionParams_Params, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.unkToken !== undefined) { + writer.uint32(10).string(message.unkToken); + } + if (message.opts !== undefined) { + GetCommentsSectionParams_Params_Options.encode(message.opts, writer.uint32(34).fork()).join(); + } + if (message.repliesOpts !== undefined) { + GetCommentsSectionParams_Params_RepliesOptions.encode(message.repliesOpts, writer.uint32(26).fork()).join(); + } + if (message.page !== undefined) { + writer.uint32(40).int32(message.page); + } + if (message.target !== "") { + writer.uint32(66).string(message.target); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetCommentsSectionParams_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetCommentsSectionParams_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.unkToken = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.opts = GetCommentsSectionParams_Params_Options.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.repliesOpts = GetCommentsSectionParams_Params_RepliesOptions.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.page = reader.int32(); + continue; + case 8: + if (tag !== 66) { + break; + } + + message.target = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetCommentsSectionParams_Params { + return { + unkToken: isSet(object.unkToken) ? globalThis.String(object.unkToken) : undefined, + opts: isSet(object.opts) ? GetCommentsSectionParams_Params_Options.fromJSON(object.opts) : undefined, + repliesOpts: isSet(object.repliesOpts) + ? GetCommentsSectionParams_Params_RepliesOptions.fromJSON(object.repliesOpts) + : undefined, + page: isSet(object.page) ? globalThis.Number(object.page) : undefined, + target: isSet(object.target) ? globalThis.String(object.target) : "", + }; + }, + + toJSON(message: GetCommentsSectionParams_Params): unknown { + const obj: any = {}; + if (message.unkToken !== undefined) { + obj.unkToken = message.unkToken; + } + if (message.opts !== undefined) { + obj.opts = GetCommentsSectionParams_Params_Options.toJSON(message.opts); + } + if (message.repliesOpts !== undefined) { + obj.repliesOpts = GetCommentsSectionParams_Params_RepliesOptions.toJSON(message.repliesOpts); + } + if (message.page !== undefined) { + obj.page = Math.round(message.page); + } + if (message.target !== "") { + obj.target = message.target; + } + return obj; + }, + + create, I>>(base?: I): GetCommentsSectionParams_Params { + return GetCommentsSectionParams_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GetCommentsSectionParams_Params { + const message = createBaseGetCommentsSectionParams_Params(); + message.unkToken = object.unkToken ?? undefined; + message.opts = (object.opts !== undefined && object.opts !== null) + ? GetCommentsSectionParams_Params_Options.fromPartial(object.opts) + : undefined; + message.repliesOpts = (object.repliesOpts !== undefined && object.repliesOpts !== null) + ? GetCommentsSectionParams_Params_RepliesOptions.fromPartial(object.repliesOpts) + : undefined; + message.page = object.page ?? undefined; + message.target = object.target ?? ""; + return message; + }, +}; + +function createBaseGetCommentsSectionParams_Params_Options(): GetCommentsSectionParams_Params_Options { + return { videoId: "", sortBy: 0, type: 0, commentId: undefined }; +} + +export const GetCommentsSectionParams_Params_Options: MessageFns = { + encode(message: GetCommentsSectionParams_Params_Options, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.videoId !== "") { + writer.uint32(34).string(message.videoId); + } + if (message.sortBy !== 0) { + writer.uint32(48).int32(message.sortBy); + } + if (message.type !== 0) { + writer.uint32(120).int32(message.type); + } + if (message.commentId !== undefined) { + writer.uint32(130).string(message.commentId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetCommentsSectionParams_Params_Options { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetCommentsSectionParams_Params_Options(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 4: + if (tag !== 34) { + break; + } + + message.videoId = reader.string(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.sortBy = reader.int32(); + continue; + case 15: + if (tag !== 120) { + break; + } + + message.type = reader.int32(); + continue; + case 16: + if (tag !== 130) { + break; + } + + message.commentId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetCommentsSectionParams_Params_Options { + return { + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : "", + sortBy: isSet(object.sortBy) ? globalThis.Number(object.sortBy) : 0, + type: isSet(object.type) ? globalThis.Number(object.type) : 0, + commentId: isSet(object.commentId) ? globalThis.String(object.commentId) : undefined, + }; + }, + + toJSON(message: GetCommentsSectionParams_Params_Options): unknown { + const obj: any = {}; + if (message.videoId !== "") { + obj.videoId = message.videoId; + } + if (message.sortBy !== 0) { + obj.sortBy = Math.round(message.sortBy); + } + if (message.type !== 0) { + obj.type = Math.round(message.type); + } + if (message.commentId !== undefined) { + obj.commentId = message.commentId; + } + return obj; + }, + + create, I>>( + base?: I, + ): GetCommentsSectionParams_Params_Options { + return GetCommentsSectionParams_Params_Options.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GetCommentsSectionParams_Params_Options { + const message = createBaseGetCommentsSectionParams_Params_Options(); + message.videoId = object.videoId ?? ""; + message.sortBy = object.sortBy ?? 0; + message.type = object.type ?? 0; + message.commentId = object.commentId ?? undefined; + return message; + }, +}; + +function createBaseGetCommentsSectionParams_Params_RepliesOptions(): GetCommentsSectionParams_Params_RepliesOptions { + return { commentId: "", unkopts: undefined, channelId: undefined, videoId: "", unkParam1: 0, unkParam2: 0 }; +} + +export const GetCommentsSectionParams_Params_RepliesOptions: MessageFns< + GetCommentsSectionParams_Params_RepliesOptions +> = { + encode( + message: GetCommentsSectionParams_Params_RepliesOptions, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.commentId !== "") { + writer.uint32(18).string(message.commentId); + } + if (message.unkopts !== undefined) { + GetCommentsSectionParams_Params_RepliesOptions_UnkOpts.encode(message.unkopts, writer.uint32(34).fork()).join(); + } + if (message.channelId !== undefined) { + writer.uint32(42).string(message.channelId); + } + if (message.videoId !== "") { + writer.uint32(50).string(message.videoId); + } + if (message.unkParam1 !== 0) { + writer.uint32(64).int32(message.unkParam1); + } + if (message.unkParam2 !== 0) { + writer.uint32(72).int32(message.unkParam2); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetCommentsSectionParams_Params_RepliesOptions { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetCommentsSectionParams_Params_RepliesOptions(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + if (tag !== 18) { + break; + } + + message.commentId = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.unkopts = GetCommentsSectionParams_Params_RepliesOptions_UnkOpts.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.channelId = reader.string(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.videoId = reader.string(); + continue; + case 8: + if (tag !== 64) { + break; + } + + message.unkParam1 = reader.int32(); + continue; + case 9: + if (tag !== 72) { + break; + } + + message.unkParam2 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetCommentsSectionParams_Params_RepliesOptions { + return { + commentId: isSet(object.commentId) ? globalThis.String(object.commentId) : "", + unkopts: isSet(object.unkopts) + ? GetCommentsSectionParams_Params_RepliesOptions_UnkOpts.fromJSON(object.unkopts) + : undefined, + channelId: isSet(object.channelId) ? globalThis.String(object.channelId) : undefined, + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : "", + unkParam1: isSet(object.unkParam1) ? globalThis.Number(object.unkParam1) : 0, + unkParam2: isSet(object.unkParam2) ? globalThis.Number(object.unkParam2) : 0, + }; + }, + + toJSON(message: GetCommentsSectionParams_Params_RepliesOptions): unknown { + const obj: any = {}; + if (message.commentId !== "") { + obj.commentId = message.commentId; + } + if (message.unkopts !== undefined) { + obj.unkopts = GetCommentsSectionParams_Params_RepliesOptions_UnkOpts.toJSON(message.unkopts); + } + if (message.channelId !== undefined) { + obj.channelId = message.channelId; + } + if (message.videoId !== "") { + obj.videoId = message.videoId; + } + if (message.unkParam1 !== 0) { + obj.unkParam1 = Math.round(message.unkParam1); + } + if (message.unkParam2 !== 0) { + obj.unkParam2 = Math.round(message.unkParam2); + } + return obj; + }, + + create, I>>( + base?: I, + ): GetCommentsSectionParams_Params_RepliesOptions { + return GetCommentsSectionParams_Params_RepliesOptions.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GetCommentsSectionParams_Params_RepliesOptions { + const message = createBaseGetCommentsSectionParams_Params_RepliesOptions(); + message.commentId = object.commentId ?? ""; + message.unkopts = (object.unkopts !== undefined && object.unkopts !== null) + ? GetCommentsSectionParams_Params_RepliesOptions_UnkOpts.fromPartial(object.unkopts) + : undefined; + message.channelId = object.channelId ?? undefined; + message.videoId = object.videoId ?? ""; + message.unkParam1 = object.unkParam1 ?? 0; + message.unkParam2 = object.unkParam2 ?? 0; + return message; + }, +}; + +function createBaseGetCommentsSectionParams_Params_RepliesOptions_UnkOpts(): GetCommentsSectionParams_Params_RepliesOptions_UnkOpts { + return { unkParam: 0 }; +} + +export const GetCommentsSectionParams_Params_RepliesOptions_UnkOpts: MessageFns< + GetCommentsSectionParams_Params_RepliesOptions_UnkOpts +> = { + encode( + message: GetCommentsSectionParams_Params_RepliesOptions_UnkOpts, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.unkParam !== 0) { + writer.uint32(8).int32(message.unkParam); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetCommentsSectionParams_Params_RepliesOptions_UnkOpts { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetCommentsSectionParams_Params_RepliesOptions_UnkOpts(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.unkParam = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetCommentsSectionParams_Params_RepliesOptions_UnkOpts { + return { unkParam: isSet(object.unkParam) ? globalThis.Number(object.unkParam) : 0 }; + }, + + toJSON(message: GetCommentsSectionParams_Params_RepliesOptions_UnkOpts): unknown { + const obj: any = {}; + if (message.unkParam !== 0) { + obj.unkParam = Math.round(message.unkParam); + } + return obj; + }, + + create, I>>( + base?: I, + ): GetCommentsSectionParams_Params_RepliesOptions_UnkOpts { + return GetCommentsSectionParams_Params_RepliesOptions_UnkOpts.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GetCommentsSectionParams_Params_RepliesOptions_UnkOpts { + const message = createBaseGetCommentsSectionParams_Params_RepliesOptions_UnkOpts(); + message.unkParam = object.unkParam ?? 0; + return message; + }, +}; + +function createBaseCreateCommentParams(): CreateCommentParams { + return { videoId: "", params: undefined, number: 0 }; +} + +export const CreateCommentParams: MessageFns = { + encode(message: CreateCommentParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.videoId !== "") { + writer.uint32(18).string(message.videoId); + } + if (message.params !== undefined) { + CreateCommentParams_Params.encode(message.params, writer.uint32(42).fork()).join(); + } + if (message.number !== 0) { + writer.uint32(80).int32(message.number); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CreateCommentParams { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCreateCommentParams(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + if (tag !== 18) { + break; + } + + message.videoId = reader.string(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.params = CreateCommentParams_Params.decode(reader, reader.uint32()); + continue; + case 10: + if (tag !== 80) { + break; + } + + message.number = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CreateCommentParams { + return { + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : "", + params: isSet(object.params) ? CreateCommentParams_Params.fromJSON(object.params) : undefined, + number: isSet(object.number) ? globalThis.Number(object.number) : 0, + }; + }, + + toJSON(message: CreateCommentParams): unknown { + const obj: any = {}; + if (message.videoId !== "") { + obj.videoId = message.videoId; + } + if (message.params !== undefined) { + obj.params = CreateCommentParams_Params.toJSON(message.params); + } + if (message.number !== 0) { + obj.number = Math.round(message.number); + } + return obj; + }, + + create, I>>(base?: I): CreateCommentParams { + return CreateCommentParams.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): CreateCommentParams { + const message = createBaseCreateCommentParams(); + message.videoId = object.videoId ?? ""; + message.params = (object.params !== undefined && object.params !== null) + ? CreateCommentParams_Params.fromPartial(object.params) + : undefined; + message.number = object.number ?? 0; + return message; + }, +}; + +function createBaseCreateCommentParams_Params(): CreateCommentParams_Params { + return { index: 0 }; +} + +export const CreateCommentParams_Params: MessageFns = { + encode(message: CreateCommentParams_Params, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.index !== 0) { + writer.uint32(8).int32(message.index); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CreateCommentParams_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCreateCommentParams_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.index = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CreateCommentParams_Params { + return { index: isSet(object.index) ? globalThis.Number(object.index) : 0 }; + }, + + toJSON(message: CreateCommentParams_Params): unknown { + const obj: any = {}; + if (message.index !== 0) { + obj.index = Math.round(message.index); + } + return obj; + }, + + create, I>>(base?: I): CreateCommentParams_Params { + return CreateCommentParams_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): CreateCommentParams_Params { + const message = createBaseCreateCommentParams_Params(); + message.index = object.index ?? 0; + return message; + }, +}; + +function createBasePeformCommentActionParams(): PeformCommentActionParams { + return { + type: 0, + commentId: "", + videoId: "", + unkNum: undefined, + channelId: undefined, + translateCommentParams: undefined, + }; +} + +export const PeformCommentActionParams: MessageFns = { + encode(message: PeformCommentActionParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.type !== 0) { + writer.uint32(8).int32(message.type); + } + if (message.commentId !== "") { + writer.uint32(26).string(message.commentId); + } + if (message.videoId !== "") { + writer.uint32(42).string(message.videoId); + } + if (message.unkNum !== undefined) { + writer.uint32(16).int32(message.unkNum); + } + if (message.channelId !== undefined) { + writer.uint32(186).string(message.channelId); + } + if (message.translateCommentParams !== undefined) { + PeformCommentActionParams_TranslateCommentParams.encode(message.translateCommentParams, writer.uint32(250).fork()) + .join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PeformCommentActionParams { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeformCommentActionParams(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.type = reader.int32(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.commentId = reader.string(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.videoId = reader.string(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.unkNum = reader.int32(); + continue; + case 23: + if (tag !== 186) { + break; + } + + message.channelId = reader.string(); + continue; + case 31: + if (tag !== 250) { + break; + } + + message.translateCommentParams = PeformCommentActionParams_TranslateCommentParams.decode( + reader, + reader.uint32(), + ); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PeformCommentActionParams { + return { + type: isSet(object.type) ? globalThis.Number(object.type) : 0, + commentId: isSet(object.commentId) ? globalThis.String(object.commentId) : "", + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : "", + unkNum: isSet(object.unkNum) ? globalThis.Number(object.unkNum) : undefined, + channelId: isSet(object.channelId) ? globalThis.String(object.channelId) : undefined, + translateCommentParams: isSet(object.translateCommentParams) + ? PeformCommentActionParams_TranslateCommentParams.fromJSON(object.translateCommentParams) + : undefined, + }; + }, + + toJSON(message: PeformCommentActionParams): unknown { + const obj: any = {}; + if (message.type !== 0) { + obj.type = Math.round(message.type); + } + if (message.commentId !== "") { + obj.commentId = message.commentId; + } + if (message.videoId !== "") { + obj.videoId = message.videoId; + } + if (message.unkNum !== undefined) { + obj.unkNum = Math.round(message.unkNum); + } + if (message.channelId !== undefined) { + obj.channelId = message.channelId; + } + if (message.translateCommentParams !== undefined) { + obj.translateCommentParams = PeformCommentActionParams_TranslateCommentParams.toJSON( + message.translateCommentParams, + ); + } + return obj; + }, + + create, I>>(base?: I): PeformCommentActionParams { + return PeformCommentActionParams.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PeformCommentActionParams { + const message = createBasePeformCommentActionParams(); + message.type = object.type ?? 0; + message.commentId = object.commentId ?? ""; + message.videoId = object.videoId ?? ""; + message.unkNum = object.unkNum ?? undefined; + message.channelId = object.channelId ?? undefined; + message.translateCommentParams = + (object.translateCommentParams !== undefined && object.translateCommentParams !== null) + ? PeformCommentActionParams_TranslateCommentParams.fromPartial(object.translateCommentParams) + : undefined; + return message; + }, +}; + +function createBasePeformCommentActionParams_TranslateCommentParams(): PeformCommentActionParams_TranslateCommentParams { + return { params: undefined, commentId: "", targetLanguage: "" }; +} + +export const PeformCommentActionParams_TranslateCommentParams: MessageFns< + PeformCommentActionParams_TranslateCommentParams +> = { + encode( + message: PeformCommentActionParams_TranslateCommentParams, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.params !== undefined) { + PeformCommentActionParams_TranslateCommentParams_Params.encode(message.params, writer.uint32(26).fork()).join(); + } + if (message.commentId !== "") { + writer.uint32(18).string(message.commentId); + } + if (message.targetLanguage !== "") { + writer.uint32(34).string(message.targetLanguage); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PeformCommentActionParams_TranslateCommentParams { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeformCommentActionParams_TranslateCommentParams(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 3: + if (tag !== 26) { + break; + } + + message.params = PeformCommentActionParams_TranslateCommentParams_Params.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.commentId = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetLanguage = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PeformCommentActionParams_TranslateCommentParams { + return { + params: isSet(object.params) + ? PeformCommentActionParams_TranslateCommentParams_Params.fromJSON(object.params) + : undefined, + commentId: isSet(object.commentId) ? globalThis.String(object.commentId) : "", + targetLanguage: isSet(object.targetLanguage) ? globalThis.String(object.targetLanguage) : "", + }; + }, + + toJSON(message: PeformCommentActionParams_TranslateCommentParams): unknown { + const obj: any = {}; + if (message.params !== undefined) { + obj.params = PeformCommentActionParams_TranslateCommentParams_Params.toJSON(message.params); + } + if (message.commentId !== "") { + obj.commentId = message.commentId; + } + if (message.targetLanguage !== "") { + obj.targetLanguage = message.targetLanguage; + } + return obj; + }, + + create, I>>( + base?: I, + ): PeformCommentActionParams_TranslateCommentParams { + return PeformCommentActionParams_TranslateCommentParams.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): PeformCommentActionParams_TranslateCommentParams { + const message = createBasePeformCommentActionParams_TranslateCommentParams(); + message.params = (object.params !== undefined && object.params !== null) + ? PeformCommentActionParams_TranslateCommentParams_Params.fromPartial(object.params) + : undefined; + message.commentId = object.commentId ?? ""; + message.targetLanguage = object.targetLanguage ?? ""; + return message; + }, +}; + +function createBasePeformCommentActionParams_TranslateCommentParams_Params(): PeformCommentActionParams_TranslateCommentParams_Params { + return { comment: undefined }; +} + +export const PeformCommentActionParams_TranslateCommentParams_Params: MessageFns< + PeformCommentActionParams_TranslateCommentParams_Params +> = { + encode( + message: PeformCommentActionParams_TranslateCommentParams_Params, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.comment !== undefined) { + PeformCommentActionParams_TranslateCommentParams_Params_Comment.encode(message.comment, writer.uint32(10).fork()) + .join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PeformCommentActionParams_TranslateCommentParams_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeformCommentActionParams_TranslateCommentParams_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.comment = PeformCommentActionParams_TranslateCommentParams_Params_Comment.decode( + reader, + reader.uint32(), + ); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PeformCommentActionParams_TranslateCommentParams_Params { + return { + comment: isSet(object.comment) + ? PeformCommentActionParams_TranslateCommentParams_Params_Comment.fromJSON(object.comment) + : undefined, + }; + }, + + toJSON(message: PeformCommentActionParams_TranslateCommentParams_Params): unknown { + const obj: any = {}; + if (message.comment !== undefined) { + obj.comment = PeformCommentActionParams_TranslateCommentParams_Params_Comment.toJSON(message.comment); + } + return obj; + }, + + create, I>>( + base?: I, + ): PeformCommentActionParams_TranslateCommentParams_Params { + return PeformCommentActionParams_TranslateCommentParams_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): PeformCommentActionParams_TranslateCommentParams_Params { + const message = createBasePeformCommentActionParams_TranslateCommentParams_Params(); + message.comment = (object.comment !== undefined && object.comment !== null) + ? PeformCommentActionParams_TranslateCommentParams_Params_Comment.fromPartial(object.comment) + : undefined; + return message; + }, +}; + +function createBasePeformCommentActionParams_TranslateCommentParams_Params_Comment(): PeformCommentActionParams_TranslateCommentParams_Params_Comment { + return { text: "" }; +} + +export const PeformCommentActionParams_TranslateCommentParams_Params_Comment: MessageFns< + PeformCommentActionParams_TranslateCommentParams_Params_Comment +> = { + encode( + message: PeformCommentActionParams_TranslateCommentParams_Params_Comment, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.text !== "") { + writer.uint32(10).string(message.text); + } + return writer; + }, + + decode( + input: BinaryReader | Uint8Array, + length?: number, + ): PeformCommentActionParams_TranslateCommentParams_Params_Comment { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeformCommentActionParams_TranslateCommentParams_Params_Comment(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.text = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PeformCommentActionParams_TranslateCommentParams_Params_Comment { + return { text: isSet(object.text) ? globalThis.String(object.text) : "" }; + }, + + toJSON(message: PeformCommentActionParams_TranslateCommentParams_Params_Comment): unknown { + const obj: any = {}; + if (message.text !== "") { + obj.text = message.text; + } + return obj; + }, + + create, I>>( + base?: I, + ): PeformCommentActionParams_TranslateCommentParams_Params_Comment { + return PeformCommentActionParams_TranslateCommentParams_Params_Comment.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): PeformCommentActionParams_TranslateCommentParams_Params_Comment { + const message = createBasePeformCommentActionParams_TranslateCommentParams_Params_Comment(); + message.text = object.text ?? ""; + return message; + }, +}; + +function createBaseHashtag(): Hashtag { + return { params: undefined }; +} + +export const Hashtag: MessageFns = { + encode(message: Hashtag, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.params !== undefined) { + Hashtag_Params.encode(message.params, writer.uint32(746).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Hashtag { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHashtag(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 93: + if (tag !== 746) { + break; + } + + message.params = Hashtag_Params.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Hashtag { + return { params: isSet(object.params) ? Hashtag_Params.fromJSON(object.params) : undefined }; + }, + + toJSON(message: Hashtag): unknown { + const obj: any = {}; + if (message.params !== undefined) { + obj.params = Hashtag_Params.toJSON(message.params); + } + return obj; + }, + + create, I>>(base?: I): Hashtag { + return Hashtag.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Hashtag { + const message = createBaseHashtag(); + message.params = (object.params !== undefined && object.params !== null) + ? Hashtag_Params.fromPartial(object.params) + : undefined; + return message; + }, +}; + +function createBaseHashtag_Params(): Hashtag_Params { + return { hashtag: "", type: 0 }; +} + +export const Hashtag_Params: MessageFns = { + encode(message: Hashtag_Params, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.hashtag !== "") { + writer.uint32(10).string(message.hashtag); + } + if (message.type !== 0) { + writer.uint32(24).int32(message.type); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Hashtag_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHashtag_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.hashtag = reader.string(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.type = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Hashtag_Params { + return { + hashtag: isSet(object.hashtag) ? globalThis.String(object.hashtag) : "", + type: isSet(object.type) ? globalThis.Number(object.type) : 0, + }; + }, + + toJSON(message: Hashtag_Params): unknown { + const obj: any = {}; + if (message.hashtag !== "") { + obj.hashtag = message.hashtag; + } + if (message.type !== 0) { + obj.type = Math.round(message.type); + } + return obj; + }, + + create, I>>(base?: I): Hashtag_Params { + return Hashtag_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Hashtag_Params { + const message = createBaseHashtag_Params(); + message.hashtag = object.hashtag ?? ""; + message.type = object.type ?? 0; + return message; + }, +}; + +function createBaseReelSequence(): ReelSequence { + return { shortId: "", params: undefined, feature2: 0, feature3: 0 }; +} + +export const ReelSequence: MessageFns = { + encode(message: ReelSequence, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.shortId !== "") { + writer.uint32(10).string(message.shortId); + } + if (message.params !== undefined) { + ReelSequence_Params.encode(message.params, writer.uint32(42).fork()).join(); + } + if (message.feature2 !== 0) { + writer.uint32(80).int32(message.feature2); + } + if (message.feature3 !== 0) { + writer.uint32(104).int32(message.feature3); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ReelSequence { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseReelSequence(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.shortId = reader.string(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.params = ReelSequence_Params.decode(reader, reader.uint32()); + continue; + case 10: + if (tag !== 80) { + break; + } + + message.feature2 = reader.int32(); + continue; + case 13: + if (tag !== 104) { + break; + } + + message.feature3 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ReelSequence { + return { + shortId: isSet(object.shortId) ? globalThis.String(object.shortId) : "", + params: isSet(object.params) ? ReelSequence_Params.fromJSON(object.params) : undefined, + feature2: isSet(object.feature2) ? globalThis.Number(object.feature2) : 0, + feature3: isSet(object.feature3) ? globalThis.Number(object.feature3) : 0, + }; + }, + + toJSON(message: ReelSequence): unknown { + const obj: any = {}; + if (message.shortId !== "") { + obj.shortId = message.shortId; + } + if (message.params !== undefined) { + obj.params = ReelSequence_Params.toJSON(message.params); + } + if (message.feature2 !== 0) { + obj.feature2 = Math.round(message.feature2); + } + if (message.feature3 !== 0) { + obj.feature3 = Math.round(message.feature3); + } + return obj; + }, + + create, I>>(base?: I): ReelSequence { + return ReelSequence.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ReelSequence { + const message = createBaseReelSequence(); + message.shortId = object.shortId ?? ""; + message.params = (object.params !== undefined && object.params !== null) + ? ReelSequence_Params.fromPartial(object.params) + : undefined; + message.feature2 = object.feature2 ?? 0; + message.feature3 = object.feature3 ?? 0; + return message; + }, +}; + +function createBaseReelSequence_Params(): ReelSequence_Params { + return { number: 0 }; +} + +export const ReelSequence_Params: MessageFns = { + encode(message: ReelSequence_Params, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.number !== 0) { + writer.uint32(24).int32(message.number); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ReelSequence_Params { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseReelSequence_Params(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 3: + if (tag !== 24) { + break; + } + + message.number = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ReelSequence_Params { + return { number: isSet(object.number) ? globalThis.Number(object.number) : 0 }; + }, + + toJSON(message: ReelSequence_Params): unknown { + const obj: any = {}; + if (message.number !== 0) { + obj.number = Math.round(message.number); + } + return obj; + }, + + create, I>>(base?: I): ReelSequence_Params { + return ReelSequence_Params.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ReelSequence_Params { + const message = createBaseReelSequence_Params(); + message.number = object.number ?? 0; + return message; + }, +}; + +function createBaseShortsParam(): ShortsParam { + return { f1: undefined, p59: undefined }; +} + +export const ShortsParam: MessageFns = { + encode(message: ShortsParam, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.f1 !== undefined) { + ShortsParam_Field1.encode(message.f1, writer.uint32(10).fork()).join(); + } + if (message.p59 !== undefined) { + writer.uint32(472).int32(message.p59); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ShortsParam { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseShortsParam(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.f1 = ShortsParam_Field1.decode(reader, reader.uint32()); + continue; + case 59: + if (tag !== 472) { + break; + } + + message.p59 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ShortsParam { + return { + f1: isSet(object.f1) ? ShortsParam_Field1.fromJSON(object.f1) : undefined, + p59: isSet(object.p59) ? globalThis.Number(object.p59) : undefined, + }; + }, + + toJSON(message: ShortsParam): unknown { + const obj: any = {}; + if (message.f1 !== undefined) { + obj.f1 = ShortsParam_Field1.toJSON(message.f1); + } + if (message.p59 !== undefined) { + obj.p59 = Math.round(message.p59); + } + return obj; + }, + + create, I>>(base?: I): ShortsParam { + return ShortsParam.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ShortsParam { + const message = createBaseShortsParam(); + message.f1 = (object.f1 !== undefined && object.f1 !== null) + ? ShortsParam_Field1.fromPartial(object.f1) + : undefined; + message.p59 = object.p59 ?? undefined; + return message; + }, +}; + +function createBaseShortsParam_Field1(): ShortsParam_Field1 { + return { p1: undefined }; +} + +export const ShortsParam_Field1: MessageFns = { + encode(message: ShortsParam_Field1, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.p1 !== undefined) { + writer.uint32(8).int32(message.p1); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ShortsParam_Field1 { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseShortsParam_Field1(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.p1 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ShortsParam_Field1 { + return { p1: isSet(object.p1) ? globalThis.Number(object.p1) : undefined }; + }, + + toJSON(message: ShortsParam_Field1): unknown { + const obj: any = {}; + if (message.p1 !== undefined) { + obj.p1 = Math.round(message.p1); + } + return obj; + }, + + create, I>>(base?: I): ShortsParam_Field1 { + return ShortsParam_Field1.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ShortsParam_Field1 { + const message = createBaseShortsParam_Field1(); + message.p1 = object.p1 ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/format_initialization_metadata.ts b/protos/generated/video_streaming/format_initialization_metadata.ts new file mode 100644 index 0000000..c50891b --- /dev/null +++ b/protos/generated/video_streaming/format_initialization_metadata.ts @@ -0,0 +1,260 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/format_initialization_metadata.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { FormatId, IndexRange, InitRange } from "../misc/common.js"; + +export const protobufPackage = "video_streaming"; + +export interface FormatInitializationMetadata { + videoId?: string | undefined; + formatId?: FormatId | undefined; + endTimeMs?: number | undefined; + field4?: number | undefined; + mimeType?: string | undefined; + initRange?: InitRange | undefined; + indexRange?: IndexRange | undefined; + field8?: number | undefined; + durationMs?: number | undefined; + field10?: number | undefined; +} + +function createBaseFormatInitializationMetadata(): FormatInitializationMetadata { + return { + videoId: undefined, + formatId: undefined, + endTimeMs: undefined, + field4: undefined, + mimeType: undefined, + initRange: undefined, + indexRange: undefined, + field8: undefined, + durationMs: undefined, + field10: undefined, + }; +} + +export const FormatInitializationMetadata: MessageFns = { + encode(message: FormatInitializationMetadata, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.videoId !== undefined) { + writer.uint32(10).string(message.videoId); + } + if (message.formatId !== undefined) { + FormatId.encode(message.formatId, writer.uint32(18).fork()).join(); + } + if (message.endTimeMs !== undefined) { + writer.uint32(24).int32(message.endTimeMs); + } + if (message.field4 !== undefined) { + writer.uint32(32).int32(message.field4); + } + if (message.mimeType !== undefined) { + writer.uint32(42).string(message.mimeType); + } + if (message.initRange !== undefined) { + InitRange.encode(message.initRange, writer.uint32(50).fork()).join(); + } + if (message.indexRange !== undefined) { + IndexRange.encode(message.indexRange, writer.uint32(58).fork()).join(); + } + if (message.field8 !== undefined) { + writer.uint32(64).int32(message.field8); + } + if (message.durationMs !== undefined) { + writer.uint32(72).int32(message.durationMs); + } + if (message.field10 !== undefined) { + writer.uint32(80).int32(message.field10); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): FormatInitializationMetadata { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFormatInitializationMetadata(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.videoId = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.formatId = FormatId.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.endTimeMs = reader.int32(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.field4 = reader.int32(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.mimeType = reader.string(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.initRange = InitRange.decode(reader, reader.uint32()); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.indexRange = IndexRange.decode(reader, reader.uint32()); + continue; + case 8: + if (tag !== 64) { + break; + } + + message.field8 = reader.int32(); + continue; + case 9: + if (tag !== 72) { + break; + } + + message.durationMs = reader.int32(); + continue; + case 10: + if (tag !== 80) { + break; + } + + message.field10 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): FormatInitializationMetadata { + return { + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : undefined, + formatId: isSet(object.formatId) ? FormatId.fromJSON(object.formatId) : undefined, + endTimeMs: isSet(object.endTimeMs) ? globalThis.Number(object.endTimeMs) : undefined, + field4: isSet(object.field4) ? globalThis.Number(object.field4) : undefined, + mimeType: isSet(object.mimeType) ? globalThis.String(object.mimeType) : undefined, + initRange: isSet(object.initRange) ? InitRange.fromJSON(object.initRange) : undefined, + indexRange: isSet(object.indexRange) ? IndexRange.fromJSON(object.indexRange) : undefined, + field8: isSet(object.field8) ? globalThis.Number(object.field8) : undefined, + durationMs: isSet(object.durationMs) ? globalThis.Number(object.durationMs) : undefined, + field10: isSet(object.field10) ? globalThis.Number(object.field10) : undefined, + }; + }, + + toJSON(message: FormatInitializationMetadata): unknown { + const obj: any = {}; + if (message.videoId !== undefined) { + obj.videoId = message.videoId; + } + if (message.formatId !== undefined) { + obj.formatId = FormatId.toJSON(message.formatId); + } + if (message.endTimeMs !== undefined) { + obj.endTimeMs = Math.round(message.endTimeMs); + } + if (message.field4 !== undefined) { + obj.field4 = Math.round(message.field4); + } + if (message.mimeType !== undefined) { + obj.mimeType = message.mimeType; + } + if (message.initRange !== undefined) { + obj.initRange = InitRange.toJSON(message.initRange); + } + if (message.indexRange !== undefined) { + obj.indexRange = IndexRange.toJSON(message.indexRange); + } + if (message.field8 !== undefined) { + obj.field8 = Math.round(message.field8); + } + if (message.durationMs !== undefined) { + obj.durationMs = Math.round(message.durationMs); + } + if (message.field10 !== undefined) { + obj.field10 = Math.round(message.field10); + } + return obj; + }, + + create, I>>(base?: I): FormatInitializationMetadata { + return FormatInitializationMetadata.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): FormatInitializationMetadata { + const message = createBaseFormatInitializationMetadata(); + message.videoId = object.videoId ?? undefined; + message.formatId = (object.formatId !== undefined && object.formatId !== null) + ? FormatId.fromPartial(object.formatId) + : undefined; + message.endTimeMs = object.endTimeMs ?? undefined; + message.field4 = object.field4 ?? undefined; + message.mimeType = object.mimeType ?? undefined; + message.initRange = (object.initRange !== undefined && object.initRange !== null) + ? InitRange.fromPartial(object.initRange) + : undefined; + message.indexRange = (object.indexRange !== undefined && object.indexRange !== null) + ? IndexRange.fromPartial(object.indexRange) + : undefined; + message.field8 = object.field8 ?? undefined; + message.durationMs = object.durationMs ?? undefined; + message.field10 = object.field10 ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/media_header.ts b/protos/generated/video_streaming/media_header.ts new file mode 100644 index 0000000..376d0de --- /dev/null +++ b/protos/generated/video_streaming/media_header.ts @@ -0,0 +1,488 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/media_header.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { FormatId } from "../misc/common.js"; + +export const protobufPackage = "video_streaming"; + +export interface MediaHeader { + headerId?: number | undefined; + videoId?: string | undefined; + itag?: number | undefined; + lmt?: number | undefined; + xtags?: string | undefined; + startDataRange?: number | undefined; + compression?: MediaHeader_Compression | undefined; + isInitSeg?: boolean | undefined; + sequenceNumber?: number | undefined; + field10?: number | undefined; + startMs?: number | undefined; + durationMs?: number | undefined; + formatId?: FormatId | undefined; + contentLength?: number | undefined; + timeRange?: MediaHeader_TimeRange | undefined; +} + +export enum MediaHeader_Compression { + VAL0 = 0, + VAL1 = 1, + GZIP = 2, + UNRECOGNIZED = -1, +} + +export function mediaHeader_CompressionFromJSON(object: any): MediaHeader_Compression { + switch (object) { + case 0: + case "VAL0": + return MediaHeader_Compression.VAL0; + case 1: + case "VAL1": + return MediaHeader_Compression.VAL1; + case 2: + case "GZIP": + return MediaHeader_Compression.GZIP; + case -1: + case "UNRECOGNIZED": + default: + return MediaHeader_Compression.UNRECOGNIZED; + } +} + +export function mediaHeader_CompressionToJSON(object: MediaHeader_Compression): string { + switch (object) { + case MediaHeader_Compression.VAL0: + return "VAL0"; + case MediaHeader_Compression.VAL1: + return "VAL1"; + case MediaHeader_Compression.GZIP: + return "GZIP"; + case MediaHeader_Compression.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export interface MediaHeader_TimeRange { + start?: number | undefined; + duration?: number | undefined; + timescale?: number | undefined; +} + +function createBaseMediaHeader(): MediaHeader { + return { + headerId: undefined, + videoId: undefined, + itag: undefined, + lmt: undefined, + xtags: undefined, + startDataRange: undefined, + compression: undefined, + isInitSeg: undefined, + sequenceNumber: undefined, + field10: undefined, + startMs: undefined, + durationMs: undefined, + formatId: undefined, + contentLength: undefined, + timeRange: undefined, + }; +} + +export const MediaHeader: MessageFns = { + encode(message: MediaHeader, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.headerId !== undefined) { + writer.uint32(8).uint32(message.headerId); + } + if (message.videoId !== undefined) { + writer.uint32(18).string(message.videoId); + } + if (message.itag !== undefined) { + writer.uint32(24).int32(message.itag); + } + if (message.lmt !== undefined) { + writer.uint32(32).uint64(message.lmt); + } + if (message.xtags !== undefined) { + writer.uint32(42).string(message.xtags); + } + if (message.startDataRange !== undefined) { + writer.uint32(48).int32(message.startDataRange); + } + if (message.compression !== undefined) { + writer.uint32(56).int32(message.compression); + } + if (message.isInitSeg !== undefined) { + writer.uint32(64).bool(message.isInitSeg); + } + if (message.sequenceNumber !== undefined) { + writer.uint32(72).int64(message.sequenceNumber); + } + if (message.field10 !== undefined) { + writer.uint32(80).int64(message.field10); + } + if (message.startMs !== undefined) { + writer.uint32(88).int32(message.startMs); + } + if (message.durationMs !== undefined) { + writer.uint32(96).int32(message.durationMs); + } + if (message.formatId !== undefined) { + FormatId.encode(message.formatId, writer.uint32(106).fork()).join(); + } + if (message.contentLength !== undefined) { + writer.uint32(112).int64(message.contentLength); + } + if (message.timeRange !== undefined) { + MediaHeader_TimeRange.encode(message.timeRange, writer.uint32(122).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): MediaHeader { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMediaHeader(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.headerId = reader.uint32(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.videoId = reader.string(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.itag = reader.int32(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.lmt = longToNumber(reader.uint64()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.xtags = reader.string(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.startDataRange = reader.int32(); + continue; + case 7: + if (tag !== 56) { + break; + } + + message.compression = reader.int32() as any; + continue; + case 8: + if (tag !== 64) { + break; + } + + message.isInitSeg = reader.bool(); + continue; + case 9: + if (tag !== 72) { + break; + } + + message.sequenceNumber = longToNumber(reader.int64()); + continue; + case 10: + if (tag !== 80) { + break; + } + + message.field10 = longToNumber(reader.int64()); + continue; + case 11: + if (tag !== 88) { + break; + } + + message.startMs = reader.int32(); + continue; + case 12: + if (tag !== 96) { + break; + } + + message.durationMs = reader.int32(); + continue; + case 13: + if (tag !== 106) { + break; + } + + message.formatId = FormatId.decode(reader, reader.uint32()); + continue; + case 14: + if (tag !== 112) { + break; + } + + message.contentLength = longToNumber(reader.int64()); + continue; + case 15: + if (tag !== 122) { + break; + } + + message.timeRange = MediaHeader_TimeRange.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): MediaHeader { + return { + headerId: isSet(object.headerId) ? globalThis.Number(object.headerId) : undefined, + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : undefined, + itag: isSet(object.itag) ? globalThis.Number(object.itag) : undefined, + lmt: isSet(object.lmt) ? globalThis.Number(object.lmt) : undefined, + xtags: isSet(object.xtags) ? globalThis.String(object.xtags) : undefined, + startDataRange: isSet(object.startDataRange) ? globalThis.Number(object.startDataRange) : undefined, + compression: isSet(object.compression) ? mediaHeader_CompressionFromJSON(object.compression) : undefined, + isInitSeg: isSet(object.isInitSeg) ? globalThis.Boolean(object.isInitSeg) : undefined, + sequenceNumber: isSet(object.sequenceNumber) ? globalThis.Number(object.sequenceNumber) : undefined, + field10: isSet(object.field10) ? globalThis.Number(object.field10) : undefined, + startMs: isSet(object.startMs) ? globalThis.Number(object.startMs) : undefined, + durationMs: isSet(object.durationMs) ? globalThis.Number(object.durationMs) : undefined, + formatId: isSet(object.formatId) ? FormatId.fromJSON(object.formatId) : undefined, + contentLength: isSet(object.contentLength) ? globalThis.Number(object.contentLength) : undefined, + timeRange: isSet(object.timeRange) ? MediaHeader_TimeRange.fromJSON(object.timeRange) : undefined, + }; + }, + + toJSON(message: MediaHeader): unknown { + const obj: any = {}; + if (message.headerId !== undefined) { + obj.headerId = Math.round(message.headerId); + } + if (message.videoId !== undefined) { + obj.videoId = message.videoId; + } + if (message.itag !== undefined) { + obj.itag = Math.round(message.itag); + } + if (message.lmt !== undefined) { + obj.lmt = Math.round(message.lmt); + } + if (message.xtags !== undefined) { + obj.xtags = message.xtags; + } + if (message.startDataRange !== undefined) { + obj.startDataRange = Math.round(message.startDataRange); + } + if (message.compression !== undefined) { + obj.compression = mediaHeader_CompressionToJSON(message.compression); + } + if (message.isInitSeg !== undefined) { + obj.isInitSeg = message.isInitSeg; + } + if (message.sequenceNumber !== undefined) { + obj.sequenceNumber = Math.round(message.sequenceNumber); + } + if (message.field10 !== undefined) { + obj.field10 = Math.round(message.field10); + } + if (message.startMs !== undefined) { + obj.startMs = Math.round(message.startMs); + } + if (message.durationMs !== undefined) { + obj.durationMs = Math.round(message.durationMs); + } + if (message.formatId !== undefined) { + obj.formatId = FormatId.toJSON(message.formatId); + } + if (message.contentLength !== undefined) { + obj.contentLength = Math.round(message.contentLength); + } + if (message.timeRange !== undefined) { + obj.timeRange = MediaHeader_TimeRange.toJSON(message.timeRange); + } + return obj; + }, + + create, I>>(base?: I): MediaHeader { + return MediaHeader.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): MediaHeader { + const message = createBaseMediaHeader(); + message.headerId = object.headerId ?? undefined; + message.videoId = object.videoId ?? undefined; + message.itag = object.itag ?? undefined; + message.lmt = object.lmt ?? undefined; + message.xtags = object.xtags ?? undefined; + message.startDataRange = object.startDataRange ?? undefined; + message.compression = object.compression ?? undefined; + message.isInitSeg = object.isInitSeg ?? undefined; + message.sequenceNumber = object.sequenceNumber ?? undefined; + message.field10 = object.field10 ?? undefined; + message.startMs = object.startMs ?? undefined; + message.durationMs = object.durationMs ?? undefined; + message.formatId = (object.formatId !== undefined && object.formatId !== null) + ? FormatId.fromPartial(object.formatId) + : undefined; + message.contentLength = object.contentLength ?? undefined; + message.timeRange = (object.timeRange !== undefined && object.timeRange !== null) + ? MediaHeader_TimeRange.fromPartial(object.timeRange) + : undefined; + return message; + }, +}; + +function createBaseMediaHeader_TimeRange(): MediaHeader_TimeRange { + return { start: undefined, duration: undefined, timescale: undefined }; +} + +export const MediaHeader_TimeRange: MessageFns = { + encode(message: MediaHeader_TimeRange, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.start !== undefined) { + writer.uint32(8).int64(message.start); + } + if (message.duration !== undefined) { + writer.uint32(16).int64(message.duration); + } + if (message.timescale !== undefined) { + writer.uint32(24).int32(message.timescale); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): MediaHeader_TimeRange { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMediaHeader_TimeRange(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.start = longToNumber(reader.int64()); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.duration = longToNumber(reader.int64()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.timescale = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): MediaHeader_TimeRange { + return { + start: isSet(object.start) ? globalThis.Number(object.start) : undefined, + duration: isSet(object.duration) ? globalThis.Number(object.duration) : undefined, + timescale: isSet(object.timescale) ? globalThis.Number(object.timescale) : undefined, + }; + }, + + toJSON(message: MediaHeader_TimeRange): unknown { + const obj: any = {}; + if (message.start !== undefined) { + obj.start = Math.round(message.start); + } + if (message.duration !== undefined) { + obj.duration = Math.round(message.duration); + } + if (message.timescale !== undefined) { + obj.timescale = Math.round(message.timescale); + } + return obj; + }, + + create, I>>(base?: I): MediaHeader_TimeRange { + return MediaHeader_TimeRange.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): MediaHeader_TimeRange { + const message = createBaseMediaHeader_TimeRange(); + message.start = object.start ?? undefined; + message.duration = object.duration ?? undefined; + message.timescale = object.timescale ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: 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; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/next_request_policy.ts b/protos/generated/video_streaming/next_request_policy.ts new file mode 100644 index 0000000..0b0ac2a --- /dev/null +++ b/protos/generated/video_streaming/next_request_policy.ts @@ -0,0 +1,175 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/next_request_policy.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { PlaybackCookie } from "./playback_cookie.js"; + +export const protobufPackage = "video_streaming"; + +export interface NextRequestPolicy { + targetAudioReadaheadMs?: number | undefined; + targetVideoReadaheadMs?: number | undefined; + backoffTimeMs?: number | undefined; + playbackCookie?: PlaybackCookie | undefined; + videoId?: string | undefined; +} + +function createBaseNextRequestPolicy(): NextRequestPolicy { + return { + targetAudioReadaheadMs: undefined, + targetVideoReadaheadMs: undefined, + backoffTimeMs: undefined, + playbackCookie: undefined, + videoId: undefined, + }; +} + +export const NextRequestPolicy: MessageFns = { + encode(message: NextRequestPolicy, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.targetAudioReadaheadMs !== undefined) { + writer.uint32(8).int32(message.targetAudioReadaheadMs); + } + if (message.targetVideoReadaheadMs !== undefined) { + writer.uint32(16).int32(message.targetVideoReadaheadMs); + } + if (message.backoffTimeMs !== undefined) { + writer.uint32(32).int32(message.backoffTimeMs); + } + if (message.playbackCookie !== undefined) { + PlaybackCookie.encode(message.playbackCookie, writer.uint32(58).fork()).join(); + } + if (message.videoId !== undefined) { + writer.uint32(66).string(message.videoId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): NextRequestPolicy { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNextRequestPolicy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.targetAudioReadaheadMs = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.targetVideoReadaheadMs = reader.int32(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.backoffTimeMs = reader.int32(); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.playbackCookie = PlaybackCookie.decode(reader, reader.uint32()); + continue; + case 8: + if (tag !== 66) { + break; + } + + message.videoId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): NextRequestPolicy { + return { + targetAudioReadaheadMs: isSet(object.targetAudioReadaheadMs) + ? globalThis.Number(object.targetAudioReadaheadMs) + : undefined, + targetVideoReadaheadMs: isSet(object.targetVideoReadaheadMs) + ? globalThis.Number(object.targetVideoReadaheadMs) + : undefined, + backoffTimeMs: isSet(object.backoffTimeMs) ? globalThis.Number(object.backoffTimeMs) : undefined, + playbackCookie: isSet(object.playbackCookie) ? PlaybackCookie.fromJSON(object.playbackCookie) : undefined, + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : undefined, + }; + }, + + toJSON(message: NextRequestPolicy): unknown { + const obj: any = {}; + if (message.targetAudioReadaheadMs !== undefined) { + obj.targetAudioReadaheadMs = Math.round(message.targetAudioReadaheadMs); + } + if (message.targetVideoReadaheadMs !== undefined) { + obj.targetVideoReadaheadMs = Math.round(message.targetVideoReadaheadMs); + } + if (message.backoffTimeMs !== undefined) { + obj.backoffTimeMs = Math.round(message.backoffTimeMs); + } + if (message.playbackCookie !== undefined) { + obj.playbackCookie = PlaybackCookie.toJSON(message.playbackCookie); + } + if (message.videoId !== undefined) { + obj.videoId = message.videoId; + } + return obj; + }, + + create, I>>(base?: I): NextRequestPolicy { + return NextRequestPolicy.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): NextRequestPolicy { + const message = createBaseNextRequestPolicy(); + message.targetAudioReadaheadMs = object.targetAudioReadaheadMs ?? undefined; + message.targetVideoReadaheadMs = object.targetVideoReadaheadMs ?? undefined; + message.backoffTimeMs = object.backoffTimeMs ?? undefined; + message.playbackCookie = (object.playbackCookie !== undefined && object.playbackCookie !== null) + ? PlaybackCookie.fromPartial(object.playbackCookie) + : undefined; + message.videoId = object.videoId ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/onesie_request.ts b/protos/generated/video_streaming/onesie_request.ts new file mode 100644 index 0000000..f2ab07f --- /dev/null +++ b/protos/generated/video_streaming/onesie_request.ts @@ -0,0 +1,164 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/onesie_request.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { HttpHeader } from "../misc/common.js"; + +export const protobufPackage = "video_streaming"; + +/** @TODO: Add the rest of the request. */ +export interface OnesieRequest { + url?: string | undefined; + headers: HttpHeader[]; + body?: string | undefined; + field4?: boolean | undefined; + field6?: boolean | undefined; +} + +function createBaseOnesieRequest(): OnesieRequest { + return { url: undefined, headers: [], body: undefined, field4: undefined, field6: undefined }; +} + +export const OnesieRequest: MessageFns = { + encode(message: OnesieRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.url !== undefined) { + writer.uint32(10).string(message.url); + } + for (const v of message.headers) { + HttpHeader.encode(v!, writer.uint32(18).fork()).join(); + } + if (message.body !== undefined) { + writer.uint32(26).string(message.body); + } + if (message.field4 !== undefined) { + writer.uint32(32).bool(message.field4); + } + if (message.field6 !== undefined) { + writer.uint32(48).bool(message.field6); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): OnesieRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseOnesieRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.url = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.headers.push(HttpHeader.decode(reader, reader.uint32())); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.body = reader.string(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.field4 = reader.bool(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.field6 = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): OnesieRequest { + return { + url: isSet(object.url) ? globalThis.String(object.url) : undefined, + headers: globalThis.Array.isArray(object?.headers) ? object.headers.map((e: any) => HttpHeader.fromJSON(e)) : [], + body: isSet(object.body) ? globalThis.String(object.body) : undefined, + field4: isSet(object.field4) ? globalThis.Boolean(object.field4) : undefined, + field6: isSet(object.field6) ? globalThis.Boolean(object.field6) : undefined, + }; + }, + + toJSON(message: OnesieRequest): unknown { + const obj: any = {}; + if (message.url !== undefined) { + obj.url = message.url; + } + if (message.headers?.length) { + obj.headers = message.headers.map((e) => HttpHeader.toJSON(e)); + } + if (message.body !== undefined) { + obj.body = message.body; + } + if (message.field4 !== undefined) { + obj.field4 = message.field4; + } + if (message.field6 !== undefined) { + obj.field6 = message.field6; + } + return obj; + }, + + create, I>>(base?: I): OnesieRequest { + return OnesieRequest.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): OnesieRequest { + const message = createBaseOnesieRequest(); + message.url = object.url ?? undefined; + message.headers = object.headers?.map((e) => HttpHeader.fromPartial(e)) || []; + message.body = object.body ?? undefined; + message.field4 = object.field4 ?? undefined; + message.field6 = object.field6 ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/playback_cookie.ts b/protos/generated/video_streaming/playback_cookie.ts new file mode 100644 index 0000000..acef27c --- /dev/null +++ b/protos/generated/video_streaming/playback_cookie.ts @@ -0,0 +1,152 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/playback_cookie.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { FormatId } from "../misc/common.js"; + +export const protobufPackage = "video_streaming"; + +export interface PlaybackCookie { + /** Always 999999?? */ + field1?: number | undefined; + field2?: number | undefined; + videoFmt?: FormatId | undefined; + audioFmt?: FormatId | undefined; +} + +function createBasePlaybackCookie(): PlaybackCookie { + return { field1: undefined, field2: undefined, videoFmt: undefined, audioFmt: undefined }; +} + +export const PlaybackCookie: MessageFns = { + encode(message: PlaybackCookie, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.field1 !== undefined) { + writer.uint32(8).int32(message.field1); + } + if (message.field2 !== undefined) { + writer.uint32(16).int32(message.field2); + } + if (message.videoFmt !== undefined) { + FormatId.encode(message.videoFmt, writer.uint32(58).fork()).join(); + } + if (message.audioFmt !== undefined) { + FormatId.encode(message.audioFmt, writer.uint32(66).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PlaybackCookie { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePlaybackCookie(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.field1 = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.field2 = reader.int32(); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.videoFmt = FormatId.decode(reader, reader.uint32()); + continue; + case 8: + if (tag !== 66) { + break; + } + + message.audioFmt = FormatId.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PlaybackCookie { + return { + field1: isSet(object.field1) ? globalThis.Number(object.field1) : undefined, + field2: isSet(object.field2) ? globalThis.Number(object.field2) : undefined, + videoFmt: isSet(object.videoFmt) ? FormatId.fromJSON(object.videoFmt) : undefined, + audioFmt: isSet(object.audioFmt) ? FormatId.fromJSON(object.audioFmt) : undefined, + }; + }, + + toJSON(message: PlaybackCookie): unknown { + const obj: any = {}; + if (message.field1 !== undefined) { + obj.field1 = Math.round(message.field1); + } + if (message.field2 !== undefined) { + obj.field2 = Math.round(message.field2); + } + if (message.videoFmt !== undefined) { + obj.videoFmt = FormatId.toJSON(message.videoFmt); + } + if (message.audioFmt !== undefined) { + obj.audioFmt = FormatId.toJSON(message.audioFmt); + } + return obj; + }, + + create, I>>(base?: I): PlaybackCookie { + return PlaybackCookie.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PlaybackCookie { + const message = createBasePlaybackCookie(); + message.field1 = object.field1 ?? undefined; + message.field2 = object.field2 ?? undefined; + message.videoFmt = (object.videoFmt !== undefined && object.videoFmt !== null) + ? FormatId.fromPartial(object.videoFmt) + : undefined; + message.audioFmt = (object.audioFmt !== undefined && object.audioFmt !== null) + ? FormatId.fromPartial(object.audioFmt) + : undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/playback_start_policy.ts b/protos/generated/video_streaming/playback_start_policy.ts new file mode 100644 index 0000000..538b8b4 --- /dev/null +++ b/protos/generated/video_streaming/playback_start_policy.ts @@ -0,0 +1,209 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/playback_start_policy.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "video_streaming"; + +export interface PlaybackStartPolicy { + startMinReadaheadPolicy?: PlaybackStartPolicy_ReadaheadPolicy | undefined; + resumeMinReadaheadPolicy?: PlaybackStartPolicy_ReadaheadPolicy | undefined; +} + +export interface PlaybackStartPolicy_ReadaheadPolicy { + minReadaheadMs?: number | undefined; + minBandwidthBytesPerSec?: number | undefined; +} + +function createBasePlaybackStartPolicy(): PlaybackStartPolicy { + return { startMinReadaheadPolicy: undefined, resumeMinReadaheadPolicy: undefined }; +} + +export const PlaybackStartPolicy: MessageFns = { + encode(message: PlaybackStartPolicy, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.startMinReadaheadPolicy !== undefined) { + PlaybackStartPolicy_ReadaheadPolicy.encode(message.startMinReadaheadPolicy, writer.uint32(10).fork()).join(); + } + if (message.resumeMinReadaheadPolicy !== undefined) { + PlaybackStartPolicy_ReadaheadPolicy.encode(message.resumeMinReadaheadPolicy, writer.uint32(18).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PlaybackStartPolicy { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePlaybackStartPolicy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.startMinReadaheadPolicy = PlaybackStartPolicy_ReadaheadPolicy.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.resumeMinReadaheadPolicy = PlaybackStartPolicy_ReadaheadPolicy.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PlaybackStartPolicy { + return { + startMinReadaheadPolicy: isSet(object.startMinReadaheadPolicy) + ? PlaybackStartPolicy_ReadaheadPolicy.fromJSON(object.startMinReadaheadPolicy) + : undefined, + resumeMinReadaheadPolicy: isSet(object.resumeMinReadaheadPolicy) + ? PlaybackStartPolicy_ReadaheadPolicy.fromJSON(object.resumeMinReadaheadPolicy) + : undefined, + }; + }, + + toJSON(message: PlaybackStartPolicy): unknown { + const obj: any = {}; + if (message.startMinReadaheadPolicy !== undefined) { + obj.startMinReadaheadPolicy = PlaybackStartPolicy_ReadaheadPolicy.toJSON(message.startMinReadaheadPolicy); + } + if (message.resumeMinReadaheadPolicy !== undefined) { + obj.resumeMinReadaheadPolicy = PlaybackStartPolicy_ReadaheadPolicy.toJSON(message.resumeMinReadaheadPolicy); + } + return obj; + }, + + create, I>>(base?: I): PlaybackStartPolicy { + return PlaybackStartPolicy.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PlaybackStartPolicy { + const message = createBasePlaybackStartPolicy(); + message.startMinReadaheadPolicy = + (object.startMinReadaheadPolicy !== undefined && object.startMinReadaheadPolicy !== null) + ? PlaybackStartPolicy_ReadaheadPolicy.fromPartial(object.startMinReadaheadPolicy) + : undefined; + message.resumeMinReadaheadPolicy = + (object.resumeMinReadaheadPolicy !== undefined && object.resumeMinReadaheadPolicy !== null) + ? PlaybackStartPolicy_ReadaheadPolicy.fromPartial(object.resumeMinReadaheadPolicy) + : undefined; + return message; + }, +}; + +function createBasePlaybackStartPolicy_ReadaheadPolicy(): PlaybackStartPolicy_ReadaheadPolicy { + return { minReadaheadMs: undefined, minBandwidthBytesPerSec: undefined }; +} + +export const PlaybackStartPolicy_ReadaheadPolicy: MessageFns = { + encode(message: PlaybackStartPolicy_ReadaheadPolicy, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.minReadaheadMs !== undefined) { + writer.uint32(16).int32(message.minReadaheadMs); + } + if (message.minBandwidthBytesPerSec !== undefined) { + writer.uint32(8).int32(message.minBandwidthBytesPerSec); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PlaybackStartPolicy_ReadaheadPolicy { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePlaybackStartPolicy_ReadaheadPolicy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + if (tag !== 16) { + break; + } + + message.minReadaheadMs = reader.int32(); + continue; + case 1: + if (tag !== 8) { + break; + } + + message.minBandwidthBytesPerSec = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PlaybackStartPolicy_ReadaheadPolicy { + return { + minReadaheadMs: isSet(object.minReadaheadMs) ? globalThis.Number(object.minReadaheadMs) : undefined, + minBandwidthBytesPerSec: isSet(object.minBandwidthBytesPerSec) + ? globalThis.Number(object.minBandwidthBytesPerSec) + : undefined, + }; + }, + + toJSON(message: PlaybackStartPolicy_ReadaheadPolicy): unknown { + const obj: any = {}; + if (message.minReadaheadMs !== undefined) { + obj.minReadaheadMs = Math.round(message.minReadaheadMs); + } + if (message.minBandwidthBytesPerSec !== undefined) { + obj.minBandwidthBytesPerSec = Math.round(message.minBandwidthBytesPerSec); + } + return obj; + }, + + create, I>>( + base?: I, + ): PlaybackStartPolicy_ReadaheadPolicy { + return PlaybackStartPolicy_ReadaheadPolicy.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): PlaybackStartPolicy_ReadaheadPolicy { + const message = createBasePlaybackStartPolicy_ReadaheadPolicy(); + message.minReadaheadMs = object.minReadaheadMs ?? undefined; + message.minBandwidthBytesPerSec = object.minBandwidthBytesPerSec ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/request_cancellation_policy.ts b/protos/generated/video_streaming/request_cancellation_policy.ts new file mode 100644 index 0000000..42b29bf --- /dev/null +++ b/protos/generated/video_streaming/request_cancellation_policy.ts @@ -0,0 +1,229 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/request_cancellation_policy.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "video_streaming"; + +export interface RequestCancellationPolicy { + N0?: number | undefined; + items: RequestCancellationPolicy_Item[]; + jq?: number | undefined; +} + +export interface RequestCancellationPolicy_Item { + fR?: number | undefined; + NK?: number | undefined; + minReadaheadMs?: number | undefined; +} + +function createBaseRequestCancellationPolicy(): RequestCancellationPolicy { + return { N0: undefined, items: [], jq: undefined }; +} + +export const RequestCancellationPolicy: MessageFns = { + encode(message: RequestCancellationPolicy, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.N0 !== undefined) { + writer.uint32(8).int32(message.N0); + } + for (const v of message.items) { + RequestCancellationPolicy_Item.encode(v!, writer.uint32(18).fork()).join(); + } + if (message.jq !== undefined) { + writer.uint32(24).int32(message.jq); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RequestCancellationPolicy { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRequestCancellationPolicy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.N0 = reader.int32(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.items.push(RequestCancellationPolicy_Item.decode(reader, reader.uint32())); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.jq = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): RequestCancellationPolicy { + return { + N0: isSet(object.N0) ? globalThis.Number(object.N0) : undefined, + items: globalThis.Array.isArray(object?.items) + ? object.items.map((e: any) => RequestCancellationPolicy_Item.fromJSON(e)) + : [], + jq: isSet(object.jq) ? globalThis.Number(object.jq) : undefined, + }; + }, + + toJSON(message: RequestCancellationPolicy): unknown { + const obj: any = {}; + if (message.N0 !== undefined) { + obj.N0 = Math.round(message.N0); + } + if (message.items?.length) { + obj.items = message.items.map((e) => RequestCancellationPolicy_Item.toJSON(e)); + } + if (message.jq !== undefined) { + obj.jq = Math.round(message.jq); + } + return obj; + }, + + create, I>>(base?: I): RequestCancellationPolicy { + return RequestCancellationPolicy.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): RequestCancellationPolicy { + const message = createBaseRequestCancellationPolicy(); + message.N0 = object.N0 ?? undefined; + message.items = object.items?.map((e) => RequestCancellationPolicy_Item.fromPartial(e)) || []; + message.jq = object.jq ?? undefined; + return message; + }, +}; + +function createBaseRequestCancellationPolicy_Item(): RequestCancellationPolicy_Item { + return { fR: undefined, NK: undefined, minReadaheadMs: undefined }; +} + +export const RequestCancellationPolicy_Item: MessageFns = { + encode(message: RequestCancellationPolicy_Item, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.fR !== undefined) { + writer.uint32(8).int32(message.fR); + } + if (message.NK !== undefined) { + writer.uint32(16).int32(message.NK); + } + if (message.minReadaheadMs !== undefined) { + writer.uint32(24).int32(message.minReadaheadMs); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RequestCancellationPolicy_Item { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRequestCancellationPolicy_Item(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.fR = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.NK = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.minReadaheadMs = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): RequestCancellationPolicy_Item { + return { + fR: isSet(object.fR) ? globalThis.Number(object.fR) : undefined, + NK: isSet(object.NK) ? globalThis.Number(object.NK) : undefined, + minReadaheadMs: isSet(object.minReadaheadMs) ? globalThis.Number(object.minReadaheadMs) : undefined, + }; + }, + + toJSON(message: RequestCancellationPolicy_Item): unknown { + const obj: any = {}; + if (message.fR !== undefined) { + obj.fR = Math.round(message.fR); + } + if (message.NK !== undefined) { + obj.NK = Math.round(message.NK); + } + if (message.minReadaheadMs !== undefined) { + obj.minReadaheadMs = Math.round(message.minReadaheadMs); + } + return obj; + }, + + create, I>>(base?: I): RequestCancellationPolicy_Item { + return RequestCancellationPolicy_Item.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): RequestCancellationPolicy_Item { + const message = createBaseRequestCancellationPolicy_Item(); + message.fR = object.fR ?? undefined; + message.NK = object.NK ?? undefined; + message.minReadaheadMs = object.minReadaheadMs ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/sabr_error.ts b/protos/generated/video_streaming/sabr_error.ts new file mode 100644 index 0000000..20b427a --- /dev/null +++ b/protos/generated/video_streaming/sabr_error.ts @@ -0,0 +1,114 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/sabr_error.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "video_streaming"; + +export interface SabrError { + type?: string | undefined; + code?: number | undefined; +} + +function createBaseSabrError(): SabrError { + return { type: undefined, code: undefined }; +} + +export const SabrError: MessageFns = { + encode(message: SabrError, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.type !== undefined) { + writer.uint32(10).string(message.type); + } + if (message.code !== undefined) { + writer.uint32(16).int32(message.code); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SabrError { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSabrError(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.type = reader.string(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.code = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SabrError { + return { + type: isSet(object.type) ? globalThis.String(object.type) : undefined, + code: isSet(object.code) ? globalThis.Number(object.code) : undefined, + }; + }, + + toJSON(message: SabrError): unknown { + const obj: any = {}; + if (message.type !== undefined) { + obj.type = message.type; + } + if (message.code !== undefined) { + obj.code = Math.round(message.code); + } + return obj; + }, + + create, I>>(base?: I): SabrError { + return SabrError.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SabrError { + const message = createBaseSabrError(); + message.type = object.type ?? undefined; + message.code = object.code ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/sabr_redirect.ts b/protos/generated/video_streaming/sabr_redirect.ts new file mode 100644 index 0000000..200e8ef --- /dev/null +++ b/protos/generated/video_streaming/sabr_redirect.ts @@ -0,0 +1,96 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/sabr_redirect.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "video_streaming"; + +export interface SabrRedirect { + url?: string | undefined; +} + +function createBaseSabrRedirect(): SabrRedirect { + return { url: undefined }; +} + +export const SabrRedirect: MessageFns = { + encode(message: SabrRedirect, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.url !== undefined) { + writer.uint32(10).string(message.url); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SabrRedirect { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSabrRedirect(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.url = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SabrRedirect { + return { url: isSet(object.url) ? globalThis.String(object.url) : undefined }; + }, + + toJSON(message: SabrRedirect): unknown { + const obj: any = {}; + if (message.url !== undefined) { + obj.url = message.url; + } + return obj; + }, + + create, I>>(base?: I): SabrRedirect { + return SabrRedirect.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SabrRedirect { + const message = createBaseSabrRedirect(); + message.url = object.url ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/stream_protection_status.ts b/protos/generated/video_streaming/stream_protection_status.ts new file mode 100644 index 0000000..d004494 --- /dev/null +++ b/protos/generated/video_streaming/stream_protection_status.ts @@ -0,0 +1,114 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/stream_protection_status.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "video_streaming"; + +export interface StreamProtectionStatus { + status?: number | undefined; + field2?: number | undefined; +} + +function createBaseStreamProtectionStatus(): StreamProtectionStatus { + return { status: undefined, field2: undefined }; +} + +export const StreamProtectionStatus: MessageFns = { + encode(message: StreamProtectionStatus, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.status !== undefined) { + writer.uint32(8).int32(message.status); + } + if (message.field2 !== undefined) { + writer.uint32(16).int32(message.field2); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): StreamProtectionStatus { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseStreamProtectionStatus(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.status = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.field2 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): StreamProtectionStatus { + return { + status: isSet(object.status) ? globalThis.Number(object.status) : undefined, + field2: isSet(object.field2) ? globalThis.Number(object.field2) : undefined, + }; + }, + + toJSON(message: StreamProtectionStatus): unknown { + const obj: any = {}; + if (message.status !== undefined) { + obj.status = Math.round(message.status); + } + if (message.field2 !== undefined) { + obj.field2 = Math.round(message.field2); + } + return obj; + }, + + create, I>>(base?: I): StreamProtectionStatus { + return StreamProtectionStatus.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): StreamProtectionStatus { + const message = createBaseStreamProtectionStatus(); + message.status = object.status ?? undefined; + message.field2 = object.field2 ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/generated/video_streaming/video_playback_abr_request.ts b/protos/generated/video_streaming/video_playback_abr_request.ts new file mode 100644 index 0000000..1ac47aa --- /dev/null +++ b/protos/generated/video_streaming/video_playback_abr_request.ts @@ -0,0 +1,2872 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.2.0 +// protoc v5.28.0 +// source: video_streaming/video_playback_abr_request.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { FormatId } from "../misc/common.js"; + +export const protobufPackage = "video_streaming"; + +export interface VideoPlaybackAbrRequest { + mediaInfo?: MediaInfo | undefined; + formatIds: FormatId[]; + ud: Zpa[]; + videoPlaybackUstreamerConfig?: Uint8Array | undefined; + lo?: Lo | undefined; + audioFormatIds: FormatId[]; + videoFormatIds: FormatId[]; + sc?: Upa | undefined; + field21?: OQa | undefined; + field22?: number | undefined; + field23?: number | undefined; + field1000: Pqa[]; +} + +export interface MediaInfo { + timeSinceLastManualFormatSelectionMs?: number | undefined; + lastManualDirection?: number | undefined; + videoWidth?: number | undefined; + detailedNetworkType?: number | undefined; + B7?: number | undefined; + A7?: number | undefined; + iea?: number | undefined; + r7?: number | undefined; + startTimeMs?: number | undefined; + zea?: number | undefined; + visibility?: number | undefined; + d8?: number | undefined; + mediaCapabilities?: MediaInfo_MediaCapabilities | undefined; + yea?: + | number + | undefined; + /** optional int32 Gw = 40; */ + mediaType?: MediaInfo_MediaType | undefined; + playerState?: number | undefined; + a8?: boolean | undefined; + Jda?: number | undefined; + qw?: number | undefined; + Ky?: number | undefined; + Eq?: number | undefined; + l?: boolean | undefined; + G7?: number | undefined; + No?: boolean | undefined; + qj?: number | undefined; + Hx?: number | undefined; + isPrefetch?: boolean | undefined; + Iz?: number | undefined; + sabrLicenseConstraint?: Uint8Array | undefined; + l2?: number | undefined; + k2?: number | undefined; + Tqb?: number | undefined; + c?: number | undefined; +} + +export enum MediaInfo_MediaType { + MEDIA_TYPE_DEFAULT = 0, + MEDIA_TYPE_AUDIO = 1, + MEDIA_TYPE_VIDEO = 2, + UNRECOGNIZED = -1, +} + +export function mediaInfo_MediaTypeFromJSON(object: any): MediaInfo_MediaType { + switch (object) { + case 0: + case "MEDIA_TYPE_DEFAULT": + return MediaInfo_MediaType.MEDIA_TYPE_DEFAULT; + case 1: + case "MEDIA_TYPE_AUDIO": + return MediaInfo_MediaType.MEDIA_TYPE_AUDIO; + case 2: + case "MEDIA_TYPE_VIDEO": + return MediaInfo_MediaType.MEDIA_TYPE_VIDEO; + case -1: + case "UNRECOGNIZED": + default: + return MediaInfo_MediaType.UNRECOGNIZED; + } +} + +export function mediaInfo_MediaTypeToJSON(object: MediaInfo_MediaType): string { + switch (object) { + case MediaInfo_MediaType.MEDIA_TYPE_DEFAULT: + return "MEDIA_TYPE_DEFAULT"; + case MediaInfo_MediaType.MEDIA_TYPE_AUDIO: + return "MEDIA_TYPE_AUDIO"; + case MediaInfo_MediaType.MEDIA_TYPE_VIDEO: + return "MEDIA_TYPE_VIDEO"; + case MediaInfo_MediaType.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export interface MediaInfo_MediaCapabilities { + videoFormatCapabilities: MediaInfo_MediaCapabilities_VideoFormatCapability[]; + audioFormatCapabilities: MediaInfo_MediaCapabilities_AudioFormatCapability[]; + hdrModeBitmask?: number | undefined; +} + +export interface MediaInfo_MediaCapabilities_VideoFormatCapability { + videoCodec?: number | undefined; + maxHeight?: number | undefined; + maxWidth?: number | undefined; + maxFramerate?: number | undefined; + maxBitrateBps?: number | undefined; + is10BitSupported?: boolean | undefined; +} + +export interface MediaInfo_MediaCapabilities_AudioFormatCapability { + audioCodec?: number | undefined; + numChannels?: number | undefined; + maxBitrateBps?: number | undefined; + spatialCapabilityBitmask?: number | undefined; +} + +export interface Lo { + formatId?: FormatId | undefined; + Lj?: number | undefined; + sequenceNumber?: number | undefined; + field4?: Lo_Field4 | undefined; + MZ?: number | undefined; +} + +export interface Lo_Field4 { + field1?: number | undefined; + field2?: number | undefined; + field3?: number | undefined; +} + +export interface Kob { + EW: Kob_Pa[]; +} + +export interface Kob_Pa { + videoId?: string | undefined; + lmt?: number | undefined; +} + +export interface YPa { + field1?: number | undefined; + field2?: number | undefined; + field3?: number | undefined; +} + +export interface Zpa { + formatId: FormatId | undefined; + startTimeMs: number; + durationMs: number; + field4: number; + field5: number; + field9?: Kob | undefined; + field11?: YPa | undefined; + field12?: YPa | undefined; +} + +export interface Upa { + clientInfo?: Upa_ClientInfo | undefined; + poToken?: Uint8Array | undefined; + playbackCookie?: Uint8Array | undefined; + gp?: Uint8Array | undefined; + field5: Upa_Fqa[]; + field6: number[]; + field7?: string | undefined; + field8?: Upa_Gqa | undefined; +} + +export interface Upa_ClientInfo { + deviceMake?: string | undefined; + deviceModel?: string | undefined; + clientName?: number | undefined; + clientVersion?: string | undefined; + osName?: string | undefined; + osVersion?: string | undefined; +} + +export interface Upa_Fqa { + type?: number | undefined; + value?: Uint8Array | undefined; +} + +export interface Upa_Gqa { + field1?: Uint8Array | undefined; + field2?: Upa_Gqa_Hqa | undefined; +} + +export interface Upa_Gqa_Hqa { + code?: number | undefined; + message?: string | undefined; +} + +export interface OQa { + field1: string[]; + field2?: Uint8Array | undefined; + field3?: string | undefined; + field4?: number | undefined; + field5?: number | undefined; + field6?: string | undefined; +} + +export interface Pqa { + formatIds: FormatId[]; + ud: Zpa[]; + clipId?: string | undefined; +} + +function createBaseVideoPlaybackAbrRequest(): VideoPlaybackAbrRequest { + return { + mediaInfo: undefined, + formatIds: [], + ud: [], + videoPlaybackUstreamerConfig: undefined, + lo: undefined, + audioFormatIds: [], + videoFormatIds: [], + sc: undefined, + field21: undefined, + field22: undefined, + field23: undefined, + field1000: [], + }; +} + +export const VideoPlaybackAbrRequest: MessageFns = { + encode(message: VideoPlaybackAbrRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.mediaInfo !== undefined) { + MediaInfo.encode(message.mediaInfo, writer.uint32(10).fork()).join(); + } + for (const v of message.formatIds) { + FormatId.encode(v!, writer.uint32(18).fork()).join(); + } + for (const v of message.ud) { + Zpa.encode(v!, writer.uint32(26).fork()).join(); + } + if (message.videoPlaybackUstreamerConfig !== undefined) { + writer.uint32(42).bytes(message.videoPlaybackUstreamerConfig); + } + if (message.lo !== undefined) { + Lo.encode(message.lo, writer.uint32(50).fork()).join(); + } + for (const v of message.audioFormatIds) { + FormatId.encode(v!, writer.uint32(130).fork()).join(); + } + for (const v of message.videoFormatIds) { + FormatId.encode(v!, writer.uint32(138).fork()).join(); + } + if (message.sc !== undefined) { + Upa.encode(message.sc, writer.uint32(154).fork()).join(); + } + if (message.field21 !== undefined) { + OQa.encode(message.field21, writer.uint32(170).fork()).join(); + } + if (message.field22 !== undefined) { + writer.uint32(176).int32(message.field22); + } + if (message.field23 !== undefined) { + writer.uint32(184).int32(message.field23); + } + for (const v of message.field1000) { + Pqa.encode(v!, writer.uint32(8002).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VideoPlaybackAbrRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVideoPlaybackAbrRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.mediaInfo = MediaInfo.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.formatIds.push(FormatId.decode(reader, reader.uint32())); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.ud.push(Zpa.decode(reader, reader.uint32())); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.videoPlaybackUstreamerConfig = reader.bytes(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.lo = Lo.decode(reader, reader.uint32()); + continue; + case 16: + if (tag !== 130) { + break; + } + + message.audioFormatIds.push(FormatId.decode(reader, reader.uint32())); + continue; + case 17: + if (tag !== 138) { + break; + } + + message.videoFormatIds.push(FormatId.decode(reader, reader.uint32())); + continue; + case 19: + if (tag !== 154) { + break; + } + + message.sc = Upa.decode(reader, reader.uint32()); + continue; + case 21: + if (tag !== 170) { + break; + } + + message.field21 = OQa.decode(reader, reader.uint32()); + continue; + case 22: + if (tag !== 176) { + break; + } + + message.field22 = reader.int32(); + continue; + case 23: + if (tag !== 184) { + break; + } + + message.field23 = reader.int32(); + continue; + case 1000: + if (tag !== 8002) { + break; + } + + message.field1000.push(Pqa.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VideoPlaybackAbrRequest { + return { + mediaInfo: isSet(object.mediaInfo) ? MediaInfo.fromJSON(object.mediaInfo) : undefined, + formatIds: globalThis.Array.isArray(object?.formatIds) + ? object.formatIds.map((e: any) => FormatId.fromJSON(e)) + : [], + ud: globalThis.Array.isArray(object?.ud) ? object.ud.map((e: any) => Zpa.fromJSON(e)) : [], + videoPlaybackUstreamerConfig: isSet(object.videoPlaybackUstreamerConfig) + ? bytesFromBase64(object.videoPlaybackUstreamerConfig) + : undefined, + lo: isSet(object.lo) ? Lo.fromJSON(object.lo) : undefined, + audioFormatIds: globalThis.Array.isArray(object?.audioFormatIds) + ? object.audioFormatIds.map((e: any) => FormatId.fromJSON(e)) + : [], + videoFormatIds: globalThis.Array.isArray(object?.videoFormatIds) + ? object.videoFormatIds.map((e: any) => FormatId.fromJSON(e)) + : [], + sc: isSet(object.sc) ? Upa.fromJSON(object.sc) : undefined, + field21: isSet(object.field21) ? OQa.fromJSON(object.field21) : undefined, + field22: isSet(object.field22) ? globalThis.Number(object.field22) : undefined, + field23: isSet(object.field23) ? globalThis.Number(object.field23) : undefined, + field1000: globalThis.Array.isArray(object?.field1000) + ? object.field1000.map((e: any) => Pqa.fromJSON(e)) + : [], + }; + }, + + toJSON(message: VideoPlaybackAbrRequest): unknown { + const obj: any = {}; + if (message.mediaInfo !== undefined) { + obj.mediaInfo = MediaInfo.toJSON(message.mediaInfo); + } + if (message.formatIds?.length) { + obj.formatIds = message.formatIds.map((e) => FormatId.toJSON(e)); + } + if (message.ud?.length) { + obj.ud = message.ud.map((e) => Zpa.toJSON(e)); + } + if (message.videoPlaybackUstreamerConfig !== undefined) { + obj.videoPlaybackUstreamerConfig = base64FromBytes(message.videoPlaybackUstreamerConfig); + } + if (message.lo !== undefined) { + obj.lo = Lo.toJSON(message.lo); + } + if (message.audioFormatIds?.length) { + obj.audioFormatIds = message.audioFormatIds.map((e) => FormatId.toJSON(e)); + } + if (message.videoFormatIds?.length) { + obj.videoFormatIds = message.videoFormatIds.map((e) => FormatId.toJSON(e)); + } + if (message.sc !== undefined) { + obj.sc = Upa.toJSON(message.sc); + } + if (message.field21 !== undefined) { + obj.field21 = OQa.toJSON(message.field21); + } + if (message.field22 !== undefined) { + obj.field22 = Math.round(message.field22); + } + if (message.field23 !== undefined) { + obj.field23 = Math.round(message.field23); + } + if (message.field1000?.length) { + obj.field1000 = message.field1000.map((e) => Pqa.toJSON(e)); + } + return obj; + }, + + create, I>>(base?: I): VideoPlaybackAbrRequest { + return VideoPlaybackAbrRequest.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): VideoPlaybackAbrRequest { + const message = createBaseVideoPlaybackAbrRequest(); + message.mediaInfo = (object.mediaInfo !== undefined && object.mediaInfo !== null) + ? MediaInfo.fromPartial(object.mediaInfo) + : undefined; + message.formatIds = object.formatIds?.map((e) => FormatId.fromPartial(e)) || []; + message.ud = object.ud?.map((e) => Zpa.fromPartial(e)) || []; + message.videoPlaybackUstreamerConfig = object.videoPlaybackUstreamerConfig ?? undefined; + message.lo = (object.lo !== undefined && object.lo !== null) ? Lo.fromPartial(object.lo) : undefined; + message.audioFormatIds = object.audioFormatIds?.map((e) => FormatId.fromPartial(e)) || []; + message.videoFormatIds = object.videoFormatIds?.map((e) => FormatId.fromPartial(e)) || []; + message.sc = (object.sc !== undefined && object.sc !== null) ? Upa.fromPartial(object.sc) : undefined; + message.field21 = (object.field21 !== undefined && object.field21 !== null) + ? OQa.fromPartial(object.field21) + : undefined; + message.field22 = object.field22 ?? undefined; + message.field23 = object.field23 ?? undefined; + message.field1000 = object.field1000?.map((e) => Pqa.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseMediaInfo(): MediaInfo { + return { + timeSinceLastManualFormatSelectionMs: undefined, + lastManualDirection: undefined, + videoWidth: undefined, + detailedNetworkType: undefined, + B7: undefined, + A7: undefined, + iea: undefined, + r7: undefined, + startTimeMs: undefined, + zea: undefined, + visibility: undefined, + d8: undefined, + mediaCapabilities: undefined, + yea: undefined, + mediaType: undefined, + playerState: undefined, + a8: undefined, + Jda: undefined, + qw: undefined, + Ky: undefined, + Eq: undefined, + l: undefined, + G7: undefined, + No: undefined, + qj: undefined, + Hx: undefined, + isPrefetch: undefined, + Iz: undefined, + sabrLicenseConstraint: undefined, + l2: undefined, + k2: undefined, + Tqb: undefined, + c: undefined, + }; +} + +export const MediaInfo: MessageFns = { + encode(message: MediaInfo, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.timeSinceLastManualFormatSelectionMs !== undefined) { + writer.uint32(104).int32(message.timeSinceLastManualFormatSelectionMs); + } + if (message.lastManualDirection !== undefined) { + writer.uint32(112).int32(message.lastManualDirection); + } + if (message.videoWidth !== undefined) { + writer.uint32(128).int32(message.videoWidth); + } + if (message.detailedNetworkType !== undefined) { + writer.uint32(136).int32(message.detailedNetworkType); + } + if (message.B7 !== undefined) { + writer.uint32(144).int32(message.B7); + } + if (message.A7 !== undefined) { + writer.uint32(152).int32(message.A7); + } + if (message.iea !== undefined) { + writer.uint32(168).int32(message.iea); + } + if (message.r7 !== undefined) { + writer.uint32(184).int32(message.r7); + } + if (message.startTimeMs !== undefined) { + writer.uint32(224).int32(message.startTimeMs); + } + if (message.zea !== undefined) { + writer.uint32(232).int32(message.zea); + } + if (message.visibility !== undefined) { + writer.uint32(272).int32(message.visibility); + } + if (message.d8 !== undefined) { + writer.uint32(288).int32(message.d8); + } + if (message.mediaCapabilities !== undefined) { + MediaInfo_MediaCapabilities.encode(message.mediaCapabilities, writer.uint32(306).fork()).join(); + } + if (message.yea !== undefined) { + writer.uint32(312).int32(message.yea); + } + if (message.mediaType !== undefined) { + writer.uint32(320).int32(message.mediaType); + } + if (message.playerState !== undefined) { + writer.uint32(352).int32(message.playerState); + } + if (message.a8 !== undefined) { + writer.uint32(368).bool(message.a8); + } + if (message.Jda !== undefined) { + writer.uint32(384).int32(message.Jda); + } + if (message.qw !== undefined) { + writer.uint32(400).int32(message.qw); + } + if (message.Ky !== undefined) { + writer.uint32(408).int32(message.Ky); + } + if (message.Eq !== undefined) { + writer.uint32(432).int32(message.Eq); + } + if (message.l !== undefined) { + writer.uint32(448).bool(message.l); + } + if (message.G7 !== undefined) { + writer.uint32(456).int32(message.G7); + } + if (message.No !== undefined) { + writer.uint32(464).bool(message.No); + } + if (message.qj !== undefined) { + writer.uint32(472).int32(message.qj); + } + if (message.Hx !== undefined) { + writer.uint32(480).int32(message.Hx); + } + if (message.isPrefetch !== undefined) { + writer.uint32(488).bool(message.isPrefetch); + } + if (message.Iz !== undefined) { + writer.uint32(496).int32(message.Iz); + } + if (message.sabrLicenseConstraint !== undefined) { + writer.uint32(506).bytes(message.sabrLicenseConstraint); + } + if (message.l2 !== undefined) { + writer.uint32(512).int32(message.l2); + } + if (message.k2 !== undefined) { + writer.uint32(528).int32(message.k2); + } + if (message.Tqb !== undefined) { + writer.uint32(536).int32(message.Tqb); + } + if (message.c !== undefined) { + writer.uint32(544).int32(message.c); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): MediaInfo { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMediaInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 13: + if (tag !== 104) { + break; + } + + message.timeSinceLastManualFormatSelectionMs = reader.int32(); + continue; + case 14: + if (tag !== 112) { + break; + } + + message.lastManualDirection = reader.int32(); + continue; + case 16: + if (tag !== 128) { + break; + } + + message.videoWidth = reader.int32(); + continue; + case 17: + if (tag !== 136) { + break; + } + + message.detailedNetworkType = reader.int32(); + continue; + case 18: + if (tag !== 144) { + break; + } + + message.B7 = reader.int32(); + continue; + case 19: + if (tag !== 152) { + break; + } + + message.A7 = reader.int32(); + continue; + case 21: + if (tag !== 168) { + break; + } + + message.iea = reader.int32(); + continue; + case 23: + if (tag !== 184) { + break; + } + + message.r7 = reader.int32(); + continue; + case 28: + if (tag !== 224) { + break; + } + + message.startTimeMs = reader.int32(); + continue; + case 29: + if (tag !== 232) { + break; + } + + message.zea = reader.int32(); + continue; + case 34: + if (tag !== 272) { + break; + } + + message.visibility = reader.int32(); + continue; + case 36: + if (tag !== 288) { + break; + } + + message.d8 = reader.int32(); + continue; + case 38: + if (tag !== 306) { + break; + } + + message.mediaCapabilities = MediaInfo_MediaCapabilities.decode(reader, reader.uint32()); + continue; + case 39: + if (tag !== 312) { + break; + } + + message.yea = reader.int32(); + continue; + case 40: + if (tag !== 320) { + break; + } + + message.mediaType = reader.int32() as any; + continue; + case 44: + if (tag !== 352) { + break; + } + + message.playerState = reader.int32(); + continue; + case 46: + if (tag !== 368) { + break; + } + + message.a8 = reader.bool(); + continue; + case 48: + if (tag !== 384) { + break; + } + + message.Jda = reader.int32(); + continue; + case 50: + if (tag !== 400) { + break; + } + + message.qw = reader.int32(); + continue; + case 51: + if (tag !== 408) { + break; + } + + message.Ky = reader.int32(); + continue; + case 54: + if (tag !== 432) { + break; + } + + message.Eq = reader.int32(); + continue; + case 56: + if (tag !== 448) { + break; + } + + message.l = reader.bool(); + continue; + case 57: + if (tag !== 456) { + break; + } + + message.G7 = reader.int32(); + continue; + case 58: + if (tag !== 464) { + break; + } + + message.No = reader.bool(); + continue; + case 59: + if (tag !== 472) { + break; + } + + message.qj = reader.int32(); + continue; + case 60: + if (tag !== 480) { + break; + } + + message.Hx = reader.int32(); + continue; + case 61: + if (tag !== 488) { + break; + } + + message.isPrefetch = reader.bool(); + continue; + case 62: + if (tag !== 496) { + break; + } + + message.Iz = reader.int32(); + continue; + case 63: + if (tag !== 506) { + break; + } + + message.sabrLicenseConstraint = reader.bytes(); + continue; + case 64: + if (tag !== 512) { + break; + } + + message.l2 = reader.int32(); + continue; + case 66: + if (tag !== 528) { + break; + } + + message.k2 = reader.int32(); + continue; + case 67: + if (tag !== 536) { + break; + } + + message.Tqb = reader.int32(); + continue; + case 68: + if (tag !== 544) { + break; + } + + message.c = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): MediaInfo { + return { + timeSinceLastManualFormatSelectionMs: isSet(object.timeSinceLastManualFormatSelectionMs) + ? globalThis.Number(object.timeSinceLastManualFormatSelectionMs) + : undefined, + lastManualDirection: isSet(object.lastManualDirection) + ? globalThis.Number(object.lastManualDirection) + : undefined, + videoWidth: isSet(object.videoWidth) ? globalThis.Number(object.videoWidth) : undefined, + detailedNetworkType: isSet(object.detailedNetworkType) + ? globalThis.Number(object.detailedNetworkType) + : undefined, + B7: isSet(object.B7) ? globalThis.Number(object.B7) : undefined, + A7: isSet(object.A7) ? globalThis.Number(object.A7) : undefined, + iea: isSet(object.iea) ? globalThis.Number(object.iea) : undefined, + r7: isSet(object.r7) ? globalThis.Number(object.r7) : undefined, + startTimeMs: isSet(object.startTimeMs) ? globalThis.Number(object.startTimeMs) : undefined, + zea: isSet(object.zea) ? globalThis.Number(object.zea) : undefined, + visibility: isSet(object.visibility) ? globalThis.Number(object.visibility) : undefined, + d8: isSet(object.d8) ? globalThis.Number(object.d8) : undefined, + mediaCapabilities: isSet(object.mediaCapabilities) + ? MediaInfo_MediaCapabilities.fromJSON(object.mediaCapabilities) + : undefined, + yea: isSet(object.yea) ? globalThis.Number(object.yea) : undefined, + mediaType: isSet(object.mediaType) ? mediaInfo_MediaTypeFromJSON(object.mediaType) : undefined, + playerState: isSet(object.playerState) ? globalThis.Number(object.playerState) : undefined, + a8: isSet(object.a8) ? globalThis.Boolean(object.a8) : undefined, + Jda: isSet(object.Jda) ? globalThis.Number(object.Jda) : undefined, + qw: isSet(object.qw) ? globalThis.Number(object.qw) : undefined, + Ky: isSet(object.Ky) ? globalThis.Number(object.Ky) : undefined, + Eq: isSet(object.Eq) ? globalThis.Number(object.Eq) : undefined, + l: isSet(object.l) ? globalThis.Boolean(object.l) : undefined, + G7: isSet(object.G7) ? globalThis.Number(object.G7) : undefined, + No: isSet(object.No) ? globalThis.Boolean(object.No) : undefined, + qj: isSet(object.qj) ? globalThis.Number(object.qj) : undefined, + Hx: isSet(object.Hx) ? globalThis.Number(object.Hx) : undefined, + isPrefetch: isSet(object.isPrefetch) ? globalThis.Boolean(object.isPrefetch) : undefined, + Iz: isSet(object.Iz) ? globalThis.Number(object.Iz) : undefined, + sabrLicenseConstraint: isSet(object.sabrLicenseConstraint) + ? bytesFromBase64(object.sabrLicenseConstraint) + : undefined, + l2: isSet(object.l2) ? globalThis.Number(object.l2) : undefined, + k2: isSet(object.k2) ? globalThis.Number(object.k2) : undefined, + Tqb: isSet(object.Tqb) ? globalThis.Number(object.Tqb) : undefined, + c: isSet(object.c) ? globalThis.Number(object.c) : undefined, + }; + }, + + toJSON(message: MediaInfo): unknown { + const obj: any = {}; + if (message.timeSinceLastManualFormatSelectionMs !== undefined) { + obj.timeSinceLastManualFormatSelectionMs = Math.round(message.timeSinceLastManualFormatSelectionMs); + } + if (message.lastManualDirection !== undefined) { + obj.lastManualDirection = Math.round(message.lastManualDirection); + } + if (message.videoWidth !== undefined) { + obj.videoWidth = Math.round(message.videoWidth); + } + if (message.detailedNetworkType !== undefined) { + obj.detailedNetworkType = Math.round(message.detailedNetworkType); + } + if (message.B7 !== undefined) { + obj.B7 = Math.round(message.B7); + } + if (message.A7 !== undefined) { + obj.A7 = Math.round(message.A7); + } + if (message.iea !== undefined) { + obj.iea = Math.round(message.iea); + } + if (message.r7 !== undefined) { + obj.r7 = Math.round(message.r7); + } + if (message.startTimeMs !== undefined) { + obj.startTimeMs = Math.round(message.startTimeMs); + } + if (message.zea !== undefined) { + obj.zea = Math.round(message.zea); + } + if (message.visibility !== undefined) { + obj.visibility = Math.round(message.visibility); + } + if (message.d8 !== undefined) { + obj.d8 = Math.round(message.d8); + } + if (message.mediaCapabilities !== undefined) { + obj.mediaCapabilities = MediaInfo_MediaCapabilities.toJSON(message.mediaCapabilities); + } + if (message.yea !== undefined) { + obj.yea = Math.round(message.yea); + } + if (message.mediaType !== undefined) { + obj.mediaType = mediaInfo_MediaTypeToJSON(message.mediaType); + } + if (message.playerState !== undefined) { + obj.playerState = Math.round(message.playerState); + } + if (message.a8 !== undefined) { + obj.a8 = message.a8; + } + if (message.Jda !== undefined) { + obj.Jda = Math.round(message.Jda); + } + if (message.qw !== undefined) { + obj.qw = Math.round(message.qw); + } + if (message.Ky !== undefined) { + obj.Ky = Math.round(message.Ky); + } + if (message.Eq !== undefined) { + obj.Eq = Math.round(message.Eq); + } + if (message.l !== undefined) { + obj.l = message.l; + } + if (message.G7 !== undefined) { + obj.G7 = Math.round(message.G7); + } + if (message.No !== undefined) { + obj.No = message.No; + } + if (message.qj !== undefined) { + obj.qj = Math.round(message.qj); + } + if (message.Hx !== undefined) { + obj.Hx = Math.round(message.Hx); + } + if (message.isPrefetch !== undefined) { + obj.isPrefetch = message.isPrefetch; + } + if (message.Iz !== undefined) { + obj.Iz = Math.round(message.Iz); + } + if (message.sabrLicenseConstraint !== undefined) { + obj.sabrLicenseConstraint = base64FromBytes(message.sabrLicenseConstraint); + } + if (message.l2 !== undefined) { + obj.l2 = Math.round(message.l2); + } + if (message.k2 !== undefined) { + obj.k2 = Math.round(message.k2); + } + if (message.Tqb !== undefined) { + obj.Tqb = Math.round(message.Tqb); + } + if (message.c !== undefined) { + obj.c = Math.round(message.c); + } + return obj; + }, + + create, I>>(base?: I): MediaInfo { + return MediaInfo.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): MediaInfo { + const message = createBaseMediaInfo(); + message.timeSinceLastManualFormatSelectionMs = object.timeSinceLastManualFormatSelectionMs ?? undefined; + message.lastManualDirection = object.lastManualDirection ?? undefined; + message.videoWidth = object.videoWidth ?? undefined; + message.detailedNetworkType = object.detailedNetworkType ?? undefined; + message.B7 = object.B7 ?? undefined; + message.A7 = object.A7 ?? undefined; + message.iea = object.iea ?? undefined; + message.r7 = object.r7 ?? undefined; + message.startTimeMs = object.startTimeMs ?? undefined; + message.zea = object.zea ?? undefined; + message.visibility = object.visibility ?? undefined; + message.d8 = object.d8 ?? undefined; + message.mediaCapabilities = (object.mediaCapabilities !== undefined && object.mediaCapabilities !== null) + ? MediaInfo_MediaCapabilities.fromPartial(object.mediaCapabilities) + : undefined; + message.yea = object.yea ?? undefined; + message.mediaType = object.mediaType ?? undefined; + message.playerState = object.playerState ?? undefined; + message.a8 = object.a8 ?? undefined; + message.Jda = object.Jda ?? undefined; + message.qw = object.qw ?? undefined; + message.Ky = object.Ky ?? undefined; + message.Eq = object.Eq ?? undefined; + message.l = object.l ?? undefined; + message.G7 = object.G7 ?? undefined; + message.No = object.No ?? undefined; + message.qj = object.qj ?? undefined; + message.Hx = object.Hx ?? undefined; + message.isPrefetch = object.isPrefetch ?? undefined; + message.Iz = object.Iz ?? undefined; + message.sabrLicenseConstraint = object.sabrLicenseConstraint ?? undefined; + message.l2 = object.l2 ?? undefined; + message.k2 = object.k2 ?? undefined; + message.Tqb = object.Tqb ?? undefined; + message.c = object.c ?? undefined; + return message; + }, +}; + +function createBaseMediaInfo_MediaCapabilities(): MediaInfo_MediaCapabilities { + return { videoFormatCapabilities: [], audioFormatCapabilities: [], hdrModeBitmask: undefined }; +} + +export const MediaInfo_MediaCapabilities: MessageFns = { + encode(message: MediaInfo_MediaCapabilities, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.videoFormatCapabilities) { + MediaInfo_MediaCapabilities_VideoFormatCapability.encode(v!, writer.uint32(10).fork()).join(); + } + for (const v of message.audioFormatCapabilities) { + MediaInfo_MediaCapabilities_AudioFormatCapability.encode(v!, writer.uint32(18).fork()).join(); + } + if (message.hdrModeBitmask !== undefined) { + writer.uint32(40).int32(message.hdrModeBitmask); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): MediaInfo_MediaCapabilities { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMediaInfo_MediaCapabilities(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.videoFormatCapabilities.push( + MediaInfo_MediaCapabilities_VideoFormatCapability.decode(reader, reader.uint32()), + ); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.audioFormatCapabilities.push( + MediaInfo_MediaCapabilities_AudioFormatCapability.decode(reader, reader.uint32()), + ); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.hdrModeBitmask = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): MediaInfo_MediaCapabilities { + return { + videoFormatCapabilities: globalThis.Array.isArray(object?.videoFormatCapabilities) + ? object.videoFormatCapabilities.map((e: any) => MediaInfo_MediaCapabilities_VideoFormatCapability.fromJSON(e)) + : [], + audioFormatCapabilities: globalThis.Array.isArray(object?.audioFormatCapabilities) + ? object.audioFormatCapabilities.map((e: any) => MediaInfo_MediaCapabilities_AudioFormatCapability.fromJSON(e)) + : [], + hdrModeBitmask: isSet(object.hdrModeBitmask) ? globalThis.Number(object.hdrModeBitmask) : undefined, + }; + }, + + toJSON(message: MediaInfo_MediaCapabilities): unknown { + const obj: any = {}; + if (message.videoFormatCapabilities?.length) { + obj.videoFormatCapabilities = message.videoFormatCapabilities.map((e) => + MediaInfo_MediaCapabilities_VideoFormatCapability.toJSON(e) + ); + } + if (message.audioFormatCapabilities?.length) { + obj.audioFormatCapabilities = message.audioFormatCapabilities.map((e) => + MediaInfo_MediaCapabilities_AudioFormatCapability.toJSON(e) + ); + } + if (message.hdrModeBitmask !== undefined) { + obj.hdrModeBitmask = Math.round(message.hdrModeBitmask); + } + return obj; + }, + + create, I>>(base?: I): MediaInfo_MediaCapabilities { + return MediaInfo_MediaCapabilities.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): MediaInfo_MediaCapabilities { + const message = createBaseMediaInfo_MediaCapabilities(); + message.videoFormatCapabilities = + object.videoFormatCapabilities?.map((e) => MediaInfo_MediaCapabilities_VideoFormatCapability.fromPartial(e)) || + []; + message.audioFormatCapabilities = + object.audioFormatCapabilities?.map((e) => MediaInfo_MediaCapabilities_AudioFormatCapability.fromPartial(e)) || + []; + message.hdrModeBitmask = object.hdrModeBitmask ?? undefined; + return message; + }, +}; + +function createBaseMediaInfo_MediaCapabilities_VideoFormatCapability(): MediaInfo_MediaCapabilities_VideoFormatCapability { + return { + videoCodec: undefined, + maxHeight: undefined, + maxWidth: undefined, + maxFramerate: undefined, + maxBitrateBps: undefined, + is10BitSupported: undefined, + }; +} + +export const MediaInfo_MediaCapabilities_VideoFormatCapability: MessageFns< + MediaInfo_MediaCapabilities_VideoFormatCapability +> = { + encode( + message: MediaInfo_MediaCapabilities_VideoFormatCapability, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.videoCodec !== undefined) { + writer.uint32(8).int32(message.videoCodec); + } + if (message.maxHeight !== undefined) { + writer.uint32(24).int32(message.maxHeight); + } + if (message.maxWidth !== undefined) { + writer.uint32(32).int32(message.maxWidth); + } + if (message.maxFramerate !== undefined) { + writer.uint32(88).int32(message.maxFramerate); + } + if (message.maxBitrateBps !== undefined) { + writer.uint32(96).int32(message.maxBitrateBps); + } + if (message.is10BitSupported !== undefined) { + writer.uint32(120).bool(message.is10BitSupported); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): MediaInfo_MediaCapabilities_VideoFormatCapability { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMediaInfo_MediaCapabilities_VideoFormatCapability(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.videoCodec = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.maxHeight = reader.int32(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.maxWidth = reader.int32(); + continue; + case 11: + if (tag !== 88) { + break; + } + + message.maxFramerate = reader.int32(); + continue; + case 12: + if (tag !== 96) { + break; + } + + message.maxBitrateBps = reader.int32(); + continue; + case 15: + if (tag !== 120) { + break; + } + + message.is10BitSupported = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): MediaInfo_MediaCapabilities_VideoFormatCapability { + return { + videoCodec: isSet(object.videoCodec) ? globalThis.Number(object.videoCodec) : undefined, + maxHeight: isSet(object.maxHeight) ? globalThis.Number(object.maxHeight) : undefined, + maxWidth: isSet(object.maxWidth) ? globalThis.Number(object.maxWidth) : undefined, + maxFramerate: isSet(object.maxFramerate) ? globalThis.Number(object.maxFramerate) : undefined, + maxBitrateBps: isSet(object.maxBitrateBps) ? globalThis.Number(object.maxBitrateBps) : undefined, + is10BitSupported: isSet(object.is10BitSupported) ? globalThis.Boolean(object.is10BitSupported) : undefined, + }; + }, + + toJSON(message: MediaInfo_MediaCapabilities_VideoFormatCapability): unknown { + const obj: any = {}; + if (message.videoCodec !== undefined) { + obj.videoCodec = Math.round(message.videoCodec); + } + if (message.maxHeight !== undefined) { + obj.maxHeight = Math.round(message.maxHeight); + } + if (message.maxWidth !== undefined) { + obj.maxWidth = Math.round(message.maxWidth); + } + if (message.maxFramerate !== undefined) { + obj.maxFramerate = Math.round(message.maxFramerate); + } + if (message.maxBitrateBps !== undefined) { + obj.maxBitrateBps = Math.round(message.maxBitrateBps); + } + if (message.is10BitSupported !== undefined) { + obj.is10BitSupported = message.is10BitSupported; + } + return obj; + }, + + create, I>>( + base?: I, + ): MediaInfo_MediaCapabilities_VideoFormatCapability { + return MediaInfo_MediaCapabilities_VideoFormatCapability.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): MediaInfo_MediaCapabilities_VideoFormatCapability { + const message = createBaseMediaInfo_MediaCapabilities_VideoFormatCapability(); + message.videoCodec = object.videoCodec ?? undefined; + message.maxHeight = object.maxHeight ?? undefined; + message.maxWidth = object.maxWidth ?? undefined; + message.maxFramerate = object.maxFramerate ?? undefined; + message.maxBitrateBps = object.maxBitrateBps ?? undefined; + message.is10BitSupported = object.is10BitSupported ?? undefined; + return message; + }, +}; + +function createBaseMediaInfo_MediaCapabilities_AudioFormatCapability(): MediaInfo_MediaCapabilities_AudioFormatCapability { + return { + audioCodec: undefined, + numChannels: undefined, + maxBitrateBps: undefined, + spatialCapabilityBitmask: undefined, + }; +} + +export const MediaInfo_MediaCapabilities_AudioFormatCapability: MessageFns< + MediaInfo_MediaCapabilities_AudioFormatCapability +> = { + encode( + message: MediaInfo_MediaCapabilities_AudioFormatCapability, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.audioCodec !== undefined) { + writer.uint32(8).int32(message.audioCodec); + } + if (message.numChannels !== undefined) { + writer.uint32(16).int32(message.numChannels); + } + if (message.maxBitrateBps !== undefined) { + writer.uint32(24).int32(message.maxBitrateBps); + } + if (message.spatialCapabilityBitmask !== undefined) { + writer.uint32(48).int32(message.spatialCapabilityBitmask); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): MediaInfo_MediaCapabilities_AudioFormatCapability { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMediaInfo_MediaCapabilities_AudioFormatCapability(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.audioCodec = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.numChannels = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.maxBitrateBps = reader.int32(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.spatialCapabilityBitmask = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): MediaInfo_MediaCapabilities_AudioFormatCapability { + return { + audioCodec: isSet(object.audioCodec) ? globalThis.Number(object.audioCodec) : undefined, + numChannels: isSet(object.numChannels) ? globalThis.Number(object.numChannels) : undefined, + maxBitrateBps: isSet(object.maxBitrateBps) ? globalThis.Number(object.maxBitrateBps) : undefined, + spatialCapabilityBitmask: isSet(object.spatialCapabilityBitmask) + ? globalThis.Number(object.spatialCapabilityBitmask) + : undefined, + }; + }, + + toJSON(message: MediaInfo_MediaCapabilities_AudioFormatCapability): unknown { + const obj: any = {}; + if (message.audioCodec !== undefined) { + obj.audioCodec = Math.round(message.audioCodec); + } + if (message.numChannels !== undefined) { + obj.numChannels = Math.round(message.numChannels); + } + if (message.maxBitrateBps !== undefined) { + obj.maxBitrateBps = Math.round(message.maxBitrateBps); + } + if (message.spatialCapabilityBitmask !== undefined) { + obj.spatialCapabilityBitmask = Math.round(message.spatialCapabilityBitmask); + } + return obj; + }, + + create, I>>( + base?: I, + ): MediaInfo_MediaCapabilities_AudioFormatCapability { + return MediaInfo_MediaCapabilities_AudioFormatCapability.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): MediaInfo_MediaCapabilities_AudioFormatCapability { + const message = createBaseMediaInfo_MediaCapabilities_AudioFormatCapability(); + message.audioCodec = object.audioCodec ?? undefined; + message.numChannels = object.numChannels ?? undefined; + message.maxBitrateBps = object.maxBitrateBps ?? undefined; + message.spatialCapabilityBitmask = object.spatialCapabilityBitmask ?? undefined; + return message; + }, +}; + +function createBaseLo(): Lo { + return { formatId: undefined, Lj: undefined, sequenceNumber: undefined, field4: undefined, MZ: undefined }; +} + +export const Lo: MessageFns = { + encode(message: Lo, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.formatId !== undefined) { + FormatId.encode(message.formatId, writer.uint32(10).fork()).join(); + } + if (message.Lj !== undefined) { + writer.uint32(16).int32(message.Lj); + } + if (message.sequenceNumber !== undefined) { + writer.uint32(24).int32(message.sequenceNumber); + } + if (message.field4 !== undefined) { + Lo_Field4.encode(message.field4, writer.uint32(34).fork()).join(); + } + if (message.MZ !== undefined) { + writer.uint32(40).int32(message.MZ); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Lo { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.formatId = FormatId.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.Lj = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.sequenceNumber = reader.int32(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.field4 = Lo_Field4.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.MZ = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Lo { + return { + formatId: isSet(object.formatId) ? FormatId.fromJSON(object.formatId) : undefined, + Lj: isSet(object.Lj) ? globalThis.Number(object.Lj) : undefined, + sequenceNumber: isSet(object.sequenceNumber) ? globalThis.Number(object.sequenceNumber) : undefined, + field4: isSet(object.field4) ? Lo_Field4.fromJSON(object.field4) : undefined, + MZ: isSet(object.MZ) ? globalThis.Number(object.MZ) : undefined, + }; + }, + + toJSON(message: Lo): unknown { + const obj: any = {}; + if (message.formatId !== undefined) { + obj.formatId = FormatId.toJSON(message.formatId); + } + if (message.Lj !== undefined) { + obj.Lj = Math.round(message.Lj); + } + if (message.sequenceNumber !== undefined) { + obj.sequenceNumber = Math.round(message.sequenceNumber); + } + if (message.field4 !== undefined) { + obj.field4 = Lo_Field4.toJSON(message.field4); + } + if (message.MZ !== undefined) { + obj.MZ = Math.round(message.MZ); + } + return obj; + }, + + create, I>>(base?: I): Lo { + return Lo.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Lo { + const message = createBaseLo(); + message.formatId = (object.formatId !== undefined && object.formatId !== null) + ? FormatId.fromPartial(object.formatId) + : undefined; + message.Lj = object.Lj ?? undefined; + message.sequenceNumber = object.sequenceNumber ?? undefined; + message.field4 = (object.field4 !== undefined && object.field4 !== null) + ? Lo_Field4.fromPartial(object.field4) + : undefined; + message.MZ = object.MZ ?? undefined; + return message; + }, +}; + +function createBaseLo_Field4(): Lo_Field4 { + return { field1: undefined, field2: undefined, field3: undefined }; +} + +export const Lo_Field4: MessageFns = { + encode(message: Lo_Field4, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.field1 !== undefined) { + writer.uint32(8).int32(message.field1); + } + if (message.field2 !== undefined) { + writer.uint32(16).int32(message.field2); + } + if (message.field3 !== undefined) { + writer.uint32(24).int32(message.field3); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Lo_Field4 { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLo_Field4(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.field1 = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.field2 = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.field3 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Lo_Field4 { + return { + field1: isSet(object.field1) ? globalThis.Number(object.field1) : undefined, + field2: isSet(object.field2) ? globalThis.Number(object.field2) : undefined, + field3: isSet(object.field3) ? globalThis.Number(object.field3) : undefined, + }; + }, + + toJSON(message: Lo_Field4): unknown { + const obj: any = {}; + if (message.field1 !== undefined) { + obj.field1 = Math.round(message.field1); + } + if (message.field2 !== undefined) { + obj.field2 = Math.round(message.field2); + } + if (message.field3 !== undefined) { + obj.field3 = Math.round(message.field3); + } + return obj; + }, + + create, I>>(base?: I): Lo_Field4 { + return Lo_Field4.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Lo_Field4 { + const message = createBaseLo_Field4(); + message.field1 = object.field1 ?? undefined; + message.field2 = object.field2 ?? undefined; + message.field3 = object.field3 ?? undefined; + return message; + }, +}; + +function createBaseKob(): Kob { + return { EW: [] }; +} + +export const Kob: MessageFns = { + encode(message: Kob, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.EW) { + Kob_Pa.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Kob { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseKob(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.EW.push(Kob_Pa.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Kob { + return { EW: globalThis.Array.isArray(object?.EW) ? object.EW.map((e: any) => Kob_Pa.fromJSON(e)) : [] }; + }, + + toJSON(message: Kob): unknown { + const obj: any = {}; + if (message.EW?.length) { + obj.EW = message.EW.map((e) => Kob_Pa.toJSON(e)); + } + return obj; + }, + + create, I>>(base?: I): Kob { + return Kob.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Kob { + const message = createBaseKob(); + message.EW = object.EW?.map((e) => Kob_Pa.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseKob_Pa(): Kob_Pa { + return { videoId: undefined, lmt: undefined }; +} + +export const Kob_Pa: MessageFns = { + encode(message: Kob_Pa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.videoId !== undefined) { + writer.uint32(10).string(message.videoId); + } + if (message.lmt !== undefined) { + writer.uint32(16).uint64(message.lmt); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Kob_Pa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseKob_Pa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.videoId = reader.string(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.lmt = longToNumber(reader.uint64()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Kob_Pa { + return { + videoId: isSet(object.videoId) ? globalThis.String(object.videoId) : undefined, + lmt: isSet(object.lmt) ? globalThis.Number(object.lmt) : undefined, + }; + }, + + toJSON(message: Kob_Pa): unknown { + const obj: any = {}; + if (message.videoId !== undefined) { + obj.videoId = message.videoId; + } + if (message.lmt !== undefined) { + obj.lmt = Math.round(message.lmt); + } + return obj; + }, + + create, I>>(base?: I): Kob_Pa { + return Kob_Pa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Kob_Pa { + const message = createBaseKob_Pa(); + message.videoId = object.videoId ?? undefined; + message.lmt = object.lmt ?? undefined; + return message; + }, +}; + +function createBaseYPa(): YPa { + return { field1: undefined, field2: undefined, field3: undefined }; +} + +export const YPa: MessageFns = { + encode(message: YPa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.field1 !== undefined) { + writer.uint32(8).int32(message.field1); + } + if (message.field2 !== undefined) { + writer.uint32(16).int32(message.field2); + } + if (message.field3 !== undefined) { + writer.uint32(24).int32(message.field3); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): YPa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseYPa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.field1 = reader.int32(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.field2 = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.field3 = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): YPa { + return { + field1: isSet(object.field1) ? globalThis.Number(object.field1) : undefined, + field2: isSet(object.field2) ? globalThis.Number(object.field2) : undefined, + field3: isSet(object.field3) ? globalThis.Number(object.field3) : undefined, + }; + }, + + toJSON(message: YPa): unknown { + const obj: any = {}; + if (message.field1 !== undefined) { + obj.field1 = Math.round(message.field1); + } + if (message.field2 !== undefined) { + obj.field2 = Math.round(message.field2); + } + if (message.field3 !== undefined) { + obj.field3 = Math.round(message.field3); + } + return obj; + }, + + create, I>>(base?: I): YPa { + return YPa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): YPa { + const message = createBaseYPa(); + message.field1 = object.field1 ?? undefined; + message.field2 = object.field2 ?? undefined; + message.field3 = object.field3 ?? undefined; + return message; + }, +}; + +function createBaseZpa(): Zpa { + return { + formatId: undefined, + startTimeMs: 0, + durationMs: 0, + field4: 0, + field5: 0, + field9: undefined, + field11: undefined, + field12: undefined, + }; +} + +export const Zpa: MessageFns = { + encode(message: Zpa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.formatId !== undefined) { + FormatId.encode(message.formatId, writer.uint32(10).fork()).join(); + } + if (message.startTimeMs !== 0) { + writer.uint32(16).int32(message.startTimeMs); + } + if (message.durationMs !== 0) { + writer.uint32(24).int32(message.durationMs); + } + if (message.field4 !== 0) { + writer.uint32(32).int32(message.field4); + } + if (message.field5 !== 0) { + writer.uint32(40).int32(message.field5); + } + if (message.field9 !== undefined) { + Kob.encode(message.field9, writer.uint32(74).fork()).join(); + } + if (message.field11 !== undefined) { + YPa.encode(message.field11, writer.uint32(90).fork()).join(); + } + if (message.field12 !== undefined) { + YPa.encode(message.field12, writer.uint32(98).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Zpa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZpa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.formatId = FormatId.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.startTimeMs = reader.int32(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.durationMs = reader.int32(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.field4 = reader.int32(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.field5 = reader.int32(); + continue; + case 9: + if (tag !== 74) { + break; + } + + message.field9 = Kob.decode(reader, reader.uint32()); + continue; + case 11: + if (tag !== 90) { + break; + } + + message.field11 = YPa.decode(reader, reader.uint32()); + continue; + case 12: + if (tag !== 98) { + break; + } + + message.field12 = YPa.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Zpa { + return { + formatId: isSet(object.formatId) ? FormatId.fromJSON(object.formatId) : undefined, + startTimeMs: isSet(object.startTimeMs) ? globalThis.Number(object.startTimeMs) : 0, + durationMs: isSet(object.durationMs) ? globalThis.Number(object.durationMs) : 0, + field4: isSet(object.field4) ? globalThis.Number(object.field4) : 0, + field5: isSet(object.field5) ? globalThis.Number(object.field5) : 0, + field9: isSet(object.field9) ? Kob.fromJSON(object.field9) : undefined, + field11: isSet(object.field11) ? YPa.fromJSON(object.field11) : undefined, + field12: isSet(object.field12) ? YPa.fromJSON(object.field12) : undefined, + }; + }, + + toJSON(message: Zpa): unknown { + const obj: any = {}; + if (message.formatId !== undefined) { + obj.formatId = FormatId.toJSON(message.formatId); + } + if (message.startTimeMs !== 0) { + obj.startTimeMs = Math.round(message.startTimeMs); + } + if (message.durationMs !== 0) { + obj.durationMs = Math.round(message.durationMs); + } + if (message.field4 !== 0) { + obj.field4 = Math.round(message.field4); + } + if (message.field5 !== 0) { + obj.field5 = Math.round(message.field5); + } + if (message.field9 !== undefined) { + obj.field9 = Kob.toJSON(message.field9); + } + if (message.field11 !== undefined) { + obj.field11 = YPa.toJSON(message.field11); + } + if (message.field12 !== undefined) { + obj.field12 = YPa.toJSON(message.field12); + } + return obj; + }, + + create, I>>(base?: I): Zpa { + return Zpa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Zpa { + const message = createBaseZpa(); + message.formatId = (object.formatId !== undefined && object.formatId !== null) + ? FormatId.fromPartial(object.formatId) + : undefined; + message.startTimeMs = object.startTimeMs ?? 0; + message.durationMs = object.durationMs ?? 0; + message.field4 = object.field4 ?? 0; + message.field5 = object.field5 ?? 0; + message.field9 = (object.field9 !== undefined && object.field9 !== null) + ? Kob.fromPartial(object.field9) + : undefined; + message.field11 = (object.field11 !== undefined && object.field11 !== null) + ? YPa.fromPartial(object.field11) + : undefined; + message.field12 = (object.field12 !== undefined && object.field12 !== null) + ? YPa.fromPartial(object.field12) + : undefined; + return message; + }, +}; + +function createBaseUpa(): Upa { + return { + clientInfo: undefined, + poToken: undefined, + playbackCookie: undefined, + gp: undefined, + field5: [], + field6: [], + field7: undefined, + field8: undefined, + }; +} + +export const Upa: MessageFns = { + encode(message: Upa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.clientInfo !== undefined) { + Upa_ClientInfo.encode(message.clientInfo, writer.uint32(10).fork()).join(); + } + if (message.poToken !== undefined) { + writer.uint32(18).bytes(message.poToken); + } + if (message.playbackCookie !== undefined) { + writer.uint32(26).bytes(message.playbackCookie); + } + if (message.gp !== undefined) { + writer.uint32(34).bytes(message.gp); + } + for (const v of message.field5) { + Upa_Fqa.encode(v!, writer.uint32(42).fork()).join(); + } + writer.uint32(50).fork(); + for (const v of message.field6) { + writer.int32(v); + } + writer.join(); + if (message.field7 !== undefined) { + writer.uint32(58).string(message.field7); + } + if (message.field8 !== undefined) { + Upa_Gqa.encode(message.field8, writer.uint32(66).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Upa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseUpa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.clientInfo = Upa_ClientInfo.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.poToken = reader.bytes(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.playbackCookie = reader.bytes(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.gp = reader.bytes(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.field5.push(Upa_Fqa.decode(reader, reader.uint32())); + continue; + case 6: + if (tag === 48) { + message.field6.push(reader.int32()); + + continue; + } + + if (tag === 50) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.field6.push(reader.int32()); + } + + continue; + } + + break; + case 7: + if (tag !== 58) { + break; + } + + message.field7 = reader.string(); + continue; + case 8: + if (tag !== 66) { + break; + } + + message.field8 = Upa_Gqa.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Upa { + return { + clientInfo: isSet(object.clientInfo) ? Upa_ClientInfo.fromJSON(object.clientInfo) : undefined, + poToken: isSet(object.poToken) ? bytesFromBase64(object.poToken) : undefined, + playbackCookie: isSet(object.playbackCookie) ? bytesFromBase64(object.playbackCookie) : undefined, + gp: isSet(object.gp) ? bytesFromBase64(object.gp) : undefined, + field5: globalThis.Array.isArray(object?.field5) ? object.field5.map((e: any) => Upa_Fqa.fromJSON(e)) : [], + field6: globalThis.Array.isArray(object?.field6) ? object.field6.map((e: any) => globalThis.Number(e)) : [], + field7: isSet(object.field7) ? globalThis.String(object.field7) : undefined, + field8: isSet(object.field8) ? Upa_Gqa.fromJSON(object.field8) : undefined, + }; + }, + + toJSON(message: Upa): unknown { + const obj: any = {}; + if (message.clientInfo !== undefined) { + obj.clientInfo = Upa_ClientInfo.toJSON(message.clientInfo); + } + if (message.poToken !== undefined) { + obj.poToken = base64FromBytes(message.poToken); + } + if (message.playbackCookie !== undefined) { + obj.playbackCookie = base64FromBytes(message.playbackCookie); + } + if (message.gp !== undefined) { + obj.gp = base64FromBytes(message.gp); + } + if (message.field5?.length) { + obj.field5 = message.field5.map((e) => Upa_Fqa.toJSON(e)); + } + if (message.field6?.length) { + obj.field6 = message.field6.map((e) => Math.round(e)); + } + if (message.field7 !== undefined) { + obj.field7 = message.field7; + } + if (message.field8 !== undefined) { + obj.field8 = Upa_Gqa.toJSON(message.field8); + } + return obj; + }, + + create, I>>(base?: I): Upa { + return Upa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Upa { + const message = createBaseUpa(); + message.clientInfo = (object.clientInfo !== undefined && object.clientInfo !== null) + ? Upa_ClientInfo.fromPartial(object.clientInfo) + : undefined; + message.poToken = object.poToken ?? undefined; + message.playbackCookie = object.playbackCookie ?? undefined; + message.gp = object.gp ?? undefined; + message.field5 = object.field5?.map((e) => Upa_Fqa.fromPartial(e)) || []; + message.field6 = object.field6?.map((e) => e) || []; + message.field7 = object.field7 ?? undefined; + message.field8 = (object.field8 !== undefined && object.field8 !== null) + ? Upa_Gqa.fromPartial(object.field8) + : undefined; + return message; + }, +}; + +function createBaseUpa_ClientInfo(): Upa_ClientInfo { + return { + deviceMake: undefined, + deviceModel: undefined, + clientName: undefined, + clientVersion: undefined, + osName: undefined, + osVersion: undefined, + }; +} + +export const Upa_ClientInfo: MessageFns = { + encode(message: Upa_ClientInfo, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.deviceMake !== undefined) { + writer.uint32(98).string(message.deviceMake); + } + if (message.deviceModel !== undefined) { + writer.uint32(106).string(message.deviceModel); + } + if (message.clientName !== undefined) { + writer.uint32(128).int32(message.clientName); + } + if (message.clientVersion !== undefined) { + writer.uint32(138).string(message.clientVersion); + } + if (message.osName !== undefined) { + writer.uint32(146).string(message.osName); + } + if (message.osVersion !== undefined) { + writer.uint32(154).string(message.osVersion); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Upa_ClientInfo { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseUpa_ClientInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 12: + if (tag !== 98) { + break; + } + + message.deviceMake = reader.string(); + continue; + case 13: + if (tag !== 106) { + break; + } + + message.deviceModel = reader.string(); + continue; + case 16: + if (tag !== 128) { + break; + } + + message.clientName = reader.int32(); + continue; + case 17: + if (tag !== 138) { + break; + } + + message.clientVersion = reader.string(); + continue; + case 18: + if (tag !== 146) { + break; + } + + message.osName = reader.string(); + continue; + case 19: + if (tag !== 154) { + break; + } + + message.osVersion = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Upa_ClientInfo { + return { + deviceMake: isSet(object.deviceMake) ? globalThis.String(object.deviceMake) : undefined, + deviceModel: isSet(object.deviceModel) ? globalThis.String(object.deviceModel) : undefined, + clientName: isSet(object.clientName) ? globalThis.Number(object.clientName) : undefined, + clientVersion: isSet(object.clientVersion) ? globalThis.String(object.clientVersion) : undefined, + osName: isSet(object.osName) ? globalThis.String(object.osName) : undefined, + osVersion: isSet(object.osVersion) ? globalThis.String(object.osVersion) : undefined, + }; + }, + + toJSON(message: Upa_ClientInfo): unknown { + const obj: any = {}; + if (message.deviceMake !== undefined) { + obj.deviceMake = message.deviceMake; + } + if (message.deviceModel !== undefined) { + obj.deviceModel = message.deviceModel; + } + if (message.clientName !== undefined) { + obj.clientName = Math.round(message.clientName); + } + if (message.clientVersion !== undefined) { + obj.clientVersion = message.clientVersion; + } + if (message.osName !== undefined) { + obj.osName = message.osName; + } + if (message.osVersion !== undefined) { + obj.osVersion = message.osVersion; + } + return obj; + }, + + create, I>>(base?: I): Upa_ClientInfo { + return Upa_ClientInfo.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Upa_ClientInfo { + const message = createBaseUpa_ClientInfo(); + message.deviceMake = object.deviceMake ?? undefined; + message.deviceModel = object.deviceModel ?? undefined; + message.clientName = object.clientName ?? undefined; + message.clientVersion = object.clientVersion ?? undefined; + message.osName = object.osName ?? undefined; + message.osVersion = object.osVersion ?? undefined; + return message; + }, +}; + +function createBaseUpa_Fqa(): Upa_Fqa { + return { type: undefined, value: undefined }; +} + +export const Upa_Fqa: MessageFns = { + encode(message: Upa_Fqa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.type !== undefined) { + writer.uint32(8).int32(message.type); + } + if (message.value !== undefined) { + writer.uint32(18).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Upa_Fqa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseUpa_Fqa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.type = reader.int32(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.value = reader.bytes(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Upa_Fqa { + return { + type: isSet(object.type) ? globalThis.Number(object.type) : undefined, + value: isSet(object.value) ? bytesFromBase64(object.value) : undefined, + }; + }, + + toJSON(message: Upa_Fqa): unknown { + const obj: any = {}; + if (message.type !== undefined) { + obj.type = Math.round(message.type); + } + if (message.value !== undefined) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create, I>>(base?: I): Upa_Fqa { + return Upa_Fqa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Upa_Fqa { + const message = createBaseUpa_Fqa(); + message.type = object.type ?? undefined; + message.value = object.value ?? undefined; + return message; + }, +}; + +function createBaseUpa_Gqa(): Upa_Gqa { + return { field1: undefined, field2: undefined }; +} + +export const Upa_Gqa: MessageFns = { + encode(message: Upa_Gqa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.field1 !== undefined) { + writer.uint32(10).bytes(message.field1); + } + if (message.field2 !== undefined) { + Upa_Gqa_Hqa.encode(message.field2, writer.uint32(18).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Upa_Gqa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseUpa_Gqa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.field1 = reader.bytes(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.field2 = Upa_Gqa_Hqa.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Upa_Gqa { + return { + field1: isSet(object.field1) ? bytesFromBase64(object.field1) : undefined, + field2: isSet(object.field2) ? Upa_Gqa_Hqa.fromJSON(object.field2) : undefined, + }; + }, + + toJSON(message: Upa_Gqa): unknown { + const obj: any = {}; + if (message.field1 !== undefined) { + obj.field1 = base64FromBytes(message.field1); + } + if (message.field2 !== undefined) { + obj.field2 = Upa_Gqa_Hqa.toJSON(message.field2); + } + return obj; + }, + + create, I>>(base?: I): Upa_Gqa { + return Upa_Gqa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Upa_Gqa { + const message = createBaseUpa_Gqa(); + message.field1 = object.field1 ?? undefined; + message.field2 = (object.field2 !== undefined && object.field2 !== null) + ? Upa_Gqa_Hqa.fromPartial(object.field2) + : undefined; + return message; + }, +}; + +function createBaseUpa_Gqa_Hqa(): Upa_Gqa_Hqa { + return { code: undefined, message: undefined }; +} + +export const Upa_Gqa_Hqa: MessageFns = { + encode(message: Upa_Gqa_Hqa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.code !== undefined) { + writer.uint32(8).int32(message.code); + } + if (message.message !== undefined) { + writer.uint32(18).string(message.message); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Upa_Gqa_Hqa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseUpa_Gqa_Hqa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.code = reader.int32(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.message = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Upa_Gqa_Hqa { + return { + code: isSet(object.code) ? globalThis.Number(object.code) : undefined, + message: isSet(object.message) ? globalThis.String(object.message) : undefined, + }; + }, + + toJSON(message: Upa_Gqa_Hqa): unknown { + const obj: any = {}; + if (message.code !== undefined) { + obj.code = Math.round(message.code); + } + if (message.message !== undefined) { + obj.message = message.message; + } + return obj; + }, + + create, I>>(base?: I): Upa_Gqa_Hqa { + return Upa_Gqa_Hqa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Upa_Gqa_Hqa { + const message = createBaseUpa_Gqa_Hqa(); + message.code = object.code ?? undefined; + message.message = object.message ?? undefined; + return message; + }, +}; + +function createBaseOQa(): OQa { + return { field1: [], field2: undefined, field3: undefined, field4: undefined, field5: undefined, field6: undefined }; +} + +export const OQa: MessageFns = { + encode(message: OQa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.field1) { + writer.uint32(10).string(v!); + } + if (message.field2 !== undefined) { + writer.uint32(18).bytes(message.field2); + } + if (message.field3 !== undefined) { + writer.uint32(26).string(message.field3); + } + if (message.field4 !== undefined) { + writer.uint32(32).int32(message.field4); + } + if (message.field5 !== undefined) { + writer.uint32(40).int32(message.field5); + } + if (message.field6 !== undefined) { + writer.uint32(50).string(message.field6); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): OQa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseOQa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.field1.push(reader.string()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.field2 = reader.bytes(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.field3 = reader.string(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.field4 = reader.int32(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.field5 = reader.int32(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.field6 = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): OQa { + return { + field1: globalThis.Array.isArray(object?.field1) ? object.field1.map((e: any) => globalThis.String(e)) : [], + field2: isSet(object.field2) ? bytesFromBase64(object.field2) : undefined, + field3: isSet(object.field3) ? globalThis.String(object.field3) : undefined, + field4: isSet(object.field4) ? globalThis.Number(object.field4) : undefined, + field5: isSet(object.field5) ? globalThis.Number(object.field5) : undefined, + field6: isSet(object.field6) ? globalThis.String(object.field6) : undefined, + }; + }, + + toJSON(message: OQa): unknown { + const obj: any = {}; + if (message.field1?.length) { + obj.field1 = message.field1; + } + if (message.field2 !== undefined) { + obj.field2 = base64FromBytes(message.field2); + } + if (message.field3 !== undefined) { + obj.field3 = message.field3; + } + if (message.field4 !== undefined) { + obj.field4 = Math.round(message.field4); + } + if (message.field5 !== undefined) { + obj.field5 = Math.round(message.field5); + } + if (message.field6 !== undefined) { + obj.field6 = message.field6; + } + return obj; + }, + + create, I>>(base?: I): OQa { + return OQa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): OQa { + const message = createBaseOQa(); + message.field1 = object.field1?.map((e) => e) || []; + message.field2 = object.field2 ?? undefined; + message.field3 = object.field3 ?? undefined; + message.field4 = object.field4 ?? undefined; + message.field5 = object.field5 ?? undefined; + message.field6 = object.field6 ?? undefined; + return message; + }, +}; + +function createBasePqa(): Pqa { + return { formatIds: [], ud: [], clipId: undefined }; +} + +export const Pqa: MessageFns = { + encode(message: Pqa, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.formatIds) { + FormatId.encode(v!, writer.uint32(10).fork()).join(); + } + for (const v of message.ud) { + Zpa.encode(v!, writer.uint32(18).fork()).join(); + } + if (message.clipId !== undefined) { + writer.uint32(26).string(message.clipId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Pqa { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePqa(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.formatIds.push(FormatId.decode(reader, reader.uint32())); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.ud.push(Zpa.decode(reader, reader.uint32())); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.clipId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Pqa { + return { + formatIds: globalThis.Array.isArray(object?.formatIds) + ? object.formatIds.map((e: any) => FormatId.fromJSON(e)) + : [], + ud: globalThis.Array.isArray(object?.ud) ? object.ud.map((e: any) => Zpa.fromJSON(e)) : [], + clipId: isSet(object.clipId) ? globalThis.String(object.clipId) : undefined, + }; + }, + + toJSON(message: Pqa): unknown { + const obj: any = {}; + if (message.formatIds?.length) { + obj.formatIds = message.formatIds.map((e) => FormatId.toJSON(e)); + } + if (message.ud?.length) { + obj.ud = message.ud.map((e) => Zpa.toJSON(e)); + } + if (message.clipId !== undefined) { + obj.clipId = message.clipId; + } + return obj; + }, + + create, I>>(base?: I): Pqa { + return Pqa.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Pqa { + const message = createBasePqa(); + message.formatIds = object.formatIds?.map((e) => FormatId.fromPartial(e)) || []; + message.ud = object.ud?.map((e) => Zpa.fromPartial(e)) || []; + message.clipId = object.clipId ?? undefined; + return message; + }, +}; + +function bytesFromBase64(b64: string): Uint8Array { + const bin = globalThis.atob(b64); + const arr = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; ++i) { + arr[i] = bin.charCodeAt(i); + } + return arr; +} + +function base64FromBytes(arr: Uint8Array): string { + const bin: string[] = []; + arr.forEach((byte) => { + bin.push(globalThis.String.fromCharCode(byte)); + }); + return globalThis.btoa(bin.join("")); +} + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: 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; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/protos/misc/common.proto b/protos/misc/common.proto new file mode 100644 index 0000000..d8ebecc --- /dev/null +++ b/protos/misc/common.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package misc; + +message HttpHeader { + optional string name = 1; + optional string value = 2; +} + +message FormatId { + optional int32 itag = 1; + optional uint64 last_modified = 2; + optional string xtags = 3; +} + +message InitRange { + optional int32 start = 1; + optional int32 end = 2; +} + +message IndexRange { + optional int32 start = 1; + optional int32 end = 2; +} + +message KeyValuePair { + optional string key = 1; + optional string value = 2; +} \ No newline at end of file diff --git a/protos/misc/params.proto b/protos/misc/params.proto new file mode 100644 index 0000000..93c0409 --- /dev/null +++ b/protos/misc/params.proto @@ -0,0 +1,227 @@ +syntax = "proto3"; +package misc; + +message VisitorData { + string id = 1; + int32 timestamp = 5; +} + +message SearchFilter { + optional SortBy sort_by = 1; + + enum SortBy { + RELEVANCE = 0; + RATING = 1; + UPLOAD_DATE = 2; + VIEW_COUNT = 3; + } + + message Filters { + optional UploadDate upload_date = 1; + optional SearchType type = 2; + optional Duration duration = 3; + optional MusicSearchType music_search_type = 17; + + optional bool features_hd = 4; + optional bool features_subtitles = 5; + optional bool features_creative_commons = 6; + optional bool features_3d = 7; + optional bool features_live = 8; + optional bool features_purchased = 9; + optional bool features_4k = 14; + optional bool features_360 = 15; + optional bool features_location = 23; + optional bool features_hdr = 25; + optional bool features_vr180 = 26; + + enum UploadDate { + ANY_DATE = 0; + HOUR = 1; + TODAY = 2; + WEEK = 3; + MONTH = 4; + YEAR = 5; + } + + enum SearchType { + ANY_TYPE = 0; + VIDEO = 1; + CHANNEL = 2; + PLAYLIST = 3; + MOVIE = 4; + } + + enum Duration { + ANY_DURATION = 0; + SHORT = 1; + LONG = 2; + MEDIUM = 3; + } + + message MusicSearchType { + optional bool song = 1; + optional bool video = 2; + optional bool album = 3; + optional bool artist = 4; + optional bool playlist = 5; + } + } + + optional Filters filters = 2; +} + +message ChannelAnalytics { + message Params { + string channel_id = 1001; + } + + Params params = 32; +} + +message SoundInfoParams { + message Sound { + message Params { + message Ids { + string id_1 = 1; + string id_2 = 2; + string id_3 = 3; + } + Ids ids = 2; + } + Params params = 1; + } + + Sound sound = 94; +} + +message NotificationPreferences { + string channel_id = 1; + + message Preference { + int32 index = 1; + } + + Preference pref_id = 2; + + optional int32 number_0 = 3; + optional int32 number_1 = 4; +} + +message LiveMessageParams { + message Params { + message Ids { + string channel_id = 1; + string video_id = 2; + } + Ids ids = 5; + } + + Params params = 1; + + optional int32 number_0 = 2; + optional int32 number_1 = 3; +} + +message GetCommentsSectionParams { + message Context { + string video_id = 2; + } + Context ctx = 2; + + int32 unk_param = 3; + + message Params { + optional string unk_token = 1; + + message Options { + string video_id = 4; + int32 sort_by = 6; + int32 type = 15; + optional string comment_id = 16; + } + + message RepliesOptions { + string comment_id = 2; + + message UnkOpts { + int32 unk_param = 1; + } + UnkOpts unkopts = 4; + + optional string channel_id = 5; + string video_id = 6; + + int32 unk_param_1 = 8; + int32 unk_param_2 = 9; + } + + optional Options opts = 4; + optional RepliesOptions replies_opts = 3; + + optional int32 page = 5; + string target = 8; + } + + Params params = 6; +} + +message CreateCommentParams { + string video_id = 2; + message Params { + int32 index = 1; + } + Params params = 5; + int32 number = 10; +} + +message PeformCommentActionParams { + int32 type = 1; + string comment_id = 3; + string video_id = 5; + + optional int32 unk_num = 2; + optional string channel_id = 23; + + message TranslateCommentParams { + message Params { + message Comment { + string text = 1; + } + Comment comment = 1; + } + Params params = 3; + + string comment_id = 2; + string target_language = 4; + } + + optional TranslateCommentParams translate_comment_params = 31; +} + +message Hashtag { + message Params { + string hashtag = 1; + int32 type = 3; + } + + Params params = 93; +} + +message ReelSequence { + string short_id = 1; + message Params { + int32 number = 3; + } + + Params params = 5; + int32 feature_2 = 10; + int32 feature_3 = 13; +} + +message ShortsParam { + message Field1 { + optional int32 p1 = 1; + } + optional Field1 f1 = 1; + optional int32 p59 = 59; +} \ No newline at end of file diff --git a/protos/video_streaming/format_initialization_metadata.proto b/protos/video_streaming/format_initialization_metadata.proto new file mode 100644 index 0000000..c25506b --- /dev/null +++ b/protos/video_streaming/format_initialization_metadata.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package video_streaming; + +import "misc/common.proto"; + +message FormatInitializationMetadata { + optional string video_id = 1; + optional .misc.FormatId format_id = 2; + optional int32 end_time_ms = 3; + optional int32 field4 = 4; + optional string mime_type = 5; + optional .misc.InitRange init_range = 6; + optional .misc.IndexRange index_range = 7; + optional int32 field8 = 8; + optional int32 duration_ms = 9; + optional int32 field10 = 10; +} \ No newline at end of file diff --git a/protos/video_streaming/media_header.proto b/protos/video_streaming/media_header.proto new file mode 100644 index 0000000..38964ee --- /dev/null +++ b/protos/video_streaming/media_header.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; +package video_streaming; + +import "misc/common.proto"; + +message MediaHeader { + optional uint32 header_id = 1; + optional string video_id = 2; + optional int32 itag = 3; + optional uint64 lmt = 4; + optional string xtags = 5; + optional int32 start_data_range = 6; + optional Compression compression = 7; + optional bool is_init_seg = 8; + optional int64 sequence_number = 9; + optional int64 field10 = 10; + optional int32 start_ms = 11; + optional int32 duration_ms = 12; + optional .misc.FormatId format_id = 13; + optional int64 content_length = 14; + optional TimeRange time_range = 15; + + message TimeRange { + optional int64 start = 1; + optional int64 duration = 2; + optional int32 timescale = 3; + } + + enum Compression { + VAL0 = 0; + VAL1 = 1; + GZIP = 2; + } + +} \ No newline at end of file diff --git a/protos/video_streaming/next_request_policy.proto b/protos/video_streaming/next_request_policy.proto new file mode 100644 index 0000000..7541512 --- /dev/null +++ b/protos/video_streaming/next_request_policy.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package video_streaming; + +import "video_streaming/playback_cookie.proto"; + +message NextRequestPolicy { + optional int32 target_audio_readahead_ms = 1; + optional int32 target_video_readahead_ms = 2; + optional int32 backoff_time_ms = 4; + optional .video_streaming.PlaybackCookie playback_cookie = 7; + optional string video_id = 8; +} \ No newline at end of file diff --git a/protos/video_streaming/onesie_request.proto b/protos/video_streaming/onesie_request.proto new file mode 100644 index 0000000..08f273e --- /dev/null +++ b/protos/video_streaming/onesie_request.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package video_streaming; + +import "misc/common.proto"; + +// @TODO: Add the rest of the request. +message OnesieRequest { + optional string url = 1; + repeated misc.HttpHeader headers = 2; + optional string body = 3; + optional bool field4 = 4; + optional bool field6 = 6; +} \ No newline at end of file diff --git a/protos/video_streaming/playback_cookie.proto b/protos/video_streaming/playback_cookie.proto new file mode 100644 index 0000000..65cc848 --- /dev/null +++ b/protos/video_streaming/playback_cookie.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package video_streaming; + +import "misc/common.proto"; + +message PlaybackCookie { + optional int32 field1 = 1; // Always 999999?? + optional int32 field2 = 2; + optional .misc.FormatId video_fmt = 7; + optional .misc.FormatId audio_fmt = 8; +} \ No newline at end of file diff --git a/protos/video_streaming/playback_start_policy.proto b/protos/video_streaming/playback_start_policy.proto new file mode 100644 index 0000000..d599962 --- /dev/null +++ b/protos/video_streaming/playback_start_policy.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package video_streaming; + +message PlaybackStartPolicy { + message ReadaheadPolicy { + optional int32 min_readahead_ms = 2; + optional int32 min_bandwidth_bytes_per_sec = 1; + } + + optional ReadaheadPolicy start_min_readahead_policy = 1; + optional ReadaheadPolicy resume_min_readahead_policy = 2; +} \ No newline at end of file diff --git a/protos/video_streaming/request_cancellation_policy.proto b/protos/video_streaming/request_cancellation_policy.proto new file mode 100644 index 0000000..db96730 --- /dev/null +++ b/protos/video_streaming/request_cancellation_policy.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package video_streaming; + +message RequestCancellationPolicy { + message Item { + optional int32 fR = 1; + optional int32 NK = 2; + optional int32 minReadaheadMs = 3; + } + + optional int32 N0 = 1; + repeated Item items = 2; + optional int32 jq = 3; +} \ No newline at end of file diff --git a/protos/video_streaming/sabr_error.proto b/protos/video_streaming/sabr_error.proto new file mode 100644 index 0000000..638e901 --- /dev/null +++ b/protos/video_streaming/sabr_error.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; +package video_streaming; + +message SabrError { + optional string type = 1; + optional int32 code = 2; +} \ No newline at end of file diff --git a/protos/video_streaming/sabr_redirect.proto b/protos/video_streaming/sabr_redirect.proto new file mode 100644 index 0000000..2d4f748 --- /dev/null +++ b/protos/video_streaming/sabr_redirect.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package video_streaming; + +message SabrRedirect { + optional string url = 1; +} \ No newline at end of file diff --git a/protos/video_streaming/stream_protection_status.proto b/protos/video_streaming/stream_protection_status.proto new file mode 100644 index 0000000..c708788 --- /dev/null +++ b/protos/video_streaming/stream_protection_status.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; +package video_streaming; + +message StreamProtectionStatus { + optional int32 status = 1; + optional int32 field2 = 2; +} \ No newline at end of file diff --git a/protos/video_streaming/video_playback_abr_request.proto b/protos/video_streaming/video_playback_abr_request.proto new file mode 100644 index 0000000..ca8de4e --- /dev/null +++ b/protos/video_streaming/video_playback_abr_request.proto @@ -0,0 +1,172 @@ +syntax = "proto3"; +package video_streaming; + +import "misc/common.proto"; + +message VideoPlaybackAbrRequest { + optional MediaInfo media_info = 1; + repeated .misc.FormatId format_ids = 2; + repeated Zpa ud = 3; + optional bytes video_playback_ustreamer_config = 5; + optional Lo lo = 6; + repeated .misc.FormatId audio_format_ids = 16; + repeated .misc.FormatId video_format_ids = 17; + optional Upa sc = 19; + optional OQa field21 = 21; + optional int32 field22 = 22; + optional int32 field23 = 23; + repeated Pqa field1000 = 1000; +} + +message MediaInfo { + message MediaCapabilities { + repeated VideoFormatCapability video_format_capabilities = 1; + repeated AudioFormatCapability audio_format_capabilities = 2; + optional int32 hdr_mode_bitmask = 5; + + message VideoFormatCapability { + optional int32 video_codec = 1; + optional int32 max_height = 3; + optional int32 max_width = 4; + optional int32 max_framerate = 11; + optional int32 max_bitrate_bps = 12; + optional bool is_10_bit_supported = 15; + } + + message AudioFormatCapability { + optional int32 audio_codec = 1; + optional int32 num_channels = 2; + optional int32 max_bitrate_bps = 3; + optional int32 spatial_capability_bitmask = 6; + } + } + + optional int32 time_since_last_manual_format_selection_ms = 13; + optional int32 last_manual_direction = 14; + optional int32 video_width = 16; + optional int32 detailed_network_type = 17; + optional int32 B7 = 18; + optional int32 A7 = 19; + optional int32 iea = 21; + optional int32 r7 = 23; + optional int32 startTimeMs = 28; + optional int32 zea = 29; + optional int32 visibility = 34; + optional int32 d8 = 36; + optional MediaCapabilities media_capabilities = 38; + optional int32 yea = 39; + // optional int32 Gw = 40; + optional MediaType media_type = 40; + optional int32 player_state = 44; + optional bool a8 = 46; + optional int32 Jda = 48; + optional int32 qw = 50; + optional int32 Ky = 51; + optional int32 Eq = 54; + optional bool l = 56; + optional int32 G7 = 57; + optional bool No = 58; + optional int32 qj = 59; + optional int32 Hx = 60; + optional bool is_prefetch = 61; + optional int32 Iz = 62; + optional bytes sabr_license_constraint = 63; + optional int32 l2 = 64; + optional int32 k2 = 66; + optional int32 Tqb = 67; + optional int32 c = 68; + + enum MediaType { + MEDIA_TYPE_DEFAULT = 0; + MEDIA_TYPE_AUDIO = 1; + MEDIA_TYPE_VIDEO = 2; + } +} + +message Lo { + message Field4 { + optional int32 field1 = 1; + optional int32 field2 = 2; + optional int32 field3 = 3; + } + optional .misc.FormatId format_id = 1; + optional int32 Lj = 2; + optional int32 sequence_number = 3; + optional Field4 field4 = 4; + optional int32 MZ = 5; +} + +message Kob { + message Pa { + optional string video_id = 1; + optional uint64 lmt = 2; + } + repeated Pa EW = 1; +} + +message YPa { + optional int32 field1 = 1; + optional int32 field2 = 2; + optional int32 field3 = 3; +} + +message Zpa { + .misc.FormatId format_id = 1; + int32 startTimeMs = 2; + int32 durationMs = 3; + int32 field4 = 4; + int32 field5 = 5; + optional Kob field9 = 9; + optional YPa field11 = 11; + optional YPa field12 = 12; +} + +message Upa { + message ClientInfo { + optional string device_make = 12; + optional string device_model = 13; + optional int32 client_name = 16; + optional string client_version = 17; + optional string os_name = 18; + optional string os_version = 19; + } + + message Fqa { + optional int32 type = 1; + optional bytes value = 2; + } + + message Gqa { + message Hqa { + optional int32 code = 1; + optional string message = 2; + } + + optional bytes field1 = 1; + optional Hqa field2 = 2; + } + + optional ClientInfo client_info = 1; + optional bytes po_token = 2; + optional bytes playback_cookie = 3; + optional bytes gp = 4; + repeated Fqa field5 = 5; + repeated int32 field6 = 6; + optional string field7 = 7; + optional Gqa field8 = 8; +} + +message OQa { + repeated string field1 = 1; + optional bytes field2 = 2; + optional string field3 = 3; + optional int32 field4 = 4; + optional int32 field5 = 5; + optional string field6 = 6; +} + +message Pqa { + repeated .misc.FormatId format_ids = 1; + repeated Zpa ud = 2; + optional string clip_id = 3; +} \ No newline at end of file diff --git a/src/core/ChunkedDataBuffer.ts b/src/core/ChunkedDataBuffer.ts new file mode 100644 index 0000000..911704f --- /dev/null +++ b/src/core/ChunkedDataBuffer.ts @@ -0,0 +1,106 @@ +export class ChunkedDataBuffer { + public chunks: Uint8Array[]; + public currentChunkOffset: number; + public currentChunkIndex: number; + public currentDataView?: DataView; + public totalLength: number; + + constructor(chunks: Uint8Array[] = []) { + this.chunks = []; + this.currentChunkOffset = this.currentChunkIndex = 0; + this.currentDataView = undefined; + this.totalLength = 0; + chunks.forEach((chunk) => { + this.append(chunk); + }); + } + + getLength(): number { + return this.totalLength; + } + + append(chunk: Uint8Array): void { + if (this.canMergeWithLastChunk(chunk)) { + const lastChunk = this.chunks[this.chunks.length - 1]; + this.chunks[this.chunks.length - 1] = new Uint8Array( + lastChunk.buffer, + lastChunk.byteOffset, + lastChunk.length + chunk.length + ); + this.resetFocus(); + } else { + this.chunks.push(chunk); + } + this.totalLength += chunk.length; + } + + split(position: number): { extractedBuffer: ChunkedDataBuffer; remainingBuffer: ChunkedDataBuffer } { + const extractedBuffer = new ChunkedDataBuffer(); + const remainingBuffer = new ChunkedDataBuffer(); + const iterator = this.chunks[Symbol.iterator](); + let item = iterator.next(); + + while (!item.done) { + const chunk = item.value; + if (position >= chunk.length) { + extractedBuffer.append(chunk); + position -= chunk.length; + } else if (position > 0) { + extractedBuffer.append(new Uint8Array(chunk.buffer, chunk.byteOffset, position)); + remainingBuffer.append( + new Uint8Array(chunk.buffer, chunk.byteOffset + position, chunk.length - position) + ); + position = 0; + } else { + remainingBuffer.append(chunk); + } + item = iterator.next(); + } + + return { extractedBuffer, remainingBuffer }; + } + + isFocused(position: number): boolean { + return position >= this.currentChunkOffset && position < this.currentChunkOffset + this.chunks[this.currentChunkIndex].length; + } + + focus(position: number): void { + if (!this.isFocused(position)) { + if (position < this.currentChunkOffset) this.resetFocus(); + + while ( + this.currentChunkOffset + this.chunks[this.currentChunkIndex].length <= position && + this.currentChunkIndex < this.chunks.length - 1 + ) { + this.currentChunkOffset += this.chunks[this.currentChunkIndex].length; + this.currentChunkIndex += 1; + } + + this.currentDataView = undefined; + } + } + + canReadBytes(position: number, length: number): boolean { + return position + length <= this.totalLength; + } + + getUint8(position: number): number { + this.focus(position); + return this.chunks[this.currentChunkIndex][position - this.currentChunkOffset]; + } + + private canMergeWithLastChunk(chunk: Uint8Array): boolean { + if (this.chunks.length === 0) return false; + const lastChunk = this.chunks[this.chunks.length - 1]; + return ( + lastChunk.buffer === chunk.buffer && + lastChunk.byteOffset + lastChunk.length === chunk.byteOffset + ); + } + + private resetFocus(): void { + this.currentDataView = undefined; + this.currentChunkIndex = 0; + this.currentChunkOffset = 0; + } +} \ No newline at end of file diff --git a/src/core/ServerAbrStream.ts b/src/core/ServerAbrStream.ts new file mode 100644 index 0000000..06cf9f5 --- /dev/null +++ b/src/core/ServerAbrStream.ts @@ -0,0 +1,300 @@ +/** + * TODO: Use camelCase for all variables and functions here (except for protobuf generated stuff) + * I was originally planning to implement this into YouTube.js, but as I started implementing more + * googlevideo related things, I realized this would be better suited as a separate module :). + */ + +import { UMP } from './UMP.js'; +import { EventEmitterLike, PART, base64ToU8 } from '../utils/index.js'; + +import { MediaInfo_MediaType } from '../../protos/generated/video_streaming/video_playback_abr_request.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'; +import { FormatInitializationMetadata } from '../../protos/generated/video_streaming/format_initialization_metadata.js'; +import { SabrRedirect } from '../../protos/generated/video_streaming/sabr_redirect.js'; +import { SabrError } from '../../protos/generated/video_streaming/sabr_error.js'; +import { StreamProtectionStatus } from '../../protos/generated/video_streaming/stream_protection_status.js'; +import { PlaybackCookie } from '../../protos/generated/video_streaming/playback_cookie.js'; + +import type { FormatId } from '../../protos/generated/misc/common.js'; +import type { MediaInfo } from '../../protos/generated/video_streaming/video_playback_abr_request.js'; +import type { FetchFunction, InitializedFormat, InitOptions, MediaArgs, ServerAbrResponse, ServerAbrStreamOptions } from '../utils/types.js'; +import { ChunkedDataBuffer } from './ChunkedDataBuffer.js'; + +export class ServerAbrStream extends EventEmitterLike { + private fetch_fn: FetchFunction; + private server_abr_streaming_url: string; + private video_playback_ustreamer_config: string; + private po_token?: string; + private playback_cookie?: PlaybackCookie; + private initialized_formats: InitializedFormat[] = []; + private total_duration_ms: number; + + constructor(args: ServerAbrStreamOptions) { + super(); + this.fetch_fn = args.fetch || fetch; + this.server_abr_streaming_url = args.server_abr_streaming_url; + this.video_playback_ustreamer_config = args.video_playback_ustreamer_config; + this.po_token = args.po_token; + this.total_duration_ms = args.duration_ms; + } + + public on(event: 'data', listener: (data: ServerAbrResponse) => void): void; + public on(event: 'error', listener: (error: Error) => void): void; + public on(event: string, listener: (...args: any[]) => void): void { + super.on(event, listener); + } + + public once(event: 'data', listener: (data: ServerAbrResponse) => void): void; + public once(event: 'error', listener: (error: Error) => void): void; + public once(event: string, listener: (...args: any[]) => void): void { + super.once(event, listener); + } + + public async init(args: InitOptions) { + const { audio_formats, video_formats, media_info: initial_media_info } = args; + + const first_video_format = video_formats ? video_formats[0] : undefined; + + const media_info: MediaInfo = { + lastManualDirection: 0, + timeSinceLastManualFormatSelectionMs: 0, + videoWidth: video_formats.length === 1 ? first_video_format?.width : 720, + iea: video_formats.length === 1 ? first_video_format?.width : 720, + startTimeMs: 0, + visibility: 0, + mediaType: MediaInfo_MediaType.MEDIA_TYPE_DEFAULT, + ...initial_media_info + }; + + const audio_format_ids = audio_formats.map((fmt) => ({ + itag: fmt.itag, + lastModified: parseInt(fmt.last_modified_ms), + xtags: fmt.xtags + })); + + const video_format_ids = video_formats.map((fmt) => ({ + itag: fmt.itag, + lastModified: parseInt(fmt.last_modified_ms), + xtags: fmt.xtags + })); + + if (typeof media_info.startTimeMs !== 'number') + throw new Error('Invalid media start time'); + + try { + while (media_info.startTimeMs < this.total_duration_ms) { + const data = await this.fetchMedia({ media_info, audio_format_ids, video_format_ids }); + + this.emit('data', data); + + if (data.sabr_error) break; + + const main_format = + media_info.mediaType === MediaInfo_MediaType.MEDIA_TYPE_DEFAULT + ? data.initialized_formats.find((fmt) => fmt.mime_type?.includes('video')) + : data.initialized_formats[0]; + + if (!main_format) break; + if (main_format?.sequence_count === main_format.sequence_list[main_format.sequence_list.length - 1].sequence_number) break; + + media_info.startTimeMs += main_format.sequence_list.reduce((acc, seq) => acc + (seq.duration_ms || 0), 0); + } + } catch (error) { + this.emit('error', error); + } + } + + private async fetchMedia(args: MediaArgs): Promise { + const { media_info, audio_format_ids, video_format_ids } = args; + + this.initialized_formats.forEach((format) => { + format.sequence_list = []; + format.media_data = new Uint8Array(0); + }); + + const body = VideoPlaybackAbrRequest.encode({ + mediaInfo: media_info, + formatIds: this.initialized_formats.map((fmt) => fmt.format_id), + audioFormatIds: audio_format_ids, + videoFormatIds: video_format_ids, + videoPlaybackUstreamerConfig: base64ToU8(this.video_playback_ustreamer_config), + sc: { + field5: [], + field6: [], + poToken: this.po_token ? base64ToU8(this.po_token) : undefined, + playbackCookie: this.playback_cookie ? PlaybackCookie.encode(this.playback_cookie).finish() : undefined, + clientInfo: { + clientName: 1, + clientVersion: '2.2040620.05.00', + osName: 'Windows', + osVersion: '10.0' + } + }, + ud: this.initialized_formats.map((fmt) => fmt._state), + field1000: [] + }).finish(); + + const response = await this.fetch_fn(this.server_abr_streaming_url, { method: 'POST', body }); + + return this.processUMPResponse(response); + } + + public async processUMPResponse(response: Response) { + let sabr_error: SabrError | undefined; + let stream_protection_status: StreamProtectionStatus | undefined; + + const data = await response.arrayBuffer(); + const ump = new UMP(new ChunkedDataBuffer([ new Uint8Array(data) ])); + + ump.parse((part) => { + const data = part.data.chunks[0]; + switch (part.type) { + case PART.MEDIA_HEADER: + this.processMediaHeader(data); + break; + case PART.MEDIA: + this.processMediaData(part.data); + break; + case PART.MEDIA_END: + this.processEndOfMedia(part.data); + break; + case PART.NEXT_REQUEST_POLICY: + this.processNextRequestPolicy(data); + break; + case PART.FORMAT_INITIALIZATION_METADATA: + this.processFormatInitialization(data); + break; + case PART.SABR_REDIRECT: + this.processSabrRedirect(data); + break; + case PART.SABR_ERROR: + sabr_error = SabrError.decode(data); + break; + case PART.STREAM_PROTECTION_STATUS: + stream_protection_status = StreamProtectionStatus.decode(data); + break; + default: + break; + } + }); + + return { + initialized_formats: this.initialized_formats, + stream_protection_status, + sabr_error + }; + } + + private processMediaHeader(data: Uint8Array) { + const media_header = MediaHeader.decode(data); + const target_format = this.initialized_formats.find((fmt) => fmt.format_id.itag === media_header.itag); + + if (!target_format) return; + + // Skip processing if this is an init segment and we've already received it. + if (media_header.isInitSeg) { + if (!target_format.init_segment) { + target_format._init_segment_media_id = media_header.headerId; + } else return; + } + + // Save the header's ID so we can identify its media data later. + if (!target_format._media_data_ids.includes(media_header.headerId || 0)) { + target_format._media_data_ids.push(media_header.headerId || 0); + } + + if (media_header.sequenceNumber && !target_format.sequence_list.some((seq) => seq.sequence_number === media_header.sequenceNumber)) { + target_format.sequence_list.push({ + itag: media_header.itag, + format_id: media_header.formatId, + duration_ms: media_header.durationMs, + start_ms: media_header.startMs, + start_data_range: media_header.startDataRange, + sequence_number: media_header.sequenceNumber, + content_length: media_header.contentLength, + time_range: media_header.timeRange + }); + + // This ensures sequences are retrieved in order. + this.initialized_formats.forEach((item) => { + if (item._state && item.format_id.itag === media_header.itag) { + item._state.durationMs += media_header.durationMs || 0; + item._state.field5 += 1; + } + }); + } + } + + private processMediaData(data: ChunkedDataBuffer) { + const media_data_id = data.getUint8(0); + const new_data = data.split(1).remainingBuffer.chunks[0]; + + const target_format = this.initialized_formats.find((fmt) => fmt._media_data_ids.includes(media_data_id)); + + if (!target_format) return; + + const isInitSegData = target_format._init_segment_media_id === media_data_id; + + if (target_format.init_segment && isInitSegData) + return; + + if (isInitSegData) { + target_format.init_segment = new_data; + delete target_format._init_segment_media_id; + return; + } + + const combined_length = target_format.media_data.length + new_data.length; + const temp_media_data = new Uint8Array(combined_length); + + temp_media_data.set(target_format.media_data); + temp_media_data.set(new_data, target_format.media_data.length); + + target_format.media_data = temp_media_data; + } + + private processEndOfMedia(data: ChunkedDataBuffer) { + const media_data_id = data.getUint8(0); + const target_format = this.initialized_formats.find((fmt) => fmt._media_data_ids.includes(media_data_id)); + if (target_format) target_format._media_data_ids.splice(target_format._media_data_ids.indexOf(media_data_id), 1); + } + + private processNextRequestPolicy(data: Uint8Array) { + const next_request_policy = NextRequestPolicy.decode(data); + this.playback_cookie = next_request_policy.playbackCookie; + } + + private processFormatInitialization(data: Uint8Array) { + const format_initialization_metadata = FormatInitializationMetadata.decode(data); + if (format_initialization_metadata.formatId && !this.initialized_formats.some((item) => item.format_id.itag === format_initialization_metadata.formatId?.itag)) { + this.initialized_formats.push({ + format_id: format_initialization_metadata.formatId, + duration_ms: format_initialization_metadata.durationMs, + mime_type: format_initialization_metadata.mimeType, + sequence_count: format_initialization_metadata.field4, + sequence_list: [], + media_data: new Uint8Array(), + // Only meant to be used internally. + _media_data_ids: [], + _state: { + formatId: format_initialization_metadata.formatId, + startTimeMs: 0, + durationMs: 0, + field4: 1, + field5: 0 + } + }); + } + } + + private processSabrRedirect(data: Uint8Array) { + const sabr_redirect = SabrRedirect.decode(data); + + if (!sabr_redirect.url) + throw new Error('Invalid SABR redirect'); + + this.server_abr_streaming_url = sabr_redirect.url; + } +} \ No newline at end of file diff --git a/src/core/UMP.ts b/src/core/UMP.ts new file mode 100644 index 0000000..6d7f071 --- /dev/null +++ b/src/core/UMP.ts @@ -0,0 +1,127 @@ +import type { Part } from '../index.js'; +import type { ChunkedDataBuffer } from './ChunkedDataBuffer.js'; + +export class UMP { + private chunkedDataBuffer: ChunkedDataBuffer; + + constructor(chunkedDataBuffer: ChunkedDataBuffer) { + this.chunkedDataBuffer = chunkedDataBuffer; + } + + public parse(handlePart: (part: Part) => void) { + while (true) { + let offset = 0; + + const [ partType, newOffset ] = this.readVarInt(offset); + offset = newOffset; + + const [ partSize, finalOffset ] = this.readVarInt(offset); + offset = finalOffset; + + if (partType < 0 || partSize < 0) + break; + + // Note that we don't handle cases like this YET.. + if (!this.chunkedDataBuffer.canReadBytes(offset, partSize)) + break; + + const splitResult = this.chunkedDataBuffer.split(offset).remainingBuffer.split(partSize); + offset = 0; + + handlePart({ + type: partType, + size: partSize, + data: splitResult.extractedBuffer + }); + + this.chunkedDataBuffer = splitResult.remainingBuffer; + } + } + + public readVarInt(offset: number): [ number, number ] { + let byteLength: number; + + if (this.chunkedDataBuffer.canReadBytes(offset, 1)) { + const firstByte = this.chunkedDataBuffer.getUint8(offset); + + // Determine the length of the val + if (firstByte < 128) { + byteLength = 1; + } else if (firstByte < 192) { + byteLength = 2; + } else if (firstByte < 224) { + byteLength = 3; + } else if (firstByte < 240) { + byteLength = 4; + } else { + byteLength = 5; + } + } else { + byteLength = 0; + } + + if (byteLength < 1 || !this.chunkedDataBuffer.canReadBytes(offset, byteLength)) { + return [ -1, offset ]; + } + + let value: number; + + // Now read it based on the length + switch (byteLength) { + case 1: + value = this.chunkedDataBuffer.getUint8(offset++); + break; + case 2: { + const byte1 = this.chunkedDataBuffer.getUint8(offset++); + const byte2 = this.chunkedDataBuffer.getUint8(offset++); + value = (byte1 & 0x3f) + 64 * byte2; + break; + } + case 3: { + const byte1 = this.chunkedDataBuffer.getUint8(offset++); + const byte2 = this.chunkedDataBuffer.getUint8(offset++); + const byte3 = this.chunkedDataBuffer.getUint8(offset++); + value = (byte1 & 0x1f) + 32 * (byte2 + 256 * byte3); + break; + } + case 4: { + const byte1 = this.chunkedDataBuffer.getUint8(offset++); + const byte2 = this.chunkedDataBuffer.getUint8(offset++); + const byte3 = this.chunkedDataBuffer.getUint8(offset++); + const byte4 = this.chunkedDataBuffer.getUint8(offset++); + value = (byte1 & 0x0f) + 16 * (byte2 + 256 * (byte3 + 256 * byte4)); + break; + } + default: { + const tempOffset = offset + 1; + this.chunkedDataBuffer.focus(tempOffset); + + if (this.canReadFromCurrentChunk(tempOffset, 4)) { + value = this.getCurrentDataView().getUint32(tempOffset - this.chunkedDataBuffer.currentChunkOffset, true); + } else { + const byte3 = this.chunkedDataBuffer.getUint8(tempOffset + 2) + 256 * this.chunkedDataBuffer.getUint8(tempOffset + 3); + value = + this.chunkedDataBuffer.getUint8(tempOffset) + + 256 * (this.chunkedDataBuffer.getUint8(tempOffset + 1) + 256 * byte3); + } + offset += 5; + break; + } + } + + return [ value, offset ]; + } + + public canReadFromCurrentChunk(offset: number, length: number): boolean { + this.chunkedDataBuffer.isFocused(offset); + return offset - this.chunkedDataBuffer.currentChunkOffset + length <= this.chunkedDataBuffer.chunks[this.chunkedDataBuffer.currentChunkIndex].length; + } + + public getCurrentDataView(): DataView { + if (!this.chunkedDataBuffer.currentDataView) { + const currentChunk = this.chunkedDataBuffer.chunks[this.chunkedDataBuffer.currentChunkIndex]; + this.chunkedDataBuffer.currentDataView = new DataView(currentChunk.buffer, currentChunk.byteOffset, currentChunk.length); + } + return this.chunkedDataBuffer.currentDataView; + } +} \ No newline at end of file diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 0000000..8a785f8 --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,3 @@ +export * from './ChunkedDataBuffer.js'; +export * from './UMP.js'; +export * from './ServerAbrStream.js'; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..d24a65b --- /dev/null +++ b/src/index.ts @@ -0,0 +1,4 @@ +import * as GoogleVideo from './core/index.js'; +export { GoogleVideo }; +export default GoogleVideo; +export * from './utils/index.js'; \ No newline at end of file diff --git a/src/utils/EventEmitterLike.ts b/src/utils/EventEmitterLike.ts new file mode 100644 index 0000000..ddb5363 --- /dev/null +++ b/src/utils/EventEmitterLike.ts @@ -0,0 +1,47 @@ +import { CustomEvent } from './index.js'; + +export class EventEmitterLike extends EventTarget { + #legacy_listeners = new Map<(...args: any[]) => void, EventListener>(); + + constructor() { + super(); + } + + emit(type: string, ...args: any[]) { + const event = new CustomEvent(type, { detail: args }); + this.dispatchEvent(event); + } + + on(type: string, listener: (...args: any[]) => void) { + const wrapper: EventListener = (ev) => { + if (ev instanceof CustomEvent) { + listener(...ev.detail as any[]); + } else { + listener(ev); + } + }; + this.#legacy_listeners.set(listener, wrapper); + this.addEventListener(type, wrapper); + } + + once(type: string, listener: (...args: any[]) => void) { + const wrapper: EventListener = (ev) => { + if (ev instanceof CustomEvent) { + listener(...ev.detail as any[]); + } else { + listener(ev); + } + this.off(type, listener); + }; + this.#legacy_listeners.set(listener, wrapper); + this.addEventListener(type, wrapper); + } + + off(type: string, listener: (...args: any[]) => void) { + const wrapper = this.#legacy_listeners.get(listener); + if (wrapper) { + this.removeEventListener(type, wrapper); + this.#legacy_listeners.delete(listener); + } + } +} \ No newline at end of file diff --git a/src/utils/Protos.ts b/src/utils/Protos.ts new file mode 100644 index 0000000..8a57485 --- /dev/null +++ b/src/utils/Protos.ts @@ -0,0 +1,10 @@ +export { FormatInitializationMetadata } from '../../protos/generated/video_streaming/format_initialization_metadata.js'; +export { MediaHeader } from '../../protos/generated/video_streaming/media_header.js'; +export { NextRequestPolicy } from '../../protos/generated/video_streaming/next_request_policy.js'; +export { PlaybackCookie } from '../../protos/generated/video_streaming/playback_cookie.js'; +export { PlaybackStartPolicy } from '../../protos/generated/video_streaming/playback_start_policy.js'; +export { RequestCancellationPolicy } from '../../protos/generated/video_streaming/request_cancellation_policy.js'; +export { SabrError } from '../../protos/generated/video_streaming/sabr_error.js'; +export { SabrRedirect } from '../../protos/generated/video_streaming/sabr_redirect.js'; +export { StreamProtectionStatus } from '../../protos/generated/video_streaming/stream_protection_status.js'; +export { VideoPlaybackAbrRequest } from '../../protos/generated/video_streaming/video_playback_abr_request.js'; \ No newline at end of file diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts new file mode 100644 index 0000000..93400b9 --- /dev/null +++ b/src/utils/helpers.ts @@ -0,0 +1,65 @@ +export enum PART { + ONESIE_HEADER = 10, + ONESIE_DATA = 11, + MEDIA_HEADER = 20, + MEDIA = 21, + MEDIA_END = 22, + LIVE_METADATA = 31, + HOSTNAME_CHANGE_HINT = 32, + LIVE_METADATA_PROMISE = 33, + LIVE_METADATA_PROMISE_CANCELLATION = 34, + NEXT_REQUEST_POLICY = 35, + USTREAMER_VIDEO_AND_FORMAT_DATA = 36, + FORMAT_SELECTION_CONFIG = 37, + USTREAMER_SELECTED_MEDIA_STREAM = 38, + FORMAT_INITIALIZATION_METADATA = 42, + SABR_REDIRECT = 43, + SABR_ERROR = 44, + SABR_SEEK = 45, + RELOAD_PLAYER_RESPONSE = 46, + PLAYBACK_START_POLICY = 47, + ALLOWED_CACHED_FORMATS = 48, + START_BW_SAMPLING_HINT = 49, + PAUSE_BW_SAMPLING_HINT = 50, + SELECTABLE_FORMATS = 51, + REQUEST_IDENTIFIER = 52, + REQUEST_CANCELLATION_POLICY = 53, + ONESIE_PREFETCH_REJECTION = 54, + TIMELINE_CONTEXT = 55, + REQUEST_PIPELINING = 56, + SABR_CONTEXT_UPDATE = 57, + STREAM_PROTECTION_STATUS = 58, + SABR_CONTEXT_SENDING_POLICY = 59, + LAWNMOWER_POLICY = 60, + SABR_ACK = 61, + END_OF_TRACK = 62, + CACHE_LOAD_POLICY = 63, + LAWNMOWER_MESSAGING_POLICY = 64, + PREWARM_CONNECTION = 65 +} + +export { MediaInfo_MediaType as MediaType } from '../../protos/generated/video_streaming/video_playback_abr_request.js'; + +export function u8ToBase64(u8: Uint8Array): string { + return btoa(String.fromCharCode.apply(null, Array.from(u8))); +} + +export function base64ToU8(base64: string): Uint8Array { + const standard_base64 = base64.replace(/-/g, '+').replace(/_/g, '/'); + const padded_base64 = standard_base64.padEnd(standard_base64.length + (4 - standard_base64.length % 4) % 4, '='); + return new Uint8Array(atob(padded_base64).split('').map((char) => char.charCodeAt(0))); +} + +// See https://github.com/nodejs/node/issues/40678#issuecomment-1126944677 +export class CustomEvent extends Event { + #detail; + + constructor(type: string, options?: CustomEventInit) { + super(type, options); + this.#detail = options?.detail ?? null; + } + + get detail() { + return this.#detail; + } +} \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..cd211d2 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from './helpers.js'; +export * from './EventEmitterLike.js'; +export * as Protos from './Protos.js'; +export type * from './types.js'; \ No newline at end of file diff --git a/src/utils/types.ts b/src/utils/types.ts new file mode 100644 index 0000000..5d43e51 --- /dev/null +++ b/src/utils/types.ts @@ -0,0 +1,133 @@ +import type { FormatId } from '../../protos/generated/misc/common.js'; +import type { MediaHeader_TimeRange } from '../../protos/generated/video_streaming/media_header.js'; +import type { SabrError } from '../../protos/generated/video_streaming/sabr_error.js'; +import type { StreamProtectionStatus } from '../../protos/generated/video_streaming/stream_protection_status.js'; +import type { Zpa, MediaInfo } from '../../protos/generated/video_streaming/video_playback_abr_request.js'; +import type { ChunkedDataBuffer } from '../core/index.js'; + +export type Part = { + type: number; + size: number; + data: ChunkedDataBuffer; +}; + +export type ServerAbrStreamOptions = { + fetch: FetchFunction; + server_abr_streaming_url: string; + video_playback_ustreamer_config: string; + po_token?: string; + duration_ms: number; +} +export type ServerAbrResponse = { + initialized_formats: InitializedFormat[]; + stream_protection_status?: StreamProtectionStatus; + sabr_error?: SabrError; +} + +export type Sequence = { + itag?: number; + format_id?: FormatId; + duration_ms?: number; + start_ms?: number; + start_data_range?: number; + sequence_number?: number; + content_length?: number; + time_range?: MediaHeader_TimeRange; +} + +export type InitializedFormat = { + format_id: FormatId; + duration_ms?: number; + mime_type?: string; + sequence_count?: number; + init_segment?: Uint8Array; + sequence_list: Sequence[]; + media_data: Uint8Array; + _init_segment_media_id?: number; + _media_data_ids: number[]; + _state: Zpa; +} + +export type InitOptions = { + audio_formats: Format[]; + video_formats: Format[]; + media_info?: MediaInfo; +}; + +export type MediaArgs = { + media_info: MediaInfo; + audio_format_ids: FormatId[]; + video_format_ids: FormatId[]; +} + +export type Format = { + itag: number; + url?: string; + width?: number; + height?: number; + last_modified: Date; + last_modified_ms: string; + content_length?: number; + quality?: string; + xtags?: string; + drm_families?: string[]; + fps?: number; + quality_label?: string; + projection_type?: 'RECTANGULAR' | 'EQUIRECTANGULAR' | 'EQUIRECTANGULAR_THREED_TOP_BOTTOM' | 'MESH'; + average_bitrate?: number; + bitrate: number; + spatial_audio_type?: 'AMBISONICS_5_1' | 'AMBISONICS_QUAD' | 'FOA_WITH_NON_DIEGETIC'; + target_duration_dec?: number; + fair_play_key_uri?: string; + stereo_layout?: 'LEFT_RIGHT' | 'TOP_BOTTOM'; + max_dvr_duration_sec?: number; + high_replication?: boolean; + audio_quality?: string; + approx_duration_ms: number; + audio_sample_rate?: number; + audio_channels?: number; + loudness_db?: number; + signature_cipher?: string; + is_drc?: boolean; + drm_track_type?: string; + distinct_params?: string; + track_absolute_loudness_lkfs?: number; + mime_type: string; + is_type_otf: boolean; + init_range?: { + start: number; + end: number; + }; + index_range?: { + start: number; + end: number; + }; + cipher?: string; + audio_track?: { + audio_is_default: boolean; + display_name: string; + id: string; + }; + has_audio: boolean; + has_video: boolean; + has_text: boolean; + language?: string | null; + is_dubbed?: boolean; + is_descriptive?: boolean; + is_secondary?: boolean; + is_original?: boolean; + color_info?: { + primaries?: string; + transfer_characteristics?: string; + matrix_coefficients?: string; + }; + caption_track?: { + display_name: string; + vss_id: string; + language_code: string; + kind?: 'asr' | 'frc'; + id: string; + }; +} + +export type FetchFunction = typeof fetch; \ No newline at end of file diff --git a/test.ts b/test.ts new file mode 100644 index 0000000..7c49c0a --- /dev/null +++ b/test.ts @@ -0,0 +1,34 @@ +import Innertube, { UniversalCache } from 'youtubei.js'; +import { GoogleVideo, Protos } from './dist/src/index.js'; + +const pot = 'MogByekTEuMCHffJ1fWU29jibLXb2em_4I0sBL3WX8kzmtnI2VOVIlJJjZ7mCf1E-4DaRwrPPqBXdL2ECFrjdNt2vIdAiTgbN44Q1asvZdjBr0bWFJsIzQRXUSXBRZDPq0IRZHTNc_B8ItbgV6yx7kJ4FOgkDsqj-_lubvsyWHjnq85WqGxEut11eQ=='; + +const innertube = await Innertube.create({ + cache: new UniversalCache(true), + po_token: pot, + visitor_data: 'CgtHelk0ajJwY185SSi91OO2BjIKCgJCUhIEGgAgZzoKILKg8r3TybrsZg%3D%3D', +}); + +const info = await innertube.getBasicInfo('nVSXA2t3F0U'); + +const audioFormat = info.chooseFormat({ + quality: "best", + format: "mp4", + type: 'audio', +}); + +const url = audioFormat.decipher(innertube.session.player); + +const response = await fetch(url + `&range=4583871-5785063&ump=1&srfvp=1`, { + method: 'POST', +}); + +const data = await response.arrayBuffer(); + +let dataBuffer = new GoogleVideo.ChunkedDataBuffer([new Uint8Array(data)]); + +const ump = new GoogleVideo.UMP(dataBuffer); + +ump.parse((part) => { + console.log(part); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..7b7105e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,98 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "ES2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + /* Modules */ + "module": "NodeNext", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [ "node" ], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + "declarationDir": "./dist", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Interop Constraints */ + "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": [ + "src/**/*" + ], +} \ No newline at end of file