From a0055cf08831e539644c9169a992bd5db5499692 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Wed, 5 Nov 2025 04:14:25 +1300 Subject: [PATCH 1/3] Companion Fixes --- materialious/src/lib/components/Player.svelte | 32 +++++++++++++++++-- .../src/lib/css/shaka-player-theme.css | 5 +++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/materialious/src/lib/components/Player.svelte b/materialious/src/lib/components/Player.svelte index 6c2c5b52..e887a7fa 100644 --- a/materialious/src/lib/components/Player.svelte +++ b/materialious/src/lib/components/Player.svelte @@ -324,15 +324,19 @@ let dashUrl: string; + let usingCorsCompanionPatch = + import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE && Capacitor.getPlatform() === 'web'; + let usingCompanion = false; + // Due to CORs issues with redirects, hosted instances of Materialious // dirctly provide the companion instance // while clients can just use the reirect provided by Invidious' API - if (import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE && Capacitor.getPlatform() === 'web') { + if (usingCorsCompanionPatch) { dashUrl = `${import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE}/api/manifest/dash/id/${data.video.videoId}`; + usingCompanion = true; } else { if (!data.video.dashUrl) { error(500, 'No dash manifest found'); - return; } dashUrl = data.video.dashUrl; } @@ -341,6 +345,19 @@ dashUrl += '?local=true'; } + if (!usingCorsCompanionPatch) { + const dashUrlObject = new URL(dashUrl); + if (!dashUrlObject.pathname.includes('companion')) { + dashUrlObject.pathname = `/companion${dashUrlObject.pathname}`; + + const companionTestResp = await fetch(dashUrlObject, { method: 'HEAD' }); + if (companionTestResp.ok) { + dashUrl = dashUrlObject.toString(); + usingCompanion = true; + } + } + } + if ( Capacitor.getPlatform() === 'android' && $playerProxyVideosStore && @@ -354,8 +371,17 @@ if (data.video.captions) { for (const caption of data.video.captions) { + let captionUrl: string; + if (!usingCorsCompanionPatch) { + captionUrl = caption.url.startsWith('http') + ? caption.url + : `${get(instanceStore)}${usingCompanion ? '/companion' : ''}${caption.url}`; + } else { + captionUrl = `${import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE}/api/v1/captions/${data.video.videoId}`; + } + await player.addTextTrackAsync( - caption.url.startsWith('http') ? caption.url : `${get(instanceStore)}${caption.url}`, + captionUrl, caption.language_code, 'captions', undefined, diff --git a/materialious/src/lib/css/shaka-player-theme.css b/materialious/src/lib/css/shaka-player-theme.css index 75feabaf..fd9e9b85 100644 --- a/materialious/src/lib/css/shaka-player-theme.css +++ b/materialious/src/lib/css/shaka-player-theme.css @@ -7,6 +7,11 @@ color: var(--on-surface) !important; } +.shaka-current-time { + color: #fff !important; + opacity: 1 !important; +} + .player-theme .shaka-video-container * { font-family: var(--font) !important; color: var(--on-surface) !important; From 1a1a4e5f59f83dc2d0ea04b26bcac079c408a2f3 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Wed, 5 Nov 2025 04:14:35 +1300 Subject: [PATCH 2/3] Bump version --- materialious/android/app/build.gradle | 4 ++-- materialious/electron/materialious.metainfo.xml | 6 +++++- materialious/electron/package.json | 2 +- materialious/package.json | 2 +- update_versions.py | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/materialious/android/app/build.gradle b/materialious/android/app/build.gradle index 07c5c7d9..10167ee9 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 161 - versionName "1.11.1" + versionCode 162 + versionName "1.11.2" 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/materialious.metainfo.xml b/materialious/electron/materialious.metainfo.xml index 6b199450..141006f3 100644 --- a/materialious/electron/materialious.metainfo.xml +++ b/materialious/electron/materialious.metainfo.xml @@ -71,7 +71,11 @@ - + + + https://github.com/Materialious/Materialious/releases/tag/1.11.2 + + https://github.com/Materialious/Materialious/releases/tag/1.11.1 diff --git a/materialious/electron/package.json b/materialious/electron/package.json index 31724f70..b55c6f18 100644 --- a/materialious/electron/package.json +++ b/materialious/electron/package.json @@ -1,6 +1,6 @@ { "name": "Materialious", - "version": "1.11.1", + "version": "1.11.2", "description": "Modern material design for Invidious.", "author": { "name": "Ward Pearce", diff --git a/materialious/package.json b/materialious/package.json index d49f8aa1..d4be42b9 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -1,6 +1,6 @@ { "name": "materialious", - "version": "1.11.1", + "version": "1.11.2", "private": true, "scripts": { "dev": "vite dev", diff --git a/update_versions.py b/update_versions.py index 91ed0ea2..6cf8998d 100644 --- a/update_versions.py +++ b/update_versions.py @@ -3,7 +3,7 @@ import os import re from datetime import datetime -LATEST_VERSION = "1.11.1" +LATEST_VERSION = "1.11.2" RELEASE_DATE = datetime.now().strftime("%Y-%-m-%d") # Format: YYYY-M-D WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "materialious") From 16b7d43321f16bf9a824c03c272858ec7abd6ea4 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Wed, 5 Nov 2025 04:52:26 +1300 Subject: [PATCH 3/3] Subtitle fix for companion --- docs/DOCKER.md | 9 +++++ docs/INSTANCES.md | 10 +---- materialious/electron/package-lock.json | 4 +- materialious/src/lib/components/Player.svelte | 38 +++++++------------ 4 files changed, 25 insertions(+), 36 deletions(-) diff --git a/docs/DOCKER.md b/docs/DOCKER.md index 94daa4ac..abc221d1 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -106,6 +106,15 @@ http: ### Invidious Companion support The `VITE_DEFAULT_COMPANION_INSTANCE` environment variable allows you to specify a custom [Invidious Companion](https://github.com/iv-org/invidious-companion) instance. +`public_url` **MUST** be set in Invidious under **invidious_companion** for companion to work with Materialious. + +e.g. +```yml +invidious_companion: + - private_url: "http://companion:8282/companion" + public_url: "http://companion.example.com/companion" +``` + To use this with Materialious, your Invidious Companion instance must be accessible with proper CORS headers. Fortunately, you can reuse the same reverse proxy configuration (with CORS modifications) that you applied to your Invidious instance—just apply it to your companion domain as well. For example, if you're using Caddy, you can configure your companion domain like this: diff --git a/docs/INSTANCES.md b/docs/INSTANCES.md index e45af722..66ecedce 100644 --- a/docs/INSTANCES.md +++ b/docs/INSTANCES.md @@ -1,10 +1,2 @@ # Public instances -- [app.materialio.us](https://app.materialio.us) - - **Location:** New Zealand - - **Threads:** 6 - - **IPV6 rotation:** Yes - - **Man in the Middle:** No - - **Accounts:** Yes - - **RYD-Proxy:** Yes - - **API Extended integration:** Yes - - **Self-hosted PeerJS:** No +N/A diff --git a/materialious/electron/package-lock.json b/materialious/electron/package-lock.json index 8c38fa56..0626e891 100644 --- a/materialious/electron/package-lock.json +++ b/materialious/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "Materialious", - "version": "1.11.1", + "version": "1.11.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Materialious", - "version": "1.11.1", + "version": "1.11.2", "license": "MIT", "dependencies": { "@capacitor-community/electron": "^5.0.0", diff --git a/materialious/src/lib/components/Player.svelte b/materialious/src/lib/components/Player.svelte index e887a7fa..bddfba86 100644 --- a/materialious/src/lib/components/Player.svelte +++ b/materialious/src/lib/components/Player.svelte @@ -324,16 +324,11 @@ let dashUrl: string; - let usingCorsCompanionPatch = - import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE && Capacitor.getPlatform() === 'web'; - let usingCompanion = false; - // Due to CORs issues with redirects, hosted instances of Materialious // dirctly provide the companion instance // while clients can just use the reirect provided by Invidious' API - if (usingCorsCompanionPatch) { + if (import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE) { dashUrl = `${import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE}/api/manifest/dash/id/${data.video.videoId}`; - usingCompanion = true; } else { if (!data.video.dashUrl) { error(500, 'No dash manifest found'); @@ -345,19 +340,6 @@ dashUrl += '?local=true'; } - if (!usingCorsCompanionPatch) { - const dashUrlObject = new URL(dashUrl); - if (!dashUrlObject.pathname.includes('companion')) { - dashUrlObject.pathname = `/companion${dashUrlObject.pathname}`; - - const companionTestResp = await fetch(dashUrlObject, { method: 'HEAD' }); - if (companionTestResp.ok) { - dashUrl = dashUrlObject.toString(); - usingCompanion = true; - } - } - } - if ( Capacitor.getPlatform() === 'android' && $playerProxyVideosStore && @@ -370,14 +352,15 @@ } if (data.video.captions) { + console.log(data.video.captions); for (const caption of data.video.captions) { let captionUrl: string; - if (!usingCorsCompanionPatch) { + if (!import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE) { captionUrl = caption.url.startsWith('http') ? caption.url - : `${get(instanceStore)}${usingCompanion ? '/companion' : ''}${caption.url}`; + : `${get(instanceStore)}${caption.url}`; } else { - captionUrl = `${import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE}/api/v1/captions/${data.video.videoId}`; + captionUrl = `${import.meta.env.VITE_DEFAULT_COMPANION_INSTANCE}${caption.url}`; } await player.addTextTrackAsync( @@ -732,10 +715,15 @@ try { await loadVideo(); } catch (error: unknown) { - if (!Capacitor.isNativePlatform() || data.video.fallbackPatch === 'youtubejs') return; - showVideoRetry = true; + if ( + !Capacitor.isNativePlatform() || + data.video.fallbackPatch === 'youtubejs' || + (error as shaka.extern.Error).code !== 1001 + ) + return; - if ((error as shaka.extern.Error).code === 1001 && $playerYouTubeJsFallback) { + showVideoRetry = true; + if ($playerYouTubeJsFallback) { await reloadVideo(); } }