From 2174a992c27acf975b94b1ec1377ac342ff14292 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Mon, 11 Aug 2025 11:07:51 -0600 Subject: [PATCH] update animetsu --- src/providers/all.ts | 4 + src/providers/embeds/animetsu.ts | 123 ++++++++++-------------------- src/providers/sources/animetsu.ts | 2 +- 3 files changed, 44 insertions(+), 85 deletions(-) diff --git a/src/providers/all.ts b/src/providers/all.ts index cab6dc9..b230c3d 100644 --- a/src/providers/all.ts +++ b/src/providers/all.ts @@ -19,6 +19,7 @@ import { vidsrcsuScraper } from '@/providers/sources/vidsrcsu'; import { vidsrcvipScraper } from '@/providers/sources/vidsrcvip'; import { zoechipScraper } from '@/providers/sources/zoechip'; +import { AnimetsuEmbeds } from './embeds/animetsu'; import { autoembedBengaliScraper, autoembedEnglishScraper, @@ -64,6 +65,7 @@ import { warezPlayerScraper } from './embeds/warezcdn/warezplayer'; import { zunimeEmbeds } from './embeds/zunime'; import { EightStreamScraper } from './sources/8stream'; import { animeflvScraper } from './sources/animeflv'; +import { animetsuScraper } from './sources/animetsu'; import { cinemaosScraper } from './sources/cinemaos'; import { coitusScraper } from './sources/coitus'; import { cuevana3Scraper } from './sources/cuevana3'; @@ -122,6 +124,7 @@ export function gatherAllSources(): Array { vidifyScraper, rivestreamScraper, zunimeScraper, + animetsuScraper, ]; } @@ -178,5 +181,6 @@ export function gatherAllEmbeds(): Array { ...vidifyEmbeds, ...rivestreamEmbeds, ...zunimeEmbeds, + ...AnimetsuEmbeds, ]; } diff --git a/src/providers/embeds/animetsu.ts b/src/providers/embeds/animetsu.ts index 2026c83..3a3b5d1 100644 --- a/src/providers/embeds/animetsu.ts +++ b/src/providers/embeds/animetsu.ts @@ -6,51 +6,6 @@ import { EmbedOutput, makeEmbed } from '../base'; const ANIMETSU_SERVERS = ['pahe', 'zoro', 'zaza', 'meg', 'bato'] as const; -function getFirstStreamUrlFromSources(sources: any): string | null { - if (Array.isArray(sources)) { - for (const source of sources) { - if (typeof source?.url === 'string') { - return source.url; - } - } - return null; - } - if (typeof sources?.url === 'string') { - return sources.url; - } - return null; -} - -function findFirstM3U8Url(input: unknown): string | null { - const visited = new Set(); - - function dfs(node: unknown): string | null { - if (node == null) return null; - if (visited.has(node)) return null; - if (typeof node === 'object') visited.add(node); - - if (typeof node === 'string' && node.includes('http')) return node; - - if (Array.isArray(node)) { - for (const element of node) { - const found = dfs(element); - if (found) return found; - } - return null; - } - - if (typeof node === 'object') { - for (const value of Object.values(node as Record)) { - const found = dfs(value); - if (found) return found; - } - } - return null; - } - - return dfs(input); -} - const baseUrl = 'https://backend.animetsu.to'; const headers = { referer: 'https://animetsu.to/', @@ -60,24 +15,6 @@ const headers = { 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', }; -async function resolveTiddiesUrl( - ctx: { proxiedFetcher: (url: string, options?: any) => Promise }, - url: string, - extraHeaders: Record, -) { - const jsonRes = await ctx.proxiedFetcher(url, { - headers: { - ...headers, - ...extraHeaders, - }, - }); - - if (typeof jsonRes?.url === 'string') return jsonRes.url; - if (typeof jsonRes === 'string' && jsonRes.includes('m3u8')) return jsonRes; - - throw new NotFoundError('Could not resolve tiddies link'); -} - export function makeAnimetsuEmbed(id: string, rank: number = 100) { return makeEmbed({ id: `animetsu-${id}`, @@ -106,47 +43,65 @@ export function makeAnimetsuEmbed(id: string, rank: number = 100) { console.log('Animetsu API Response:', JSON.stringify(res, null, 2)); - const resAny: any = res as any; + const source = res?.sources?.[0]; + if (!source?.url) throw new NotFoundError('No source URL found'); - let playlistUrl: string | null = - getFirstStreamUrlFromSources(resAny?.sources) ?? - (typeof resAny?.url === 'string' ? resAny.url : null) ?? - findFirstM3U8Url(resAny); - - console.log('Extracted playlistUrl:', playlistUrl); - - if (!playlistUrl) throw new NotFoundError('No playlist URL found'); - - if (playlistUrl.includes('tiddies.animetsu.to')) { - playlistUrl = await resolveTiddiesUrl(ctx, playlistUrl, resAny?.sources?.headers ?? {}); - } - - if (!playlistUrl) throw new NotFoundError('No playlist URL found after resolving tiddies'); + const streamUrl = source.url; + const sourceType = source.type; + const sourceQuality = source.quality; let streamHeaders = { ...headers }; // change headers if the url has backend.animetsu.cc bc they tried to make it harder - if (playlistUrl.includes('backend.animetsu.cc')) { + if (streamUrl.includes('animetsu.cc')) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { referer, origin, ...restHeaders } = streamHeaders; streamHeaders = { ...restHeaders, - Host: 'backend.animetsu.cc', - Origin: 'https://backend.animetsu.cc', - Referer: 'https://backend.animetsu.cc', + origin: 'https://backend.animetsu.cc', + referer: 'https://backend.animetsu.cc/', }; } ctx.progress(100); + if (sourceType === 'mp4') { + let qualityKey: string | number = 'unknown'; + if (sourceQuality) { + const qualityMatch = sourceQuality.match(/(\d+)p?/); + if (qualityMatch) { + qualityKey = parseInt(qualityMatch[1], 10); + } + } + + return { + stream: [ + { + id: 'primary', + captions: [], + qualities: { + [qualityKey]: { + type: 'mp4', + url: streamUrl, + }, + }, + type: 'file', + headers: streamHeaders, + flags: [], + }, + ], + }; + } + return { stream: [ { id: 'primary', type: 'hls', - playlist: playlistUrl, + playlist: streamUrl, headers: streamHeaders, - flags: [flags.CORS_ALLOWED], + flags: [], captions: [], }, ], diff --git a/src/providers/sources/animetsu.ts b/src/providers/sources/animetsu.ts index 44c2239..61bbc60 100644 --- a/src/providers/sources/animetsu.ts +++ b/src/providers/sources/animetsu.ts @@ -48,7 +48,7 @@ async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promis export const animetsuScraper = makeSourcerer({ id: 'animetsu', name: 'Animetsu', - rank: 111, // change this yeah? + rank: 112, flags: [], scrapeShow: comboScraper, });