Add option to unblur thumbnails in YouTube search results

This commit is contained in:
absidue 2022-02-03 18:23:14 +01:00
parent 5d4485a54e
commit 9670e6ccfb
2 changed files with 65 additions and 3 deletions

View File

@ -2,11 +2,23 @@ import { YouTubeVideo } from '../classes/Video';
import { YouTubePlayList } from '../classes/Playlist';
import { YouTubeChannel } from '../classes/Channel';
import { YouTube } from '..';
import { YouTubeThumbnail } from '../classes/Thumbnail';
import { writeFileSync } from 'fs';
const BLURRED_THUMBNAILS = [
'-oaymwEpCOADEI4CSFryq4qpAxsIARUAAAAAGAElAADIQj0AgKJDeAHtAZmZGUI=',
'-oaymwEiCOADEI4CSFXyq4qpAxQIARUAAIhCGAFwAcABBu0BmZkZQg==',
'-oaymwEiCOgCEMoBSFXyq4qpAxQIARUAAIhCGAFwAcABBu0BZmbmQQ==',
'-oaymwEiCNAFEJQDSFXyq4qpAxQIARUAAIhCGAFwAcABBu0BZmZmQg==',
'-oaymwEdCNAFEJQDSFryq4qpAw8IARUAAIhCGAHtAWZmZkI=',
'-oaymwEdCNACELwBSFryq4qpAw8IARUAAIhCGAHtAT0K10E='
];
export interface ParseSearchInterface {
type?: 'video' | 'playlist' | 'channel';
limit?: number;
language?: string;
unblurNSFWThumbnails?: boolean;
}
export interface thumbnail {
@ -25,6 +37,7 @@ export function ParseSearchResult(html: string, options?: ParseSearchInterface):
if (!options) options = { type: 'video', limit: 0 };
else if (!options.type) options.type = 'video';
const hasLimit = typeof options.limit === 'number' && options.limit > 0;
options.unblurNSFWThumbnails ??= false;
const data = html
.split('var ytInitialData = ')?.[1]
@ -35,13 +48,17 @@ export function ParseSearchResult(html: string, options?: ParseSearchInterface):
const details =
json_data.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents[0]
.itemSectionRenderer.contents;
writeFileSync('results.json', JSON.stringify(details));
for (const detail of details) {
if (hasLimit && results.length === options.limit) break;
if (!detail.videoRenderer && !detail.channelRenderer && !detail.playlistRenderer) continue;
switch (options.type) {
case 'video': {
const parsed = parseVideo(detail);
if (parsed) results.push(parsed);
if (parsed) {
if (options.unblurNSFWThumbnails) parsed.thumbnails.forEach(unblurThumbnail);
results.push(parsed);
}
break;
}
case 'channel': {
@ -51,7 +68,10 @@ export function ParseSearchResult(html: string, options?: ParseSearchInterface):
}
case 'playlist': {
const parsed = parsePlaylist(detail);
if (parsed) results.push(parsed);
if (parsed) {
if (options.unblurNSFWThumbnails && parsed.thumbnail) unblurThumbnail(parsed.thumbnail);
results.push(parsed);
}
break;
}
default:
@ -189,3 +209,36 @@ export function parsePlaylist(data?: any): YouTubePlayList {
return res;
}
function unblurThumbnail(thumbnail: YouTubeThumbnail) {
if (BLURRED_THUMBNAILS.find((sqp) => thumbnail.url.includes(sqp))) {
thumbnail.url = thumbnail.url.split('?')[0];
// we need to update the size parameters as the sqp parameter also included a cropped size
switch (thumbnail.url.split('/').at(-1)!.split('.')[0]) {
case 'hq2':
case 'hqdefault':
thumbnail.width = 480;
thumbnail.height = 360;
break;
case 'hq720':
thumbnail.width = 1280;
thumbnail.height = 720;
break;
case 'sddefault':
thumbnail.width = 640;
thumbnail.height = 480;
break;
case 'mqdefault':
thumbnail.width = 320;
thumbnail.height = 180;
break;
case 'default':
thumbnail.width = 120;
thumbnail.height = 90;
break;
default:
thumbnail.width = thumbnail.height = NaN;
}
}
}

View File

@ -67,6 +67,11 @@ interface SearchOptions {
};
fuzzy?: boolean;
language?: string;
/**
* !!! Before enabling this for public servers, please consider using Discord features like NSFW channels as not everyone in your server wants to see NSFW images. !!!
* Unblurred images will likely have different dimensions than specified in the {@link YouTubeThumbnail} objects.
*/
unblurNSFWThumbnails?: boolean;
}
import { createInterface } from 'node:readline';
@ -184,6 +189,9 @@ async function search(query: string, options?: SearchOptions): Promise<YouTubeVi
*
* - `number` limit : No of searches you want to have.
* - `string` language : Sets language of searched content [ YouTube search only. ], e.g. "en-US"
* - `boolean` unblurNSFWThumbnails : Unblurs NSFW thumbnails. Defaults to `false` [ YouTube search only. ]
* !!! Before enabling this for public servers, please consider using Discord features like NSFW channels as not everyone in your server wants to see NSFW images. !!!
* Unblurred images will likely have different dimensions than specified in the {@link YouTubeThumbnail} objects.
* - `boolean` fuzzy : Whether the search should be fuzzy or only return exact matches. Defaults to `true`. [ for `Deezer` Only ]
* - `Object` source : Contains type of source and type of result you want to have
* ```ts
@ -204,7 +212,8 @@ async function search(
return await yt_search(query, {
limit: options.limit,
type: options.source.youtube,
language: options.language
language: options.language,
unblurNSFWThumbnails: options.unblurNSFWThumbnails
});
else if (options.source.spotify) return await sp_search(query, options.source.spotify, options.limit);
else if (options.source.soundcloud) return await so_search(query, options.source.soundcloud, options.limit);