diff --git a/examples/README.md b/examples/README.md index 9a0e8f6..ced0380 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,24 +1,10 @@ -**NOTE:** -Build the library first before running the examples! - -```bash -npm run build -``` - -## Browser Example - -```bash -cd examples/browser/web -npm install -npm run dev - -# Proxy server -deno run --allow-net --allow-read examples/browser/proxy/deno.ts -``` +## SABR/UMP Player Example +https://github.com/LuanRT/yt-sabr-shaka-demo ## Downloader Example ```bash +npm run build # If you haven't built the project yet. cd examples/downloader npm install npx tsx main.ts @@ -30,6 +16,7 @@ npx tsx ffmpeg-example.ts ## "Onesie" Request Example ```bash +npm run build # If you haven't built the project yet. cd examples/onesie-request npm install npx tsx main.ts diff --git a/examples/browser/proxy/deno.ts b/examples/browser/proxy/deno.ts deleted file mode 100644 index 14b7313..0000000 --- a/examples/browser/proxy/deno.ts +++ /dev/null @@ -1,87 +0,0 @@ -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 deleted file mode 100644 index a547bf3..0000000 --- a/examples/browser/web/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# 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 deleted file mode 100644 index de4aedd..0000000 --- a/examples/browser/web/favicon.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/examples/browser/web/index.html b/examples/browser/web/index.html deleted file mode 100644 index 108ce59..0000000 --- a/examples/browser/web/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - 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 deleted file mode 100644 index 0dde33d..0000000 --- a/examples/browser/web/package-lock.json +++ /dev/null @@ -1,931 +0,0 @@ -{ - "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" - }, - "devDependencies": { - "typescript": "^4.6.4", - "vite": "^5.4.8" - } - }, - "../../..": { - "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/@bufbuild/protobuf": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.0.0.tgz", - "integrity": "sha512-sw2JhwJyvyL0zlhG61aDzOVryEfJg2PDZFSV7i7IdC7nAE41WuXCru3QWLGiP87At0BMzKOoKO/FqEGoKygGZQ==" - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "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/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "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/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.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "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", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "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" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", - "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.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/youtubei.js": { - "version": "10.4.0", - "resolved": "git+ssh://git@github.com/LuanRT/YouTube.js.git#0a5d3aa76ded999a40b6cdddf035f83b4f247f59", - "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/browser/web/package.json b/examples/browser/web/package.json deleted file mode 100644 index b4a23c4..0000000 --- a/examples/browser/web/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "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": "^5.4.8" - }, - "dependencies": { - "bgutils-js": "^2.0.1", - "shaka-player": "^4.11.2", - "youtubei.js": "github:LuanRT/YouTube.js" - } -} diff --git a/examples/browser/web/public/service-worker.js b/examples/browser/web/public/service-worker.js deleted file mode 100644 index c594f73..0000000 --- a/examples/browser/web/public/service-worker.js +++ /dev/null @@ -1,3 +0,0 @@ -/* 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 deleted file mode 100644 index 576d753..0000000 --- a/examples/browser/web/public/service-worker.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "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 deleted file mode 100644 index e7b8dfb..0000000 --- a/examples/browser/web/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/browser/web/src/assets/player.css b/examples/browser/web/src/assets/player.css deleted file mode 100644 index ce4a420..0000000 --- a/examples/browser/web/src/assets/player.css +++ /dev/null @@ -1,423 +0,0 @@ -@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 deleted file mode 100644 index 62f455a..0000000 --- a/examples/browser/web/src/assets/style.css +++ /dev/null @@ -1,135 +0,0 @@ -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 deleted file mode 100644 index 1d0b322..0000000 --- a/examples/browser/web/src/main.ts +++ /dev/null @@ -1,408 +0,0 @@ -import { BG } from 'bgutils-js'; -import GoogleVideo, { PART, Protos } from '../../../..'; -import { Innertube, ProtoUtils, 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 = ProtoUtils.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 deleted file mode 100644 index 11f02fe..0000000 --- a/examples/browser/web/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/examples/browser/web/tsconfig.json b/examples/browser/web/tsconfig.json deleted file mode 100644 index 3cacf7e..0000000 --- a/examples/browser/web/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "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"] -}