add embed.su

This commit is contained in:
Pas 2025-02-02 18:52:00 -07:00
parent 79be492355
commit ad3a9198dc
3 changed files with 111 additions and 0 deletions

View file

@ -74,12 +74,14 @@ import {
VidsrcsuServer8Scraper,
VidsrcsuServer9Scraper,
} from './embeds/vidsrcsu';
import { viperScraper } from './embeds/viper';
import { voeScraper } from './embeds/voe';
import { warezcdnembedHlsScraper } from './embeds/warezcdn/hls';
import { warezcdnembedMp4Scraper } from './embeds/warezcdn/mp4';
import { warezPlayerScraper } from './embeds/warezcdn/warezplayer';
import { webtor1080Scraper, webtor480Scraper, webtor4kScraper, webtor720Scraper } from './embeds/webtor';
import { wootlyScraper } from './embeds/wootly';
import { embedsuScraper } from './sources/embedsu';
import { goojaraScraper } from './sources/goojara';
import { hdRezkaScraper } from './sources/hdrezka';
import { m4uScraper } from './sources/m4ufree';
@ -129,6 +131,7 @@ export function gatherAllSources(): Array<Sourcerer> {
TASFScraper,
mp4hydraScraper,
webtorScraper,
embedsuScraper,
];
}
@ -197,5 +200,6 @@ export function gatherAllEmbeds(): Array<Embed> {
webtor1080Scraper,
webtor720Scraper,
webtor480Scraper,
viperScraper,
];
}

View file

@ -0,0 +1,36 @@
import { flags } from '@/entrypoint/utils/targets';
import { makeEmbed } from '@/providers/base';
import { NotFoundError } from '@/utils/errors';
export const viperScraper = makeEmbed({
id: 'viper',
name: 'Viper',
rank: 182,
async scrape(ctx) {
const apiResponse = await ctx.proxiedFetcher.full<{
source: string;
}>(ctx.url, {
headers: {
Accept: 'application/json',
Referer: 'https://embed.su/',
},
});
if (!apiResponse.body.source) {
throw new NotFoundError('No source found');
}
const playlistUrl = apiResponse.body.source.replace(/^.*\/viper\//, 'https://');
return {
stream: [
{
type: 'hls',
id: 'primary',
playlist: playlistUrl,
flags: [flags.CORS_ALLOWED],
captions: [],
},
],
};
},
});

View file

@ -0,0 +1,71 @@
import { flags } from '@/entrypoint/utils/targets';
import { SourcererEmbed, SourcererOutput, makeSourcerer } from '@/providers/base';
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
import { NotFoundError } from '@/utils/errors';
// custom atob 💀
async function stringAtob(input: string): Promise<string> {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
const str = input.replace(/=+$/, '');
let output = '';
if (str.length % 4 === 1) {
throw new Error('The string to be decoded is not correctly encoded.');
}
for (let bc = 0, bs = 0, i = 0; i < str.length; i++) {
const buffer = str.charAt(i);
const charIndex = chars.indexOf(buffer);
if (charIndex === -1) continue;
bs = bc % 4 ? bs * 64 + charIndex : charIndex;
if (bc++ % 4) {
output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)));
}
}
return output;
}
async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise<SourcererOutput> {
const embedUrl = `https://embed.su/embed/${ctx.media.type === 'movie' ? `movie/${ctx.media.tmdbId}` : `tv/${ctx.media.tmdbId}/${ctx.media.season.number}/${ctx.media.episode.number}`}`;
const embedPage = await ctx.proxiedFetcher<string>(embedUrl, {
headers: {
Referer: 'https://embed.su/',
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
},
});
const vConfigMatch = embedPage.match(/window\.vConfig\s*=\s*JSON\.parse\(atob\(`([^`]+)/i);
const encodedConfig = vConfigMatch?.[1];
if (!encodedConfig) throw new NotFoundError('No encoded config found');
const decodedConfig = JSON.parse(await stringAtob(encodedConfig));
if (!decodedConfig?.hash) throw new NotFoundError('No stream hash found');
const firstDecode = (await stringAtob(decodedConfig.hash))
.split('.')
.map((item) => item.split('').reverse().join(''));
const secondDecode = JSON.parse(await stringAtob(firstDecode.join('').split('').reverse().join(''))) as Array<{
name: string;
hash: string;
}>;
if (!secondDecode?.length) throw new NotFoundError('No servers found');
ctx.progress(50);
const embeds: SourcererEmbed[] = secondDecode.map((server) => ({
embedId: 'viper',
url: `https://embed.su/api/e/${server.hash}`,
}));
ctx.progress(90);
return { embeds };
}
export const embedsuScraper = makeSourcerer({
id: 'embedsu',
name: 'embed.su',
rank: 229,
flags: [flags.CORS_ALLOWED],
scrapeMovie: comboScraper,
scrapeShow: comboScraper,
});