diff --git a/materialious/android/app/build.gradle b/materialious/android/app/build.gradle
index 55e505f3..63e2f67d 100644
--- a/materialious/android/app/build.gradle
+++ b/materialious/android/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 81
- versionName "1.6.30"
+ versionCode 82
+ versionName "1.7.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
diff --git a/materialious/electron/package.json b/materialious/electron/package.json
index 8fee234d..6840beff 100644
--- a/materialious/electron/package.json
+++ b/materialious/electron/package.json
@@ -1,6 +1,6 @@
{
"name": "Materialious",
- "version": "1.6.30",
+ "version": "1.7.0",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
diff --git a/materialious/package.json b/materialious/package.json
index 2a57b7b4..582dbe11 100644
--- a/materialious/package.json
+++ b/materialious/package.json
@@ -1,6 +1,6 @@
{
"name": "materialious",
- "version": "1.6.30",
+ "version": "1.7.0",
"private": true,
"scripts": {
"dev": "vite dev",
@@ -75,4 +75,4 @@
"vidstack": "^1.12.9",
"youtubei.js": "^12.2.0"
}
-}
+}
\ No newline at end of file
diff --git a/materialious/src/lib/components/Player.svelte b/materialious/src/lib/components/Player.svelte
index 634626eb..cb09dacd 100644
--- a/materialious/src/lib/components/Player.svelte
+++ b/materialious/src/lib/components/Player.svelte
@@ -2,7 +2,7 @@
import 'vidstack/bundle';
import { page } from '$app/stores';
- import { getBestThumbnail, proxyGoogleImage } from '$lib/images';
+ import { getBestThumbnail } from '$lib/images';
import { padTime, videoLength } from '$lib/time';
import { Capacitor } from '@capacitor/core';
import { ScreenOrientation, type ScreenOrientationResult } from '@capacitor/screen-orientation';
@@ -366,7 +366,11 @@
await loadPlayerPos();
});
- if (Capacitor.getPlatform() === 'android' && data.video.adaptiveFormats.length > 0) {
+ if (
+ Capacitor.getPlatform() === 'android' &&
+ data.video.adaptiveFormats.length > 0 &&
+ data.video.fallbackPatch === undefined
+ ) {
if (get(playerAndroidBgPlayer)) {
const highestBitrateAudio = data.video.adaptiveFormats
.filter((format) => format.type.startsWith('audio/'))
@@ -605,9 +609,7 @@
>
{#if !audioMode}
-
{/if}
diff --git a/materialious/src/lib/patches/youtubejs.ts b/materialious/src/lib/patches/youtubejs.ts
index 89ac4d2a..8bbd08cc 100644
--- a/materialious/src/lib/patches/youtubejs.ts
+++ b/materialious/src/lib/patches/youtubejs.ts
@@ -16,7 +16,7 @@ async function getPo(identifier: string): Promise {
const requestKey = 'O43z0dpjhgX20SCx4KAo';
const bgConfig = {
- fetch: fetch,
+ fetch: Capacitor.getPlatform() === 'android' ? capacitorFetch : fetch,
globalObj: window,
requestKey,
identifier
diff --git a/materialious/static/nodejs-android/index.js b/materialious/static/nodejs-android/index.js
index db5bc1cc..41465795 100644
--- a/materialious/static/nodejs-android/index.js
+++ b/materialious/static/nodejs-android/index.js
@@ -1,5 +1,109 @@
-const corsAnywhere = require('cors-anywhere');
+const http = require('http');
+const https = require('https');
-corsAnywhere.createServer({
- originWhitelist: [],
-}).listen(3000, 'localhost');
\ No newline at end of file
+const HOST = 'localhost';
+const PORT = 3000;
+const MAX_REDIRECTS = 5;
+const ORIGIN = `https://${HOST}`;
+
+function setCorsHeaders(res) {
+ res.setHeader('Access-Control-Allow-Origin', ORIGIN);
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
+ res.setHeader('Access-Control-Allow-Headers', '*');
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
+}
+
+function fetchWithRedirects(targetUrl, options, redirectCount = 0) {
+ return new Promise((resolve, reject) => {
+ const httpClient = targetUrl.protocol.startsWith('https') ? https : http;
+
+ const req = httpClient.request(targetUrl, options, (res) => {
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
+ if (redirectCount >= MAX_REDIRECTS) {
+ return reject(new Error('Too many redirects'));
+ }
+
+ let redirectHeaderLocation = res.headers.location;
+
+ // Handle relative URLs
+ if (redirectHeaderLocation.startsWith('/')) {
+ redirectHeaderLocation = targetUrl.host + redirectHeaderLocation;
+ }
+
+ // Add http:// if missing from the Location header
+ if (!redirectHeaderLocation.startsWith('http')) {
+ redirectHeaderLocation = 'http://' + redirectHeaderLocation;
+ }
+
+ try {
+ // Attempt to create the redirect URL
+ let redirectUrl = new URL(redirectHeaderLocation);
+ return resolve(fetchWithRedirects(redirectUrl, options, redirectCount + 1));
+ } catch (error) {
+ // Catch invalid URL errors
+ return reject(new Error(`Invalid URL in redirect: ${error.message}`));
+ }
+ }
+ resolve(res); // Resolve with the final response if not a redirect
+ });
+
+ req.on('error', reject);
+ req.end();
+ });
+}
+
+
+const server = http.createServer(async (req, res) => {
+ setCorsHeaders(res);
+
+ if (req.method === 'OPTIONS') {
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
+ return res.end();
+ }
+
+ if (!req.url || req.url === '/') {
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
+ return res.end('No URL provided to fetch.');
+ }
+
+ const targetUrl = req.url.slice(1); // Remove leading '/'
+ let parsedTarget;
+ try {
+ if (!targetUrl.startsWith('http')) {
+ targetUrl = 'http://' + targetUrl;
+ }
+ parsedTarget = new URL(targetUrl);
+ } catch (error) {
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
+ return res.end(`Invalid URL: ${error.message}`);
+ }
+
+ const options = {
+ method: req.method,
+ headers: {
+ ...req.headers,
+ host: parsedTarget.hostname, // Ensure correct host header
+ },
+ };
+
+ try {
+ const proxyRes = await fetchWithRedirects(parsedTarget, options);
+ res.writeHead(proxyRes.statusCode, {
+ ...proxyRes.headers,
+ 'Access-Control-Allow-Origin': ORIGIN,
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Headers': '*',
+ 'Access-Control-Allow-Credentials': 'true',
+ });
+
+ proxyRes.pipe(res); // Pipe response data back to the client
+ } catch (error) {
+ console.error('Proxy error:', error);
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
+ res.end(`Error: ${error.message}`);
+ }
+});
+
+server.listen(PORT, () => {
+ console.log(`Server is running on http://${HOST}:${PORT}`);
+});
diff --git a/materialious/static/nodejs-android/package-lock.json b/materialious/static/nodejs-android/package-lock.json
index 2ce1406a..140d2606 100644
--- a/materialious/static/nodejs-android/package-lock.json
+++ b/materialious/static/nodejs-android/package-lock.json
@@ -6,49 +6,7 @@
"packages": {
"": {
"name": "cors-patch",
- "version": "0.0.1",
- "dependencies": {
- "cors-anywhere": "^0.4.4"
- }
- },
- "node_modules/cors-anywhere": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/cors-anywhere/-/cors-anywhere-0.4.4.tgz",
- "integrity": "sha512-8OBFwnzMgR4mNrAeAyOLB2EruS2z7u02of2bOu7i9kKYlZG+niS7CTHLPgEXKWW2NAOJWRry9RRCaL9lJRjNqg==",
- "dependencies": {
- "http-proxy": "1.11.1",
- "proxy-from-env": "0.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/eventemitter3": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
- "integrity": "sha512-DOFqA1MF46fmZl2xtzXR3MPCRsXqgoFqdXcrCVYM3JNnfUeHTm/fh/v/iU7gBFpwkuBmoJPAm5GuhdDfSEJMJA=="
- },
- "node_modules/http-proxy": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.11.1.tgz",
- "integrity": "sha512-qz7jZarkVG3G6GMq+4VRJPSN4NkIjL4VMTNhKGd8jc25BumeJjWWvnY3A7OkCGa8W1TTxbaK3dcE0ijFalITVA==",
- "dependencies": {
- "eventemitter3": "1.x.x",
- "requires-port": "0.x.x"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/proxy-from-env": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-0.0.1.tgz",
- "integrity": "sha512-B9Hnta3CATuMS0q6kt5hEezOPM+V3dgaRewkFtFoaRQYTVNsHqUvFXmndH06z3QO1ZdDnRELv5vfY6zAj/gG7A=="
- },
- "node_modules/requires-port": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-0.0.1.tgz",
- "integrity": "sha512-AzPDCliPoWDSvEVYRQmpzuPhGGEnPrQz9YiOEvn+UdB9ixBpw+4IOZWtwctmpzySLZTy7ynpn47V14H4yaowtA=="
+ "version": "0.0.1"
}
}
}
diff --git a/materialious/static/nodejs-android/package.json b/materialious/static/nodejs-android/package.json
index 7741a1dd..dfd11e64 100644
--- a/materialious/static/nodejs-android/package.json
+++ b/materialious/static/nodejs-android/package.json
@@ -1,8 +1,5 @@
{
"name": "cors-patch",
"version": "0.0.1",
- "main": "./index.js",
- "dependencies": {
- "cors-anywhere": "^0.4.4"
- }
-}
\ No newline at end of file
+ "main": "./index.js"
+}
diff --git a/update_versions.py b/update_versions.py
index 83e6e2a9..a68d8ac8 100644
--- a/update_versions.py
+++ b/update_versions.py
@@ -5,7 +5,7 @@ import json
import os
import re
-LATEST_VERSION = "1.6.30"
+LATEST_VERSION = "1.7.0"
WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "materialious")
ROOT_PACKAGE = os.path.join(WORKING_DIR, "package.json")