Started youtube js backup
This commit is contained in:
Generated
+2632
-7
File diff suppressed because it is too large
Load Diff
@@ -26,16 +26,20 @@
|
||||
"@typescript-eslint/eslint-plugin": "^7.16.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"@vite-pwa/sveltekit": "^0.6.5",
|
||||
"buffer": "^6.0.3",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.44.0",
|
||||
"i": "^0.3.7",
|
||||
"npm": "^10.8.3",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"svelte": "^4.2.19",
|
||||
"svelte-check": "^3.8.6",
|
||||
"tslib": "^2.7.0",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.5"
|
||||
"vite": "^5.4.5",
|
||||
"youtubei.js": "^10.4.0"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
@@ -62,4 +66,4 @@
|
||||
"svelte-persisted-store": "^0.11.0",
|
||||
"vidstack": "^1.12.9"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { numberWithCommas } from '$lib/misc';
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { get } from 'svelte/store';
|
||||
import {
|
||||
authStore,
|
||||
@@ -16,13 +18,16 @@ import type {
|
||||
Comments,
|
||||
DeArrow,
|
||||
Feed,
|
||||
Image,
|
||||
Playlist,
|
||||
PlaylistPage,
|
||||
ReturnYTDislikes,
|
||||
SearchSuggestion,
|
||||
Subscription,
|
||||
SynciousProgressModel,
|
||||
Thumbnail,
|
||||
Video,
|
||||
VideoBase,
|
||||
VideoPlay
|
||||
} from './model';
|
||||
|
||||
@@ -68,7 +73,83 @@ export async function getPopular(): Promise<Video[]> {
|
||||
}
|
||||
|
||||
export async function getVideo(videoId: string, local: boolean = false): Promise<VideoPlay> {
|
||||
const resp = await fetchErrorHandle(await fetch(setRegion(buildPath(`videos/${videoId}?local=${local}`))));
|
||||
const resp = await fetch(setRegion(buildPath(`videos/${videoId}?local=${local}`)));
|
||||
if (!resp.ok && Capacitor.getPlatform() !== 'web') {
|
||||
const innertube = (await import('youtubei.js')).Innertube;
|
||||
const youtube = await innertube.create();
|
||||
|
||||
const video = await youtube.getInfo(videoId);
|
||||
|
||||
if (!video.primary_info || !video.secondary_info) {
|
||||
throw new Error('Unable to pull video info from youtube.js');
|
||||
}
|
||||
|
||||
const manifest = await video.toDash();
|
||||
const dashUri = URL.createObjectURL(new Blob([manifest], { type: 'application/dash+xml;charset=utf8' }));
|
||||
|
||||
const descString = video.secondary_info.description.toString();
|
||||
|
||||
let authorThumbnails: Image[];
|
||||
if (video.basic_info.channel_id) {
|
||||
authorThumbnails = (await youtube.getChannel(video.basic_info.channel_id)).metadata.avatar as Image[];
|
||||
} else {
|
||||
authorThumbnails = [];
|
||||
}
|
||||
|
||||
let recommendedVideos: VideoBase[] = [];
|
||||
video.watch_next_feed?.forEach((recommended: Record<string, any>) => {
|
||||
recommendedVideos.push({
|
||||
videoThumbnails: recommended?.thumbnails as Thumbnail[] || [],
|
||||
videoId: recommended?.id || '',
|
||||
title: recommended?.title.toString() || '',
|
||||
viewCountText: numberWithCommas(Number(recommended?.view_count.toString().replace(/\D/g, '') || 0)) || '',
|
||||
lengthSeconds: recommended?.duration?.seconds || 0,
|
||||
author: recommended?.author.name || '',
|
||||
authorId: recommended?.author.id || ''
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
type: 'video',
|
||||
title: video.primary_info.title.toString(),
|
||||
viewCount: Number(video.primary_info.view_count.toString().replace(/\D/g, '')),
|
||||
viewCountText: video.primary_info.view_count.toString(),
|
||||
likeCount: video.basic_info.like_count || 0,
|
||||
dislikeCount: 0,
|
||||
allowRatings: false,
|
||||
rating: 0,
|
||||
isListed: 0,
|
||||
isFamilyFriendly: video.basic_info.is_family_safe || true,
|
||||
genre: video.basic_info.category || '',
|
||||
genreUrl: '',
|
||||
dashUrl: dashUri,
|
||||
adaptiveFormats: [],
|
||||
formatStreams: [],
|
||||
recommendedVideos: recommendedVideos,
|
||||
authorThumbnails: authorThumbnails,
|
||||
captions: [],
|
||||
authorId: video.basic_info.channel_id || '',
|
||||
authorUrl: `/channel/${video.basic_info.channel_id}`,
|
||||
authorVerified: false,
|
||||
description: descString,
|
||||
descriptionHtml: video.secondary_info.description.toHTML() || descString,
|
||||
published: 0,
|
||||
publishedText: video.primary_info.published.toString(),
|
||||
premiereTimestamp: 0,
|
||||
liveNow: false,
|
||||
premium: false,
|
||||
isUpcoming: false,
|
||||
videoId: videoId,
|
||||
videoThumbnails: video.basic_info.thumbnail as Thumbnail[],
|
||||
author: video.basic_info.author || 'Unknown',
|
||||
lengthSeconds: video.basic_info.duration || 0,
|
||||
subCountText: '',
|
||||
keywords: video.basic_info.keywords || [],
|
||||
allowedRegions: []
|
||||
};
|
||||
} else {
|
||||
await fetchErrorHandle(resp);
|
||||
}
|
||||
return await resp.json();
|
||||
}
|
||||
|
||||
|
||||
@@ -234,15 +234,15 @@ export function getBestThumbnail(
|
||||
maxHeightDimension = 360
|
||||
): string {
|
||||
if (images && images.length > 0) {
|
||||
images = images.filter(
|
||||
const imagesFiltered = images.filter(
|
||||
(image) => image.width < maxWidthDimension && image.height < maxHeightDimension
|
||||
);
|
||||
|
||||
if (images.length === 0) {
|
||||
return '';
|
||||
if (imagesFiltered.length === 0) {
|
||||
return images[0].url;
|
||||
}
|
||||
|
||||
images.sort((a, b) => {
|
||||
imagesFiltered.sort((a, b) => {
|
||||
return b.width * b.height - a.width * a.height;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user