From 9863cf74dfcb610f71bd60736cdb80eaf19872dc Mon Sep 17 00:00:00 2001 From: WardPearce Date: Tue, 1 Apr 2025 03:46:00 +1300 Subject: [PATCH] More progress --- .../src/lib/android/http/androidRequests.ts | 29 ++++++++++--------- materialious/src/lib/components/Player.svelte | 1 - .../src/lib/components/Transcript.svelte | 2 -- materialious/src/lib/patches/youtubejs.ts | 15 +++++----- materialious/static/nodejs-android/index.js | 6 +++- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/materialious/src/lib/android/http/androidRequests.ts b/materialious/src/lib/android/http/androidRequests.ts index 7a44ecac..1bc95d1f 100644 --- a/materialious/src/lib/android/http/androidRequests.ts +++ b/materialious/src/lib/android/http/androidRequests.ts @@ -4,38 +4,39 @@ import { Capacitor } from "@capacitor/core"; if (Capacitor.getPlatform() === 'android') { const originalFetch = window.fetch; + const currentOrigin: string = window.location.protocol + '//' + window.location.host; + + function needsProxying(target: string): boolean { + const targetOriginMatch = /^https?:\/\/([^\/]+)/i.exec(target); + return (targetOriginMatch && targetOriginMatch[0].toLowerCase()) !== currentOrigin; + } + const corsProxyUrl: string = 'http://localhost:3000/'; window.fetch = async (requestInput: string | URL | Request, requestOptions?: RequestInit): Promise => { - let requestUrl: string; + const uri = requestInput.toString(); - if (typeof requestInput === 'string') { - requestUrl = requestInput; - } else if ('url' in requestInput) { - requestUrl = requestInput.url; - } else { - requestUrl = requestInput.toString(); + console.log(uri, needsProxying(uri)); + + if (needsProxying(uri)) { + requestInput = corsProxyUrl + uri; } - if (!requestUrl.startsWith(corsProxyUrl) && !requestUrl.startsWith('/') && !requestUrl.startsWith('blob:')) { - requestInput = corsProxyUrl + requestUrl; - } + console.log(requestInput); // Use the original fetch with the proxied URL and options return originalFetch(requestInput, requestOptions); }; - const currentOrigin: string = window.location.protocol + '//' + window.location.host; const originalXhrOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function (...args: any[]): void { - const targetOriginMatch = /^https?:\/\/([^\/]+)/i.exec(args[1]); - if (targetOriginMatch && targetOriginMatch[0].toLowerCase() !== currentOrigin) { + if (needsProxying(args[1])) { args[1] = corsProxyUrl + args[1]; } /* @ts-ignore */ return originalXhrOpen.apply(this, args); }; - setTimeout(() => goto('/', { replaceState: true }), 10); + setTimeout(() => goto('/', { replaceState: true }), 100); } diff --git a/materialious/src/lib/components/Player.svelte b/materialious/src/lib/components/Player.svelte index 7b625584..45f2bcef 100644 --- a/materialious/src/lib/components/Player.svelte +++ b/materialious/src/lib/components/Player.svelte @@ -147,7 +147,6 @@ const url = new URL(request.uris[0]); if (url.hostname.endsWith('.googlevideo.com') && url.pathname === '/videoplayback') { - console.log('Modifying request'); if (request.headers.Range) { url.searchParams.set('range', request.headers.Range.split('=')[1]); url.searchParams.set('ump', '1'); diff --git a/materialious/src/lib/components/Transcript.svelte b/materialious/src/lib/components/Transcript.svelte index e7080456..79a11973 100644 --- a/materialious/src/lib/components/Transcript.svelte +++ b/materialious/src/lib/components/Transcript.svelte @@ -24,8 +24,6 @@ let currentTime = $state(0); let search: string = $state(''); - console.log('playerElement', playerElement); - playerElement.addEventListener('timeupdate', () => { currentTime = playerElement.currentTime; diff --git a/materialious/src/lib/patches/youtubejs.ts b/materialious/src/lib/patches/youtubejs.ts index d0fa7b2e..dfdc8a52 100644 --- a/materialious/src/lib/patches/youtubejs.ts +++ b/materialious/src/lib/patches/youtubejs.ts @@ -1,4 +1,3 @@ -import { capacitorFetch } from '$lib/android/http/capacitorFetch'; import type { AdaptiveFormats, Captions, Image, StoryBoard, Thumbnail, VideoBase, VideoPlay } from '$lib/api/model'; import { interfaceRegionStore, poTokenCacheStore } from '$lib/store'; import { numberWithCommas } from '$lib/time'; @@ -8,8 +7,6 @@ import { Buffer } from 'buffer'; import { get } from 'svelte/store'; import { Innertube, UniversalCache } from 'youtubei.js'; -const fetchClient = Capacitor.getPlatform() === 'android' ? capacitorFetch : fetch; - export async function patchYoutubeJs(videoId: string): Promise { if (!Capacitor.isNativePlatform()) { throw new Error('Platform not supported'); @@ -18,19 +15,23 @@ export async function patchYoutubeJs(videoId: string): Promise { let youtube: Innertube; if (!get(poTokenCacheStore)) { - youtube = await Innertube.create({ retrieve_player: false, fetch: fetchClient }); + youtube = await Innertube.create({ retrieve_player: false, fetch: fetch }); const requestKey = 'O43z0dpjhgX20SCx4KAo'; - const visitorData = youtube.session.context.client.visitorData as string; + const visitorData = youtube.session.context.client.visitorData; + + if (!visitorData) + throw new Error('Could not get visitor data'); const bgConfig: BgConfig = { - fetch: fetchClient, + fetch: (input: string | URL | Request, init?: RequestInit) => fetch(input, init), globalObj: globalThis, identifier: visitorData, requestKey }; const bgChallenge = await BG.Challenge.create(bgConfig); + if (!bgChallenge) throw new Error('Could not get challenge'); @@ -55,7 +56,7 @@ export async function patchYoutubeJs(videoId: string): Promise { const cachedPoToken = get(poTokenCacheStore); youtube = await Innertube.create({ - fetch: fetchClient, + fetch: fetch, generate_session_locally: true, cache: new UniversalCache(false), location: get(interfaceRegionStore), diff --git a/materialious/static/nodejs-android/index.js b/materialious/static/nodejs-android/index.js index 91d5209b..3621258c 100644 --- a/materialious/static/nodejs-android/index.js +++ b/materialious/static/nodejs-android/index.js @@ -3,12 +3,13 @@ const https = require('https'); const HOST = 'localhost'; const PORT = 3000; -const MAX_REDIRECTS = 5; +const MAX_REDIRECTS = 10; function setCorsHeaders(res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', '*'); + res.setHeader('Access-Control-Max-Age', '86400') res.setHeader('Access-Control-Allow-Credentials', 'true'); } @@ -86,6 +87,9 @@ const server = http.createServer(async (req, res) => { ) }; + options.headers.host = parsedTarget.host; + options.headers.origin = parsedTarget.origin; + // For POST and PUT methods, pass the body to the outgoing request if (req.method === 'POST' || req.method === 'PUT') { options.headers['Content-Length'] = Buffer.byteLength(body);