Fixed watch resuming & added android background play

This commit is contained in:
WardPearce
2024-05-10 11:28:24 +12:00
parent feddd3f2f7
commit eb0c34a67c
8 changed files with 70 additions and 23 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.0.5",
"version": "1.0.6",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.0.5",
"version": "1.0.6",
"private": true,
"scripts": {
"dev": "vite dev",
+33 -13
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import 'vidstack/bundle';
import { App } from '@capacitor/app';
import { SponsorBlock, type Category } from 'sponsorblock-api';
import { onDestroy, onMount } from 'svelte';
import { _ } from 'svelte-i18n';
@@ -12,6 +13,7 @@
instanceStore,
miniPlayerSrcStore,
playerAlwaysLoopStore,
playerAndroidBackgroundPlayStore,
playerAutoPlayStore,
playerDashStore,
playerProxyVideosStore,
@@ -198,20 +200,24 @@
return;
}
if (get(playerSavePlaybackPositionStore)) {
if (get(synciousStore) && get(authStore)) {
try {
player.currentTime = (await getVideoProgress(data.video.videoId))[0].time;
} catch {}
} else {
try {
const playerPos = localStorage.getItem(`v_${data.video.videoId}`);
if (playerPos) {
player.currentTime = Number(playerPos);
}
} catch {}
}
let toSetTime = 0;
if (get(synciousStore) && get(authStore)) {
try {
toSetTime = (await getVideoProgress(data.video.videoId))[0].time;
} catch {}
}
if (get(playerSavePlaybackPositionStore)) {
try {
const playerPos = localStorage.getItem(`v_${data.video.videoId}`);
if (playerPos && Number(playerPos) > toSetTime) {
toSetTime = Number(playerPos);
}
} catch {}
}
if (toSetTime > 0) player.currentTime = toSetTime;
}
function savePlayerPos() {
@@ -242,6 +248,20 @@
savePlayerPos();
player.pause();
player.destroy();
playerPosSet = false;
});
// Background play for Android.
App.addListener('appStateChange', (state) => {
// Very much backwards logic, but for whatever reason
// Calling play() within a conditional breaks background play.
// Maybe a race condition.
player.play();
if (!get(playerAndroidBackgroundPlayStore)) {
player.pause();
}
});
</script>
+20
View File
@@ -13,6 +13,7 @@
interfacePreviewVideoOnHoverStore,
interfaceSearchSuggestionsStore,
playerAlwaysLoopStore,
playerAndroidBackgroundPlayStore,
playerAutoPlayStore,
playerAutoplayNextByDefaultStore,
playerDashStore,
@@ -312,6 +313,25 @@
</nav>
</div>
{#if Capacitor.getPlatform() === 'android'}
<div class="field no-margin">
<nav class="no-padding">
<div class="max">
<div>{$_('layout.player.backgroundPlay')}</div>
</div>
<label class="switch">
<input
type="checkbox"
bind:checked={$playerAndroidBackgroundPlayStore}
on:click={() =>
playerAndroidBackgroundPlayStore.set(!$playerAndroidBackgroundPlayStore)}
/>
<span></span>
</label>
</nav>
</div>
{/if}
{#if Capacitor.getPlatform() !== 'android'}
<div class="field no-margin">
<nav class="no-padding">
@@ -99,6 +99,7 @@
"autoPlayNextByDefault": "Autoplay next by default",
"miniPlayer": "Mini player",
"proxyVideos": "Proxy videos",
"backgroundPlay": "Play audio in background",
"dash": "Dash"
},
"bookmarklet": "Bookmarklet",
@@ -375,10 +375,10 @@
theatreMode = !theatreMode;
}
function downloadFile(downloadUrl: string) {
function downloadFile(url: string, container: string | undefined) {
const anchor = document.createElement('a');
anchor.href = downloadUrl;
anchor.download = downloadUrl.split('/').pop() || 'unknown';
anchor.href = url;
anchor.download = container || 'mp3';
anchor.target = '_blank';
anchor.click();
document.body.removeChild(anchor);
@@ -488,7 +488,10 @@
<div class="tooltip">{$_('player.download')}</div>
<menu class="no-wrap">
{#each data.downloadOptions as download}
<a class="row" href="#download" on:click={() => downloadFile(download.url)}
<a
class="row"
href="#download"
on:click={() => downloadFile(download.url, download.container)}
>{download.title}</a
>
{/each}
@@ -24,20 +24,22 @@ export async function load({ params, url }) {
error(500, errorMessage);
}
let downloadOptions: { title: string; url: string }[] = [];
let downloadOptions: { title: string; url: string; container: string | undefined; }[] = [];
if (!video.hlsUrl) {
video.formatStreams.forEach((format) => {
downloadOptions.push({
title: `${format.type.split(';')[0].trim()} - ${format.qualityLabel} (With audio)`,
url: format.url
url: format.url,
container: format.container
});
});
video.adaptiveFormats.forEach((format) => {
downloadOptions.push({
title: `${format.type.split(';')[0].trim()} - ${format.qualityLabel || format.bitrate + ' bitrate'}`,
url: format.url
url: format.url,
container: format.container
});
});
}
@@ -64,7 +66,7 @@ export async function load({ params, url }) {
if (returnYTDislikesInstance && returnYTDislikesInstance !== '') {
try {
returnYTDislikes = get(returnYtDislikesStore) ? getDislikes(params.slug) : null;
} catch {}
} catch { }
}
return {
+1
View File
@@ -28,6 +28,7 @@ export const playerDashStore = persisted('dashEnabled', false);
export const playerTheatreModeByDefaultStore = persisted('theatreModeByDefault', false);
export const playerAutoplayNextByDefaultStore = persisted('autoplayNextByDefault', false);
export const playerMiniPlayerStore = persisted('miniPlayer', true);
export const playerAndroidBackgroundPlayStore = persisted('androidBackgroundPlayer', true);
export const returnYtDislikesStore = persisted('returnYtDislikes', false);
export const returnYTDislikesInstanceStore: Writable<string | null | undefined> = persisted(