Dash only, gen android potoken on start & fallbackpack patch alert
This commit is contained in:
@@ -8,7 +8,7 @@ const config: CapacitorConfig = {
|
||||
plugins: {
|
||||
CapacitorHttp: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ export async function getPopular(): Promise<Video[]> {
|
||||
|
||||
export async function getVideo(videoId: string, local: boolean = false): Promise<VideoPlay> {
|
||||
const resp = await fetch(setRegion(buildPath(`videos/${videoId}?local=${local}`)));
|
||||
if (!resp.ok && Capacitor.getPlatform() === 'electron' && get(playerYouTubeJsFallback)) {
|
||||
if (!resp.ok && Capacitor.isNativePlatform() && get(playerYouTubeJsFallback)) {
|
||||
return await patchYoutubeJs(videoId);
|
||||
} else {
|
||||
await fetchErrorHandle(resp);
|
||||
|
||||
@@ -102,6 +102,7 @@ export interface VideoPlay extends Video {
|
||||
storyboardHeight: number;
|
||||
storyboardCount: number;
|
||||
}[];
|
||||
fallbackPatch?: 'youtubejs' | 'piped';
|
||||
}
|
||||
|
||||
export interface ReturnYTDislikes {
|
||||
|
||||
@@ -8,13 +8,12 @@
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import type { MediaTimeUpdateEvent, PlayerSrc, VideoSrc } from 'vidstack';
|
||||
import type { MediaTimeUpdateEvent, PlayerSrc } from 'vidstack';
|
||||
import type { MediaPlayerElement } from 'vidstack/elements';
|
||||
import { deleteVideoProgress, getVideoProgress, saveVideoProgress } from './Api';
|
||||
import type { VideoPlay } from './Api/model';
|
||||
import {
|
||||
getBestThumbnail,
|
||||
proxyVideoUrl,
|
||||
pullBitratePreference,
|
||||
videoLength,
|
||||
type PhasedDescription
|
||||
@@ -25,7 +24,6 @@
|
||||
miniPlayerSrcStore,
|
||||
playerAlwaysLoopStore,
|
||||
playerAutoPlayStore,
|
||||
playerDashStore,
|
||||
playerProxyVideosStore,
|
||||
playerSavePlaybackPositionStore,
|
||||
silenceSkipperStore,
|
||||
@@ -47,7 +45,7 @@
|
||||
export let segments: Segment[] = [];
|
||||
|
||||
let src: PlayerSrc = [];
|
||||
let categoryBeingSkipped = '';
|
||||
let snackBarAlert = '';
|
||||
let playerIsLive = false;
|
||||
let playerPosSet = false;
|
||||
|
||||
@@ -312,9 +310,11 @@
|
||||
if (Math.round(player.currentTime) >= Math.round(player.duration)) {
|
||||
return;
|
||||
}
|
||||
categoryBeingSkipped = segment.category;
|
||||
player.currentTime = segment.endTime + 1;
|
||||
ui('#sponsorblock-alert');
|
||||
if (!get(sponsorBlockDisplayToastStore)) {
|
||||
snackBarAlert = `${get(_)('skipping')} ${segment.category}`;
|
||||
ui('#snackbar-alert');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -322,38 +322,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (get(playerDashStore)) {
|
||||
src = [{ src: data.video.dashUrl, type: 'application/dash+xml' }];
|
||||
src = [{ src: data.video.dashUrl, type: 'application/dash+xml' }];
|
||||
|
||||
if (!data.video.fallbackPatch) {
|
||||
if (Capacitor.getPlatform() !== 'electron' || proxyVideos) {
|
||||
(src[0] as { src: string }).src += '?local=true';
|
||||
}
|
||||
|
||||
player.addEventListener('dash-can-play', async () => {
|
||||
if (get(playerAutoPlayStore)) {
|
||||
player.play();
|
||||
}
|
||||
await loadPlayerPos();
|
||||
});
|
||||
} else {
|
||||
let formattedSrc;
|
||||
src = data.video.formatStreams.map((format) => {
|
||||
if (proxyVideos) {
|
||||
formattedSrc = proxyVideoUrl(format.url);
|
||||
} else {
|
||||
formattedSrc = format.url;
|
||||
}
|
||||
const quality = format.size.split('x');
|
||||
return {
|
||||
src: formattedSrc,
|
||||
type: format.type.split(';')[0],
|
||||
height: Number(quality[1]),
|
||||
width: Number(quality[0])
|
||||
};
|
||||
}) as VideoSrc[];
|
||||
|
||||
await loadPlayerPos();
|
||||
}
|
||||
|
||||
player.addEventListener('dash-can-play', async () => {
|
||||
if (get(playerAutoPlayStore)) {
|
||||
player.play();
|
||||
}
|
||||
await loadPlayerPos();
|
||||
});
|
||||
} else {
|
||||
playerIsLive = true;
|
||||
src = [
|
||||
@@ -368,6 +350,11 @@
|
||||
|
||||
const currentTheme = await getDynamicTheme();
|
||||
|
||||
if (data.video.fallbackPatch === 'youtubejs') {
|
||||
snackBarAlert = get(_)('player.youtubeJsFallBack');
|
||||
ui('#snackbar-alert');
|
||||
}
|
||||
|
||||
document.documentElement.style.setProperty(
|
||||
'--media-slider-track-fill-bg',
|
||||
currentTheme['--primary']
|
||||
@@ -488,11 +475,8 @@
|
||||
{/if}
|
||||
</media-player>
|
||||
|
||||
{#if !isEmbed && !$sponsorBlockDisplayToastStore}
|
||||
<div class="snackbar" id="sponsorblock-alert">
|
||||
<span
|
||||
>{$_('skipping')}
|
||||
<span class="bold" style="text-transform: capitalize;">{categoryBeingSkipped}</span></span
|
||||
>
|
||||
{#if !isEmbed}
|
||||
<div class="snackbar" id="snackbar-alert">
|
||||
<span class="bold" style="text-transform: capitalize;">{snackBarAlert}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { bookmarkletSaveToUrl } from '$lib/externalSettings';
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import ui from 'beercss';
|
||||
@@ -24,7 +25,6 @@
|
||||
playerAndroidBackgroundPlayStore,
|
||||
playerAutoPlayStore,
|
||||
playerAutoplayNextByDefaultStore,
|
||||
playerDashStore,
|
||||
playerListenByDefaultStore,
|
||||
playerMiniPlayerStore,
|
||||
playerProxyVideosStore,
|
||||
@@ -126,6 +126,7 @@
|
||||
<form
|
||||
on:submit|preventDefault={() => {
|
||||
authStore.set(null);
|
||||
goto('/');
|
||||
instanceStore.set(ensureNoTrailingSlash(invidiousInstance));
|
||||
}}
|
||||
>
|
||||
@@ -407,24 +408,6 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if Capacitor.getPlatform() !== 'android'}
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>{$_('layout.player.dash')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={$playerDashStore}
|
||||
on:click={() => playerDashStore.set(!$playerDashStore)}
|
||||
/>
|
||||
<span></span>
|
||||
</label>
|
||||
</nav>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
playerAlwaysLoopStore,
|
||||
playerAutoPlayStore,
|
||||
playerAutoplayNextByDefaultStore,
|
||||
playerDashStore,
|
||||
playerListenByDefaultStore,
|
||||
playerMiniPlayerStore,
|
||||
playerProxyVideosStore,
|
||||
@@ -74,11 +73,6 @@ const persistedStores = [
|
||||
store: playerSavePlaybackPositionStore,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'dashEnabled',
|
||||
store: playerDashStore,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'theatreModeByDefault',
|
||||
store: playerTheatreModeByDefaultStore,
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
},
|
||||
"noPlaylists": "No playlists",
|
||||
"unableToLoadComments": "Unable to load comments",
|
||||
"addToPlaylist": "Add to playlist"
|
||||
"addToPlaylist": "Add to playlist",
|
||||
"youtubeJsFallBack": "Local video fallback being used"
|
||||
},
|
||||
"layout": {
|
||||
"interface": "Interface",
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
import type { Image, Thumbnail, VideoBase, VideoPlay } from '$lib/Api/model';
|
||||
import { numberWithCommas } from '$lib/misc';
|
||||
import { androidPoToken } from '$lib/store';
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
export async function patchYoutubeJs(videoId: string): Promise<VideoPlay> {
|
||||
const innertube = (await import('youtubei.js')).Innertube;
|
||||
|
||||
const tokens = await (window as any).electron.generatePoToken();
|
||||
let tokens;
|
||||
if (Capacitor.getPlatform() === 'electron') {
|
||||
tokens = await (window as any).electron.generatePoToken();
|
||||
} else if (Capacitor.getPlatform() === 'android' && get(androidPoToken)) {
|
||||
tokens = get(androidPoToken);
|
||||
} else {
|
||||
throw new Error('This platform cant generate po tokens');
|
||||
}
|
||||
|
||||
const youtube = await innertube.create({
|
||||
visitor_data: tokens.visitorData,
|
||||
po_token: tokens.poToken
|
||||
po_token: tokens.poToken,
|
||||
// Custom fetch method required so capacitor http patch is used
|
||||
fetch: async (input: RequestInfo | URL, init?: RequestInit) => {
|
||||
return window.fetch(input, init);
|
||||
}
|
||||
});
|
||||
|
||||
const video = await youtube.getInfo(videoId);
|
||||
@@ -87,6 +101,7 @@ export async function patchYoutubeJs(videoId: string): Promise<VideoPlay> {
|
||||
lengthSeconds: video.basic_info.duration || 0,
|
||||
subCountText: '',
|
||||
keywords: video.basic_info.keywords || [],
|
||||
allowedRegions: []
|
||||
allowedRegions: [],
|
||||
fallbackPatch: 'youtubejs'
|
||||
};
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import type { DataConnection } from 'peerjs';
|
||||
import { persisted } from 'svelte-persisted-store';
|
||||
import { writable, type Writable } from 'svelte/store';
|
||||
import type { TitleCase } from './misc';
|
||||
import type { PoTokens } from './patches/poTokenAndroid';
|
||||
|
||||
function platformDependentDefault(givenValue: any, defaultValue: any): any {
|
||||
if (typeof givenValue !== 'undefined' && typeof givenValue !== null) {
|
||||
@@ -34,7 +35,6 @@ export const playerAlwaysLoopStore = persisted('alwaysLoop', false);
|
||||
export const playerProxyVideosStore = persisted('proxyVideos', false);
|
||||
export const playerListenByDefaultStore = persisted('listenByDefault', false);
|
||||
export const playerSavePlaybackPositionStore = persisted('savePlaybackPosition', true);
|
||||
export const playerDashStore = persisted('dashEnabled', false);
|
||||
export const playerTheatreModeByDefaultStore = persisted('theatreModeByDefault', false);
|
||||
export const playerAutoplayNextByDefaultStore = persisted('autoplayNextByDefault', false);
|
||||
export const playerMiniPlayerStore = persisted('miniPlayer', true);
|
||||
@@ -99,3 +99,5 @@ export const miniPlayerSrcStore: Writable<{ video: VideoPlay; time: number; } |
|
||||
writable(null);
|
||||
|
||||
export const silenceSkipperStore: Writable<boolean> = persisted('silenceSkipper', false);
|
||||
|
||||
export const androidPoToken: Writable<PoTokens> = writable();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import { bookmarkletLoadFromUrl, loadSettingsFromEnv } from '$lib/externalSettings';
|
||||
import {
|
||||
activePageStore,
|
||||
androidPoToken,
|
||||
authStore,
|
||||
darkModeStore,
|
||||
instanceStore,
|
||||
@@ -157,6 +158,13 @@
|
||||
if (isLoggedIn) {
|
||||
loadNotifications().catch(() => authStore.set(null));
|
||||
}
|
||||
|
||||
// Po token is generated for android on startup
|
||||
if (Capacitor.getPlatform() === 'android') {
|
||||
const getPoToken = (await import('../../lib/patches/poTokenAndroid')).getPoToken;
|
||||
|
||||
androidPoToken.set(await getPoToken());
|
||||
}
|
||||
});
|
||||
|
||||
$: webManifestLink = pwaInfo ? pwaInfo.webManifest.linkTag : '';
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
import { phaseDescription } from '$lib/misc';
|
||||
import {
|
||||
authStore,
|
||||
playerDashStore,
|
||||
playerProxyVideosStore,
|
||||
returnYTDislikesInstanceStore,
|
||||
returnYtDislikesStore
|
||||
@@ -56,7 +55,7 @@ export async function load({ params, url }) {
|
||||
if (
|
||||
import.meta.env.VITE_DEFAULT_DOWNLOAD_ENABLED &&
|
||||
import.meta.env.VITE_DEFAULT_DOWNLOAD_ENABLED.toString().toLowerCase() === 'true' &&
|
||||
!video.liveNow && get(playerDashStore)
|
||||
!video.liveNow
|
||||
) {
|
||||
downloadQualitiesDash = listCombinedQualities(video.dashUrl);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user