@@ -7,8 +7,8 @@ android {
|
||||
applicationId "us.materialio.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 99
|
||||
versionName "1.7.17"
|
||||
versionCode 100
|
||||
versionName "1.7.18"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
|
||||
@@ -60,7 +60,11 @@
|
||||
|
||||
|
||||
|
||||
<release version="1.7.17" date="2025-4-02">
|
||||
|
||||
<release version="1.7.18" date="2025-4-04">
|
||||
<url>https://github.com/Materialious/Materialious/releases/tag/1.7.18</url>
|
||||
</release>
|
||||
<release version="1.7.17" date="2025-4-02">
|
||||
<url>https://github.com/Materialious/Materialious/releases/tag/1.7.17</url>
|
||||
</release>
|
||||
<release version="1.7.16" date="2025-4-02">
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "Materialious",
|
||||
"version": "1.7.17",
|
||||
"version": "1.7.18",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "Materialious",
|
||||
"version": "1.7.17",
|
||||
"version": "1.7.18",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@capacitor-community/electron": "^5.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Materialious",
|
||||
"version": "1.7.17",
|
||||
"version": "1.7.18",
|
||||
"description": "Modern material design for Invidious.",
|
||||
"author": {
|
||||
"name": "Ward Pearce",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "materialious",
|
||||
"version": "1.7.17",
|
||||
"version": "1.7.18",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { NavigationBar } from '@hugotomazi/capacitor-navigation-bar';
|
||||
import { type Page } from '@sveltejs/kit';
|
||||
import { GoogleVideo, Protos } from 'googlevideo';
|
||||
import ISO6391 from 'iso-639-1';
|
||||
import 'shaka-player/dist/controls.css';
|
||||
import shaka from 'shaka-player/dist/shaka-player.ui';
|
||||
import { SponsorBlock, type Category, type Segment } from 'sponsorblock-api';
|
||||
@@ -38,7 +39,6 @@
|
||||
|
||||
interface Props {
|
||||
data: { video: VideoPlay; content: PhasedDescription; playlistId: string | null };
|
||||
audioMode?: boolean;
|
||||
isSyncing?: boolean;
|
||||
isEmbed?: boolean;
|
||||
segments?: Segment[];
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
let {
|
||||
data,
|
||||
audioMode = false,
|
||||
isEmbed = false,
|
||||
segments = $bindable([]),
|
||||
playerElement = $bindable()
|
||||
@@ -76,13 +75,13 @@
|
||||
localStorage.setItem(STORAGE_KEY_VOLUME, playerElement.volume.toString());
|
||||
}
|
||||
|
||||
function restorePreferences() {
|
||||
function restoreQualityPreference() {
|
||||
const savedQuality =
|
||||
localStorage.getItem(STORAGE_KEY_QUALITY) ??
|
||||
(import.meta.env.VITE_DEFAULT_DASH_BITRATE as string);
|
||||
(import.meta.env.VITE_DEFAULT_DASH_BITRATE as string | undefined);
|
||||
|
||||
if (savedQuality) {
|
||||
const qualityBandwidth = parseInt(savedQuality, 10);
|
||||
const qualityBandwidth = parseInt(savedQuality);
|
||||
const tracks = player.getVariantTracks();
|
||||
|
||||
let preferredTrack = tracks.find((track) => track.bandwidth === qualityBandwidth);
|
||||
@@ -96,14 +95,8 @@
|
||||
|
||||
if (preferredTrack) {
|
||||
player.selectVariantTrack(preferredTrack, true);
|
||||
player.configure({ abr: { enabled: false } });
|
||||
}
|
||||
}
|
||||
|
||||
const savedVolume = localStorage.getItem(STORAGE_KEY_VOLUME);
|
||||
if (savedVolume) {
|
||||
playerElement.volume = parseFloat(savedVolume);
|
||||
}
|
||||
}
|
||||
|
||||
function loadTimeFromUrl(page: Page): boolean {
|
||||
@@ -131,6 +124,12 @@
|
||||
player = new shaka.Player();
|
||||
playerElement = document.getElementById('player') as HTMLMediaElement;
|
||||
|
||||
// Change instantly to stop video from being loud for a second
|
||||
const savedVolume = localStorage.getItem(STORAGE_KEY_VOLUME);
|
||||
if (savedVolume) {
|
||||
playerElement.volume = parseFloat(savedVolume);
|
||||
}
|
||||
|
||||
await player.attach(playerElement);
|
||||
shakaUi = new shaka.ui.Overlay(
|
||||
player,
|
||||
@@ -138,20 +137,29 @@
|
||||
playerElement
|
||||
);
|
||||
|
||||
player.addEventListener('adaptation', () => setTimeout(saveQualityPreference, 10000));
|
||||
playerElement.addEventListener('volumechange', saveVolumePreference);
|
||||
|
||||
shakaUi.configure({
|
||||
controlPanelElements: [
|
||||
'play_pause',
|
||||
Capacitor.getPlatform() === 'android' ? '' : 'volume',
|
||||
'spacer',
|
||||
Capacitor.getPlatform() === 'electron' ? 'volume' : '',
|
||||
'chapter',
|
||||
'time_and_duration',
|
||||
'captions',
|
||||
'overflow_menu',
|
||||
'fullscreen'
|
||||
],
|
||||
overflowMenuButtons: ['cast', 'airplay', 'captions', 'quality', 'loop', 'language']
|
||||
overflowMenuButtons: [
|
||||
'cast',
|
||||
'airplay',
|
||||
'captions',
|
||||
'quality',
|
||||
'playback_rate',
|
||||
'loop',
|
||||
'language',
|
||||
'save_video_frame',
|
||||
'statistics'
|
||||
],
|
||||
enableTooltips: true
|
||||
});
|
||||
|
||||
player.configure({
|
||||
@@ -401,14 +409,6 @@
|
||||
|
||||
await loadPlayerPos();
|
||||
|
||||
const defaultLanguage = get(playerDefaultLanguage);
|
||||
if (defaultLanguage) {
|
||||
const audioLanguages = player.getAudioLanguages();
|
||||
if (audioLanguages.includes(defaultLanguage)) {
|
||||
player.selectAudioLanguage(defaultLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
if (Capacitor.getPlatform() === 'android' && data.video.adaptiveFormats.length > 0) {
|
||||
const videoFormats = data.video.adaptiveFormats.filter((format) =>
|
||||
format.type.startsWith('video/')
|
||||
@@ -465,16 +465,32 @@
|
||||
ui('#snackbar-alert');
|
||||
}
|
||||
|
||||
restorePreferences();
|
||||
player.addEventListener('buffering', saveQualityPreference);
|
||||
playerElement.addEventListener('volumechange', saveVolumePreference);
|
||||
|
||||
player.addEventListener('loaded', () => {
|
||||
restoreQualityPreference();
|
||||
|
||||
const defaultLanguage = get(playerDefaultLanguage);
|
||||
if (defaultLanguage) {
|
||||
const audioLanguages = player.getAudioLanguages();
|
||||
const langCode = ISO6391.getCode(defaultLanguage);
|
||||
|
||||
for (const audioLanguage of audioLanguages) {
|
||||
if (audioLanguage.startsWith(langCode)) {
|
||||
player.selectAudioLanguage(audioLanguage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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'
|
||||
);
|
||||
const backToOverflowButton = document.querySelector('.shaka-back-to-overflow-button');
|
||||
if (backToOverflowButton) {
|
||||
backToOverflowButton.innerHTML = 'arrow_back_ios_new';
|
||||
}
|
||||
@@ -556,10 +572,6 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if audioMode}
|
||||
<div style="margin-top: 40vh;"></div>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
id="shaka-container"
|
||||
class="youtube-theme"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
playerAutoPlayStore,
|
||||
playerAutoplayNextByDefaultStore,
|
||||
playerDefaultLanguage,
|
||||
playerListenByDefaultStore,
|
||||
playerProxyVideosStore,
|
||||
playerSavePlaybackPositionStore,
|
||||
playerTheatreModeByDefaultStore,
|
||||
@@ -126,22 +125,6 @@
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>{$_('layout.player.listenByDefault')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={$playerListenByDefaultStore}
|
||||
onclick={() => playerListenByDefaultStore.set(!$playerListenByDefaultStore)}
|
||||
/>
|
||||
<span></span>
|
||||
</label>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="field no-margin m l">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
|
||||
@@ -77,7 +77,7 @@ button.row:hover {
|
||||
menu.mobile {
|
||||
z-index: 9999 !important;
|
||||
position: fixed !important;
|
||||
top: 30% !important;
|
||||
top: 20% !important;
|
||||
width: 100% !important;
|
||||
background-color: var(--surface-variant) !important;
|
||||
}
|
||||
|
||||
@@ -53,30 +53,24 @@
|
||||
.youtube-theme .shaka-controls-button-panel>* {
|
||||
margin: 0;
|
||||
padding: 3px 8px;
|
||||
color: var(--primary-text);
|
||||
color: #fff;
|
||||
height: 40px;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.youtube-theme .shaka-controls-button-panel>*:hover {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.youtube-theme .shaka-controls-button-panel>*:focus {
|
||||
outline: none;
|
||||
-webkit-box-shadow: inset 0 0 0 2px var(--primary);
|
||||
box-shadow: inset 0 0 0 2px var(--primary);
|
||||
color: var(--surface-bright);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.youtube-theme .shaka-controls-button-panel>*:hover {
|
||||
color: var(--surface-variant);
|
||||
}
|
||||
|
||||
.youtube-theme .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);
|
||||
transition: width 0.2s cubic-bezier(0.4, 0, 1, 1);
|
||||
height: 3px;
|
||||
@@ -86,7 +80,6 @@
|
||||
.youtube-theme .shaka-controls-button-panel .shaka-volume-bar-container:hover,
|
||||
.youtube-theme .shaka-controls-button-panel .shaka-volume-bar-container:focus {
|
||||
display: block;
|
||||
width: 50px;
|
||||
opacity: 1;
|
||||
padding: 0 6px;
|
||||
}
|
||||
@@ -99,7 +92,8 @@
|
||||
|
||||
.youtube-theme .shaka-current-time {
|
||||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
font-size: 1em;
|
||||
color: var(--white-text) !important;
|
||||
}
|
||||
|
||||
.youtube-theme .shaka-seek-bar-container {
|
||||
@@ -151,9 +145,6 @@
|
||||
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;
|
||||
-webkit-user-select: none;
|
||||
right: 10px;
|
||||
bottom: 50px;
|
||||
padding: 8px 0;
|
||||
@@ -307,8 +298,4 @@
|
||||
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);
|
||||
}
|
||||
|
||||
.youtube-theme .shaka-controls-button-panel>*:hover {
|
||||
color: var(--primary) !important;
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
playerAutoPlayStore,
|
||||
playerAutoplayNextByDefaultStore,
|
||||
playerDefaultLanguage,
|
||||
playerListenByDefaultStore,
|
||||
playerProxyVideosStore,
|
||||
playerSavePlaybackPositionStore,
|
||||
playerTheatreModeByDefaultStore,
|
||||
@@ -66,11 +65,6 @@ const persistedStores: { name: string, store: Writable<any>, type: 'string' | 'b
|
||||
store: playerProxyVideosStore,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'listenByDefault',
|
||||
store: playerListenByDefaultStore,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'savePlaybackPosition',
|
||||
store: playerSavePlaybackPositionStore,
|
||||
|
||||
@@ -33,7 +33,6 @@ export const activePageStore: Writable<string | null> = writable('home');
|
||||
export const playerAutoPlayStore = persisted('autoPlay', true);
|
||||
export const playerAlwaysLoopStore = persisted('alwaysLoop', false);
|
||||
export const playerProxyVideosStore = persisted('proxyVideos', true);
|
||||
export const playerListenByDefaultStore = persisted('listenByDefault', false);
|
||||
export const playerSavePlaybackPositionStore = persisted('savePlaybackPosition', true);
|
||||
export const playerTheatreModeByDefaultStore = persisted('theatreModeByDefault', false);
|
||||
export const playerAutoplayNextByDefaultStore = persisted('autoplayNextByDefault', false);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
interfaceAutoExpandDesc,
|
||||
interfaceLowBandwidthMode,
|
||||
playerAutoplayNextByDefaultStore,
|
||||
playerListenByDefaultStore,
|
||||
playerTheatreModeByDefaultStore,
|
||||
playlistSettingsStore,
|
||||
syncPartyConnectionsStore,
|
||||
@@ -67,8 +66,6 @@
|
||||
|
||||
let theatreMode = $state(get(playerTheatreModeByDefaultStore));
|
||||
|
||||
let audioMode = $state(get(playerListenByDefaultStore));
|
||||
|
||||
let segments: Segment[] = $state([]);
|
||||
|
||||
let pauseTimerSeconds: number = $state(-1);
|
||||
@@ -407,13 +404,7 @@
|
||||
<div class={`s12 m12 l${theatreMode ? '12' : '9'}`}>
|
||||
<div style="display: flex;justify-content: center;">
|
||||
{#key data.video.videoId}
|
||||
<Player
|
||||
bind:playerElement
|
||||
bind:segments
|
||||
{data}
|
||||
{audioMode}
|
||||
isSyncing={$syncPartyPeerStore !== null}
|
||||
/>
|
||||
<Player bind:playerElement bind:segments {data} isSyncing={$syncPartyPeerStore !== null} />
|
||||
{/key}
|
||||
</div>
|
||||
|
||||
@@ -493,10 +484,6 @@
|
||||
{/await}
|
||||
|
||||
<div>
|
||||
<button onclick={() => (audioMode = !audioMode)} class:border={!audioMode}>
|
||||
<i>headphones</i>
|
||||
<div class="tooltip">{$_('player.audioOnly')}</div>
|
||||
</button>
|
||||
<button onclick={toggleTheatreMode} class="m l" class:border={!theatreMode}>
|
||||
<i>width_wide</i>
|
||||
<div class="tooltip">{$_('player.theatreMode')}</div>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
LATEST_VERSION = "1.7.17"
|
||||
LATEST_VERSION = "1.7.18"
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user