diff --git a/materialious/android/app/build.gradle b/materialious/android/app/build.gradle index d5df8626..872b9060 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 219 - versionName "1.16.1" + versionCode 220 + versionName "1.16.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 38fb68e9..bdc66377 100644 --- a/materialious/electron/materialious.metainfo.xml +++ b/materialious/electron/materialious.metainfo.xml @@ -84,7 +84,11 @@ - + + + https://github.com/Materialious/Materialious/releases/tag/1.16.2 + + https://github.com/Materialious/Materialious/releases/tag/1.16.1 diff --git a/materialious/electron/package.json b/materialious/electron/package.json index b7e67a5f..a94d1e63 100644 --- a/materialious/electron/package.json +++ b/materialious/electron/package.json @@ -1,6 +1,6 @@ { "name": "Materialious", - "version": "1.16.1", + "version": "1.16.2", "description": "Modern material design for YouTube and Invidious.", "author": { "name": "Ward Pearce", @@ -45,4 +45,4 @@ "capacitor", "electron" ] -} +} \ No newline at end of file diff --git a/materialious/package-lock.json b/materialious/package-lock.json index ade68fa3..ed3a2f4e 100644 --- a/materialious/package-lock.json +++ b/materialious/package-lock.json @@ -1,12 +1,12 @@ { "name": "materialious", - "version": "1.16.1", + "version": "1.16.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "materialious", - "version": "1.16.1", + "version": "1.16.2", "hasInstallScript": true, "dependencies": { "@capacitor-community/electron": "^5.0.1", diff --git a/materialious/package.json b/materialious/package.json index 5d6d69d3..457d9e95 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -1,6 +1,6 @@ { "name": "materialious", - "version": "1.16.1", + "version": "1.16.2", "private": true, "scripts": { "dev": "npm run patch:github && vite dev", @@ -96,4 +96,4 @@ "youtubei.js": "^16.0.1", "zod": "^4.3.6" } -} \ No newline at end of file +} diff --git a/materialious/src/lib/api/model.ts b/materialious/src/lib/api/model.ts index 7902c11c..793e795c 100644 --- a/materialious/src/lib/api/model.ts +++ b/materialious/src/lib/api/model.ts @@ -98,6 +98,8 @@ export interface Ytjs { rawApiResponse: ApiResponse; } +export type FallbackPatches = 'youtubejs' | 'piped'; + export interface VideoPlay extends Video { keywords: string[]; likeCount: number; @@ -120,7 +122,7 @@ export interface VideoPlay extends Video { captions: Captions[]; storyboards?: StoryBoard[]; ytjs?: Ytjs; - fallbackPatch?: 'youtubejs' | 'piped'; + fallbackPatch?: FallbackPatches; } export interface StoryBoard { diff --git a/materialious/src/lib/components/player/ClosedCaptions.svelte b/materialious/src/lib/components/player/ClosedCaptions.svelte new file mode 100644 index 00000000..00d2fd8c --- /dev/null +++ b/materialious/src/lib/components/player/ClosedCaptions.svelte @@ -0,0 +1,129 @@ + + + + +{#if trackVisible && captionsCues.length > 0} + {#if currentCaption} +
+ {#if currentCaption} +

+ + {@html renderVTTCueString(currentCaption, currentTime)} +

+ {/if} +
+ {/if} +{/if} + + diff --git a/materialious/src/lib/components/player/Player.svelte b/materialious/src/lib/components/player/Player.svelte index 0b43535f..4c689e34 100644 --- a/materialious/src/lib/components/player/Player.svelte +++ b/materialious/src/lib/components/player/Player.svelte @@ -17,7 +17,6 @@ import type { VideoPlay } from '$lib/api/model'; import { invidiousAuthStore, - invidiousInstanceStore, isAndroidTvStore, playerAlwaysLoopStore, playerAndroidLockOrientation, @@ -65,6 +64,7 @@ import TouchControls from './TouchControls.svelte'; import { Network, type ConnectionStatus } from '@capacitor/network'; import { ScreenOrientation, type ScreenOrientationResult } from '@capacitor/screen-orientation'; + import ClosedCaptions from './ClosedCaptions.svelte'; interface Props { data: { video: VideoPlay; content: ParsedDescription; playlistId: string | null }; @@ -286,28 +286,6 @@ await player.load(dashUrl, await getLastPlayPos()); } - if (data.video.captions) { - for (const caption of data.video.captions) { - let captionUrl: string; - if (!getPublicEnv('DEFAULT_COMPANION_INSTANCE') && $invidiousInstanceStore) { - captionUrl = caption.url.startsWith('http') - ? caption.url - : `${new URL($invidiousInstanceStore).origin}${caption.url}`; - } else { - captionUrl = `${getPublicEnv('DEFAULT_COMPANION_INSTANCE')}${caption.url}`; - } - - await player.addTextTrackAsync( - captionUrl, - caption.language_code, - 'captions', - undefined, - undefined, - caption.label - ); - } - } - if (data.content.timestamps) { try { player.addChaptersTrack( @@ -479,31 +457,6 @@ const error = (event as CustomEvent).detail as shaka.util.Error; console.error('Player error:', error); }); - player.getNetworkingEngine()?.registerResponseFilter((type, response) => { - if ( - type !== shaka.net.NetworkingEngine.RequestType.SEGMENT || - !response.uri.includes('/api/timedtext') - ) { - return; - } - - const url = new URL(response.uri); - - // Fix positioning for auto-generated subtitles - // Credit to Freetube! - if ( - url.hostname.endsWith('.youtube.com') && - url.pathname === '/api/timedtext' && - url.searchParams.get('caps') === 'asr' && - url.searchParams.get('kind') === 'asr' && - url.searchParams.get('fmt') === 'vtt' - ) { - const stringBody = new TextDecoder().decode(response.data); - // position:0% for LTR text and position:100% for RTL text - const cleaned = stringBody.replaceAll(/ align:start position:(?:10)?0%$/gm, ''); - response.data = new TextEncoder().encode(cleaned).buffer; - } - }); playerElement?.addEventListener('volumechange', saveVolumePreference); @@ -894,6 +847,8 @@ }} bind:this={playerContainer} > + +